🎫Provably Fair

Verifying the SHFL Lottery Results

This guide will help you independently verify the fairness of the lottery draw using the provided information and code. You'll learn what each component means and how to use them to reproduce the lottery results.


Contents

  1. Understanding the Components

    • Block Number

    • Bitcoin Hash

    • CSV Hash

    • Server Seed

    • Server Seed (hashed)

  2. Verification Steps

    • Before the Draw (Seed Blank)

    • After the Draw (Seed Filled In)

  3. Running the Code

    • Verifying the CSV Hash

    • Generating the Lottery Results

  4. Conclusion & Appendix


Understanding the Components

Before we begin, let's understand each of the elements provided:

1. Block Number

  • What It Is: A specific block in the Bitcoin blockchain identified by its number.

  • Purpose: Serves as a public, unpredictable source of randomness because its hash is unknown until the block is mined.

  • Example: Block Number: 863041

2. Bitcoin Hash

  • What It Is: The hash of the Bitcoin block specified by the Block Number.

  • Purpose: Provides a random value that cannot be predicted or manipulated by anyone.

  • Example: Bitcoin Hash: 000000000000000000018d6b5c7eb685185573b5fc38c41715ee2a84accc321c

3. CSV Hash

  • What It Is: A SHA-256 hash of the CSV file containing all participants.

  • Purpose: Ensures the participant list hasn't been altered after the hash was published.

  • Example: CSV Hash: e32157d1b2c37d52fa29431e4538daacc6b4b7c93ea0c0e60c3da3657af2443e

4. Server Seed

  • What It Is: A secret value generated by the lottery provider before the draw.

  • Purpose: Used in combination with the Bitcoin Hash to generate the lottery results.

  • Example (after the draw): Server Seed: 472216619e50c0a41a5cceff86e78a5c0da023fd9836f509eaa3c46c7872c3dc

5. Server Seed (hashed)

  • What It Is: The SHA-256 hash of the Server Seed.

  • Purpose: Published before the draw to commit to the Server Seed without revealing it.

  • Example: Server Seed (hashed): 5f480fe8a281ac23e473d8bb4c8bda65046bd7186ddc1ce247e247d3c8d324b5


Verification Steps

Before the Draw (Seed Blank)

At this stage, the Server Seed is hidden, and only its hash is available. Here's what you can do:

After Entries are closed

  1. Verify the CSV Hash

    • Purpose: Ensure the participant list is fixed and cannot be changed after the draw.

    • How-To:

      • Download the draw.csv file via the provably fair tab.

      • Compute its SHA-256 hash.

      • Compare it with the provided CSV Hash.

  2. Note the Block Number and Server Seed (hashed)

    • Block Number: 863041

    • Server Seed (hashed): 5f480fe8a281ac23e473d8bb4c8bda65046bd7186ddc1ce247e247d3c8d324b5

  3. Wait for the Draw

    • After the specified Bitcoin block is mined, the Bitcoin Hash will be known.

    • Shuffle will reveal the Server Seed.

After the Draw (Seed Filled In)

Now that the Server Seed is revealed, you can fully verify the lottery results.

  1. Verify the Server Seed

    • Purpose: Ensure the Server Seed wasn't altered after the draw.

    • How-To:

      • Compute the SHA-256 hash of the revealed Server Seed.

      • Compare it with the pre-published Server Seed (hashed).

      • They should match.

  2. Verify the Bitcoin Hash

    • Purpose: Confirm that the correct Bitcoin Hash was used.

    • How-To:

      • Use a Bitcoin blockchain explorer to look up Block Number 863041.

      • Verify that the Block Hash matches the provided Bitcoin Hash.

  3. Reproduce the Lottery Results

    • Purpose: Independently generate the lottery results to ensure fairness.

    • How-To:

      • Use the provided code with the Server Seed and Bitcoin Hash.

      • Generate the lottery numbers.

      • Compare them with the official results.


Running the Code

Verifying the CSV Hash

Purpose: To ensure the participant list (draw.csv) hasn't been altered.

Steps:

  1. Download the CSV File

    • Obtain the draw.csv file from the lottery website.

  2. Compute the SHA-256 Hash

    • Option A: Using the Provided Node.js Script

      // Save this code as hashCSVFile.js
      import * as fs from 'fs';
      import * as crypto from 'crypto';
      
      function hashCSVFile(filePath) {
        return new Promise((resolve, reject) => {
          const hash = crypto.createHash('sha256');
          const stream = fs.createReadStream(filePath);
      
          stream.on('data', data => {
            hash.update(data);
          });
      
          stream.on('end', () => {
            const fileHash = hash.digest('hex');
            resolve(fileHash);
          });
      
          stream.on('error', error => {
            reject(error);
          });
        });
      }
      
      // Example usage
      const csvFilePath = 'draw.csv';
      
      hashCSVFile(csvFilePath)
        .then(hash => {
          console.log(`Hash of the CSV file: ${hash}`);
        })
        .catch(error => {
          console.error('Error hashing the file:', error);
        });
      • How to Run:

        • Ensure you have Node.js installed.

        • Save the code as hashCSVFile.js.

        • Place hashCSVFile.js and draw.csv in the same folder.

        • Open a terminal, navigate to the folder, and run:

          node hashCSVFile.js
        • The script will output the hash of the CSV file.

    • Option B: Using Command Line

      • On macOS or Linux:

        shasum -a 256 draw.csv
      • On Windows:

        certutil -hashfile draw.csv SHA256
  3. Compare the Hashes

    • Computed CSV Hash: (This will be the output from the script or command.)

    • Provided CSV Hash: e32157d1b2c37d52fa29431e4538daacc6b4b7c93ea0c0e60c3da3657af2443e

    • Result: If they match, the participant list is verified.

Generating the Lottery Results

Purpose: To reproduce the lottery draw and verify its fairness.

Steps:

  1. Prepare the Code

    Option A: Using an Online Editor

    • Website: PlayCode.io

    • Instructions:

      • In the editor, paste the following code into the scripts.js file:

        import { createHash, createHmac } from 'crypto';
        
        const bitcoinHash = '000000000000000000010d9b10b5e83643dc4ec360b262d1ec4240c18675ff7d';
        const seed = '7294d90bddbfc336e846121218c607d00d389116a8d2b3305e31c2da82246e6b';
        
        function fisherYatesShuffle(array, hash) {
          const result = [...array];
          let hashOffset = 0;
          for (let i = result.length - 1; i > 0; i--) {
            const value = hash.readUInt32BE(hashOffset % (hash.length - 3));
            hashOffset += 4;
            const j = value % (i + 1);
            [result[i], result[j]] = [result[j], result[i]];
          }
          return result;
        }
        
        function generateLotteryResults(seed, blockHash) {
          const hash = createHmac('sha256', seed).update(blockHash).digest();
        
          const shuffledPrimaryBalls = fisherYatesShuffle(
            Array.from({ length: 55 }, (_, i) => i + 1),
            hash,
          );
        
          const shuffledPowerBalls = fisherYatesShuffle(
            Array.from({ length: 18 }, (_, i) => i + 1),
            hash,
          );
        
          return [...shuffledPrimaryBalls.slice(0, 5), shuffledPowerBalls[0]];
        }
        
        console.log('hashed seed:', createHash('sha256').update(seed).digest('hex'));
        console.log('generated results are:', generateLotteryResults(seed, bitcoinHash));
      • Module Installation:

        • If prompted with imported module 'crypto-browserify' from '' is not installed., click INSTALL MODULE.

      • Run the Code:

        • Click the Run button.

      • View the Results:

        • The console at the bottom will display the lottery results.

  2. Understanding the Results

    • Expected Output:

      Generated Lottery Results:
      Primary Balls: [36, 7, 23, 45, 37]
      Power Ball: 14
    • Compare with Official Results:

      • If the generated numbers match the official lottery results, the draw is verified as fair.


Conclusion

By following this guide, you've:

  • Verified the Integrity of the Participant List:

    • Ensured that the draw.csv file hasn't been altered by matching its hash with the provided CSV Hash.

  • Confirmed the Authenticity of the Bitcoin Hash:

    • Verified that the Bitcoin Hash corresponds to Block Number 863041.

  • Validated the Server Seed:

    • Confirmed that the Server Seed was not changed after the draw by comparing its hash to the pre-published Server Seed (hashed).

  • Reproduced the Lottery Results:

    • Independently generated the lottery numbers and matched them with the official results, confirming fairness.

This process ensures that the Shuffle lottery draw was conducted fairly and transparently.


Appendix: Understanding the Code

For those interested, here's a brief explanation of how the code works:

  • Combining Server Seed and Bitcoin Hash:

    const hash = createHmac('sha256', Buffer.from(seed, 'hex'))
      .update(Buffer.from(blockHash, 'hex'))
      .digest();
    • Explanation:

      • Uses HMAC-SHA256 to combine the Server Seed and Bitcoin Hash to produce a unique hash.

      • Server Seed: Acts as the secret key.

      • Bitcoin Hash: Acts as the message.

      • The result is a 32-byte hash used as the source of randomness.

  • Fisher-Yates Shuffle Algorithm:

    function fisherYatesShuffle(array, hash) {
      // Shuffles the array using the hash as the randomness source
    }
    • Explanation:

      • Randomly shuffles an array of numbers (primary balls or power balls).

      • Randomness Source: The hash generated from combining the Server Seed and Bitcoin Hash.

      • Deterministic Process: Using the same inputs will always produce the same shuffled array.

  • Generating the Lottery Results:

    const shuffledPrimaryBalls = fisherYatesShuffle([...], hash);
    const shuffledPowerBalls = fisherYatesShuffle([...], hash);
    • Explanation:

      • Creates two arrays:

        • Primary Balls: Numbers 1 to 55.

        • Power Balls: Numbers 1 to 18.

      • Shuffles both arrays using the Fisher-Yates algorithm.

      • Selecting Numbers:

        • Primary Balls: Takes the first 5 numbers from the shuffled array.

        • Power Ball: Takes the first number from the shuffled power balls.


Need Help?

If you encounter any issues or have questions, please contact Shuffle support for assistance.


Note: This guide is designed to be user-friendly and requires minimal technical expertise. By following the steps, you can independently verify the fairness of the SHFL Lottery.

Last updated