
Building a Privacy Mixer in Solidity: Why My Merkle Proofs Were Failing
Privacy in Web3 is often seen as a "black box" of complex zero-knowledge proofs. However, the heart of most privacy protocols like Tornado Cash is a much older and simpler structure: the Merkle Tree. Recently, while building a research-based ETH Mixer, I ran into a classic synchronization issue between on-chain verification and off-chain proof generation. Here is what I learned about Merkle Tree stability and how to avoid the "Invalid Proof" trap. The Architecture The goal was simple: Deposit: A user sends 1 ETH and a hash (commitment). Mix: The commitment is added to a Merkle Tree. Withdraw: The user provides a Merkle Proof to withdraw 1 ETH to a new address without revealing the original deposit. The Pitfall: Sorted Hashes Initially, I used a sorted-hash Merkle Tree. In this approach, nodes are sorted before hashing: Solidity // Vulnerable logic for manual proof generation computedHash = a <= b ? keccak256(abi.encodePacked(a, b)) : keccak256(abi.encodePacked(b, a)); The Problem: Whil
Continue reading on Dev.to
Opens in a new tab


