本文介绍了如何使用 Web3 在以太坊区块链上铸造 NFT。文章详细讲解了安装 Web3、创建 mint-nft.js 文件、获取合约 ABI、使用 IPFS 配置 NFT 的元数据、创建合约实例、更新 .env 文件、创建交易、签署交易以及调用 mintNFT 等步骤,并提供了详细的代码示例和操作截图。
由 Brady Werkheiser 审核
发布于 2021 年 8 月 27 日,阅读时长 5 分钟
本教程描述了如何使用 Web 3 和我们在第一部分:如何创建 NFT 中的智能合约在以太坊区块链上铸造 NFT。
预计完成本指南的时间:约 10 分钟
另外,请务必查看我们的 NFT 教程系列的其他部分:
“铸造 NFT” 是指在区块链上发布你的 ERC721 token 的一个唯一实例。现在我们已经在本 NFT 教程系列的第一部分中成功地 将智能合约部署到 Ropsten 网络,让我们展示我们的 web3 技能并铸造一个 NFT!
在本教程结束时,你将能够使用这段代码铸造任意数量的 NFT——让我们开始吧!
如果你已经按照第一个教程 创建你的 NFT 智能合约,那么你已经有了使用 Ethers.js 的经验。Web3 类似于 Ethers,因为它是一个用于简化向以太坊区块链发出请求的库。在本教程中,我们将使用 Alchemy Web3,这是一个增强的 web3 库,提供自动重试和强大的 WebSocket 支持。
在你的项目主目录中运行:
npm install @alch/alchemy-web3
在你的 scripts 目录中,创建一个 mint-nft.js 文件并添加以下代码行:
require('dotenv').config();
const API_URL = process.env.API_URL;
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(API_URL);
我们的合约 ABI (Application Binary Interface) 是与我们的智能合约交互的接口。你可以在 这里 了解更多关于合约 ABI 的信息。Hardhat 会自动为我们生成一个 ABI,并将其保存在 MyNFT.json 文件中。为了使用它,我们需要解析内容,将以下代码行添加到我们的 mint-nft.js 文件中:
const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
如果你想查看 ABI,你可以将其打印到你的控制台:
console.log(JSON.stringify(contract.abi));
要运行 mint-nft.js 并查看你的 ABI 打印到控制台,请导航到你的终端并运行
node scripts/mint-nft.js
如果你还记得我们在第一部分中的教程,我们的 mintNFT 智能合约函数接受一个 tokenURI 参数,该参数应该解析为一个描述 NFT 元数据的 JSON 文档——这才是真正让 NFT 栩栩如生的东西,允许它具有可配置的属性,例如名称、描述、图像和其他属性。
Interplanetary File System (IPFS) 是一种去中心化协议和点对点网络,用于在分布式文件系统中存储和共享数据。
我们将使用 Pinata,一个方便的 IPFS API 和工具包,来存储我们的 NFT 资产和元数据,以确保我们的 NFT 是真正去中心化的。如果你没有 Pinata 帐户,请在此处注册一个免费帐户 这里 并完成验证你的电子邮件的步骤。
创建帐户后:
导航到右上角的“Pinata Upload”按钮
上传一张图片到 pinata - 这将是你的 NFT 的图像资产。随意给你的资产命名
上传后,在页面顶部,应该会弹出一个绿色弹出窗口,允许你查看上传的哈希值 -> 复制该哈希码。你可以在以下网址查看你的上传:https://gateway.pinata.cloud/ipfs/< hash-code>
对于更喜欢视觉学习的人来说,以上步骤总结如下:现在,我们还需要上传一个文档到 Pinata。但在那之前,我们需要创建它!
上传文件到 Pinata
在你的根目录中,创建一个名为 nft-metadata.json 的新文件,并添加以下 json 代码:
{
"attributes" : [ {
"trait_type" : "Breed",
"value" : "Maltipoo"
}, {
"trait_type" : "Eye color",
"value" : "Mocha"
} ],
"description" : "The world's most adorable and sensitive pup.",
"image" : "https://gateway.pinata.cloud/ipfs/QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb",
"name" : "Ramses"
}
随意更改 json 中的数据。你可以删除或添加到 attributes 部分。最重要的是,确保 image 字段指向你的 IPFS 图像的位置——否则,你的 NFT 将包含一张(非常可爱!)的狗的照片。
完成编辑 json 文件后,保存它并将其上传到 Pinata,按照我们上传图像的相同步骤。
上传 json 文件到 Pinata
现在,为了与我们的合约交互,我们需要在我们的代码中创建一个合约实例。为此,我们需要我们的合约地址,我们可以从部署或 Etherscan 中获取,通过查找你用于部署合约的地址。
创建你的合约实例
在上面的例子中,我们的合约地址是 0x81c587EB0fE773404c42c1d2666b5f557C470eED。
接下来,我们将使用 web3 合约方法 使用 ABI 和地址创建我们的合约。在你的 mint-nft.js 文件中,添加以下代码:
const contractAddress = "0x81c587EB0fE773404c42c1d2666b5f557C470eED";
const nftContract = new web3.eth.Contract(contract.abi, contractAddress);
现在,为了创建交易并将其发送到以太坊链,我们将使用你的公共以太坊帐户地址来获取帐户 nonce(稍后解释)。
将你的公钥添加到你的 .env 文件中——如果你完成了教程的第一部分,我们的 .env 文件现在应该如下所示:
API_URL = "https://eth-ropsten.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY = "your-private-account-address"
PUBLIC_KEY = "your-public-account-address"
首先,让我们定义一个名为 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
文件现在应该如下所示:
require('dotenv').config();
const API_URL = process.env.API_URL;
const PUBLIC_KEY = process.env.PUBLIC_KEY;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(API_URL);
const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
const contractAddress = "0x81c587EB0fE773404c42c1d2666b5f557C470eED";
const nftContract = new web3.eth.Contract(contract.abi, contractAddress);
async function mintNFT(tokenURI) {
const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //get latest nonce
//the transaction
const tx = {
'from': PUBLIC_KEY,
'to': contractAddress,
'nonce': nonce,
'gas': 500000,
'maxPriorityFeePerGas': 1999999987,
'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()
};
}
我如何铸造多个 NFT: 要在单个命令中铸造 x 个 NFT,我们可以在一个包装铸造过程的函数中使用一个从 0 到 x-1 的简单 for 循环。这将允许我们每次调用包装器铸造函数时有效地铸造 x 个 NFT。
现在我们已经创建了我们的交易,我们需要签署它才能发送出去。这就是我们将使用我们的私钥的地方。
web3.eth.sendSignedTransaction
将为我们提供交易哈希,我们可以使用它来确保我们的交易已被挖掘并且没有被网络丢弃。你会在交易签署部分注意到,我们添加了一些错误检查,以便我们知道我们的交易是否成功完成。
还记得你上传到 Pinata 的 metadata.json 吗?从 Pinata 获取其哈希码,并将以下内容传递给对 mintNFT 的调用 https://gateway.pinata.cloud/ipfs/
以下是如何获取哈希码:
在 pinata 上获取你的哈希码
通过将 https://gateway.pinata.cloud/ipfs/ 加载到单独的窗口中,仔细检查你复制的哈希码是否链接到你的 metadata.json
。该页面应类似于以下屏幕截图:
在 Pinata 上返回的哈希码
总而言之,你的代码应该如下所示:
require('dotenv').config();
const API_URL = process.env.API_URL;
const PUBLIC_KEY = process.env.PUBLIC_KEY;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(API_URL);
const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json");
const contractAddress = "0x81c587EB0fE773404c42c1d2666b5f557C470eED";
const nftContract = new web3.eth.Contract(contract.abi, contractAddress);
async function mintNFT(tokenURI) {
const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //get latest nonce
//the transaction
const tx = {
'from': PUBLIC_KEY,
'to': contractAddress,
'nonce': nonce,
'gas': 500000,
'maxPriorityFeePerGas': 1999999987,
'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()
};
const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY);
signPromise.then((signedTx) => {
web3.eth.sendSignedTransaction(signedTx.rawTransaction, function(err, hash) {
if (!err) {
console.log("The hash of your transaction is: ", hash, "\nCheck Alchemy's Mempool to view the status of your transaction!");
} else {
console.log("Something went wrong when submitting your transaction:", err)
}
});
}).catch((err) => {
console.log("Promise failed:", err);
});
}
mintNFT("https://gateway.pinata.cloud/ipfs/QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP");
现在,运行 node scripts/mint-nft.js
以部署你的 NFT。几秒钟后,你应该在终端中看到如下响应:
The hash of your transaction is: 0x10e5062309de0cd0be7edc92e8dbab191aa2791111c44274483fa766039e0e00
Check Alchemy's Mempool to view the status of your transaction!
接下来,访问你的 Alchemy mempool 以查看你的交易状态(无论是 pending、mined,还是被网络丢弃)。如果你的交易被丢弃,检查 Ropsten Etherscan 并搜索你的交易哈希也很有帮助。
搜索你的交易哈希
就是这样!你现在已经在以太坊区块链上部署并铸造了一个 NFT 🎉
使用 mint-nft.js
你可以铸造任意数量的 NFT!只需确保传入一个新的 tokenURI
来描述 NFT 的元数据——否则,你最终只会制作一堆具有不同 ID 的相同 NFT。
据推测,你希望能够在你的钱包中炫耀你的 NFT 😉——所以请务必查看第三部分:如何在你的钱包中查看你的 NFT。
Supercharged | Alchemy | Substack
使用 Alchemy 的 NFT API 免费开始构建你可以想象的任何 NFT 应用程序 获取你的 API 密钥
📚 目录
分享:
- 原文链接: alchemy.com/blog/how-to-...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!