Rounds & results
Every draw, published.
Results, winners and the data to check them yourself. If a draw is not listed here, it did not happen.
Draws are open
A new draw every Sunday, 20:00 UTC.
Tickets sold before the draw enter it. The winners are chosen from a public random value that nobody, including us, can know in advance (the drand beacon), and every result is published here with the full ticket list, so you can recompute it yourself.
The logic
How the winners are chosen.
No one picks a winner by hand, and the admin cannot steer the result. The outcome is a fixed calculation on two things we do not control: who bought tickets, and a public random value.
- 1
Tickets close
At the draw time (Sunday 20:00 UTC) no more tickets can enter that draw. Every ticket number in it is sorted in alphabetical order and joined into one list.
- 2
The list is fingerprinted
We compute the SHA-256 hash of that list (the “ticket fingerprint”). Change a single ticket and the fingerprint changes completely, so the list we publish afterwards can be checked against it.
- 3
A public random value appears
The random value comes from drand, a public randomness beacon run by a group of independent organisations. It publishes a new unpredictable value every 3 seconds, signed so it can be checked. We use the value for the round published at the draw time, so neither we nor anyone else can know it before tickets close, and we cannot pick a convenient one.
- 4
Winners are calculated
seed = SHA-256(random value + ":" + fingerprint). For k = 0, 1, 2 …, take SHA-256(seed + ":" + k), read its first 8 bytes as a number, and take it modulo the number of tickets. That position in the sorted list is the next winner. If it was already picked, skip it. The first pick wins the grand prize, the next three the runner-up prizes, the next ten the lucky draws.
- 5
Published for everyone
We publish the full ticket list, the fingerprint, the drand round and value, and the winners. The button on each result repeats steps 2 to 4 in your own browser and shows every calculation.
Prize pool
90% of ticket sales. The other 10% goes to good causes, improvements and the developer.14 winners
1 grand prize (50% of the pool), 3 runner-ups (10% each), 10 lucky draws (2% each).Under 50 tickets
The draw is cancelled and every ticket is refunded in full.See the exact code
// Paste into any JavaScript console (Node 18+ or a browser) to check a draw yourself.
// tickets: the published ticket list (sorted). randomness: the drand value shown for that draw.
const sha = async (s) => [...new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(s)))]
.map((b) => b.toString(16).padStart(2, '0')).join('')
async function winners(tickets, randomness) {
const ticketsHash = await sha(tickets.join('\n'))
const seed = await sha(randomness + ':' + ticketsHash)
const picked = [], out = []
for (let k = 0; out.length < Math.min(14, tickets.length); k++) {
const d = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(seed + ':' + k))
const i = Number(new DataView(d).getBigUint64(0) % BigInt(tickets.length))
if (!picked.includes(i)) { picked.push(i); out.push(tickets[i]) }
}
return { ticketsHash, winners: out } // 1st = grand prize, 2nd-4th = runner-ups, 5th-14th = lucky draws
}You can also look up the random value yourself, straight from drand: api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/<round>