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

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? 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? May 8, 2018 at 20:46
  • Yes, it requires at least two participants.
    – Sandwich
    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)
    – MEE
    May 16, 2018 at 13:54
  • source????????? 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? 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
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 that you have read and understand our privacy policy and code of conduct.

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