Skip to main content

Private Raffle

A confidential raffle system on Solana where participants submit encrypted guesses, and winners are determined through encrypted comparisons — no one can see the winning number or anyone’s guess until results are revealed.

How It Works

The raffle follows a simple “guess the number” game:
  1. Authority creates a raffle with a ticket price
  2. Players buy tickets with encrypted guesses (1-100)
  3. Authority draws by setting an encrypted winning number
  4. Players check if their guess matches (encrypted comparison)
  5. Winners claim their prize through on-chain verification

Privacy Guarantees

DataVisibility
Player’s guessOnly the player can see
Winning numberOnly authority knows
Win/loss resultOnly the ticket owner sees
Prize amountOnly the winner sees
Ticket purchasePublic (on-chain transaction)

Key Features

  • Encrypted Guesses: Players submit encrypted numbers, hidden from everyone
  • Encrypted Drawing: The winning number is never revealed on-chain
  • Private Results: Only ticket owners can see if they won
  • On-chain Verification: Winners prove their prize amount with Ed25519 signatures
  • Trustless Payout: Prize transfers are verified and executed on-chain

Quick Example

// Player buys ticket with encrypted guess
const myGuess = 42;
const encryptedGuess = await encryptValue(BigInt(myGuess));

await program.methods
  .buyTicket(hexToBuffer(encryptedGuess))
  .accounts({
    buyer: wallet.publicKey,
    lottery: rafflePda,
    ticket: ticketPda,
    vault: vaultPda,
    // ...
  })
  .rpc();

// Later: check if won (encrypted comparison)
await program.methods.checkWinner().accounts({...}).rpc();

// Decrypt result
const result = await decrypt([isWinnerHandle], { address, signMessage });
const won = result.plaintexts[0] === "1";
console.log("Did I win?", won ? "YES!" : "No");

Source Code

git clone https://github.com/Inco-fhevm/raffle-example-solana.git