Deterministic selection · Tool 02

Replay the winner, input by input.

Fetch the public commitment and finalized target block, then run the same unbiased selection algorithm in your browser. The output should match the published winner exactly.

Complete evidence checklist

Everything needed to verify independently.

The organizer publishes two references. Every other draw value is either chosen by the verifier or read directly from Ethereum mainnet.

01 Organizer publishes
  • Commitment transaction hashPoints to the immutable OVCR payload.
  • Expected signer addressMust be both sender and recipient of the commitment.
02 Verifier provides
  • Ethereum RPC URLPublicNode is prefilled, and the verifier may replace it with any mainnet endpoint.
  • No private draw valueThe winner replay needs no secret, seed, or participant record.
03 Ethereum supplies
  • Transaction and receiptStatus, sender, recipient, value, calldata, and commitment block.
  • Committed raffle dataRaffle ID, target block, code count, Merkle root, and full ordered code list.
  • Finalized target blockIts public block hash is the future entropy used by the draw.

Public draw details

No raffle code is needed to reproduce the winner.

Reproducible by anyone. The target block hash and committed code order are public, so identical inputs produce the identical winner.

Beginner-friendly option

Ask an AI to replay the winner.

Fill in the public details above, then copy this short prompt into an AI assistant that can browse the web and run code. It will follow the complete public instructions for this audit.

Ready-to-copy verification promptIncludes your current draw inputs

Copying only places the prompt on your clipboard. Pasting it into an AI service shares these values with that provider. A legitimate verification never needs a seed phrase, private key, password, or wallet connection.

Technical details

Open verification specification

Expand this section to inspect the complete, independently reproducible method.

The exact winner-selection method.

This is the complete method implemented by the tool. It is intentionally specific enough to reproduce in another language or application.

01

Shared precondition

Authenticate the on-chain commitment.

Network

The RPC must report Ethereum mainnet.

Execution

Transaction exists and its receipt status equals 1.

Shape

from == to == expectedSigner and value == 0.

Timing

commitmentBlock < targetBlock.

02

Calldata schema

Decode the commitment with no hidden fields.

OffsetSizeFieldRule
04Magic0x4f564352 (“OVCR”)
416Raffle IDUUID bytes
208Target blockUnsigned 64-bit integer
284Code countUnsigned 32-bit integer; 1–8,000
3232Merkle root32-byte hash
649 × countRaffle codesNine UTF-8 bytes each

The payload is rejected unless its total length is exactly 64 + (9 × codeCount) bytes.

03

Public future entropy

Require the target block to be finalized.

Availability

The committed target block exists and has a 32-byte block hash.

Finality

The network’s finalized head is at or beyond the target block.

The target block hash was not available when the earlier commitment fixed the raffle ID, root, target block, and code order.

04

Selection hash

Encode the exact draw inputs in this order.

domain = keccak256(UTF8("OVCR_WINNER"))selectionHash(counter) = keccak256(abi.encode(  bytes32 domain,  bytes16 raffleId,  uint64 targetBlock,  bytes32 merkleRoot,  bytes32 targetBlockHash,  uint256 counter))

The counter begins at 0. All integer values use standard ABI encoding.

05

Unbiased mapping

Reject the tiny biased tail, then select one index.

RangeR = 2²⁵⁶
Limitlimit = R − (R mod codeCount)
Candidatecandidate = uint256(selectionHash(counter))
Retry rulewhile candidate ≥ limit: counter = counter + 1
WinnerwinnerIndex = candidate mod codeCount
CodewinnerCode = sortedCodes[winnerIndex]

Indexing note: the algorithm uses a zero-based index. The displayed winner ordinal is winnerIndex + 1.