This is a fork of @polytope-labs/solidity-merkle-trees which slims the Merkle Tree Solidity libraries down to Ethereum-only utilities, and converts the library methods to be
internalsuch that they do not be independently deployed and invoked using adelegatecall. It also increases the Solidity version requirement to 0.8.18
This library contains the implementations of various merkle tree verification algorithms. Currently supported algorithms:
- Merkle Trees (supports unbalanced trees).
- Merkle Mountain Ranges.
- Merkle-Patricia Trie.
npm install @polytope-labs/solidity-merkle-trees
This algorithm is based on the research done here: https://research.polytope.technology/merkle-multi-proofs
You can use it to verify proofs like so:
pragma solidity ^0.8.0;
import "@polytope-labs/solidity-merkle-trees/MerkleMultiProof.sol";
contract YourContract {
function verify(
bytes32 root,
Node[][] memory proof,
Node[] leaves
) public {
require(MerkleMultiProof.VerifyProof(root, proof, leaves), "Invalid proof");
}
}You can generate the 2D merkle multi proofs using this rust lib polytope-labs/rs-merkle
This algorithm is based on the research done here: https://research.polytope.technology/merkle-mountain-range-multi-proofs
You can use it to verify proofs like so:
pragma solidity ^0.8.0;
import "@polytope-labs/solidity-merkle-trees/MerkleMountainRange.sol";
contract YourContract {
function verify(
bytes32 root,
bytes32[] memory proof,
MmrLeaf[] memory leaves,
uint256 mmrSize
) public {
require(MerkleMountainRange.VerifyProof(root, proof, leaves, mmrSize), "Invalid proof");
}
}You can derive the k-indices for the mmr leaves using this rust lib polytope-labs/merkle-mountain-range.
This library also supports the verification of the different styles of merkle patricia tries:
- Ethereum
- NEAR
pragma solidity ^0.8.0;
import "@polytope-labs/solidity-merkle-trees/MerklePatricia.sol";
contract YourContract {
function verifyEthereumProof(
bytes32 root,
bytes[] memory proof,
bytes[] memory keys,
) public {
// verifies ethereum specific merkle patricia proofs as described by EIP-1188.
// can be used to verify the receipt trie, transaction trie and state trie
// contributed by @ripa1995
bytes[] values = MerklePatricia.VerifyEthereumProof(root, proof, keys);
// do something with the verified values.
}
}This guide assumes Rust...along with it's nightly version, Solidity, cargo-fuzz and Forge are installed, if not browse the official websites/repositories for instructions.
Change into the forge directory and build the contracts;
cd forge
forge buildTo run the unit tests associated with the Merkle Multi Proof library;
cargo test --lib merkle_multi_proofTo run the unit tests associated with the Merkle Mountain Range library;
cargo test --lib merkle_mountain_rangeTo run the unit and fuzz tests associated with the Merkle Patricia Trie library;
cargo test --lib merkle_patricia
cargo +nightly fuzz run trie_proof_valid
cargo +nightly fuzz run trie_proof_invalidExecute the following commands in the project directory:
git submodule update --init --recursive
# run tests for all merkle verifiers
docker run --memory="24g" --rm --user root -v "$PWD":/app -w /app rust:latest cargo test --release --manifest-path=./forge/Cargo.toml
# fuzz the merkle-patricia verifier
docker build -t test .
docker run --memory="24g" --rm --user root -v "$PWD":/app -w /app/forge/fuzz test cargo +nightly fuzz run trie_proof_valid
docker run --memory="24g" --rm --user root -v "$PWD":/app -w /app/forge/fuzz test cargo +nightly fuzz run trie_proof_invalid
This library is licensed under the Apache 2.0 License, Copyright (c) 2023 Polytope Labs.
