un.Block

Posted on Oct 09, 2021Read on Mirror.xyz

ERC721

NFT 背后的技术是 ERC721 或 ERC1155, 今天我们就来学习一下 ERC721 的开发,说不定过两周 un.Block 就有自己的 NFT 了

NFT 的组成

首先,在 ERC721 的合约中,每个 NFT 都有以下内容

  • name: 代币名字
  • symbol: 代币符号
  • tokenID: 代币编号
  • URI: NFT元数据

其中,元数据是 NFT 最重要的部分,它直接决定了 NFT 里面存放的内容。对于一些图片类的 NFT ,元数据通常都会存放图片的链接字符串,这个链接可能是中心化网站的链接(就像我们日常用的图床链接一样),或者是 ipfs 链接。

实际上,元数据可以存放的不只有字符串,以下是在 EIP-721 中给出的元数据示例:

关于 NFT 元数据的存储问题,在之前的周报 #12#13 已经解释过了,大家有兴趣可以自行阅读。

漫游 ERC721

EIP-721 给了关于 ERC721 的 3 个接口,分别是:

  • IERC721: 核心 ERC721
  • IERC721Metadata: ERC721 元数据
  • IERC721Enumerable: 关于 ERC721 的供应量、序号之类的数字接口

其中,IERC721 是唯一必须实现的接口,但这个接口过于简单,几乎没有项目会只实现一个 IERC721 就发布。

因此,我们将和大家分享多一些关于 ERC721 实用接口。

除了上述的 3 个接口之外,还有以下功能可以让 ERC721 锦上添花:

  • ERC721Pausable: 暂停 ERC721 代币交易
  • ERC721Burnable: 摧毁代币!
  • AccessControl: 合约权限管理

OpenZepplin 给出了一个功能较为完善的 ERC721 合约范例 —— ERC721PresetMinterPauserAutoId 这个范例能在 ERC721 的基础上实现以下功能:

  • 允许用户摧毁掉自己的代币
  • 一个铸造者 (minter) 角色来负责铸造代币
  • 一个交易管理员角色 (pauser),有权暂停代币转账
  • 自动生成代币编号(tokenID) 和 元数据 (URI)

ERC721: 元数据与铸币

ERC721 在某些功能,如查询余额、授权、转账,与 ERC20 如出一辙(我们在 #9 跟大家介绍过 ERC20),值得深入了解的就是 ERC721 的元数据与铸币过程

1⃣️元数据以 mapping 的形式存储

1⃣️ 通过 _setTokenURI 函数,我们可以设置 URI,这里需要传入 tokenID 和 URI元数据

3⃣️ ERC721 的 _mint 函数和 ERC20 很相似,本质就是将代币分发给用户,由于 tokenID 代表了 NFT 代币,因此调用 mint 函数的时候只需要指定用户和 tokenID 即可

值得一提的是,OpenZepplin 并不推荐我们直接使用 _mint,而是推荐使用 _safeMint 来铸造代币

_safeMint 会在铸造前进行检查,要求如下:

  • tokenID 需要不存在,可以理解为这个 tokenID 对应的 NFT 还没有被铸造
  • 收款地址需要有接受 ERC721 代币的能力,这个检查主要是针对为了合约接收代币

相关阅读: