State Proof RPC (Contracts & Slots)
Source: src/rpc/node_rpc_v1.idl, src/storage/state/proofs.rs
Overview
Section titled “Overview”state_proof returns a cryptographic proof that a contract exists (or not)
under the global state root, and optionally proves a specific storage slot
exists (or not) under that contract root.
Proofs are built from:
- Outer tree: contract address -> contract root (Binary Merkle Tree / QMDB)
- Inner tree: slot key -> slot value (contract storage tree)
The response includes enough material to verify the proof client-side without access to node state.
RPC: state_proof
Section titled “RPC: state_proof”Request
Section titled “Request”{ "address": "0x...", "slot_key": "0x...", // optional "height": 1234 // optional (defaults to latest finalized)}address: contract address (hex)slot_key: optional storage key (hex)height: optional block height; if omitted, uses latest finalized height
Response (StateProofResult)
Section titled “Response (StateProofResult)”{ "address": "0x...", "canonical_address": "0x...", "contract_root": "0x...", "state_root": "0x...", "last_loc": 42, "ops": [ { "canonical_address": "0x...", "contract_root": "0x...", "position": 0 } ], "bounded_proof": { ... }, "slot_proof": { ... } | null, "height": 1234}Key fields:
state_root: global state commitment for the given heightcontract_root: root of the contract’s storage treeops+last_loc: QMDB operation log needed to recompute the outer rootbounded_proof: membership/non-membership proof for the contract addressslot_proof: optional proof for a slot key (exists or non-exists)
Verification Flow
Section titled “Verification Flow”1) Recompute the outer root (QMDB ops)
Section titled “1) Recompute the outer root (QMDB ops)”- Sort
opsbypositionand ensure positions are contiguous0..last_loc. - Ensure canonical addresses are strictly increasing.
- Recompute the QMDB root from ops; must match
state_root.
2) Verify the contract proof
Section titled “2) Verify the contract proof”- Use
bounded_proofto prove the contract’s leaf exists (or not) in the outer tree. - The bounded proof includes a leaf proof plus left/right neighbor proofs for non-membership ordering checks.
3) Verify the slot proof (optional)
Section titled “3) Verify the slot proof (optional)”If slot_key was provided:
- Exists: verify the slot’s leaf digest under
contract_root. - NonExists: verify neighbor ordering under
contract_root.
Slot Proof Variants
Section titled “Slot Proof Variants”Exists:{ canonical_key, value, proof }NonExists:{ queried_key, left?, right? }
Both variants are verified against the contract root.
Error Cases
Section titled “Error Cases”INVALID_PARAMS: bad hex inslot_keyor malformed requestNOT_IMPLEMENTED: backend does not support state proofsINTERNAL: proof generation failed
Notes / Constraints
Section titled “Notes / Constraints”- The backend must support ordered QMDB proofs. Some backends may not.
- Proofs are for finalized state when
heightis omitted. - A missing contract returns a non-membership proof and
slot_proof = null.
Related Docs
Section titled “Related Docs”docs/design/state-layout.mddocs/design/light-client-mmr-onchain.mddocs-site/src/content/docs/upcoming/finalized-mmr-proofs.md