Skip to content
LogoLogo

Light-client demo

A server commits rows to a Merkle root and sends one row plus its proof to a client. The client holds only the trusted root. Edit the rows, pick one to prove, then change the claimed value to see tampering rejected.

The browser mirrors BinaryMerkleTree<Sha256> with WebCrypto: leaves are SHA-256(0x00 ‖ row), internal nodes SHA-256(0x01 ‖ left ‖ right), and the leaf layer is padded to a power of two with Sha256::empty(). Roots match the Rust crate for the same rows.

1 · Server builds the tree
2 · Client receives a claim
3 · Stateless verification

The same flow in Rust

merkle-variants/examples/light_client.rs
use merkle_core::{error::MerkleError, types::LeafIndex};
use merkle_variants::BinaryMerkleTree;
use merkleforge_hash::Sha256;
 
fn main() -> Result<(), MerkleError> {
    let proof;
    let root;
 
    {
        let mut tree = BinaryMerkleTree::<Sha256>::new();
        tree.insert(b"tx:alice->bob:100")?;
        tree.insert(b"tx:bob->carol:50")?;
        tree.insert(b"tx:carol->dave:25")?;
 
        root = *tree.root().expect("tree has inserted leaves");
        proof = tree.generate_proof(LeafIndex(0))?;
 
        println!("server: built tree and exported root + proof");
    }
 
    let valid = BinaryMerkleTree::<Sha256>::verify(&root, b"tx:alice->bob:100", &proof);
 
    println!("client: tree dropped before verification");
    println!("Stateless verification: {valid}");
 
    Ok(())
}
git clone https://github.com/1888-Labs/MerkleForge.git
cd MerkleForge
cargo run -p merkle-variants --example light_client
server: built tree and exported root + proof
client: tree dropped before verification
Stateless verification: true

Learn more in Proofs & stateless verification.