I am trying to use merkletreejs in node to create a hexproof - using one it works fine but I also need it to be able to generate one proof for multiple leaves.
My current js code:
const { MerkleTree } = require('merkletreejs');
const keccak256 = require('keccak256');
let tokenIDs = [
"6719509505",
"6231137281",
"3766014977",
"4955017921",
"8583738032",
];
const leafNodes = tokenIDs.map(ids => keccak256(ids));
const merkleTree = new MerkleTree(leafNodes, keccak256, {sortLeaves: true, sortPairs: true});
const rootHash = merkleTree.getHexRoot();
// CLAIMING HERE
const claimingToken = keccak256("6719509505","6231137281","8583738032");
const hexProof = merkleTree.getHexProof(claimingToken);
console.log(merkleTree.verify(hexProof, claimingToken, rootHash));
When I try this though, it gives me the same proof as if I was only using the first token ID. Basically ignoring the other IDs I put.
And in solidity it's giving me invalid proof error:
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
contract merkle {
bytes32 private merkleRoot;
event leaf (
bytes32 leaf2
);
event ids (
uint256[] tokenID
);
event merk (
bytes32[] _merkleProof
);
function mint(bytes32[] calldata _merkleProof, uint256[] calldata tokenID) public {
bytes32 leaf2 = keccak256(abi.encodePacked(tokenID));
emit ids(tokenID);
emit leaf(leaf2);
emit merk(_merkleProof);
// Check for an invalid proof
require(MerkleProof.verify(_merkleProof, merkleRoot, leaf2), "Invalid Merkle Proof.");
}
}
Any ideas on how to generate one merkle proof using multiple leaves?
EDIT
I was told merkle tree can only verify one leaf at a time, so now I am trying to figure out how to send multiple proofs and verify each one in solidity.
In js I created a sample array with proofs -
let tokenMerkle = [];
tokenMerkle.push({tokenId: "6719509505", merkleProof: proof1});
tokenMerkle.push({tokenId: "6231137281", merkleProof: proof2});
tokenMerkle.push({tokenId: "6231137281", merkleProof: proof3});
I send that with my call to my contract. Not sure how to properly verify each one though using an array of arrays -
struct Proof {
uint tokenID;
bytes32[] _merkleProof;
}
function mint(Proof[] memory proofs) public {
for (uint i; i< proofs.length;i++){
bytes32 leafs = keccak256(abi.encodePacked(proofs[i].tokenID));
require(MerkleProof.verify(proofs[i]._merkleProof, merkleRoot, leafs), "Invalid Merkle Proof.");
}
}