3

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.");
    }
}
730wavy
  • 944
  • 1
  • 19
  • 57

0 Answers0