Skip to main content

Set L2 Verification Example

A complete inclusion check, end to end. The goal is to confirm an event is in the anchored history using only the chain and a proof path — nothing that requires trusting the sequencer.

Inputs

1. Retrieve the batch commitment

Read the commitment for the batch covering your event’s sequence number. This gives you the events_root — the value everything else is checked against.
Read events_root from the chain, not from this response. The API value is convenient for development; the on-chain value is what makes the check trust-minimised. If you compare an API-supplied root against an API-supplied proof, you have verified nothing.

2. Get the Merkle proof

The response carries the sibling hashes along the path from your event’s leaf to the root, and the leaf’s index — which tells you the order to concatenate at each level.

3. Recompute the root locally

Trees are SHA-256, but every hash is domain-separated — a bare sha256(a || b) will not reproduce the root. The constants come from VES v1.0: A leaf is not simply the hash of the payload. It commits to the stream identity and position too:
Leaves are padded to the next power of two with a constant PAD_LEAF = SHA256("VES_PAD_LEAF_V1"). Skip the padding and your root will be wrong for any batch whose event count isn’t already a power of two.

4. Compare

If the roots match, the event is in the batch that was anchored on-chain. If they don’t, either a leaf field differs by one byte, the padding was skipped, or the event was never committed.

Then check continuity

Inclusion proves your event is present. It does not prove nothing else was removed. Each commitment chains via prev_state_root, so walk that chain in strict mode when you need the history to be complete rather than merely containing your event.

Then check compliance

For encrypted payloads, inclusion says the event exists but nothing about whether a policy held. That’s what compliance proofs are for.