如何创建 NFT
最后更新于
最后更新于
本教程将引导您使用以太坊和星际文件系统 (IPFS) 编写和部署不可替代 (ERC721) 令牌智能合约。
完成本指南的预计时间:~15 分钟
即使你一直生活在岩石下,你也会注意到每个主要新闻媒体都在描述 NFT 的兴起。
随着 NFT 将区块链带入公众视野,现在是通过在以太坊区块链上发布您自己的 NFT(ERC-721 代币)来了解炒作的绝佳机会!
在本教程中,我们将逐步使用Metamask、Solidity、Hardhat、Pinata和Alchemy在 Goerli 测试网络上创建和部署 ERC-721 智能合约(如果您还不明白其中的任何含义,请不要担心——我们会解释)。
有很多方法可以向以太坊区块链发出请求,但为了让事情变得最简单,我们将在Alchemy上使用一个免费帐户,这是一个区块链开发平台和 API,允许我们与以太坊链进行通信而无需运行我们自己的节点。
在本教程中,我们还将利用 Alchemy 的开发人员工具进行监控和分析,以了解智能合约部署的幕后情况。
创建 Alchemy 帐户后,您可以通过创建应用程序来生成 API 密钥。这将允许我们向 Goerli 测试网络发出请求。如果您想了解有关测试网络的更多信息,请查看本指南。
1、通过将鼠标悬停在导航栏中的“应用程序”上并单击“创建应用程序”,导航到 Alchemy 仪表板中的“创建应用程序”页面
2、为您的应用命名(我们选择“我的第一个 NFT!”),提供简短描述,为环境选择“Staging”(用于您的应用簿记),并为您的网络选择“Goerli”。
3、单击“创建应用程序”即可!您的应用程序应出现在下表中。
我们需要一个以太坊账户来发送和接收交易。在本教程中,我们将使用 Metamask,这是浏览器中的一个虚拟钱包,用于管理您的以太坊帐户地址。如果您想了解更多有关以太坊交易如何运作的信息,请查看以太坊基金会的此页面。
您可以在此处免费下载并创建 Metamask 帐户。当您正在创建一个帐户时,或者如果您已经有一个帐户,请确保切换到右上角的“Goerli 测试网络”(这样我们就不会处理真钱)。
为了将我们的智能合约部署到测试网络,我们需要一些假 Eth。要获取 Eth,您可以前往Goerli Faucet 并输入您的 Goerli 帐户地址,然后单击“发送给我 Eth”。不久之后,您应该会在您的 Metamask 帐户中看到 Eth!
为了仔细检查我们的余额,让我们使用Alchemy 的 composer 工具发出eth_getBalance请求。这将返回我们钱包中的 ETH 数量。输入您的 Metamask 帐户地址并单击“发送请求”后,您应该会看到如下响应:
{“jsonrpc”:“2.0”,“id”:0,“结果”:“0xde0b6b3a7640000”}
注意:这个结果是在 wei 而不是 eth 中。魏被用作以太的最小面额。从 wei 到 eth 的转换是:1 eth = 10¹⁸ wei。因此,如果我们将 0xde0b6b3a7640000 转换为十进制,我们将得到 1*10¹⁸,等于 1 eth。
呸!我们的假钱都在那里!🤑
首先,我们需要为我们的项目创建一个文件夹。导航到您的命令行并键入:
现在我们在我们的项目文件夹中,我们将使用 npm init 来初始化项目。如果您还没有安装 npm,请按照这些说明进行操作(我们还需要Node.js,所以也下载它!)。
您如何回答安装问题并不重要,以下是我们的回答方式以供参考:
批准 package.json,我们就可以开始了!
Hardhat 是一个用于编译、部署、测试和调试以太坊软件的开发环境。它可以帮助开发人员在部署到实时链之前在本地构建智能合约和 dApp。
导航到终端并确保您位于 my-nft 项目文件夹中,然后运行:
查看此页面以获取有关安装说明的更多详细信息。
在我们的项目文件夹中运行:
然后您应该会看到一条欢迎消息和选择您想要执行的操作的选项。选择“创建一个空的 hardhat.config.js”:
这将为我们生成一个hardhat.config.js文件,我们将在其中指定项目的所有设置(第 13 步)。
为了让我们的项目井井有条,我们将创建两个新文件夹。在命令行中导航到项目的根目录并键入:
contracts/是我们保存 NFT 智能合约代码的地方
scripts/是我们将保留脚本以部署并与我们的智能合约交互的地方
现在我们的环境已经设置好了,接下来是更令人兴奋的事情:编写我们的智能合约代码!
在您喜欢的编辑器(我们喜欢VSCode)中打开 my-nft 项目。智能合约是用一种叫做 Solidity 的语言编写的,我们将用它来编写我们的 MyNFT.sol 智能合约。
1. 导航到“contracts”文件夹并创建一个名为 MyNFT.sol 的新文件
2. 下面是我们的 NFT 智能合约代码,它基于OpenZeppelin库的 ERC721 实现。将以下内容复制并粘贴到您的 MyNFT.sol 文件中。
注意:如果您想通过智能合约为 NFT 附加价格,请查看本教程。
1. 因为我们从 OpenZepplin 合约库继承类,所以在命令行中运行以下命令将库安装到我们的文件夹中:
npm 安装@openzeppelin/ contracts @3.1.0-solc-0.7
那么,这段代码究竟做了什么?让我们逐行分解它。
在第 5-7 行,我们的代码继承了三个OpenZepplin智能合约类:
- @openzeppelin/contracts/token/ERC721/ERC721.sol包含ERC721标准的实现,我们的NFT智能合约将继承该标准。(要成为有效的 NFT,您的智能合约必须实现 ERC721 标准的所有方法。)要了解有关继承的 ERC721 功能的更多信息,请查看此处的接口定义。
- @openzeppelin/contracts/utils/Counters.sol 提供了只能递增或递减 1 的计数器。我们的智能合约使用一个计数器来跟踪铸造的 NFT 总数,并为我们的新 NFT 设置唯一 ID。每个使用智能合约铸造的 NFT 都必须分配一个唯一 ID——这里我们的唯一 ID 仅由现有 NFT 的总数决定。例如,我们用智能合约铸造的第一个 NFT 的 ID 为“1”,第二个 NFT 的 ID 为“2”,等等。
- @openzeppelin/contracts/access/Ownable.sol 在我们的智能合约上设置访问控制,因此只有智能合约的所有者(您)才能铸造 NFT。请注意,包括访问控制完全是一种偏好。如果您希望任何人都能够使用您的智能合约铸造 NFT,请删除第 10 行的 Ownable 和第 17 行的 onlyOwner 一词。
在第 10-28 行,我们有自定义的 NFT 智能合约,它非常短——它只包含一个计数器、一个构造函数和一个函数!这要归功于我们继承的 OpenZepplin 合约,它实现了我们创建 NFT 所需的大部分方法,例如 ownerOf(返回 NFT 的所有者)和 transferFrom(转移 NFT 的所有权)。
在第 14 行,您会注意到我们将 2 个字符串“MyNFT”和“NFT”传递给 ERC721 构造函数。第一个变量是智能合约的名称,第二个是它的符号。您可以随意命名这些变量中的每一个!
最后,从第 16 行开始,我们有函数 mintNFT() 允许我们铸造 NFT!你会注意到这个函数有两个变量:
- 地址收件人指定将接收您新鲜铸造的 NFT 的地址
- string memory tokenURI 是一个字符串,应该解析为描述 NFT 元数据的 JSON 文档。NFT 的元数据真正赋予它生命,使其具有额外的属性,例如名称、描述、图像和其他属性。在本教程的第 2 部分中,我们将描述如何配置此元数据。
mintNFT从继承的 ERC721 库中调用一些方法,并最终返回一个数字,代表新铸造的 NFT 的 ID。
现在我们已经创建了 Metamask 钱包、Alchemy 账户并编写了我们的智能合约,是时候连接这三者了。
从您的虚拟钱包发送的每笔交易都需要使用您唯一的私钥进行签名。为了向我们的程序提供此权限,我们可以安全地将私钥(和 Alchemy API 密钥)存储在环境文件中。
要了解有关发送交易的更多信息,请查看有关使用 web3 发送交易的教程。
首先,在您的项目目录中安装 dotenv 包:
然后,在我们项目的根目录中创建一个.env文件,并将您的 Metamask 私钥和 HTTP Alchemy API URL 添加到其中。
注意:您的 .env 文件必须命名为 .env !不要将名称更改为 xx.env
- 按照这些说明从 Metamask 导出您的私钥
- 请参阅下文以获取 HTTP Alchemy API URL 并将其复制到剪贴板
你的.env应该是这样的:
Ethers.js 是一个库,它通过使用更用户友好的方法包装标准 JSON-RPC 方法,使与以太坊交互和向以太坊发出请求变得更加容易。
Hardhat 使得集成插件以获得额外的工具和扩展功能变得超级容易。我们将利用Ethers 插件进行合约部署(Ethers.js有一些超级干净的合约部署方法)。
在您的项目目录类型中:
在下一步中,我们还将在我们的hardhat.config.js中需要以太币。
到目前为止,我们已经添加了几个依赖项和插件,现在我们需要更新hardhat.config.js以便我们的项目了解所有这些。
将hardhat.config.js更新为如下所示:
为了确保到目前为止一切正常,让我们编译我们的合约。编译任务是内置安全帽任务之一。
从命令行运行:
您可能会收到有关 SPDX 许可证标识符未在源文件中提供的警告,但无需担心 - 希望其他一切看起来都不错!如果没有,您可以随时在Alchemy discord中留言。
现在我们的合约已经编写好了,配置文件也准备好了,是时候编写我们的合约部署脚本了。
导航到scripts/文件夹并创建一个名为deploy.js的新文件,向其中添加以下内容:
Hardhat 在他们的Contracts 教程中解释了每一行代码的作用,做得非常出色,我们在这里采用了他们的解释。
ethers.js 中的ContractFactory是用于部署新智能合约的抽象,因此这里的 MyNFT 是我们 NFT 合约实例的工厂。当使用hardhat-ethers插件时, ContractFactory和Contract实例默认连接到第一个签名者。
在ContractFactory上调用deploy()将开始部署,并返回解析为Contract的Promise 。这是为我们的每个智能合约功能提供方法的对象。
我们终于准备好部署我们的智能合约了!导航回项目目录的根目录,并在命令行中运行:
然后你应该看到类似的东西:
如果我们去Goerli etherscan并搜索我们的合约地址,我们应该能够看到它已经部署成功。交易看起来像这样:
发件人地址应与您的 Metamask 帐户地址匹配,收件人地址将显示“合约创建”。如果我们点击进入交易,我们将在收件人字段中看到我们的合约地址:
哎呀!您刚刚将 NFT 智能合约部署到以太坊链 🎉
要了解幕后发生的事情,让我们导航到Alchemy 仪表板中的资源管理器选项卡。如果您有多个 Alchemy 应用程序,请确保按应用程序过滤并选择“MyNFT”。
在这里,您将看到 Hardhat/Ethers 在我们调用.deploy()函数时在后台为我们进行的一些 JSON-RPC 调用。
这里需要指出的两个重要的是eth_sendRawTransaction,这是将我们的智能合约实际写入 Goerli 链的请求,以及eth_getTransactionByHash,这是在给定哈希值的情况下读取有关我们交易的信息的请求(发送交易时的典型模式)。
要了解有关发送交易的更多信息,请查看有关使用 Web3 发送交易的教程。