Randomness Tutorial
Example Code: The complete working example for this tutorial is available at sb-on-demand-examples/solana/randomness/coin-flip
This tutorial demonstrates how to integrate verifiable randomness into your Solana program using Switchboard's commit-reveal pattern. You'll build a provably fair coin flip game.
Version source of truth: SDK Version Matrix
Why Verifiable Randomness?
On-chain randomness is hard. Naive approaches fail because:
Block hashes are predictable: Validators can see future block data
Timestamps are manipulable: Validators control block timestamps
External sources are untrusted: Off-chain randomness can be faked
Switchboard solves this with a commit-reveal pattern where neither party knows the outcome until after commitment.
How It Works
1. COMMIT → 2. GENERATE → 3. REVEAL
Player Oracle Settlement
commits to generates Player reveals
slothash randomness and uses valueCommit: Player commits to using a specific Solana slothash
Generate: Oracle generates randomness based on the committed slot
Reveal: Player reveals the randomness and uses it in their program
This is secure because:
The player commits before knowing the randomness
The oracle generates randomness after commitment
Neither party can manipulate the outcome
What You'll Build
A coin flip game where:
Player guesses heads or tails
Switchboard generates verifiable random outcome
Winner receives double their wager
Prerequisites
Rust and Cargo installed
Anchor framework 0.31.1
Solana CLI installed and configured
Node.js and pnpm
A Solana keypair with SOL
Key Concepts
Randomness Account
A dedicated Solana account that stores:
The committed slothash
The seed slot
The revealed random value (after revelation)
RandomnessAccountData
The on-chain struct for parsing randomness state:
Note: Randomness is not read from
quote.feeds(). For Solana commit-reveal, callRandomnessAccountData::get_value(clock.slot), which returns a 32-byte randomness value (for example,random_bytes[0] % 2for a coin flip).
Slot-Based Freshness
Randomness must be used within a specific slot window:
Collateral on Commit (Critical!)
Always take payment when committing, not when revealing.
Why? If you take payment on reveal, a malicious user could:
Commit to randomness
Wait for reveal
Only reveal if they won (selective revelation attack)
The On-Chain Program
Dependencies
Program Structure
Account Structures
Error Codes
The TypeScript Client
Setup
Create Randomness Account
Commit Phase
Reveal Phase
Retry Logic
Network issues can cause commit/reveal to fail. Add retry logic:
Running the Example
1. Clone the Repository
2. Install Dependencies
3. Point Solana CLI at Devnet
4. Run the Example Against the Preconfigured Devnet Program
The checked-in Anchor.toml already includes a devnet program ID for sb_randomness, so you can run the example directly:
5. Deploy Your Own Program (Optional)
If you want to deploy your own instance instead of using the preconfigured devnet program:
The example script resolves the example program ID from Anchor.toml. To override that at runtime, set SB_RANDOMNESS_PROGRAM_ID:
Expected Output
Security Best Practices
1. Always Take Collateral at Commit Time
2. Validate Slot Freshness
3. Verify Randomness Account Reference
4. Check Randomness Not Already Revealed
Use Cases
Gaming & Gambling
Casino games (dice, slots, roulette)
Provably fair betting
Skill-based games with random elements
NFT Minting
Random trait assignment
Fair rarity distribution
Blind box reveals
Lotteries
Ticket drawing
Raffle winners
Prize distribution
Fair Distribution
Airdrop selection
Whitelist randomization
Token allocation
Advanced Topics
Reusing Randomness Accounts
Save the keypair to reuse across sessions:
Multiple Random Values
The revealed value is 32 bytes. Use different bytes for different outcomes:
Next Steps
Price Feeds: Learn oracle integration in Basic Price Feed
Prediction Markets: See feed verification in Prediction Market
Custom Feeds: Create your own feeds in Custom Feeds
Last updated