Provably fair
Every draw is settled by a keeper commit-reveal hash chain mixed with a future blockhash — no oracle, and no way for one party to choose the outcome. Here is that machinery, live. Full explanation →
01
Commit
The keeper hashes a secret chain and publishes only its head on-chain — before any draw exists. Every future word is locked to a preimage nobody has seen.
02
Pin a future block
Each draw fixes a seed block 5 blocks ahead. Nobody — keeper included — knows that block's hash yet, so nobody can pick the outcome.
03
Reveal & mix
Once the seed block is history the keeper reveals the next preimage; the word is keccak256(preimage, blockhash, requestId). Neither side controls it alone.
Adapter state
Status
Idle
Reveals remaining
863
Keeper bond
5 ETH
Recorded skips
0
0x9f2c7d…1122— (no draw in flight)Recent randomness
| Request | Seed block | Status | Word | Latency |
|---|---|---|---|---|
| #12 | 41920005 | revealed | 0x7b4e…c1a9 | 42s |
| #11 | 41916408 | revealed | 0x2f80…44de | 55s |
| #10 | 41912810 | revealed | 0xd311…9f02 | 1m 1s |
| #9 | 41909212 | skipped | — | 65m 0s |
| #8 | 41905614 | revealed | 0x5a6c…07bb | 48s |
Verify a word yourself
Once a request is revealed, its word is fully determined by three public values — reproduce it and confirm nothing was tampered with:
userSeed = keccak256(requestId, blockhash(seedBlock)) word = keccak256(preimage, userSeed, requestId)
The preimage is the revealed value (its keccak256 equals the previous chain head); blockhash(seedBlock) is the pinned future block. Because the head was committed before the seed block existed, neither the keeper nor the sequencer could have known both in advance.