如何在不发出传输的情况下在 erc721 上调用 _mint()

How to call _mint() on erc721 without emit Transfer

我读到 here 可以在单笔交易中铸造 2^256 个 nft。我试图通过直接分配 _owners 和 _balances 映射来实现这一点,但是这些是私有变量,所以我无法更改它们。我尝试进行 _mint() 覆盖,但这也没有用。这个过程是如何运作的?

老实说,我不知道如果不支付高得离谱的汽油,这怎么可能。你为什么要铸造那么多代币?你想把所有的 NFT 都收集到一个集合中吗?如果是这样,无论如何你都必须为每个薄荷支付 gas 费用。

为了简化,让我们做一个 10k NFT 的场景。

这不是调用单个 mint() 函数 10k 次,而是以允许设置一系列有效 ID 的方式构建合约逻辑。

使用 IPFS 的 MFS 部分,您可以使用相同的目录 ID 和实际文件名将多个文件上传到一个文件夹中。示例:

https://ipfs.io/ipfs/<dir_id_abc>/1.json
https://ipfs.io/ipfs/<dir_id_abc>/2.json
https://ipfs.io/ipfs/<dir_id_abc>/3.json
etc...

这些元数据文件包含图像链接。

然后,如果满足以下两个条件,您的合约可以实现一个自定义功能,将授权地址隐藏为 NFT 的所有者:

  1. ID 在有效范围内(在我们的例子中是 1-10k)
  2. NFT 不属于任何其他人所有(即它属于默认地址 0x0
function _exists(uint256 tokenId) override internal view returns (bool) {
    if (tokenId >= 1 && tokenId <= 10000) {
        return true;
    }

    return super._exists(tokenId);
}

function ownerOf(uint256 tokenId) override public view returns (address) {
    address owner = _owners[tokenId];

    // The ID is in a valid range (in our case 1-10k)
    // The NFT is not owned by anybody else (i.e. it's owned by the default address 0x0)
    if (tokenId >= 1 && tokenId <= 10000 && owner == address(0x0)) {
        // shadows an authorized address as an owner
        return address(0x123);
    }

    return super.ownerOf(tokenId);
}

tokenURI() 函数然后验证令牌是否存在(使用 _exists() 函数)和 returns 从基本 URI (https://ipfs.io/ipfs/<dir_id_abc>/) 连接的最终 URI, ID,以及 .json 后缀。

请注意,这种方法 不适用于 OpenZeppelin 实现,因为它们的 _owners 属性 是 private 并且无法从 child合同。但是您可以将此片段作为自定义实现的灵感,允许模拟 10k(甚至 2^256)个令牌的任意默认所有者。