编译 ERC721URIStorage 合约

Compiling an ERC721URIStorage contract

这个问题本质上是 的后续问题。我一直在尝试按照 Alchemy 文档创建 NFT 合约,但遇到了导入 ERC721URIStorage 的需求(如链接问题中所述)。但是,我现在遇到了一些对我来说意义不大的编译问题。

为了响应第一个错误(见下文),我尝试在 ERC721 的导入语句中添加:import "@openzeppelin/contracts/token/ERC721/ERC721.sol";这并没有改变编译错误集中的任何内容。

应该是这样的:>

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

contract LeafNFT is ERC721, ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("LeafNFT", "NFL") {}

    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

我能够让代码稍微改变一下。相关的混淆点好像是:

  • 是否应导入 {ERC721, ERC721URIStorage} 中的零个、一个或两个。答案似乎是只导入 ERC721URIStorage。
  • 合约是定义为ERC721URIStorage, ERC721, Ownable,还是定义为ERC721URIStorage, Ownable。答案似乎是后者。
  • 构造函数是使用ERC721还是ERC721URIStorage。答案好像是ERC721。

我认为前两点很直观(它们是我首先尝试并出现在问题所示代码中的东西)。这是因为 ERC721URIStorage 继承自 ERC721,因此无需显式导入 ERC721 或定义合约。

第三点出乎意料,但事后看来,我认为构造函数必须引用ERC721,因为ERC721URIStorage没有自己的构造函数,而且构造函数可以从哪里继承存在歧义(要么来自ERC721URIStorage 的父级或来自 Ownable。

工作合同如下: