A Node.js client–server project demonstrating Merkle Tree cryptographic proofs to verify list membership securely — without revealing the full dataset.
Originally based on the Alchemy University Week 2 assignment, this enhanced version focuses on data integrity, proof generation, and efficient verification using cryptographic hashing.
- Generate a Merkle Root representing the entire
niceList.json - Create proofs that a specific name exists in the list
- Verify those proofs on the server using only the stored Merkle Root
- Prevent tampering — any change in the list invalidates the root
- Demonstrates zero-knowledge style membership verification
cd client
npm install
node index.js💡 Edit the name variable in client/index.js to test different proofs. The client generates a Merkle proof for that name and sends it to the server.
cd server
npm install
node index.jsServer runs by default on port 1225. It stores only the Merkle Root — the minimal cryptographic fingerprint of the entire list.
A Merkle Tree is a cryptographic data structure that combines all data entries (in this case, 1000 names) into a single hash — the Merkle Root. Each pair of hashes is concatenated and hashed repeatedly until one hash remains.
Name → Leaf Hashes → Combined Hashes → Merkle Root
If even one character in the list changes, the resulting Merkle Root will be completely different.
On the client side, the proof for a specific name is generated:
const merkleTree = new MerkleTree(niceList);
const name = "Norman Block";
const index = niceList.findIndex(n => n === name);
const proof = merkleTree.getProof(index);This proof is a minimal set of sibling hashes that can reconstruct the Merkle Root.
On the server side, the proof is verified using the stored Merkle Root:
const isInTheList = verifyProof(proof, name, MERKLE\_ROOT);
if (isInTheList) {
res.send("🎁 You got a toy robot!");
} else {
res.send("🚫 You are not on the list.");
}This ensures the server can validate membership without ever needing to see or store the full list.
merkle-tree-giftlist/
│
├── client/ # Generates Merkle proof and sends request to server
├── server/ # Verifies proof using stored Merkle Root
└── utils/ # MerkleTree class, verifyProof function, and niceList.json| Concept | Description |
|---|---|
| Merkle Tree | Binary tree combining hashes of data to form a single root hash |
| Proof | Set of sibling hashes used to reconstruct the root for one leaf |
| Verification | Uses keccak256 to compare the reconstructed root with the known one |
| Hash Function | Ethereum’s keccak256 (same used in Ethereum addresses) |
| Library | ethereum-cryptography |
Titan Aji Nurceha
Developed as part of Alchemy University’s Web3 Developer Path.
Focused on cryptographic data verification and Merkle proof validation concepts.
This project builds upon the official Alchemy “Merkle Tree Gift List” exercise. You can view the original course and setup guide below 👇
📜 View Original Course README
To get started with the repository, clone it and then run npm install in the top-level directory to install the depedencies.
There are three folders in this repository:
You can run the client from the top-level directory with node client/index. This file is a script which will send an HTTP request to the server.
Think of the client as the prover here. It needs to prove to the server that some name is in the MERKLE_ROOT on the server.
You can run the server from the top-level directory with node server/index. This file is an express server which will be hosted on port 1225 and respond to the client's request.
Think of the server as the verifier here. It needs to verify that the name passed by the client is in the MERKLE_ROOT. If it is, then we can send the gift!
There are a few files in utils:
- The
niceList.jsonwhich contains all the names of the people who deserve a gift this year (this is randomly generated, feel free to add yourself and others to this list!) - The
example.jsscript shows how we can generate a root, generate a proof and verify that some value is in the root using the proof. Try it out from the top-level folder withnode/example.js - The
MerkleTree.jsshould look familiar from the Merkle Tree module! This one has been modified so you should not have to deal with any crypto type conversion. You can import this in your client/server - The
verifyProof.jsshould also look familiar. This was the last stage in the module. You can use this function to prove a name is in the merkle root, as show in the example.
- Backend: Node.js + Express
- Crypto Library: ethereum-cryptography (keccak256)
- Language: JavaScript (CommonJS)
- Data: JSON-based list (1000 names)
This project demonstrates:
- Efficient data verification using Merkle Trees
- Secure client–server communication with cryptographic proofs
- Real-world application of hash functions and proof verification in Web3 contexts