阅读时间 12 分钟
概述
自《Cryptokitties》推出以来,符合 ERC-721 标准的数字收藏品已广受欢迎,并在近几个月朝着被广泛采用的方向迈进。本指南将介绍如何使用OpenZeppelin标准创建和部署 NFT(ERC-721)。
更喜欢视频教程吗?跟着 Radek 一起学习,20 分钟内掌握如何创建和部署 ERC-721(NFT)。
您将负责的工作内容
- 了解非同质化代币(NFT)及其应用场景
- 为即将构建的 ERC-721 代币创建元数据
- 将您的文件上传到去中心化存储系统(IPFS)
- 使用 Remix.IDE 创建并部署 ERC-721 代币
您需要准备的物品
- 一个 Quicknode 端点(您可以在这里免费创建一个)
- 一个内含测试版 ETH 的 Web3 钱包(例如 MetaMask、Coinbase Wallet、Phantom 或兼容 WalletConnect 的钱包)(您可以在Multi-Chain Quicknode 水龙头上获取一些)
- 已安装IPFS CLI
- 一款现代网络浏览器(例如 Chrome)
什么是不可替代代币?
“可替代性”是指相同或可互换。例如,以太坊代币——即某特定代币类别的所有成员——具有相同的价值。卡尔达诺代币也是如此。可替代代币可以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 功能
balanceOf:该函数用于返回特定地址持有的 NFT(非同质化代币)数量。
ownerOf:该函数返回特定代币所有者的地址。每个 ERC721 代币都是唯一的,由一个 ID 表示。该函数允许用户或应用程序根据代币的唯一 ID 确定其所有者。
safeTransferFrom(不带数据):该函数可将特定代币的所有权安全地从一个地址转移至另一个地址。该函数会检查接收方是否为智能合约。如果是,则必须实现一个特定函数(onERC721Received)才能接受该转账。
transferFrom:此函数用于将代币的所有权从一个地址转移到另一个地址。通常在发送方已获授权转移该代币时使用。
批准:此功能用于授权某个地址转出特定代币。这支持委托转账,即代币所有者可以允许另一方代表其转出代币。
getApproved:该函数用于获取特定代币的已授权地址。如果该代币没有已授权地址,则该函数将返回一个空地址。
setApprovalForAll:此函数允许一个或多个代币的所有者,授权或撤销对操作员的管理其所有代币的授权。
isApprovedForAll:该函数用于检查操作员是否被授权管理所有者的所有代币。
safeTransferFrom(带数据):该函数与 safeTransferFrom(不带数据)类似,但额外增加了一个数据参数。如果接收方是智能合约,则可利用该额外数据在转账过程中传递附加信息。该函数还会检查接收方是否为智能合约,以及其是否实现了 onERC721Received 函数。
ERC-721 活动
转账:当代币的所有权从一个地址转移到另一个地址时,会触发此事件。该事件包含有关发送方(from)、接收方(to)以及被转账的具体代币(按 ID 标识)的详细信息。此事件允许外部监听器(如用户界面或其他合约)对转账操作做出响应。
授权:当某个地址被授权转移特定代币时,会触发此事件。该事件包含代币的当前持有者(owner)、现已获授权可转移该代币的地址(approved),以及已被授权转移的特定代币(通过 ID 标识)。此事件使应用程序能够跟踪代币的授权情况并作出相应响应。
ApprovalForAll:当所有者批准或撤销对操作员管理其所有代币的授权时,会触发此事件。该事件包含所有者的地址(owner)、操作员的地址(operator)以及一个布尔值,用于指示操作员是否获得授权(approved)。该事件使应用程序能够追踪哪些地址已被授予管理特定所有者所有代币的权限。
非同质化代币(NFT)的应用场景
-
数字艺术(或实体艺术):艺术品是NFT最受欢迎的应用场景。数字艺术拍卖是NFT的首个应用领域,且仍在持续发展。
-
游戏:提供游戏内的购买项目和收藏品。
-
房地产:房产通证化、智能合约以及买卖操作。
-
金融:包括贷款、期货等金融工具及其他相关责任。
-
软件名称:用于确保打击盗版和保护隐私的软件许可证。
-
演唱会门票/体育赛事门票:为确保售票过程中杜绝欺诈行为,并让粉丝们能够在一个地方查看过往的观赛体验。
-
KYC合规:为特定用户的KYC创建一个代币。
获取测试以太币
既然我们已经了解了什么是 ERC-721 代币以及它们的工作原理,接下来让我们看看如何构建和部署自己的代币。
我们将把合约部署到以太坊 Sepolia 测试网。开始之前,您需要安装MetaMask浏览器扩展程序(或其他兼容的 web3 钱包,如 Phantom 或支持 WalletConnect 的钱包),并准备一些测试用 ETH——您可以通过访问Quicknode 多链水龙头获取。只需连接您的钱包或粘贴地址,然后点击“继续”即可。 系统会提示您分享一条推文以获取奖励(我们建议您这样做!);否则,只需点击“不用了,直接给我 0.05 ETH”即可。请注意,要在以太坊主网使用 EVM 水龙头,主网余额需达到 0.001 ETH。

将文件添加到 IPFS
在编写 NFT 合约之前,我们需要托管用于 NFT 的艺术作品并创建元数据文件;为此,我们将使用IPFS——一个点对点文件存储和共享的分布式系统。 与 IPFS 协议交互的方法有多种。您可以选择在自己的系统上部署并运行 IPFS,也可以选择 Quicknode 这一更简便的解决方案。Quicknode 通过管理底层基础设施,简化了您对 IPFS 的访问。这种方法让您能够专注于内容本身,免去了为数据固定而维护本地 IPFS 节点的负担。借助 Quicknode,技术上的复杂问题将由其为您处理。
我们将介绍两种将文件上传至 IPFS 的方法:使用标准的 IPFS 命令行界面(CLI),或者使用简化的Quicknode IPFS 服务。
标准方法:使用 IPFS 命令行界面 (CLI)
请按照IPFS 文档中的安装指南,根据您的操作系统下载并安装 IPFS CLI。
以下是托管图像和元数据文件的步骤。
步骤 1:创建 IPFS 仓库
在终端/命令提示符窗口中输入以下内容,启动 IPFS 仓库。
ipfs init
步骤 2:启动 IPFS 守护进程
启动 IPFS 守护进程,打开另一个终端/命令提示符窗口,然后输入以下内容。
IPFS 守护进程
第 3 步:将图片添加到 IPFS
切换到第一个终端窗口,将图片(此处为 art.png)上传到 IPFS。
ipfs add 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 add nft.json
取以Qm开头的哈希值,并在其前加上“https://ipfs.io/ipfs/”作为前缀;结果应类似于https://ipfs.io/ipfs/QmUFbUjAifv9GwJo7ufTB5sccnrNqELhDMafoEmZdPPng7
请保存此网址。我们需要它来铸造我们的 NFT。
Quicknode IPFS 解决方案:一种更简便的替代方案
如需进一步了解 Quicknode IPFS 的价格信息,请点击此处查看我们的定价方案。
如果您正在寻找一种更简便的方法,Quicknode 的 IPFS 服务可为您提供一种易于使用且高效的 NFT 资产上传方案。借助 Quicknode,您无需再为管理基础设施的复杂性而烦恼,从而能够专注于内容创作,而非维护本地 IPFS 节点。
要开始使用 Quicknode 访问 IPFS,请按照以下步骤操作:
步骤 1:登录 Quicknode
登录Quicknode,然后从左侧边栏中选择“IPFS”选项:

步骤 2:使用 Quicknode 将图片上传到 IPFS
您可以通过拖放或点击从“Finder”/“文件资源管理器”窗口中选择文件,快速上传图像文件。在本指南中,我们将使用下图。

上传完成后,在“文件”选项卡中点击文件名,然后点击“复制IPFS 链接”按钮。如下图所示。
https://qn-shared.quicknode-ipfs.com/ipfs/QmQEVVLJUR1WLN15S49rzDJsSP7za9DxeqpUzWuG4aondg

第 3 步:使用 Quicknode 将 JSON 文件上传到 IPFS
创建一个名为 nft.json, 请在 图片 字段,然后保存。保存后,将您的 JSON 文件上传到 IPFS,操作方法与上一步类似。
{
"name": "NFT Art",
"description": "This image shows the true nature of NFT.",
"image": "https://qn-shared.quicknode-ipfs.com/ipfs/QmQEVVLJUR1WLN15S49rzDJsSP7za9DxeqpUzWuG4aondg"
}
上传完成后,在“文件”选项卡中点击文件名,然后复制 IPFS 链接。该链接应与下方的示例类似。
https://qn-shared.quicknode-ipfs.com/ipfs/QmeVHZzKGEDbEbG5MVz4hUucNf4qZTRfW18AgdJNTrv22m
请保存此网址。我们需要它来铸造我们的 NFT。
创建我们自己的代币
为了方便和安全起见,我们将使用OpenZeppelin的ERC-721合约来创建我们的 NFT。借助 OpenZeppelin,我们无需编写完整的 ERC-721 接口,而是可以导入该库合约并使用其中的函数。
请前往以太坊 RemixIDE,创建一个新的 Solidity 文件,例如:MyToken.sol
将以下代码粘贴到你的新 Solidity 脚本中:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts@5.0.0/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts@5.0.0/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts@5.0.0/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts@5.0.0/access/Ownable.sol";
contract MyToken is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
constructor(address initialOwner)
ERC721("MyToken", "MTK")
Ownable(initialOwner)
{}
function safeMint(address to, uint256 tokenId, string memory uri)
public
onlyOwner
{
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
// The following functions are overrides required by Solidity.
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721URIStorage)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
上述代码的说明:
第 1 行:将 SPDX 许可类型指定为 MIT。这表明该代码采用 MIT 许可,这是一种宽松的开源许可,允许在几乎没有限制的情况下使用、修改和分发该代码。
第 2 行:声明 Solidity 版本为 ^0.8.20。这表示该代码是使用 Solidity 0.8.20 版本或与其兼容的版本编写的。
第 4-7 行:从 OpenZeppelin 库导入必要的合约。
-
ERC721.sol:该合约从 OpenZeppelin 库中导入,实现了 ERC721 标准的基础功能。ERC721 是非同质化代币(NFT)的标准。
-
ERC721URIStorage.sol:该合约继承了 ERC721 标准,并增加了用于存储和管理与 NFT 相关的元数据 URI 的功能。元数据 URI 通常指向有关该 NFT 的附加信息。
-
ERC721Burnable.sol:该合约同样扩展了 ERC721 标准,并增加了销毁(销毁)NFT 的功能。它提供了一个用于将 NFT 永久移出流通领域的函数,且仅限所有者调用该函数。
-
Ownable.sol:该合约用于访问控制。它允许您指定一名拥有合约内特殊权限的所有者。该所有者可以执行其他用户无法执行的某些操作。
第 9 行:启动名为 MyToken 并提到它扩展了 ERC721、ERC721URIStorage 和 Ownable 合约。这意味着该 MyToken 该合约继承了这些合约中定义的功能和属性。
第 10 行:构造函数从这里开始。在 Solidity 中,构造函数是一种特殊函数,仅在合约部署时执行一次。该构造函数接受一个参数, 初始所有者,这是一个以太坊地址。
第 11 行:该行调用 ERC721 合约的构造函数,传入的参数为“MyToken”和“MTK”。它将 NFT 合约的名称初始化为“MyToken”,符号初始化为“MTK”。
第 12 行:此行调用了 Ownable 合约的构造函数,将 MyToken 合约的初始所有者设置为作为 initialOwner 提供的地址。
第 15 行:声明函数 safeMint 该函数有三个参数:to(NFT 代币接收者的地址)、tokenId(代币的唯一标识符)和 uri(与该代币关联的 JSON 文件的 URI)。该函数仅可由合约所有者调用(由 onlyOwner 修饰符)。
第 19 行:通过调用 _safeMint 从 ERC721 合约继承的函数。它会创建一个新代币,并将其分配给指定的接收者地址。
第 20 行:使用 _setTokenURI 从……继承的函数 ERC721URIStorage 合同。URI 是根据提供的 tokenId 和 uri 设置的。
第 25-32 行:实现 Solidity 要求的对 ERC721 以及 ERC721URIStorage 合同。 tokenURI 这是一个用于检索与给定 tokenId 关联的元数据 URI 的函数。它被标记为 public 和 view,表明这是一个只读函数,任何人都可以调用它。
第 34-41 行:实现 supportsInterface 函数,该函数是 ERC721 以及 ERC721URIStorage 合约。该函数用于检查给定的 interfaceId 是否受该合约支持,并据此返回一个布尔值。
通过结合这些功能和合约,该代码创建了一个名为 MyToken. 该合约允许合约所有者安全地铸造新代币,为其关联元数据 URI,并支持 ERC721 标准定义的必要接口。
现在,如果您愿意,请花一分钟时间根据您的具体情况自定义智能合约。您可以通过修改以下这一行来更新代币名称和符号—— ERC721("MyToken", "MTK").
完成后,请编译智能合约,并使用以下命令将其部署: 注入的提供者 (在编译合约之前,请务必在 Metamask 上选择 Sepolia 测试网)。然后,将您的钱包地址粘贴到紧邻 部署 按钮以定义 初始所有者 构造函数的参数。最后,点击 部署 在 Remix.IDE 上。

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

现在请转到 Remix 中的“已部署合约”部分,并展开该已部署合约。你会看到许多函数/方法。展开 safeMint 函数,并添加以下详细信息:
- 在_to字段中添加您的钱包地址。
- 在_tokenId字段中输入任意“大数”值。我们建议使用“1”,因为它代表正在铸造的第一个代币。
- 对于 _uri 在该字段中,输入与您在上一步骤中使用的方法相对应的 JSON 文件的 URI:
- 如果您使用了标准的 IPFS CLI 方法:请使用在“标准方法:使用 IPFS CLI”一节中将文件上传至 IPFS 后获得的 URI。该 URI 是以https://ipfs.io/ipfs/ 为前缀,后跟文件哈希值的 IPFS 链接。
- 如果您选择了 Quicknode 的 IPFS 服务: 请在“Quicknode IPFS 解决方案:更简便的选择”一节中上传文件后,使用 Quicknode 提供的 URI。Quicknode 会为您的文件生成一个唯一的 URI,您应将其填入此处。

点击“交易”,并在 MetaMask 中确认交易。这可能需要几分钟时间,但您可以随时通过Etherscan 等区块浏览器确认交易是否已执行。现在,您已在 Sepolia 链上拥有了该 NFT。
您可以查看其他详细信息,例如 名称, 符号, ownerOf,或 tokenURI 输入我们之前提到的令牌 ID。

结论
恭喜您成功创建了自己的NFT!您可以帮助艺术家朋友将他们的艺术作品发布到以太坊区块链上,或者自己成为一名艺术家。查看OpenZeppelin 的向导以获取更多示例。
订阅我们的通讯,获取更多关于以太坊的文章和指南。如果您有任何反馈,欢迎通过Twitter 联系我们。您还可以随时在我们的Discord社区服务器上与我们交流,那里聚集了您能遇到的最酷的开发者们 :)
我们 ❤️ 您的反馈!
如果您有任何反馈或对新主题的建议,请告诉我们。我们非常期待您的来信。
