如何为 NFT 开发 pre-reveal 预披露机制?

每当一款类似于“Bored Ape Yacht Club”这种 PFP 风格NFT集合推出时,为每一个NFT使用一个占位符图像,并且只有在所有 NFT 都被创建后才显示最终的 NFT 的方式,已经成为一种常见的做法。我们可以称这种方式为预披露机制。

这是一个重要的操作,因为没有它,人们可以根据元数据暴露的特性的稀缺性来选择创建哪些NFT。

在开始构建此功能之前,让我们先看一下业务需求:

  • 隐藏代币和元数据,直到所有代币都被铸造。
  • 一旦用户铸造了代币,就向他们发送一个“pre-reveal”版本的代币。
  • 允许合约所有者“显示”集合中的所有代币。

我们的智能合约负责返回每个代币 metadata.json 文件所在的 URL。

解决上述问题的方法是创建一个“pre-reveal”元数据文件,并将其上传到某处。这个“pre-reveal URI”是在显示发生之前,我们希望为每个代币返回的URI。

在此之后,我们能够使用一个新URL来更新智能合约,该URL可用于生成正确的代币URI。

例如,如果我们已经将所有的代币上传到一个响应为 https://exmaple.org/tokens/:tokenId 的 web 服务器上,那么我们希望用自己的 baseURI(https://example.org/tokens/) 来更新智能合约,这样可以通过简单地将 tokenID 附加到 baseURI 来轻松地生成正确的 tokenURI

有了这些知识,现可以将问题重新定义为智能合约的更具体的要求:

  • 当集合尚未显示时,它应该返回通用元数据。
  • 它应该允许合约所有者更新baseURI
  • 当显示代币时,它应该返回正确的元数据。

实现 NFT pre-reveal 功能

假设我们正在为 NFT 集合开发一个智能合约,该集合扩展了通常的 OpenZeppelinERC721来实现。

如果检查ERC721.sol合约,就会发现tokenURI实现了一个功能。

这个功能就是上图中 OpenZeppelin 对 tokenURI 的实现。这段代码主要是把 baseURI 与正在检索的 tokenID 连接起来。

这对于 AFTER reveal 非常有用,但是对于 pre-reveal,我们需要重写这个函数来返回 pre-reveal URI:

可以注意到在这里引用了两个全局变量:isRevealedpreRevealURI。可以随心所欲地实现它们,但最简单的方法是,在合约的顶部定义它们:

接下来,我们需要创建一个函数来“显示”代币。

上面的 reveal 函数将传递的 baseURI 保存到一个名为 postRevealBaseURI 的全局变量中,并将 isreveal 布尔值设置为 true

_isreveal 布尔值设置为 true,然后我们之前编写的 tokenURI 函数将推迟到父类的实现。

这个实现调用_baseURI函数来检索基本URI。

如果检查该实现,我们可以看到它实际上可以被覆盖:

让我们使用 OpenZeppelin 并重写 _baseURI 函数来返回正确的基本 URI!

至此,我们便已了解了一种实现 NFT pre-reveal 预披露机制的简单、安全且有效的方法。