Skip to main content
What you’ll be able to do
  • Select a participant using a future random value from the network.
  • Verify the selection from finalized chain data.
  • Cancel an unresolved selection after a fixed deadline.
The randomness beacon is not on Metal Testnet yet. Follow this guide on a network that has code at its address.
Metal’s randomness beacon is a network service that publishes random values onchain. Your application can use these values to choose a participant in a draw or shuffle a list. Once a value is published, anyone can reproduce the result using the same inputs and selection rules. This guide selects one participant from a fixed list. You first record the list and a future slot, a one-second interval of chain time, before its random value is available. Once the value is published, the application uses it to select a participant, and anyone can verify the selection.

Check the beacon and its assumptions

The beacon contract at 0x00000000000000000000000000000000000000ff stores a signature produced jointly by validators for each available slot. The API calls this signature a slot key. randomness(slot) returns the random value derived from that key as keccak256(keyAt(slot)). Check for beacon runtime bytecode and hasKey() == true at a finalized block. Record groupKey() and keySet() with the block number and hash.
Honest validators release signature shares after the slot ends in finalized chain time. Chain time can lead wall time by up to 60 seconds, or 2 seconds when the scheduler is active, so choose the future slot relative to the chain timestamp. Unpredictability depends on the validators keeping their key shares secret. With n validators and f = floor((n - 1) / 3), a key with no publicly revealed shares resists up to 2f colluding validators. A key distribution round can reveal up to f shares, reducing that resistance to f colluders until the shares are redistributed. Redistribution preserves the group secret, so a quorum of former validators that retained old shares can also recover future slot keys.

Commit the decision before the slot

The FutureSelection contract records one selection. In one transaction, its owner commits an ordered participant list, a unique business decision ID, a future slot, and a cancellation deadline. These inputs remain fixed, and anyone can submit the transaction that resolves the selection.
Deploy the contract, then call commit with the decision ID and agreed participant order. Choose a slot far enough beyond the latest chain timestamp to allow inclusion and finality. This contract requires the slot to be at least 30 seconds ahead at execution and the cancellation deadline to fall within the following 120 seconds. Use the SDK signing procedure and fee estimates for each call. Save the transaction hash and signed bytes before broadcasting. Verify a successful receipt containing Committed, check its canonical block and finality, and read the commitment, slot, deadline, and participant array at that block. Independently recompute the commitment using ABI types uint256,address,bytes32,uint64,uint64,address[] in the contract’s field order. Save the selection contract address with the business decision and accept only that contract’s commitment for it. This prevents an operator from discarding an unfavorable result and running another selection. Share the finalized commitment with participants before its slot ends.

Read and verify the result

Poll randomness(slot) at finalized blocks using the committed slot. Once its key is available, the returned entropy lets you reproduce the selection:
Rejection sampling gives each participant an equal chance even when the participant count does not divide 2^256. The contract and client both test candidates in the same order, using the committed inputs. If all 16 attempts reject, the selection remains pending until its cancellation deadline. Submit finish() in time to execute before the deadline. It reads the slot’s entropy and records the winner. Verify Selected in a successful receipt, check the receipt’s canonical block and finality, and compare winner with the participant at the index returned by selectIndex. Mark the business decision complete once using the stored commitment. Follow finalized receipt verification and settlement semantics.

Handle a delayed or missing key

The beacon stores keys in a 4096-slot ring indexed by slot % 4096. Each position holds one key and its slot label. NotInRing means the requested key has either not arrived or been overwritten by a later slot at the same position. Save finalized results promptly if you need to retain them for an audit. Nodes sign the 65 slots up to the newest finalized block, so a long halt can leave older slots permanently without a key. Key generation or validator transitions can also delay publication. Keep the decision pending and retry the same slot until the fixed deadline. If the selection remains unresolved after the deadline, call cancelExpired() and verify its finalized Cancelled event. Cancellation is final even if a key becomes available later. If your application issues refunds, use this cancellation state to authorize them. Test past slots, duplicate commitments, reordered participants, unauthorized commits, repeat resolution, delayed keys, expiry, and ring lookup failures. Use controlled candidate values to exercise sampling rejection. Then run a selection on the network and verify its finalized commitment and result.