ethereumsoliditytruffleopenzeppelin

DeclarationError: Undeclared identifier - although it's present in ERC721.sol


I am writing a contract on solidity 0.8.3 and I get this strange error for _setTokenURI() although the method is defined in OpenZeppelin 4.X.

pragma solidity ^0.8.3;

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

contract NFTB is ERC721 {

  using Counters for Counters.Counter;
  Counters.Counter private _tokenIds;
  mapping(string => uint8) hashes;

  constructor() public ERC721("NFTB", "NFTB") {}

  function awardItem(address recipient, string memory hash, string memory metadata) public returns (uint256) {
    require(hashes[hash] != 1);
    hashes[hash] = 1;
    _tokenIds.increment();
    uint256 newItemId = _tokenIds.current();
    _setTokenURI(newItemId, metadata);
    _mint(recipient, newItemId);
    return newItemId;
  } }

enter image description here


Solution

  • Function _setTokenURI() is defined in @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol (source on GitHub), but this contract is not imported by your code (including nested imports). That's why the function is undeclared.

    Since ERC721URIStorage extends ERC721, you can extend your NFTB directly from ERC721URIStorage.

    import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; // changed import
    import "@openzeppelin/contracts/utils/Counters.sol";
    
    contract NFTB is ERC721URIStorage { // changed parent