Skip to content

Learn

Crypto Spot Research

State proofs: connect an account value to a trusted block root

A state proof can establish that particular bytes belong under a particular state root. It cannot establish that the root came from the chain you intended to study, or that an integer represents the economic quantity named in a dashboard. A useful research packet therefore separates the trusted block, the cryptographic path and the interpretation of the verified value.

The task here is narrow: verify one account value and one storage value at a historical observation. This is different from asking an archive provider to return a historical number. A provider can supply the proof material, while a separately checked reference determines which root the material must satisfy.

Start with a claim that has an exact key

Write the network, account address, block identity and requested quantity before collecting a proof. “The treasury held seven ether” requires an account balance. “The treasury had twelve claim units in a contract” requires a storage location and an explanation of its meaning. Those statements involve different data even if one interface displays them together.

In EIP-1186, the Abstract and Specification, account and storage proofs are connected to a block state root. The response includes account fields and proof nodes, with a separate proof for each requested storage key. The proposal’s status is Stagnant; record the actual client’s supported behavior rather than treating its label as an endpoint compatibility guarantee.

Keep the original request and response. Record the exact address bytes, requested slot bytes, block number, observed block hash and retrieval time. A number alone is insufficient because a different address or a different historical block can produce an internally valid but irrelevant proof.

Establish the root through a separate trust path

Choose the block reference independently of the server supplying the candidate values. For example, retain a header obtained through a locally validated chain and document the validation and finality convention. An alternative trust arrangement needs its own explicit assumptions. Two commercial endpoints repeating one upstream header are not automatically independent checks.

Bind the header’s state root to its block hash and selected network. A timestamp is a useful label, but it does not replace that binding. If the provider’s response concerns another block at the same height after a reorganization, reject the identity mismatch before discussing the value.

Do not ask the same untrusted endpoint for a proof and its root, accept both without further checking, and call the result independent verification. That exercise can test internal consistency. It does not test whether the supplied root is authoritative for your research cutoff.

Verify the account before the storage slot

Use a verifier that implements the relevant Ethereum trie rules. It must derive the account key correctly, decode the proof nodes and check the path against the chosen state root. Distinguish successful membership, valid absence and malformed or incomplete evidence. A generic binary Merkle-tree routine is not a substitute for the required trie logic.

Decode the proven account leaf rather than trusting neighboring JSON labels. Compare its nonce, native balance, storage root and code hash with the response’s convenience fields. A provider could return correct nodes beside an incorrect displayed balance; the decoded leaf is what the path authenticates.

Next verify the requested storage path against the storage root obtained from that account leaf. Merely checking a slot proof against a storage root supplied separately in the response skips the account-to-state link. This two-level connection is the central deliverable.

If the claim concerns contract behavior, save the applicable storage layout and code identity as another evidence layer. A cryptographically authenticated slot does not tell you whether it contains a customer balance, configuration flag or packed collection of fields.

Preserve the storage-key derivation

For a mapped balance, the business identifier and storage location are not interchangeable. Keep a reproducible record explaining how the historical layout turns the requested owner or claim identifier into slot K. The trie verifier then checks that slot’s path; it does not discover the application’s mapping rule. A perfectly verified proof for a neighboring configuration slot cannot support a customer-balance claim merely because its integer happens to match an expected number.

A hypothetical two-level proof packet

Assume a fictional test environment has an independently retained header H with state root R. At H, account A has a native balance of 7,000,000,000,000,000,000 wei. Its account leaf commits to storage root S. A designated storage key K has integer value 12. These are stipulated inputs, not a report about a live treasury.

CheckCandidate inputRequired result
Header identityH, network and RMatches the independently retained reference
Account pathA and account proofValid under R
Account decodingProven account leafBalance is 7 × 10^18 wei; storage root is S
Storage pathK and storage proofValid under S with integer 12
Display conversionNative balance divided by 10^18Exactly 7 ETH
Economic interpretationLayout and field definitionDefines what 12 measures, or remains unresolved

The native-unit conversion is reproducible: 7,000,000,000,000,000,000 ÷ 1,000,000,000,000,000,000 = 7. The storage integer needs its own scale. If the verified layout says one stored unit represents one hundredth of a claim unit, the displayed quantity is 12/100 = 0.12, not twelve whole tokens.

Run a negative check. Keep H, R, A, K and all proof nodes unchanged, but substitute claimed storage value 13. Verification or the comparison with the decoded leaf must fail. If a tool still reports success merely because it checked that the nodes form a valid path, it has not authenticated the claimed value.

Run a second negative check against a different root R2. A proof valid under R should not be accepted under an unrelated R2. Record the precise failure rather than interpreting it as evidence that the original value changed.

A valid proof of the wrong thing

Suppose a provider returns a complete proof for account B, whose balance also happens to be seven ether. Every hash check can pass while the treasury claim remains unsupported. Comparing the requested address with the proven key catches this identity error; comparing only the displayed amount does not.

Another boundary involves a proxy upgrade. A slot may genuinely contain 12 at the observation block, while today’s implementation assigns that position another meaning. Match interpretation to the implementation and layout relevant then. If that mapping cannot be established, publish the verified bytes with an unresolved semantic status.

Valid absence also differs from an empty response. A supported non-membership proof can establish that the requested account or storage key is absent under a chosen root. A timeout, pruned state or unsupported method establishes only that this retrieval attempt failed. Never fill such failures with a proven zero.

An executable review table

Review actionEvidence to retainStop condition
Confirm the selected chainNetwork and independently checked headerRoot exists only in the candidate provider’s response
Check account identityRequested address and derived trie keyProven key differs
Decode the accountLeaf fields and verifier outputJSON display disagrees with the leaf
Connect both proof levelsAccount storage root and slot pathSlot checked against an unbound root
Interpret the integerHistorical layout, units and code identityField meaning cannot be established
Preserve reproducibilityRaw nodes, request, verifier version and errorsOnly a screenshot survives

Make the output a bounded statement: the selected proof authenticates specified bytes under the independently chosen root, and specified interpretation evidence supports the named quantity. Reopen the packet after a chain-identity correction, verifier defect, layout correction or conflicting proof for the same key and root. A later block with a different value is a new observation, not a reason to erase the earlier verified state.

FAQ

Does a valid proof mean the RPC provider is trustworthy?

It authenticates the checked object against the chosen root. It does not certify every response, the provider’s completeness or the origin of an unchecked root.

Can I call an unavailable storage proof a zero balance?

No. Preserve retrieval failure separately. A zero or absence conclusion needs the corresponding state evidence and the correct interpretation of that state.