W3
EIP-721ERC代币标准Final(2018-01-24)

非同质化代币(NFT)标准

每个 tokenId 唯一、不可互换的所有权标准。核心是 ownerOf + 安全转账 + 授权与元数据扩展。

适用链:全部 EVM 链 + 各 L2

为什么重要:NFT 的「唯一性」不是靠图片,而是靠链上 tokenId 到 owner 的映射。看懂 ERC-721 就能一眼分辨「真上链的藏品」和「只是一张指向服务器的图片链接」。

函数签名与选择器

选择器是签名的 keccak256 前 4 字节;事件则是完整的 32 字节 topic0。 点一下即可复制。

签名 / 字段选择器 / topic0说明
balanceOf(address)该地址持有的 NFT 数量,不是 tokenId 列表。
ownerOf(uint256)tokenId 的持有人。不存在的 tokenId 必须 revert。
transferFrom(address,address,uint256)直接转移,不检查接收方是否支持(转进合约可能永久锁死)。
safeTransferFrom(address,address,uint256)推荐用法:接收方是合约时会调用 onERC721Received 检查。
safeTransferFrom(address,address,uint256,bytes)带额外 data,用于传递业务上下文。
approve(address,uint256)授权单个 tokenId 给某人。
setApprovalForAll(address,bool)授权全部藏品给某操作者,NFT 市场靠它挂单,也是被盗重灾区。
getApproved(uint256)查询单个 tokenId 的授权对象。
isApprovedForAll(address,address)查询操作者是否被全局授权。
supportInterface(bytes4)EIP-165:声明自己实现了 ERC-721 与 Metadata 扩展。
tokenURI(uint256)Metadata 扩展:返回元数据 JSON 的 URI。
event Transfer(address,address,uint256)事件与 ERC-20 同名但语义不同:第三个参数是 tokenId。

代码模板

最小实现(含 safeTransferFrom 接收检查)
最小实现(含 safeTransferFrom 接收检查)Solidity

转移时 delete _tokenApprovals 是必需的安全动作。漏掉它会让上一任 owner 给的授权在换手后依然有效。

元数据 JSON 的结构
元数据 JSON 的结构JSON

image 用 ipfs:// 而不是 https://,是区分「不可篡改」与「随时能换图」的关键信号。

实现与使用时的常见陷阱

  • setApprovalForAll 一旦授权,对方能搬走你该系列的全部藏品。挂单完成后及时撤销,或使用支持「限价单委托」的市场。
  • tokenURI 指向中心化服务器时,项目方随时能换掉图片,链上只留一个 tokenId。
  • transferFrom 不检查接收方,转进不支持 ERC-721 的合约会永久锁死;一律优先用 safeTransferFrom。
  • 实现 Metadata 扩展时 tokenURI 必须对不存在的 tokenId revert,返回空字符串会让市场显示成「无元数据」。
  • supportsInterface 要返回 true 的 id 必须与实际实现一致,否则部分市场会拒绝展示。

相关标准

同属「代币标准」的其他标准
想把这个标准用起来?开发者路径的第 1–2 阶段讲了怎么把它写进项目;合约 IDE里有对应的可编辑模板与静态自检;链上 API 参考则给出前端调用它的三种写法。