Gate a payout on a receipt
A vault, a DAO payout or an x402 facilitator can decline to release funds until the caller supplies an AINumbers receipt that RISC Zero's deployed verifier accepts. This page describes the pattern in words. It ships no contract, and nothing described here has been audited.
Read this first
No contract is published with this page, and nothing here has been audited. The flow below is a description of how the pieces fit, not a recommendation to deploy anything. Anyone who builds on it owns the contract, its review and its operation.
§1Start from the verify call
The check itself is already documented step by step in the On-Chain Receipt Verification Recipe: how to derive the seal, the image ID and the journal digest, and how to confirm routing before you call. This page does not repeat that. It only asks what changes when a contract, rather than a person with a command line, makes the same call.
§2How the flow runs
- The contract is configured with one known journal digest. That digest is the SHA-256 of the canonical journal bytes for the specific result the payout depends on, for example a particular reconciliation or approval outcome. The contract also holds the image ID of the program that must have produced it, and the address of the RISC Zero verifier router it will ask.
- A caller submits a receipt. In practice that is the seal bytes, with the 4-byte verifier selector in front, as the recipe describes. The caller can be anyone: a keeper, the payee, or a facilitator acting for the payee.
- The contract calls the router's verify function with the seal, its stored image ID and its stored journal digest. The call reverts if the proof does not verify, and returns normally if it does.
- The contract releases funds only if that call did not revert. A revert undoes the whole transaction, so a failed check cannot leave a half-paid state behind.
§3Why compare a digest instead of reading the journal
The journal is JSON in clear. A contract could in principle receive the journal bytes, hash them, and parse fields out of the text, but parsing JSON on-chain is costly and easy to get wrong. The cheaper pattern is the one above: the contract is told in advance which digest it will accept and compares that single 32-byte value. If the caller's journal differs in any byte, its digest differs and the verifier call fails.
The consequence is that the gate answers a narrow question: did the program with this image ID commit exactly this journal? To release different amounts for different outcomes, the contract needs a different known digest for each outcome it is prepared to honor.
§4Three places this could sit
- A vault that releases a position only when a receipt for an agreed calculation is presented.
- A DAO payout where a proposal pays out only against a receipt for the computation the proposal named.
- An x402 facilitator that settles a paid request only after the response carries a receipt the facilitator's contract accepts.
In each case the receipt shows that a stated program produced a stated journal. It says nothing about whether the program encodes the right rule for the deal, and that question stays with the parties.
§5The lifecycle caveat
A gate depends on the operator and on the version
RISC Zero stops and then removes verifiers for older versions. Receipts proven under a removed version can no longer be routed on-chain. A payout gate that calls the router therefore depends on the operator keeping the matching verifier available, and on the version of the proof system your receipts were produced under. If the verifier for that version is stopped, the gate cannot release funds until the contract is pointed at something that works.
The local verifier remains the durable path. It runs on the reader's own machine, needs no operator, and does not expire with a deployment. Treat the on-chain gate as time-limited, and keep a way to re-check the same receipt locally.
§6What this does and does not show
A passing check shows that a RISC Zero Groth16 proof of this journal, under this image ID, verifies on the deployed verifier. It does not show that the rule inside the program is correct, and the deployed verifier for this version can be stopped by its operator. Nothing on this page has been audited, and no contract is shipped with it.