You don't have to trust us. The proof is public.
Like locking a sealed envelope in a public vault.
When the raffle ends, every ticket is uploaded to IPFS and its fingerprint is recorded on Arbitrum. From this moment on, no one — including us — can add, remove, or edit tickets.
An independent referee rolls the dice.
A random number is delivered by Chainlink VRF, together with a cryptographic proof the number wasn't tampered with. We can't predict it, retry it, or influence the outcome.
Open the envelope, apply the dice roll, read the name.
The formula is public: (random % totalTickets) + 1. Given the same random number and the same frozen ticket list, anyone re-runs the formula and gets the same winner.
A public ledger makes the draw verifiable. A public ledger must never carry personal data. Here's how we split them.
The identity commitmentis a one-way SHA-256 hash of your account combined with the raffle ID. Nobody can reverse it to find you, but you can recompute it yourself to prove the ticket is yours. Because the hash is raffle-scoped, your activity also can't be linked across raffles.
Enter your raffle and ticket code. Here's what you'll see.
Your ticket inside the frozen IPFS dataset.
Cryptographic proof it was committed before the draw.
The random number and formula that picked the winner.
The full verification pipeline is open for inspection. After any completed raffle, you can independently reconstruct the result:
Commitment struct to get the manifest hash, ticket count, and winner countRandomWordsFulfilled event to get the VRF random numbers// Commit-Reveal Protocol
// Step 1: Before random number exists
const ticketManifest = buildManifest(allTickets);
const commitHash = sha256(ticketManifest);
await blockchain.commit(commitHash); // Locked forever
// Step 2: Random number generated (can't be influenced)
const randomNumber = await chainlinkVRF.getRandomNumber();
// Step 3: Apply random to committed data
const winner = selectWinner(ticketManifest, randomNumber);
// Manipulation impossible: data locked before randomness// Winner Selection Formula
const randomNumber = BigInt("0x7a3b9c2d...4f2c1e8a");
const totalTickets = 12_847n;
// Simple modulo operation
const winningIndex = Number(randomNumber % totalTickets);
const winningTicket = winningIndex + 1;
// Result: Ticket #8432 wins
// Anyone can verify: (random % 12847) + 1 = 8432Every winner on Rafli can be independently verified.
Browse Raffles