OpenZeppelin ERC721 URIStorage 實現缺少可列舉函式
我正在嘗試使用預設的 OpenZeppelin 4.x ERC721URIStorage 實現來建構 ERC721 合約。在此 URL ( https://docs.openzeppelin.com/contracts/4.x/erc721 ) 的文件中,您可以找到以下文本:
ERC721URIStorage 合約是 ERC721 的實現,包括所有標準擴展(IERC721Metadata 和 IERC721Enumerable)。
現在,如果您在此處查看 IERC721Enumerable 介面文件(https://docs.openzeppelin.com/contracts/4.x/api/token/erc721#IERC721Enumerable),您可以看到有一個tokenOfOwnerByIndex函式,但不幸的是它不可用在 OpenZeppelin ERC712URIStorage 實現中,因為它應該根據文件。
我錯過了什麼還是 OpenZeppelin 文件有誤?
這是程式碼:
// contracts/GameItem.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract GameItem is ERC721URIStorage { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor() ERC721("GameItem", "ITM") {} function awardItem(address player, string memory tokenURI) public returns (uint256) { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _mint(player, newItemId); _setTokenURI(newItemId, tokenURI); return newItemId; } }
ERC721URIStorage 合約是 ERC721 的實現,包括所有標準擴展(IERC721Metadata 和 IERC721Enumerable)。
不, ERC721 oz 實現只包括
IERC721Metadata
擴展而不包括IERC721Enumerable
tokenOfOwner
可作為ERC721Enumerable
擴展的一部分而且你只是繼承自
ERC721URIStorage
,實習生只繼承自ERC721
實現,它只包括Metadata extension
請參閱下面的 ERC721 實現描述,
ERC721URIStorage
您的範例合約使用該實現:ERC721 不可替代令牌標準的實施,包括元數據擴展,但不包括可作為 ERC721Enumerable 單獨提供的 Enumerable 擴展。
您的範例的完整實現如下:
// contracts/GameItem.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract GameItem is ERC721URIStorage, ERC721Enumerable, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor() ERC721("GameItem", "ITM") {} function awardItem(address player, string memory tokenURI) public returns (uint256) { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _mint(player, newItemId); _setTokenURI(newItemId, tokenURI); return newItemId; } function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId); } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { super._burn(tokenId); } function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { return super.tokenURI(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } function safeMint(address to, uint256 tokenId) public onlyOwner { _safeMint(to, tokenId); } }
IDK 我對我的答案的感覺如何,但我所做的是我進入我的 node_modules 文件夾,並將 ERC721Enumerable 中的所有程式碼複製到 ERC721URIStorage 中,這就是我能夠組合兩個模組的方式。不確定這是否是正確的解決方法,但到目前為止它已在我的程式碼中執行