How can I generate a random number within the smart contract without external oracles. Maybe based on the block number or is there any other element that can be used for that?


There are some approaches on GitHub, this one looks promising and seems, as you have suggested, to rely on the block timestamp to generate random numbers:


The contract itself is rather simple (although I cannot estimate how expensive its execution is):

pragma solidity ^0.4.4;

contract Random {
  uint64 _seed = 0;

  // return a pseudo random number between lower and upper bounds
  // given the number of previous blocks it should hash.
  function random(uint64 upper) public returns (uint64 randomNumber) {
    _seed = uint64(sha3(sha3(block.blockhash(block.number), _seed), now));
    return _seed % upper;
  • This appears to be the block hash, which isn't ideal but it's better than the block timestamp, which can be manipulated by the miner at no cost. – Edmund Edgar Dec 6 '17 at 11:38
  • I think it is not just the block hash. They are also having a call to now, which should be the same as block.timestamp. – javahippie Dec 6 '17 at 12:13
  • Sorry, yes, you're right, I missed that. This is a bad idea, they'd be safer with just the block hash. – Edmund Edgar Dec 6 '17 at 12:42
  • 1
    I agree with you, and in a way also the maintainers of the Repo agree: "Firstly, the block timestamp is not terribly unpredictable and yet it's one of the strongest sources of entropy available in the blockchain along with contract's internal seed [..] If security is a main focus, it may be best to look into purchasing an oracle solution" – javahippie Dec 6 '17 at 12:49
  • block.blockhash(block.number) always returns 0x0 so it doesn't add any randomness. blog.positive.com/… – medvedev1088 Feb 21 '18 at 15:41

You probably shouldn't do this

By default, just don't.

Why you shouldn't

Using on-chain data (eg. the block number) as entropy to generate a random number gives an advantage to miners. For example, a miner can decide to not integrate a transaction to its next wanna-be block, because the outcome is not in its favor. The transaction will be integrated later in another block, thus leading to a second chance for the miner.

There are other examples of how such procedure can be broken.

When it might be okay

To quote this answer:

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.

In other words, random number generation without external calls can only be used for low stake applications.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.