跳转至主要内容

如何创建和发行 ERC-721(NFT)

更新于
2025年11月26日

阅读时间 8 分钟

引言

自《Cryptokitties》发布以来,符合 ERC-721 标准的数字收藏品便大受欢迎,并在过去几个月里得到了广泛采用。本指南将介绍如何使用智能合约库0xcert/ethereum-erc721来创建和发布我们自己的 ERC-721(NFT)。

什么是不可替代代币?

“可替代性”意味着它们是相同的,或者可以互换。例如,以太坊的代币,同一类别的所有代币都具有相同的价值。卡尔达诺的代币也是如此。可替代代币可以按1:1的比例互换。

基于这一点,NFT 是独一无二的,每个 NFT 都各不相同,且具有独特的特征。 可以作为NFT的物品包括收藏卡、艺术品、机票等。它们彼此之间都有明显的区别,且不可互换。不妨将非同质化代币(NFT)视为极其稀有的收藏品,每件都拥有独特的特征、非同寻常的属性,而且在大多数情况下,还带有其专属的元数据。

什么是 ERC-721?

ERC 是“以太坊意见征询”(Ethereum Request for Comment)的缩写,721 是该提案的编号。ERC 是以太坊生态系统中的应用层标准,例如ERC-20 就是一种智能合约标准。

ERC提案的作者有责任与以太坊社区达成共识;一旦提案经社区审查并批准,它便成为一项标准。你可以在这里查看所有最新的ERC提案。

ERC-721 的设计初衷是为智能合约中的 NFT 提供追踪和转移功能。

ERC-721是一项开放标准,描述了如何在兼容 EVM(以太坊虚拟机)的区块链上创建非同质化代币(NFT)。它定义了一套规则,使处理 NFT 变得更加便捷。NFT 不仅包括 ERC-721 代币,还可以是ERC-1155 代币。

以下是 ERC-721 标准中定义的功能和事件:

ERC-721 定义了一些符合 ERC-20 标准的函数。这使得在某些现有的钱包中显示代币信息变得更加容易。

ERC-20 功能

  • 名称:用于确定其他合约或应用程序可用于识别您的名称。
  • 符号:用于确定符号或简称。
  • totalSupply:该函数用于定义区块链中现有的代币总量,该数值不一定是常量。
  • balanceOf:返回某个地址持有的 NFT 数量。

与代币所有权相关的功能

  • ownerOf:该函数返回代币所有者的地址。由于每个 ERC-721 代币都是唯一的且不可互换的,因此它们在区块链上通过一个 ID 来表示。其他用户、合约或应用程序可以使用该 ID 来确定代币的所有者。
  • 批准:此功能用于批准代币转账。
  • takeOwnership:这是一个可选函数,用于从用户处提取代币,前提是该地址此前已获准提取代币。
  • 转账:一项功能,允许代币持有者将其代币转账至其他地址,就像转账任何其他代币或货币一样。
  • tokenOfOwnerByIndex:这是一个可选函数,但强烈建议实现。每个代币持有者可以同时拥有多个相同的 NFT。每个 NFT 的唯一 ID 有助于识别它们,但随着数量增加,追踪这些 ID 会变得非常困难。因此,合约会记录与持有者相关的 ID,而该函数使我们能够获取进行追踪所需的相应信息。

元数据功能

  • tokenMetadata:此可选特性是一个接口,可用于获取令牌的相关信息。

活动

  • 转账:当代币的所有者发生变更时,会触发此事件。该事件会发布有关代币由哪个地址转出、哪个地址接收以及转出的代币ID等信息。
  • 批准:当一个用户批准另一个用户可以使用该代币时,会触发此事件,例如在调用 approve 函数时。该事件会返回以下信息:当前持有该代币的地址、被批准将来可以使用该代币的地址,以及被批准拥有该代币的所有权的代币 ID。

非同质化代币(NFT)的应用场景:

  • 数字艺术(或实体艺术):这是 NFT 最受欢迎的应用场景。数字艺术拍卖是 NFT 的早期应用之一,且仍在持续增长
  • 游戏:用于提供游戏内购和收藏品。
  • 房地产:能够将房产通证化,并生成智能合约以实现买卖交易。
  • 财务:金融工具,如贷款、期货及其他负债。
  • 软件:软件许可,旨在保障反盗版和隐私保护。
  • 音乐会或体育赛事门票:为了防止票务销售中的欺诈行为,并让粉丝们有一个集中平台来回顾过去的体验。

获取 ETH 测试币

既然我们已经了解了 ERC-721 代币是什么以及它是如何运作的,接下来就来看看如何创建并发行我们自己的代币。

我们将把合约部署到 Ropsten 测试链上。首先,你需要安装Metamask浏览器扩展程序,以便创建一个 ETH 钱包,并从Ropsten 水龙头获取少量测试用 ETH。在你的 Metamask 钱包中选择“Ropsten 测试网”,将钱包地址复制到水龙头的文本框中,然后点击“Send me test Ether”。

将文件添加到 IPFS

在编写 NFT 合约之前,我们需要保存与该 NFT 相关的艺术作品并创建一个元数据文件,为此,我们将使用IPFS——一个分布式文件共享系统。请按照以下IPFS 安装指南,为您的操作系统下载并安装 IPFS CLI。

以下是保存图像和元数据文件的步骤

步骤 1:创建 IPFS 存储库 在终端中输入以下命令以启动 IPFS 存储库

ipfs init

步骤 2:启动 IPFS 监视器

打开一个新的终端窗口,并输入以下命令

IPFS 守护进程

步骤 3:将图片添加到 IPFS

在第一个终端中添加图片(此处为 art.png)

ipfs 添加 art.png

复制以 Qm 开头的哈希值,并在开头添加https://ipfs.io/ipfs/,结果应类似于以下内容:https://ipfs.io/ipfs/QmQEVVLJUR1WLN15S49rzDJsSP7za9DxeqpUzWuG4aondg

步骤 4:将 JSON 文件添加到 IPFS

创建一个名为 nft.json 的 JSON 文件,并将其保存到图片所在的同一目录下。

JSON 文件:

{
"name": "NFT Art",
"description": "This image shows the true nature of NFT.",
"image": "https://ipfs.io/ipfs/QmZzBdKF7sQX1Q49CQGmreuZHxt9sVB3hTc3TTXYcVZ7jC",
}

现在,将该 JSON 文件添加到 IPFS 中

ipfs 添加 nft.json

复制以 Qm 开头的哈希值,并在开头添加https://ipfs.io/ipfs/,结果应类似于以下内容:https://ipfs.io/ipfs/QmUFbUjAifv9GwJo7ufTB5sccnrNqELhDMafoEmZdPPng7

请查看这个网址,我们需要它来发布我们的NFT。

创建我们的代币

为了方便和安全起见,我们将使用0xcert/ethereum-erc721来创建我们的 NFT 合约。使用 0xcert/ethereum-erc721 时,我们无需从头编写整个 ERC-721 接口,而是可以直接导入并使用其中的函数。

请访问Ethereum RemixIDE,并创建一个新的 Solidity 文件,例如 - nft.sol

将以下代码粘贴到你的新 Solidity 文件中:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;

import "https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/nf-token-metadata.sol";
import "https://github.com/0xcert/ethereum-erc721/src/contracts/ownership/ownable.sol";

contract newNFT is NFTokenMetadata, Ownable {

constructor() {
nftName = "Synth NFT";
nftSymbol = "SYN";
}

function mint(address _to, uint256 _tokenId, string calldata _uri) external onlyOwner {
super._mint(_to, _tokenId);
super._setTokenUri(_tokenId, _uri);
}

}

上述代码的说明:

第 1 行:SPDX 许可证类型的指定,这是 Solidity ^0.6.8 之后的必要补充。 每当智能合约代码向公众公开时,这些许可都能帮助解决并避免版权方面的纠纷。如果您不想指定任何许可类型,可以使用“Unlicensed”值,或者直接不添加该注释(这不会导致错误,仅会显示一条提示)。

第 2 行:声明智能合约的 Solidity 版本。

第4-5行:导入合约 0xcert/ethereum-erc721

第7行:合约以“newNFT”为名开始,该合约继承了名为“NFTokenMetadata”和“Ownable”的其他合约。

第9-12行:初始化构造函数并设置名称,即我们令牌的符号。

第 14 行:我们声明了一个带有三个参数的 mint 函数:类型为 address 的变量 _to,用于存储将接收 NFT 代币的地址;类型为 uint256 的变量 _tokenId,用于存储代币的 ID;以及类型为 string 的变量 _uri,用于存储 JSON 文件的 URI。 将该 mint 函数声明为 external,意味着其他智能合约以及该合约自身作用域之外的程序均可调用它。

第 15 行:使用将接收该代币的地址和代币 ID 来存储该代币。

第 16 行:使用令牌 ID 和 JSON 文件的 URI 来设置 URI。

编译智能合约,并使用注入的 Web3 进行部署(在编译合约之前,请确保在 Metamask 中已选择 Ropsten 测试网)。

在 Metamask 中确认交易。

如果在部署前收到“此合约可能是抽象合约”的错误提示,请确保在“合约”选项中选择了正确的合约。

现在请转到 Remix 中的“已部署合约”部分,展开刚刚部署的合约。你会看到许多函数/方法。展开 mint 函数,并添加以下详细信息:

  1. 将您的 Ropsten 地址添加到 _to 字段中
  2. 在 _tokenid 字段中添加一个数字(建议填 1,因为这是第一个)
  3. 将 JSON 文件的 URI 添加到 _uri 字段中,该 URI 我们在上一节中已获取。

点击“Transact”,并在 Metamask 中确认该操作。现在,你已在 Ropsten 网络上持有该代币。

您可以通过输入前面提到的 tokenid,来核对其他详细信息,例如名称、符号、所有者和 tokenuri。

结论

恭喜你成功创建了自己的 NFT!你可以帮助一位艺术家朋友,将他们的艺术作品发布到以太坊网络上,或者自己也成为一名艺术家。你可以查看0xcert/ethereum-erc721 的 GitHub页面,获取更多示例。

订阅我们的新闻通讯,获取更多关于以太坊的文章和指南。如果您有任何意见或建议,欢迎在我们的Twitter 上留言。您随时可以在我们的Discord 服务器上与我们交流,那里聚集了许多顶尖的开发者 :)

分享本指南