The Ethereum blockchain being deterministic, imposes certain difficulties for those who write their own pseudo-random number generator (PRNG).
If you are using the block variables like block.coinbase, block.difficulty, block.timestamp etc. as the entropy source, they can be manipulated by miners. Therefore, they cannot be used as a source of entropy. As the block variables are obviously shared within the same block, you can easily use internal messages to yield the same outcome.
Other methods including the usage of blockhash of current or some past block, or blockhash of a past block combined with a private seed.
block.blockhash(block.number) function is used in these cases. However, at the moment of transaction execution in the EVM, the blockhash of the block that is being created is not yet known for obvious reasons and the EVM will always yield zero. If we are trying it with the blockhash of a previous block, an attacker can make an exploit contract with the same code in order to call the target contract via an internal message. The “random” numbers for the two contracts will be the same.
Even if we combine the blockhash with a private seed, the blockchain must not be used to store secrets in plaintext.
Some areas that are worth exploring:
- External oracles
With External oracles like Oraclize, smart contracts can request data from web APIs such as currency exchange rates, weather forecasts, and stock prices (like random.org). The key drawback of this approach is that it is centralized.
Instead of Oraclize, we can also use BTCRelay which is a bridge between Ethereum and Bitcoin blockchains. Using BTCRelay, smart contracts in the Ethereum blockchain can request future Bitcoin block hashes and use them as a source of entropy.
Signidice is an algorithm based on cryptographic signatures that can be used for random number generation in smart contracts involving only two parties: the player and the house.