Introduction
DICE is verifiable randomness for Solana, produced by a small fleet of physical devices running a commit-reveal protocol. One CPI call, one typed callback, and you're done.
30-second pitch
Most VRF oracles answer a question you have to trust: is the number really random? They prove it with a cryptographic signature from a key held by an entity. If that key leaks — or that entity is compromised — the "randomness" stops being random.
DICE answers the same question with a physical object. Every round, 4 to 50 real ESP32-S3 devices each sample their internal true-RNG peripheral, hash-commit their slice, and then reveal. The 32-byte output is the SHA-256 of all revealed entropy shares. Any single honest device makes the result uncontrollable by anyone else.
✓ The guarantee in one line
1 of N honest devices → the output is unbiasable. You do not need to trust DICE the company, the coordinator, or the other devices.
Who is this for?
Solana developers who need randomness inside a program. Typical callers:
- Games — dice, coin flips, card shuffles, loot drops, PvP matchmaking.
- NFT launches — fair mint-order reveal, rarity rolls, trait mixing.
- Markets & protocols — lottery-style allocations, tie-breaking in auctions, rebate raffles, liquidation ordering.
- Real-world-asset platforms — regulated draws, audit-friendly decisions, compliance-grade provenance.
Trust model
The short version: you trust one physical device, not a company. The longer version is three overlapping properties.
1 · Commits land before reveals
Every node publishes hash(entropy + nonce) as an on-chain commit before any node reveals its raw entropy. A node that tries to pick its share after seeing other reveals would have to break SHA-256.
2 · Aggregation mixes every share
The final 32 bytes are SHA-256(e₁ ‖ e₂ ‖ … ‖ eₙ). Even a single honest share makes the output uncontrollable by all the others combined.
3 · Hardware signs the reveal
Each reveal is signed by a per-device ECDSA key baked into the firmware. Private keys never leave the chip. A compromised coordinator cannot forge reveals without physical access to the device.
What you get
- 32 bytes of uniform randomness delivered as a typed
DiceResultstruct. - A channel PDA that binds your program as the callback target — nothing to re-wire per round.
- Streaming mode (~4.0 s avg) for UX-critical flows, or audit mode (+8%) when you need on-chain reproducible device selection.
- Atomic payouts — operators are paid in the same transaction that finalises your round.
What DICE is not
DICE is not a replacement for application-level fairness logic. If your game decides outcomes off-chain, DICE cannot help. And DICE does not run your game — you still write dice_callback, you still own the outcome formula, you still decide how to weight the bytes.
! Latency expectation
Rounds take ~4 seconds end-to-end. This is fine for turn-based and deferred-reveal flows. It is not fine for latency-sensitive interactions like frame-by-frame procedural generation. Use a streaming feed if you need randomness at a higher rate — see Streaming feed.