如何使用 web3.js 铸造 NFT
作者:Alchemy Team
本教程介绍如何使用 Web 3 以及我们在第一部分《How to Create an NFT》中创建的智能合约,在 Ethereum 区块链上铸造一个 NFT。
预计完成本指南所需时间:约 10 分钟
此外,别忘了查看我们 NFT 教程系列的其他文章:
- 🪄 How to mint an NFT with Ether.js
- 👛 How to view your NFT in your mobile wallet
- 💸 How to set a price on an NFT
- 💻 NFT minter tutorial: How to create a full stack dApp
“铸造 NFT”是指在区块链上发布你的 ERC721 代币的一个唯一实例。既然我们已经在本 NFT 教程系列第一部分中 将智能合约部署到了 Sepolia 网络,接下来就让我们运用 web3 技能来铸造一个 NFT 吧!
完成本教程后,你就可以用这段代码随意铸造任意数量的 NFT —— 现在开始吧!
第 1 步:安装 Web3
如果你完成了第一篇教程中关于创建 NFT 智能合约的内容,你应该已经使用过 Ethers.js。Web3 与 Ethers 类似,都是用于简化向 Ethereum 区块链发起请求的库。在本教程中,我们将使用 Alchemy Web3,这是一个增强版的 web3 库,提供自动重试和稳健的 WebSocket 支持。
在你的项目根目录下运行:
第 2 步:创建 mint-nft.js 文件
在 scripts 目录下创建一个 mint-nft.js 文件,并添加以下代码:
第 3 步:获取你的合约 ABI
我们的合约 ABI(Application Binary Interface,应用二进制接口)是与智能合约交互的接口。Hardhat 会自动为我们生成 ABI,并保存在 MyNFT.json 文件中。要使用它,我们需要在 mint-nft.js 文件中添加以下代码来解析出其内容:
如果你想查看这个 ABI,可以将其打印到控制台:
要运行 mint-nft.js 并在控制台看到打印出的 ABI,请前往终端运行
第 4 步:使用 IPFS 配置 NFT 的元数据
如果你还记得第一部分教程的内容,我们的 mintNFT 智能合约函数接受一个 tokenURI 参数,该参数应指向一个描述 NFT 元数据的 JSON 文档 —— 这正是赋予 NFT 生命力的关键所在,使其能够拥有可配置的属性,比如名称、描述、图片以及其他特征。
星际文件系统(Interplanetary File System,IPFS)是一种去中心化协议,也是一个用于在分布式文件系统中存储和共享数据的点对点网络。
我们将使用 Pinata——一个便捷的 IPFS API 和工具包——来存储我们的 NFT 资产和元数据,以确保 NFT 真正去中心化。如果你还没有 Pinata 账户,请前往 pinata.cloud 注册一个免费账户,并完成邮箱验证步骤。
创建好账户后:
- 点击右上角的“Pinata Upload”按钮
- 上传一张图片到 pinata —— 这将作为你的 NFT 图像资产。你可以随意为这个资产命名
- 上传完成后,页面顶部会出现一个绿色弹窗,让你查看上传内容的哈希值 —> 复制该哈希码。你可以在这里查看你的上传内容:
https://gateway.pinata.cloud/ipfs/<hash-code>
为方便更偏好可视化学习的读者,上述步骤总结如下:接下来,我们还需要再上传一份文档到 Pinata。但在此之前,我们需要先创建它!

在你的根目录下,新建一个名为 nft-metadata.json 的文件,并添加以下 json 代码:
你可以自由修改 json 中的数据,也可以在 attributes 部分增删内容。最重要的是,确保 image 字段指向你上传到 IPFS 的图片位置 —— 否则你的 NFT 将会带有一张(非常可爱的!)狗狗照片。
编辑完 json 文件后,保存它,并按照我们上传图片时的相同步骤,将其上传到 Pinata。

第 5 步:创建你的合约实例
现在,为了与我们的合约交互,我们需要在代码中创建它的一个实例。为此,我们需要合约地址,可以从部署记录中获取,也可以通过 Etherscan 查找你用于部署合约的地址来获取。

在上面的示例中,我们的合约地址是 0x81c587EB0fE773404c42c1d2666b5f557C470eED。
接下来,我们将使用 web3 的 contract 方法,通过 ABI 和地址创建我们的合约。在你的 mint-nft.js 文件中,添加以下内容:
第 6 步:更新 .env 文件
现在,为了创建并向 Ethereum 链发送交易,我们需要使用你的公共 ethereum 账户地址来获取账户的 nonce(下文会解释)。
将你的公钥添加到 .env 文件中 —— 如果你完成了教程第一部分,.env 文件现在应该是这样的:
第 7 步:创建你的交易
首先,让我们定义一个名为 mintNFT(tokenData) 的函数,并按照以下方式创建我们的交易:
- 从 .env 文件中取出你的 PRIVATE_KEY 和 PUBLIC_KEY。
- 接下来,我们需要确定账户的 nonce。nonce 规范用于记录从你的地址发出的交易数量 —— 这既是出于安全考虑,也是为了防止重放攻击。要获取从你的地址发出的交易数量,我们使用 getTransactionCount。
- 最后,我们用以下信息配置我们的交易:
- 'from': PUBLIC_KEY:我们交易的发起地址即我们的公共地址
- 'to': contractAddress:我们希望交互并发送交易的合约
- 'nonce': nonce:账户 nonce,即从我们地址发出的交易数量
- 'gas': estimatedGas:完成交易所需的预估 gas
- 'maxPriorityFeePerGas': estimatedFee:每单位 gas 的预估出价费用
- 'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI():我们希望在此交易中执行的计算 —— 在本例中即铸造一个 NFT
你的 mint-nft.js 文件现在应该是这样的:
如何铸造多个 NFT: 要在单条命令中铸造 x 个 NFT,我们可以在包装铸造过程的函数内使用一个从 0 到 x-1 的简单 for 循环。这样,每次调用该包装铸造函数时,就能有效铸造出 x 个 NFT。
第 8 步:签名交易
现在我们已经创建了交易,需要对其进行签名才能发送出去。这时我们就需要用到私钥了。
web3.eth.sendSignedTransaction 会返回交易哈希,我们可以用它来确认交易是否被成功打包,还是被网络丢弃了。你会注意到,在交易签名部分,我们添加了一些错误检查,以便知道交易是否成功发出。
第 9 步:调用 mintNFT 并运行 node contract-interact.js
还记得你上传到 Pinata 的 metadata.json 吗?从 Pinata 获取其哈希码,并将以下内容传入对 mintNFT 的调用 https://gateway.pinata.cloud/ipfs/
获取哈希码的方法如下:

在单独的窗口中打开 https://gateway.pinata.cloud/ipfs/,仔细确认你复制的哈希码链接到的正是你的 metadata.json。该页面应类似于下方截图:

整合起来,你的代码应该类似这样:
现在,运行 node scripts/mint-nft.js 来部署你的 NFT。几秒钟后,你应该会在终端看到类似这样的响应:
接下来,访问你的 Alchemy mempool 查看交易状态(是待处理、已打包,还是被网络丢弃)。如果你的交易被丢弃了,检查 Sepolia Etherscan 并搜索你的交易哈希也会有帮助。

就是这样!你现在已经在 Ethereum 区块链上完成了 NFT 的部署和铸造 🎉
使用 mint-nft.js,你可以随心所欲(钱包也允许的话)铸造任意数量的 NFT!只需确保每次传入一个新的 tokenURI 来描述 NFT 的元数据 —— 否则,你最终只会铸造出一堆 ID 不同但内容相同的 NFT。
想必你也希望能在钱包中展示你的 NFT 😉 —— 那就一定要看看第三部分:How to View Your NFT in Your Wallet。
Alchemy 新闻通讯
第一时间获取发布信息
订阅我们的新闻通讯
获取 Alchemy 的最新产品更新和资源
填写您的电子邮箱地址即表示您同意接收我们的营销通讯和产品更新。您确认 Alchemy 按照我们的隐私声明处理我们收到的信息。您可以随时取消订阅。


