[SOLVED] MerkleProof: returns true with getter, returns false calling from another function!

I’m going crazy with a check I’m doing for a merkle tree. The reality is that it was working for me and all of a sudden it started to fail.

Let’s see, here are these two functions. If you invoke isvalid() directly, I’ve made it public for access, it will return true if it is true. But what is crazy is that if I call it from safeMint() it returns false!!!

This is in view form because I’m testing to see what happens… what’s going on here?

    function safeMint(bytes32[] memory proof) public view returns (bool) {
     //   require(isValid(proof, keccak256(abi.encodePacked(msg.sender))), "No pertenece a la White List");
        if (isValid(proof, keccak256(abi.encodePacked(msg.sender)))) return true;
        return false;
        // _tokenIdCounter.increment();
        // uint256 tokenId = _tokenIdCounter.current();
        // _safeMint(msg.sender, tokenId);
    }

    function isValid(bytes32[] memory proof, bytes32 leaf) public view returns (bool) {
        return MerkleProof.verify(proof, rootUsers[msg.sender], leaf);
    }

I am sending you all the original contract so that you can make the proofs. You have to make a merkle tree with your proof.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

contract NFT_MERKLE is ERC721 {
    using Counters for Counters.Counter;
    mapping(address => bytes32) public rootUsers;

    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("NFT ARBOL DE MERKLE", "NFTMER") {}

    function safeMint(bytes32[] memory proof) public {
        require(isValid(proof, keccak256(abi.encodePacked(msg.sender))), "No pertenece a la White List");
        _tokenIdCounter.increment();
        uint256 tokenId = _tokenIdCounter.current();
        _safeMint(msg.sender, tokenId);
    }

    function isValid(bytes32[] memory proof, bytes32 leaf) public view returns (bool) {
        return MerkleProof.verify(proof, rootUsers[msg.sender], leaf);
    }

    function rootUser(bytes32 _rootUser) public  {
         rootUsers[msg.sender] = _rootUser;
    }
}

I put in a mapping each root per user because it is a contract of formative interest. I want that each account can register its own root and validate its own tree.

I have discovered where the error is
the function

keccak256(abi.encodePacked(msg.sender)))

returns a different value than in my javascript that captured the last recorded value.
The tests were almost always performed with the valid account in the last position and for that reason I did not realize the error, since it only failed sometimes.
When doing the checks the leaf always passed its validation by getter, but when I captured my account with the msg.sender was when it rejected the transaction.
Sorry for the post creation and if you want you can delete it.

Not a problem - can be useful for someone else who has a similar issue.

1 Like