如何修复未声明的标识符,即使它存在于 ERC721Enumerable 中

How to fix undeclared identifier even though its present in ERC721Enumerable

我正在尝试准备一个 solidity 智能合约,一切看起来都很好,除了 remix 编译器上的一个未声明的错误。错误代码如下:

from solidity:
DeclarationError: Undeclared identifier.
  --> contracts/WTest.sol:66:22:
   |
66 |     uint256 supply = totalSupply();
   |                      ^^^^^^^^^^^

供参考,我的代码如下:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.2;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract WTest is ERC721, ERC721Burnable, Ownable {
    using Strings for uint256;
    using SafeMath for uint256;


    uint256 public mintPrice;
    address public blackHoleAddress;
    
    ERC721 public crateContract;

    string public baseURI;
    string public baseExtension = ".json";
    mapping(uint256 => bool) private _crateProcessList;

    bool public paused = false;
    bool public revealed = false;

    uint256 public maxSupply = 5000;
    uint256 public maxPrivateSupply = 580;
    uint256 public maxMintAmount = 20;
    string public notRevealedUri;

    event OperationResult(bool result, uint256 itemId);
   

    constructor() ERC721("WTest", "WTST") {}

    function _baseURI() internal view virtual override returns (string memory) {
    return baseURI;
  }

    function setBASEURI(string memory newuri) public onlyOwner {
        baseURI = newuri;
    }

     function setMintPrice(uint256 _mintPrice) public onlyOwner  returns(bool success) {
        mintPrice = _mintPrice;
        return true;
    }

    function getMintPrice() public view returns (uint256)
    {
    return mintPrice;
    }

    function setBlackHoleAddress(address _blackHoleAddress) public onlyOwner  returns(bool success) {
        blackHoleAddress = _blackHoleAddress;
        return true;
    }


    function setcrateContractAddress(ERC721 _crateContractAddress) public onlyOwner returns (bool success) {
        crateContract = _crateContractAddress;
        return true;
    }
function mint(uint256 _mintAmount) public payable {
    uint256 supply = totalSupply();
    require(!paused);
    require(_mintAmount > 0);
    require(_mintAmount <= maxMintAmount);
    require(supply + _mintAmount <= maxSupply);

    if (msg.sender != owner()) {
      require(msg.value >= mintPrice * _mintAmount);
    }

    for (uint256 i = 1; i <= _mintAmount; i++) {
      _safeMint(msg.sender, supply + i);
    }
  }

如您所见,我已经引用了 ERC721Enumerable.sol

如果能帮助我理解哪里出了问题,我们将不胜感激。

您必须扩展ERC721Enumerable,然后您才能使用totalSupply()功能。 您的智能合约应该与此类似:

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract WTest is ERC721, ERC721Enumerable, ERC721Burnable, Ownable {
    using Strings for uint256;
    using SafeMath for uint256;


    uint256 public mintPrice;
    address public blackHoleAddress;
    
    ERC721 public crateContract;

    string public baseURI;
    string public baseExtension = ".json";
    mapping(uint256 => bool) private _crateProcessList;

    bool public paused = false;
    bool public revealed = false;

    uint256 public maxSupply = 5000;
    uint256 public maxPrivateSupply = 580;
    uint256 public maxMintAmount = 20;
    string public notRevealedUri;

    event OperationResult(bool result, uint256 itemId);
   

    constructor() ERC721("WTest", "WTST") {}

    function _baseURI() internal view virtual override returns (string memory) {
    return baseURI;
  }

    function setBASEURI(string memory newuri) public onlyOwner {
        baseURI = newuri;
    }

     function setMintPrice(uint256 _mintPrice) public onlyOwner  returns(bool success) {
        mintPrice = _mintPrice;
        return true;
    }

    function getMintPrice() public view returns (uint256)
    {
    return mintPrice;
    }

    function setBlackHoleAddress(address _blackHoleAddress) public onlyOwner  returns(bool success) {
        blackHoleAddress = _blackHoleAddress;
        return true;
    }


    function setcrateContractAddress(ERC721 _crateContractAddress) public onlyOwner returns (bool success) {
        crateContract = _crateContractAddress;
        return true;
    }

    function mint(uint256 _mintAmount) public payable {
        uint256 supply = totalSupply();
        require(!paused);
        require(_mintAmount > 0);
        require(_mintAmount <= maxMintAmount);
        require(supply + _mintAmount <= maxSupply);

        if (msg.sender != owner()) {
        require(msg.value >= mintPrice * _mintAmount);
        }

        for (uint256 i = 1; i <= _mintAmount; i++) {
        _safeMint(msg.sender, supply + i);
        }
    }

    // NOTE: Override ERC721Enumerable functions
    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) {
        return super.supportsInterface(interfaceId);
    }

}