26

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?

3
  • 1
    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
    – Soleone
    Commented May 8, 2018 at 18:30
  • 2
    @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. Commented May 8, 2018 at 18:32
  • developers.eos.io/eosio-cpp/v1.0.0/docs/…
    – Nat
    Commented Jul 10, 2018 at 21:19

4 Answers 4

18

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); }
5
  • 1
    What is the mathematical and theoretical underpinnings for this approach? And where do the hashes and secrets come from in this example? Commented May 8, 2018 at 20:31
  • 1
    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? Commented May 8, 2018 at 20:46
  • Yes, it requires at least two participants.
    – Sandwich
    Commented 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) Commented May 16, 2018 at 13:54
  • source????????? Commented Aug 11, 2020 at 15:34
15

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.

3
  • 1
    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? Commented 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? Commented 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
    Commented Jul 24, 2019 at 9:53
4

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);
    }
};
1
4

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.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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