You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Remix中使用Counters库时遭遇DeclarationError错误求助

Solidity合约Counters库引用错误修复方案

问题详情

运行名为NFTCollection的ERC721合约时,第20行代码using Counters for Counters.counter;触发错误:

DeclarationError: Identifier not found or not unique

原合约代码:

pragma solidity ^0.8.4;
// Importing required libraries
/*
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/591c12d22de283a297e2b551175ccc914c938391/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/591c12d22de283a297e2b551175ccc914c938391/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/591c12d22de283a297e2b551175ccc914c938391/contracts/utils/Counters.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/591c12d22de283a297e2b551175ccc914c938391/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
*/


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

 // This is a simple NFT contract
 //Start of a contract
 //INitialising contract as a ERC721, ERC721Enumerable, Ownable contract.
 contract NFTCollection is ERC721, ERC721Enumerable, Ownable {
    using Counters for Counters.counter;

    // Specifing the maximum supply
    uint256 maxSupply = 1000000;
    // Initiatina a counter to store to be able to use Counters on uint265 without impacting the rest of the uint256 in the contract.
    //Counter helps to find every function from a single library to a type to reduce gass fee.
    Counters.Counter private _tokenIDCounter;
    // Initialising a constructor.
    constructor(string memory _name, string memory _symbol)
        ERC721(_name, _symbol){}
        // ERC721 interface is initialised and the _name, _symbol details aere passed in to hold.
        //End of constructor. 
        //Start of function mint.
        //This function is used to mint ERC721 tokens. 
        //Mint function adds the capability to mint ERC721 tokens and assign it to a address which accepts user address, number of tokens as arguments. 

        function mint(address _user, uint256 _amount) public {
            //Start of for loop
            for(uint256 i;i<_amount;i++)
            {
                //Incrementing the  _tokenIdCounter by 1 using increment function.
                _tokenIdCounter.increment();
                // Creating a variable which stores the current value of _tokenIdCounter.
                uint256 tokenId = _tokenIdcounter.current();
                //Using safemint to mint ERC721 Tokens.
                _safeMint(_user,tokenId);
            }
        }//End of function mint. 

        //Start of function tokensOfOwner
        // This function is used to keep track of the owners Tokens. 
        // The function seeks a owner address to check the number of tokens he owns. 
        function tokensOfOwner(address _owner) public view returns (uint256[] memory)
        {   // Creating a ownerTokenCount which stores the balance of the owner.
            uint256 ownerTokenCount = balanceOf(_owner);
            // Creating a memory variable and storing a array of ownerTokenCount. 
            uint256[] memory ownedTokenIds = new uint256[](ownerTokenCount);
            for (uint256 i; i < ownerTokenCount; ++i) {
                ownedTokenIds[i] = tokenOfOwnerByIndex(_owner, i);
            }//End of for loop
        return ownedTokenIds; //Return statement.
    }
    // Function overrides required by solidity
    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);
    }


 }

错误信息:

--> contracts/nft.sol:20:24:
|
20 | using Counters for Counters.counter;~~~

错误原因及修复步骤

1. Counters库类型大小写错误

Solidity是区分大小写的语言,OpenZeppelin的Counters库中定义的类型是**Counters.Counter**(首字母大写),原代码中写的Counters.counter(小写c)导致编译器无法识别该类型。

修复:将第20行改为:

using Counters for Counters.Counter;

2. 变量名大小写不一致

mint函数中定义的计数器变量是_tokenIDCounter,但调用时写成了_tokenIdcounter(最后一个字母c小写),触发未定义变量错误。

修复:将mint函数中的uint256 tokenId = _tokenIdcounter.current();改为:

uint256 tokenId = _tokenIDCounter.current();

修正后的完整合约代码

pragma solidity ^0.8.4;

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

contract NFTCollection is ERC721, ERC721Enumerable, Ownable {
    // 修复:Counters.Counter首字母大写
    using Counters for Counters.Counter;

    uint256 maxSupply = 1000000;
    Counters.Counter private _tokenIDCounter;

    constructor(string memory _name, string memory _symbol)
        ERC721(_name, _symbol){}

    function mint(address _user, uint256 _amount) public {
        for(uint256 i;i<_amount;i++)
        {
            _tokenIDCounter.increment();
            // 修复:变量名统一为_tokenIDCounter
            uint256 tokenId = _tokenIDCounter.current();
            // 补充:检查是否超过最大供应量
            require(tokenId <= maxSupply, "Max supply reached");
            _safeMint(_user,tokenId);
        }
    }

    function tokensOfOwner(address _owner) public view returns (uint256[] memory)
    {   
        uint256 ownerTokenCount = balanceOf(_owner);
        uint256[] memory ownedTokenIds = new uint256[](ownerTokenCount);
        for (uint256 i; i < ownerTokenCount; ++i) {
            ownedTokenIds[i] = tokenOfOwnerByIndex(_owner, i);
        }
        return ownedTokenIds;
    }

    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);
    }
 }

额外补充:在mint函数中添加了最大供应量检查,避免铸造超过上限的代币,增强合约安全性。

内容的提问来源于stack exchange,提问作者andhra bullodu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:45:23