24

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?

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); }
| improve this answer | |
  • 1
    What is the mathematical and theoretical underpinnings for this approach? And where do the hashes and secrets come from in this example? – John Haager May 8 '18 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? – John Haager May 8 '18 at 20:46
  • Yes, it requires at least two participants. – Sandwich May 11 '18 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 '18 at 13:54
  • source????????? – nicholas labrecque 2 days ago
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.

| improve this answer | |
  • 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? – Joshua Shope May 13 '18 at 6:04
  • Did you get any progress doing like that way? Do have any code example of getting the block number? – Leo Ribeiro May 17 '18 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 '19 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);
    }
};
| improve this answer | |
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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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