Skip to content

Requesting randomness ​

Inherit VerityConsumerBase, add your contract as a consumer of a funded subscription, then call:

solidity
uint256 requestId = s_coordinator.requestRandomWords(
    keyHash,                      // which oracle key (gas lane) proves the result
    subId,                        // which subscription pays
    minimumRequestConfirmations,  // blocks to wait before proving: 3..200
    callbackGasLimit,             // gas for your fulfillRandomWords
    numWords                      // 1..500 words
);
ParameterGuidance
keyHashA lane from Networks. The lane caps the gas price you can be charged.
minimumRequestConfirmationsMore confirmations means more protection against chain reorganisations, but slower results. PulseChain blocks take ~10 s; 3 is the minimum. Use more for high-value draws.
callbackGasLimitMeasure your callback's gas and add a margin. Too little means the callback reverts out of gas, and that fulfilment is final. You pay for the reservation, not the limit, so don't wildly oversize it.
numWordsEach word is an independent uint256. One word is often enough: slice it, or derive more with keccak256(abi.encode(word, i)).

What happens next ​

  1. The RandomWordsRequested event is emitted; the request is pending.
  2. After minimumRequestConfirmations blocks, the oracle node proves the result against keccak256(preSeed, blockhash(requestBlock)).
  3. The coordinator verifies the proof and calls rawFulfillRandomWords on your contract with exactly callbackGasLimit gas.
  4. Words are uint256(keccak256(abi.encode(randomness, i))) for i = 0..numWords-1. Anyone can recompute them from the RandomWordsFulfilled event.

On PulseChain testnet this takes about 45 seconds end to end.

Request ids ​

requestId = keccak256(abi.encode(keyHash, keccak256(abi.encode(coordinator, keyHash, consumer, subId, nonce)))), where coordinator is the coordinator's own address and nonce counts your consumer's requests. computeRequestId(coordinator, keyHash, consumer, subId, nonce) in the SDK reproduces it off-chain.

Because the coordinator address is part of the seed, request ids do not repeat across coordinators, even after a subscription migration restarts your consumer's nonce on a new coordinator.

Timeouts and cancellation ​

If no proof arrives within the coordinator's requestTimeoutBlocks (8,640 blocks ≈ 24 h on testnet), the consumer or the subscription owner can call cancelRequest(requestId, commitment) (or verity request cancel --request-id <id>) to release the reservation. Cancellation is a refund, not a reroll. Read the security rules.

Requests older than 256 blocks remain fulfillable: the oracle stores their block hash in the BlockhashStore before it leaves the EVM's window.

Testnet: PulseChain testnet v4. Unaudited software; do not use on mainnet yet.