1

I'm trying to implement a smart contract whitelist using Merkle trees. I have been following along This tutorial. However, instead of using the generate part, I used the online tool here: https://lab.miguelmota.com/merkletreejs/example/

In the tutorial, this is the code to allow the Merkle tree proof into my contract:

bytes32 public merkleRoot;

    constructor(bytes32 merkleRoot_) ERC721('Excited Ape Yacht Club', 'EAYC') {
        merkleRoot = merkleRoot_;
    }

    function mint(uint256 quantity, bytes32[] calldata merkleProof) public {
        bytes32 node = keccak256(abi.encodePacked(msg.sender, quantity));
        require(MerkleProof.verify(merkleProof, merkleRoot, node), 'invalid proof');

        for (uint256 i = 0; i < quantity; i++) {
            uint256 tokenId = _tokenIds.current();
            _mint(msg.sender, tokenId);

            _tokenIds.increment();
        }
    }

However when I try to mint, I get the following error in Remix:

Fail with error 'invalid proof'

Using the online generator, I added in my 3 test addresses:

[
    "0xd27B22F898797e5b67748C4fEaAA267A0c4e692c",
    "0x696D3D057Fb1b3EE4f17ed5B8A771e5a0B6c0273",
    "0x73a5a5d09BD4CC7065Ef6D0E9B6544B82Ef1577d"
]

When I click compute, it gives me the following root:

0x40c352253148504193c8b7eaa9382f350fb285cc05b8e28b233cb06d6074f0d4

I then set this root like so:

 function setMerkleRoot(bytes32 _state) public onlyOwner {
        merkleRoot = _state;
    }

Now that is done and approves, I switch to "account 3". The online generator gives me the proof:

0xb9da26818c77fef205f0493b01019871f0972a9c0e6220951c168d6975ef1905

In the mint box, I add:

1, ["0x0bd01b10932d33b719364840269205a756359e0d4615c6ccde125d45db6984a2"]

Then it fails.

The decoded message for the input is

{
    "uint256 _mintAmount": "1",
    "bytes32[] merkleProof": [
        "0x0bd01b10932d33b719364840269205a756359e0d4615c6ccde125d45db6984a2"
    ]
}

When I use the verify section on that generator and enter in the details, It returns valid.

enter image description here

I'm at a loss as to what is wrong, any ideas?

1 Answer 1

1

When you're using the online generator you're using as leaf the address of the caller. In the solidity code you're using instead the hash of the address with the quantity of tokens to mint:

bytes32 node = keccak256(abi.encodePacked(msg.sender, quantity));

The solidity version is more correct, since you want to be sure the caller includes the correct number of tokens when calling the function. Otherwise users can use their personal merkle proof to mint how many tokens they want.

By the way, your code still allows the same person to continue minting using the same proof...

So, first you need to calculate the leaf for every user using the keccak256 formula, then use these leaves to calculate the merkle root and proofs.

5
  • Thank you. This was the solution. Because I skipped the generation part and used the online generator I failed to see this. Lesson learned haha.
    – JamesG
    Commented Jan 10, 2023 at 21:33
  • P.s I am already checking the max mint per address amount before the user can mint so I think that solves the other issue?
    – JamesG
    Commented Jan 10, 2023 at 21:39
  • @JamesG yeah think so. Glad I could help!
    – 0xSanson
    Commented Jan 10, 2023 at 23:05
  • As a thank you, would you like a spot on my free mint proj?
    – JamesG
    Commented Jan 11, 2023 at 0:51
  • 1
    No thanks, I'm out of crypto for now
    – 0xSanson
    Commented Jan 11, 2023 at 11:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.