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?
2 Answers
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.
- 421
- 5
- 9
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:
https://github.com/axiomzen/eth-random
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;
}
}
- 225
- 1
- 9
now, which should be the same asblock.timestamp. – javahippie Dec 06 '17 at 12:13block.blockhash(block.number)always returns 0x0 so it doesn't add any randomness. https://blog.positive.com/predicting-random-numbers-in-ethereum-smart-contracts-e5358c6b8620 – medvedev1088 Feb 21 '18 at 15:41