在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
相关产品推荐
相关产品推荐

