Verify Commitment Inclusion
Build a sorted-pair Merkle tree, derive a proof for one Block hash, and verify its inclusion against the Merkle root hash. A valid proof confirms only that the Block hash is included in the leaf collection represented by that Merkle root.
Before You Start
Use the JavaScript Merkle helpers with valid lowercase 0x-prefixed 32-byte leaves. Synthetic Block hashes keep the example independent of production data and network access. buildMerkleTree() sorts the leaves, so leaf order does not change the Merkle root hash.
How It Works
- Build a Merkle tree from normalized Block hashes.
- Select a leaf and derive its sibling path.
- Verify its inclusion against the Merkle root.
- Change the leaf or proof and confirm verification fails.
When to Use This Workflow
Use an inclusion proof when a verifier has a trusted Merkle root hash and needs to check one Block hash without loading every leaf. The proof does not establish that the root is trustworthy; the verifier obtains the root through a trusted channel or an onchain record.
- Prerequisites
- Runnable Example
- Expected Output
- Negative Checks
- Contract Boundary
Install the package as shown in Quick Start; no network connection or deployed contract is required. The example runs on Node.js 20, 21, or 22, imports @alx-protocol/sdk and @alx-protocol/sdk/merkle, and executes entirely offchain.
Expected result: valid is true for the selected leaf and corresponding sorted-pair proof.
Create verify-inclusion.mjs:
import {deriveBlockHash} from '@alx-protocol/sdk';
import {
buildMerkleTree,
getMerkleProof,
verifyMerkleProof,
} from '@alx-protocol/sdk/merkle';
const leaves = ['alpha', 'beta', 'gamma'].map((value) => deriveBlockHash(value, []));
const {root} = buildMerkleTree(leaves);
const inclusion = getMerkleProof(leaves, leaves[1]);
if (!inclusion) throw new Error('leaf not found');
const valid = verifyMerkleProof(root, inclusion.leaf, inclusion.proof);
console.log(JSON.stringify({root, leaf: inclusion.leaf, proof: inclusion.proof, valid}, null, 2));
if (!valid) process.exitCode = 1;
node verify-inclusion.mjs
The selected leaf verifies; changing the leaf or any proof element makes verification return false.
valid must be true. For a single leaf, the returned root equals the leaf, and an empty proof verifies by direct equality. The output contains the Merkle root hash, selected leaf, proof sibling array, and result:
{
"root": "0xdab052a390cc6b8f22fb03e6b05845a556b8a60bb1b0520bfa3faa99a0608e1a",
"leaf": "0x701838ded5090272f83af395663b65ce449d310be50a9d4b4edab0c6e891d262",
"proof": [
"0x0cf565667a4a4b86e51a5f067dca168851c575a79723aad7b92354fdc8df07d8",
"0xdbab2d8278d7ae88c6d7c1e3e4957256da2771367a3a07c0301a297d8a299817"
],
"valid": true
}
A modified leaf or proof fails; an unavailable leaf produces no proof.
- Replace the selected leaf after proof generation: verification returns false.
- Replace any proof element: verification returns false.
- Request a leaf not present in the leaf collection:
getMerkleProofreturnsnull.
Offchain verification evaluates a supplied Merkle root without a network connection or deployed contract. To pair inclusion with onchain record evidence, check that the Merkle root hash was recorded. ALXAnchor stores bytes32 values and exposes isAnchored, anchoredAt, and anchoredBy. anchoredAt and anchoredBy describe the first record of each value. ALXAnchor does not verify Merkle proofs. The supported Base deployment, ALXAnchor, is listed on the ALX on Base page.