Getting error :"Error: execution reverted: ERC721: balance query for the zero address"

I deployed a contract on the Goerli tesnet, I am trying to interect with it with an application that I am building. I did some tests on the contract on Remix and everything worked fine. I also did a quick dapp with OneClickDapp.com. And also with that there has been no problems. I am now trying to interact with it via a local host and a simple dapp that I am building with react. The contract is an ERC-721 for which I activated a public _mint function and I created my send a little add_on, which requires the caller of the _mint function to have a _balanceOf >= 0.

:computer: Environment
I am using the lastest verrsions of Open Zeppelin. I developed the smart contract on Remix, deployed it on Goerli via injeted web3 on Remix, and I am coding the dAPP with visual studio code.

:memo:Details
When I perform a request for minting from my dApp i get an error which comes from the _balanceOf function of the ERC-721. The error says Error: execution reverted: ERC721: balance query for the zero address. in the attributes for the .send method I inserted the address of the user which is actually connected to the dAPP. In my code i requested that the _balanceOf of the message.sender shall be >= 0. Since I am getting this error I suppose that address from which the request comes may not be the one of the user connected to the dAPP…
I am new to programming so please bear this in mind when answering me =)

:1234: Code to reproduce
Her the code I wrote to deploy the ERC-721:

pragma solidity ^0.8.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";

contract NftExample is ERC721, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("ZION Invite NFTv0.1", "ZIONiv0.1") {}

    function mintNft(address receiver) external onlyOwner returns (uint256) {
        _tokenIds.increment();

        uint256 newNftTokenId = _tokenIds.current();
        _mint(receiver, newNftTokenId);

        return newNftTokenId;
    }

    function mintNftOwners(address receiver) external returns (uint256) {
        _tokenIds.increment();

        uint256 newNftTokenId = _tokenIds.current();
        _mint(receiver, newNftTokenId);

        require (balanceOf(msg.sender) >= 0);
        return newNftTokenId;
    }

}

and here the code for a React component:

import Web3 from "web3";
import { inviteNFT } from "../Abi/inviteNFT";

// let web3 = new Web3(Web3.givenProvider)
// let userAccount = web3.givenProvider.selectedAddress;
// note, contract address must match the address provided by Truffle after migrations
const web3 = new Web3(Web3.givenProvider);
const contractAddr = "0x045d57645680285D74DC87a39a62cA7EE6608991";
const SimpleContract = new web3.eth.Contract(inviteNFT, contractAddr);
let userAccount = web3.givenProvider.selectedAddress;

export default function InviteNFT() {
  const [address, setAddress] = useState(0);
  const [getBalance, setGetBalance] = useState(0x00);

  const handleSet = async (e) => {
    e.preventDefault();
    const gas = await SimpleContract.methods.mintNftOwners(address).estimateGas();
    const result = await SimpleContract.methods
      .mintNftOwners(address)
      .send({ from: userAccount, gas });
    console.log(result);
  };

  const handleGet = async (e) => {
    e.preventDefault();
    const accounts = await window.ethereum.enable();
    const account = accounts[0];
    const result = await SimpleContract.methods.balanceOf(account).call();
    setGetBalance(result);
    console.log(result);
  };

  return (
    <div className="App">
      <header className="App-header">
        <form onSubmit={handleSet}>
          <label>
            Set address: <br />
            <input
              type="text"
              name="name"
              value={address}
              onChange={(e) => setAddress(e.target.value)}
            />
          </label>{" "}
          <br />
          <input type="submit" value="Set address" />
        </form>
        <br />
        <button onClick={handleGet} type="button">
          Your Balance
        </button>
        {getBalance}
        <div>Ciao {userAccount}</div>
      </header>
    </div>
  );
}

Thank in advance =)

1 Like

Just like the error said, you can check what this account address really is.

1 Like

Hi @giacomogagliano,

Welcome to the community :wave:

Please note, we should only use contracts from an official release of OpenZeppelin Contracts. Currently you are importing from the master branch. We can specify a release tag when importing from GitHub.

As per @skyge I assume that accounts[0] isn’t set. I assume you haven’t connected to MetaMask (if you are using MetaMask).

1 Like

Yeah, in fact I was able to succeed enabling metamask with await window.ethereum.enable(); and now it works fine =).
About importing source, I copied the address from the browser, sorry fro my ignorance!! Where can I find the official release contracts?
Am a total noob still :face_with_hand_over_mouth:
thank for the welcome :facepunch:

1 Like

Hi @giacomogagliano,

In GitHub you can specify the tag to use:

The URLs are as follows:
OpenZeppelin Contracts 4.0.0 release candidate:

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.0.0-rc.0/contracts/token/ERC721/ERC721.sol

OpenZeppelin Contracts 3.4.0:

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC721/ERC721.sol

Everyone was new once, and not that long ago. I have been in blockchain for nearly 4 years.


You may also want to look at: Create an NFT and deploy to a public testnet, using Truffle

1 Like

Well, in fact I’m noob in any type of programming language =) But I find this so fascinating my mind wants more hihi

1 Like