Randomness Tutorial

Example Code: The complete working example for this tutorial is available at sb-on-demand-examples/solana/randomness/coin-fliparrow-up-right

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.

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 value
  1. Commit: Player commits to using a specific Solana slothash

  2. Generate: Oracle generates randomness based on the committed slot

  3. 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:

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:

  1. Commit to randomness

  2. Wait for reveal

  3. 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. Build the Program

3. Update Program ID

Get your program address:

Update lib.rs:

Rebuild:

4. Deploy

5. Install Dependencies

6. Play!

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

Last updated