[Ethereum] When can BLOCKHASH be safely used for a random number? When would it be unsafe

contract-designcryptographyevmSecurityyellow-paper

I've seen more complicated ways for a contract to generate a random number. But the Ethereum Yellow Paper itself suggests a "trivial solution" using the BLOCKHASH opcode (see below, bold is mine).

If a contract just needs a couple of random numbers (not hundreds), how secure would this method be? What example use cases would this method be satisfactory? Which use cases are attackable in a practical way, if this method was used?

Random Numbers. Providing random numbers within a deterministic system is, naturally, an impossible task. However, we can approximate
with pseudo-random numbers by utilising data which is generally
unknowable at the time of transacting. Such data might include the
block’s hash, the block’s timestamp and the block’s beneficiary
address. In order to make it hard for malicious miner to control those
values, one should use the BLOCKHASH operation in order to use hashes
of the previous 256 blocks as pseudo-random numbers. For a series of
such numbers a trivial solution would be to add some constant amount
and hashing the result.

Best Answer

Just to clarify, the "trivial solution" referred to is about how to produce a series of random numbers from a single random seed.

As a general rule, BLOCKHASH can only be safely used for a random number if the total amount of value resting on the quality of that randomness is lower than what a miner earns by mining a single block.

To see why this is the case, we can imagine the opposite situation, where a value of perhaps millions rests on the randomness obtained from a BLOCKHASH operation (for example, to select a lottery winner who will win that amount). Due to the large amount of money at stake, a well-funded attacker would have a financial incentive to buy a ticket and then generate many different alternative blocks (perhaps using millions of AWS instances for a short time period but at a substantial cost) for the block height from which the drawing is to be computed. When a block is found with a hash that will result in the miner's ticket winning, the miner then immediately mines more blocks on top of this one (to ensure it succeeds) and then submits it to the network, allowing them to guarantee themselves the prize. This operation might be very expensive, but as long as the prize is big enough it will still be a profitable attack to perform.

This is an extreme example, but the boring version of this attack where a miner just so happens to mine that one block, checks if they win, and then throws away the answer if they don't, would still be able to double their overall odds of winning and is still an "unfair" statistical manipulation, albeit a weak one. However, if throwing the block away costs more than anyone can hope to gain, it is highly unlikely that anyone will perform the attack, thus our general rule.

Related Topic