# How can I generate random numbers inside a smart contract?

If I'm building a smart contract that requires random numbers (e.g. games of chance), how do I reliably generate randomness inside a smart contract?

• Great and simple question that comes up all the time! I would have thought it comes up in the dice example smart contract on github, but I guess not: github.com/EOSIO/eos/tree/master/contracts/dice May 8, 2018 at 18:30
• @Soleone I find that contract hard to follow. A succinct discussion of the issues with generating randomness in smart contracts would go along way to helping new developers understand the issue. May 8, 2018 at 18:32

One method of achieving pseudo-randomness can be accomplished by comparing hashes

``````// variable to get result from hashing all players hashes and secrets
checksum256 result;
// hash the contents in memory, starting at game.player1 and spanning sizeof(player)*2
bytes sha256( (char *)&game.player1, sizeof(player)*2, &result);
// compares first and second 4 byte chunks in result to determine a winner
int winner = result.hash[1] < result.hash[0] ? 0 : 1;
// report appropriate winner
if( winner ) { report_winner(game.player1); } else {   report_winner(game.player2); }
``````
• What is the mathematical and theoretical underpinnings for this approach? And where do the hashes and secrets come from in this example? May 8, 2018 at 20:31
• This approach seems like it would only work if I am playing a game against other players. How do I deal with generating randomness in a single player game, such as Solitaire? May 8, 2018 at 20:46
• Yes, it requires at least two participants. May 11, 2018 at 6:45
• Hi, please format code as code block by indenting it with 4 spaces (or press Ctrl+K or the `{}` button in the editor) May 16, 2018 at 13:54
• source????????? Aug 11, 2020 at 15:34

Randomness without risk of anyone "knowing" it requires a three step process:

1. both parties commit hashes of secrets hash(secreta) and hash(secretb)
2. both parties reveal secrets secreta and secretb
3. hash(secreta + secretb)

If either party fails to reveal then the process fails.

• What about the possibility of using a future block as seed data to hash, then having the "users" commit to the random transaction before the block is produced? May 13, 2018 at 6:04
• Did you get any progress doing like that way? Do have any code example of getting the block number? May 17, 2018 at 15:15
• @JoshuaShope the future still can be controlled and gamed by BP and participant of network. That is not real randomness
– han
Jul 24, 2019 at 9:53

EOS Knights implements a random generator, which, at the moment, is MIT-licensed:

``````// Linear Congruential Generator
class random_gen {
private:
static random_gen instance;

const uint32_t a = 1103515245;
const uint32_t c = 12345;
uint64_t seed = 0;

public:
static random_gen& get_instance(account_name player) {
if (instance.seed == 0) {
instance.seed = current_time() + player;
}
return instance;
}

uint32_t range(uint32_t to) {
checksum256 result;
sha256((char *)&seed, sizeof(seed), &result);
seed = result.hash[1];
seed <<= 32;
seed |= result.hash[0];
return (uint32_t)(seed % to);

// old implementation
// seed = (a * seed + c) % 0x7fffffff;
// return (uint32_t)(seed % to);
}
};
``````
• Jun 5, 2019 at 11:23

According to this github issue, using pseudo-random number generation libraries inside the contract would break the consesus because the execution of smart contracts must be deterministic. That means that all nodes executing the same transaction must always get the same output.

Furthermore, you can deterministically derive random numbers from secret data you can pass into the contract. See for example the deterministic way EOSbet generates a random number between 0-100 from a hash which was created from hashing a secret.

• However, the way EOSbet does it appears to be manipulatable by a malicious user: medium.com/@peckshield/… May 13, 2019 at 5:51