A 3-Way Handshake Approach to Blockchain Random Number Generation

Entropy in a Deterministic System?

In our recent articles on crypto gaming in general and on the CryptoFights game, we have argued that the Blockchain is the ideal platform for ensuring fairness and traceability in computer games.

However, the openness of the Blockchain also present some challenges for game developers. Most games rely on some form of randomness to determine the outcome of certain actions, like rolling a dice in our case.

Generating random numbers (or pseudo-random numbers) is one of the harder things to do on the Blockchain, as the underlying system is both open and deterministic. The determinism of the Blockchain has many benefits, but prohibits the entropy required to make a pseudo-random number as random as possible. In other words, it’s very difficult to roll a dice without knowing the outcome beforehand.

Let’s first discuss some common approaches to generating random numbers on the Ethereum blockchain, before talking about our approach, which we believe to be innovative and secure.

Using a “secret” Seed for Entropy

Some smart contracts simply use a private variable that holds a large “secret” number, to be used as a seed for random number generation. This is often combined with one of the other approaches we will discuss below. However, nothing is private on the Blockchain. Solidity, the language used for most smart contract development, supports private variables, but the Ethereum virtual machine allows you to look at storage anyway.

As an exercise, here is the source code of a simple contract I have deployed on the Ropston test network at address 0x44496874e5200e038f7738fb5eca1042bfefe840:

pragma solidity ^ 0.4.18; 
contract  MeaningOfLife  {   
uint private theMeaningOfLife;
function MeaningOfLife(uint x) public {
theMeaningOfLife = x;

Try to figure out the meaning of life by reading the “private” storage. Here’s a hint: if you have Metamask installed, investigate how to use web3.eth.getStorageAt() from your browsers JavaScript console.

Using a Blockchain Variable as a Seed

One popular technique is using the changing values of a blockchain related variable available to the smart contract as a source of entropy for random number generation. This can be the timestamp of the current block, the blockhash of the previous block or some other variable, such as block difficulty.

The most commonly used value is the hash of the previous block. A common mistake that has been exploited in some gambling contract is to use the blockhash of the current block. As this is not known yet, the Ethereum Virtual Machine always returns 0, meaning the seed is obvious to a knowledgeable player. For this reason, the previous blockhash is a better, but still flawed alternative.

The most commonly cited objection to using blockhashes and similar variables as a source of entropy, is that the miner can manipulate them.

However, there is an even bigger problem: These variables have the same value for all transactions in the block. If a player invokes the contract through an internal call, i.e. from another smart contract, the caller has access to the values and can pre-compute the random number.

Using a Future Blockhash as a Source of Entropy

For the above reason, a safer method consists in using the hash of a future block as a source of entropy. As the blockhash of some future block is not known at the time a player commits a number, it can be combined with committed number to generate randomness, without the player being able to influence the results.

This is safer, but still does not solve the problem of miner-manipulation. Of course, basic game theory suggests, that any prize would have to be large enough to represent an incentive for a miner to participate and cheat in a game.

Using an Oracle

Another approach is using an off-chain service for random number generation. Services, such as Oracalize can be used to access off-chain service. Whilst oracles are very useful to get external data to smart contracts, they introduce trusted third parties, which in certain cases defeats the purpose of using a blockchain. We have argued for running critical decision-making of games on the blockchain for transparency reasons. If we delegate randomness to off-chain services, we might as well run the game on a traditional server backend.

The CryptoFights 3-Way Handshake Approach

As you may recall from previous articles, in CryptoFIghts, players own heroes that are put to fight in a virtual arena. Battles are modeled on traditional role-playing games. The process of rolling the dice to determine randomness has some influence on the outcome of the battle, although there are further strategy related aspects taken into account.

The CryptoFights randomness solution is based on a commit/reveal pattern with a twist. The process is as follows:

  1. The challenger of a battle creates a large random number (256-bit) off-chain.
  2. The challenger submits a hash value of his random number to the battle contract.
  3. The opponent creates his own random number off-chain.
  4. The opponent submits his random number to the contract (unhashed). With this process, the challenge is accepted.
  5. The battle commences if one of the following occurs: a) The challenger responds by revealing his random number. Of course, hashing this number has to compute to the value submitted earlier b) If the challenger does not respond within a certain time (measured in the number of mined blocks), the opponent may start the battle. The challenger loses his right to contribute randomness and the blockhash of the previous block is used instead.
  6. The battle contract performs an XOR operation on the two numbers supplied and uses the result as a seed for the random number generation.

Using this model, the contract defaults to a slightly lower security model if one of the parties does not collaborate. However, the lower security model can only benefit the collaborating party, providing an incentive for challengers to collaborate.

We believe this system to be fair and un-exploitable, whilst being efficient and practical at the same time.

Signing up for beta use is now possible at cryptofights.io. See you in the arena!