This system provides a fair and verifiable way to draw winners from a list of participants, respecting weighted entries. It uses a nonce + seed mechanism to ensure unpredictability before the draw while allowing anyone to verify the results afterward.
participants.json: Stores the list of participants and their corresponding entry weights. Edit this file to manage raffle entries.main.py: The main script to run the raffle draw. It reads participants fromparticipants.json, generates a nonce, calculates a seed, shuffles entries, selects winners, and prints the results along with verification data.verify.py: A tool to verify the results of a previous raffle draw. It takes the Base Seed and Nonce from a specific draw as input and recalculates the winners.
-
Weighted Entries (
participants.json):- Participants and their number of entries are defined in the
participants.jsonfile as a JSON object (dictionary). - The keys are the participant identifiers (e.g., usernames), and the values are their corresponding integer weights (number of entries).
- The system creates a "virtual hat" where each participant's name appears a number of times equal to their weight, ensuring probabilities are proportional to entries.
- Participants and their number of entries are defined in the
-
Nonce + Seed Mechanism:
- Base Seed: A predetermined string (
BASE_SEEDvariable inmain.py) specific to the raffle series. This should be known or announced beforehand. - Nonce: A random, unpredictable value generated at the time of the draw (
secrets.token_hex(16)inmain.py). This prevents predicting the outcome beforehand. For high-stakes raffles, this nonce ideally comes from a public, verifiable source generated after entries close (e.g., future block hash, lottery number). This script simulates this by generating it locally. The generated nonce is printed in the draw output. - Hashing (SHA-256): The
Base Seedand the generatedNonceare combined and then processed using the secure SHA-256 hashing algorithm. This produces a unique, fixed-length "Final Seed". Any tiny change to the Base Seed or Nonce results in a completely different Final Seed. - PRNG Seeding: Python's standard pseudo-random number generator (
random) is seeded with theFinal Seed(the SHA-256 hash). This makes the subsequent "random" operations (like shuffling) deterministic and reproducible if you know the Final Seed.
- Base Seed: A predetermined string (
-
Shuffling & Unique Selection:
- The "virtual hat" (list with weighted entries) is shuffled using the seeded random number generator. The order after shuffling is entirely determined by the
Final Seed. - The script iterates through the shuffled list and selects the first
N(defined byNUM_WINNERS) unique participants encountered. This ensures no one can win more than once in a single draw.
- The "virtual hat" (list with weighted entries) is shuffled using the seeded random number generator. The order after shuffling is entirely determined by the
The system achieves verifiable fairness through these combined mechanisms:
- Transparency: The participant list (
participants.json), theBase Seed, the algorithm (code), and the hashing method (SHA-256) are open. The specificNonceused for a draw is published in its results. - Unpredictability: Because the
Nonceis generated randomly at draw time (or ideally, obtained from a future public source), the outcome cannot be predicted before the draw occurs. - Reproducibility: Anyone can take the published
Base Seed, the specificNoncefrom a given draw, and theparticipants.jsonfile (as it was at the time of the draw), run theverify.pyscript (or manually perform the steps: combine, hash, seed, build list, shuffle, select), and they must arrive at the exact same list of winners. This proves that the announced winners are the legitimate result of the defined random process and weren't manipulated.
- Ensure you have Python 3 installed.
- Save the files
main.py,verify.py, andparticipants.jsonin the same directory. - Edit
participants.json: Update this file with your list of participants and their corresponding weights (number of entries). Ensure it's valid JSON. - (Optional) Edit
main.py:- Change the
BASE_SEEDvariable to something unique for your raffle series. - Adjust the
NUM_WINNERSvariable to the desired number of winners for the draw.
- Change the
- Open a terminal or command prompt in the directory containing the files.
- Run the main script:
python main.py - The script will output:
- Draw details (timestamp, number of winners, entry counts).
- The
Base Seedused. - The
Nonce Generatedfor this specific run. <<< RECORD THIS! - The calculated Final Seed (SHA-256 Hash).
- The list of
🏆 WINNERS 🏆. <<< RECORD THESE!
- Obtain the
Base Seedand the specificNoncethat were published with the results of the raffle run you want to verify. - Ensure your
participants.jsonfile accurately reflects the state of entries at the time that specific raffle was run. If entries changed later, verification against the original state is needed. - Open a terminal or command prompt in the directory containing the files.
- Run the verification script:
python verify.py - Enter the exact
Base Seedwhen prompted. - Enter the exact
Noncefrom the original draw when prompted. - Enter the number of winners that were announced for that draw when prompted.
- The script will recalculate the process and output the
Derived Winners. - Compare: Carefully compare the
Derived Winnerslist printed byverify.pyto the winners announced in the original raffle output. If they match exactly, the draw is verified. If they don't match, double-check your inputs (Base Seed, Nonce, Num Winners) and ensure theparticipants.jsonused byverify.pyis correct for the time of the draw.