Don't trust us. Verify us.
Verify this draw.
The commitment
Published before any entry was soldWe generated a secret server seed and published its SHA-256 hash the moment this competition opened. Changing the seed afterwards would break the hash — publicly and permanently.
SHA-256 commitment 73efb819b64600e55d03cc0c6c41778bd8f986ec831acd5d173d40d874e538aeThe public entrant list & client seed
Snapshotted and published at the drawTicket numbers are allocated at random within the fixed pool of 20,000 — which numbers you hold never changes your odds (tickets held ÷ tickets sold). The draw selects a position among valid sold tickets, so an unsold number can never win. The full ticket list is public: ticket numbers (JSON) — live until the draw snapshots it (refunded entries drop out, per the terms).
The client seed is the SHA-256 of
slug:entryCount:listHash:closesAtwherelistHashis the SHA-256 of that exact ticket list — the outcome is bound to the published entrant set, and the seed behind it was committed before a single ticket was sold.The result
Awaiting drawThis competition has not been drawn yet. The server seed stays sealed until the draw — it will be revealed here, next to the commitment above, so the two can be checked against each other.
Recompute it yourself
Any machine, ~5 linesRun this in Node.js with the revealed values — it must print the published hash and the same winning entry:
const { createHash, createHmac } = require("crypto"); const sha256 = (s) => createHash("sha256").update(s).digest("hex"); // numbers = the published list at /api/verify/<slug>/numbers const sorted = [...numbers].sort((a, b) => a - b); const entryCount = sorted.length; // 1. Check the commitment and the ticket-list hash console.log(sha256(serverSeed)); // must equal the published hash const listHash = sha256(sorted.join(",")); // must equal the published one const clientSeed = sha256(`${slug}:${entryCount}:${listHash}:${closesAt}`); // 2. Recompute the winning position const key = ["DRAW", slug, serverSeed, clientSeed, entryCount].join("-"); const hmac = createHmac("sha256", key).digest("hex"); const value = parseInt(hmac.slice(0, 13), 16); const position = Math.floor((value / 2 ** 52) * entryCount) + 1; // 3. The winner is the position-th ticket, ascending console.log("Winning ticket:", sorted[position - 1]);
