本文介绍了如何使用Ethers.js库在Polygon区块链上铸造NFT。
本指南演示了如何使用 Ethers.js 库在 Polygon 区块链上铸造 NFT,以及一个已部署在 Polygon Mumbai 测试网络上的 ERC-721 代币。通过从本指南中学习到的信息,你将更好地理解如何使用 Ethers.js 与其他智能合约进行交互。
前提条件
5<=
)Ethers.js 是一个完整的以太坊库,是用 Javascript 实现的钱包。由于其高效的代码库、易用性和编写良好的文档,它最近已成为 dApp 开发人员的首选库。
Ethers.js 有几个不同的模块。本指南将使用 Providers(提供者)、Signers(签名者)、Contract Interact(合约交互)和 Utility(实用工具)模块。
作为提醒,“铸造 NFT”的行为是在 ERC-721 或 ERC-1155 智能合约上调用 mint 函数。并非所有智能合约都具有相同的命名约定。
让我们快速回顾一下 solidity 代码,该函数将被调用来铸造我们的 ERC-721 代币:
function safeMint(address to, string memory uri) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
此代码定义了一个名为safeMint
的 Solidity 函数。该函数有两个参数:to
(接收者的地址)和 URI
(表示 URI 的字符串)。public
关键字使该函数可以从合约外部访问。
该函数执行以下操作:
tokenId
的 uint256
变量,并使用当前的 token ID 计数器值对其进行初始化。_tokenIdCounter.current()
函数调用返回当前的 token ID。_tokenIdCounter.increment()
递增 token ID 计数器。这是为了确保每个 token 都有一个唯一的标识符。_safeMint
函数,将 to
和 tokenId
作为参数传递。预计此函数会创建一个新 token 并将其转移到接收者的地址。_setTokenURI
函数,将 tokenId
和 uri
作为参数传递。预计此函数会为新铸造的 token 设置 token URI。你将需要一个 API endpoint 来与 Polygon Mumbai 测试区块链通信。欢迎你使用公共节点或部署和管理你自己的基础设施;但是,如果你想要快 8 倍的响应时间,你可以将繁重的工作交给我们。在此处注册一个帐户 here。
登录后,点击 Create Endpoint,然后选择 Polygon Mumbai 测试区块链。
是时候编写代码了!首先,打开一个终端窗口,然后导航到你想要将此项目放置到的目录。然后,运行以下命令:
mkdir mintWithEthers && cd mintWithEthers && npm init -y
接下来,我们将创建项目文件并安装所需的依赖项:
touch mint.js && touch abi.json && touch .secret && npm install ethers@5.4
请务必安装 ethers@5.4
我们的项目目录现在应如下所示:
我们将首先将我们的私钥粘贴到 .secret 文件中。要了解如何导出你的私钥,请查看此 MetaMask Exporting Private Key Guide。
之后,我们需要检索我们要与之交互的合约的 ABI(应用程序二进制接口)。ABI 定义了用于与合约交互的方法和结构,并以 JSON 格式表示。查看此 What is an ABI? 指南以了解更多信息。
由于我们要与之交互的 NFT 智能合约部署在 Polygon 上,因此我们将导航到 Polygonscan(一个区块浏览器)并搜索此 address: 0x66e47a27241f38b8482c0ae95e55a535324f9f54。找到该页面后,点击 Contract 选项卡并向下滚动到底部以找到合约 ABI。点击复制按钮并将内容粘贴到你的 abi.json 文件中。
现在是编写将与 ERC-721 智能合约交互的脚本的时候了。我们将逐一介绍每个代码段,并在最后将它们联系在一起。
打开你的 mint.js 文件并首先添加依赖项。
const { ethers } = require("ethers")
const fs = require('fs')
下面的这行代码使用 fs 模块来检索存储在项目目录中 .secret 文件中的私钥。
const privateKey = fs.readFileSync(".secret").toString().trim()
Ethers.js 有几个 provider class。我们将使用 JsonRpcProvider,这是一种与以太坊交互的流行方法,它在所有主要的以太坊节点实现中都可用。将以下代码段添加到你的 mint.js 脚本中,并更新 QUICKNODE_HTTP_ENDPOINT 变量以包含你的 QuickNode HTTP Provider URL。
const QUICKNODE_HTTP_ENDPOINT = "YOUR_QUICKNODE_HTTP_ENDPOINT"
const provider = new ethers.providers.JsonRpcProvider(QUICKNODE_HTTP_ENDPOINT)
现在,是时候创建我们想要与之交互的智能合约的抽象了。可以像这样创建一个合约抽象:
const contractAddress = "0x66e47a27241f38b8482c0ae95e55a535324f9f54"
const contractAbi = fs.readFileSync("abi.json").toString()
const contractInstance = new ethers.Contract(contractAddress, contractAbi, provider)
要使用 Ethers.js 发送交易,我们将需要一个 Signer 对象。你可以使用以下代码创建一个:
const wallet = new ethers.Wallet(privateKey, provider)
我们还将创建一些辅助函数,这些函数将帮助我们读取和修改数据以满足我们的需求:
async function getGasPrice() {
let feeData = (await provider.getGasPrice()).toNumber()
return feeData
}
async function getNonce(signer) {
let nonce = await provider.getTransactionCount(wallet.address)
return nonce
}
例如,getGasPrice()
函数在 provider 对象上调用 getGasPrice()
方法,该方法使用一个大数字返回其响应。然后,我们将使用 .toNumber()
方法将此值转换为数字。getNonce()
函数调用 ethers.provider.getTransactionCount()
方法,该方法采用一个地址并返回其交易计数。
接下来,我们将创建一个 mint 函数,该函数将利用我们上面创建的所有辅助函数来发送和签名交易。让我们深入了解一下下面代码的解释:
此代码定义了一个名为 mintNFT
的异步函数。该函数有两个参数:address
(接收者的地址)和 URI
(表示 NFT 的 URI 的字符串)。
该函数执行以下操作:
getNonce
函数,传递 wallet
对象,并等待结果存储在 nonce
变量中。预计 getNonce
函数会返回钱包的下一个交易 nonce。getGasPrice
函数,等待结果,并将其存储在 gasFee
变量中。预计 getGasPrice
函数会返回当前的 gas 价格。contractInstance
对象的 populateTransaction.safeMint
函数,传递 address
、URI
和一个包含 gasPrice
和 nonce
属性的对象。结果存储在 rawTxn
变量中。wallet
对象的 sendTransaction
方法,传递 rawTxn
作为参数。结果存储在 signedTxn
变量中。receipt
变量中。receipt
对象。如果它是 truthy,该函数会记录一条带有交易哈希和区块编号的成功消息。如果它是 falsy,该函数会记录一条错误消息。catch
语句会记录错误消息。async function mintNFT(address, URI) {
try {
const nonce = await getNonce(wallet)
const gasFee = await getGasPrice()
let rawTxn = await contractInstance.populateTransaction.safeMint(address, URI, {
gasPrice: gasFee,
nonce: nonce
})
console.log("...Submitting transaction with gas price of:", ethers.utils.formatUnits(gasFee, "gwei"), " - & nonce:", nonce)
let signedTxn = (await wallet).sendTransaction(rawTxn)
let reciept = (await signedTxn).wait()
if (reciept) {
console.log("Transaction is successful!!!" + '\n' + "Transaction Hash:", (await signedTxn).hash + '\n' + "Block Number: " + (await reciept).blockNumber + '\n' + "Navigate to https://polygonscan.com/tx/" + (await signedTxn).hash, "to see your transaction")
} else {
console.log("Error submitting transaction")
}
} catch (e) {
console.log("Error Caught in Catch Statement: ", e)
}
}
剩下的就是将函数调用添加到脚本的底部。在我们的示例中,我们将使用以下 metadata 铸造 NFT。为此,我们将使用以下参数调用 safeMint
函数:
mintNFT("WALLET_ADDRESS", "METADATA URI")
第一个参数 (0) 也指我们想要铸造 NFT 的地址,而第二个地址设置 token URI。如果你不知道如何创建元数据,请查看本 QuickNode guide 中的“Adding Files to IPFS”部分。
最后,你的完整脚本应如下所示:
const { ethers, Signer } = require("ethers")
const fs = require('fs')
const privateKey = fs.readFileSync(".secret").toString().trim()
const QUICKNODE_HTTP_ENDPOINT = "YOUR_QUICKNODE_HTTP_ENDPOINT"
const provider = new ethers.providers.JsonRpcProvider(QUICKNODE_HTTP_ENDPOINT);
const contractAddress = "0x66e47a27241f38b8482c0ae95e55a535324f9f54"
const contractAbi = fs.readFileSync("abi.json").toString()
const contractInstance = new ethers.Contract(contractAddress, contractAbi, provider)
const wallet = new ethers.Wallet(privateKey, provider)
async function getGasPrice() {
let feeData = (await provider.getGasPrice()).toNumber()
return feeData
}
async function getNonce(signer) {
let nonce = await provider.getTransactionCount(wallet.address)
return nonce
}
async function mintNFT(address, URI) {
try {
const nonce = await getNonce(wallet)
const gasFee = await getGasPrice()
let rawTxn = await contractInstance.populateTransaction.safeMint(address, URI, {
gasPrice: gasFee,
nonce: nonce
})
console.log("...Submitting transaction with gas price of:", ethers.utils.formatUnits(gasFee, "gwei"), " - & nonce:", nonce)
let signedTxn = (await wallet).sendTransaction(rawTxn)
let reciept = (await signedTxn).wait()
if (reciept) {
console.log("Transaction is successful!!!" + '\n' + "Transaction Hash:", (await signedTxn).hash + '\n' + "Block Number: " + (await reciept).blockNumber + '\n' + "Navigate to https://polygonscan.com/tx/" + (await signedTxn).hash, "to see your transaction")
} else {
console.log("Error submitting transaction")
}
} catch (e) {
console.log("Error Caught in Catch Statement: ", e)
}
}
mintNFT("WALLET_ADDRESS", "METADATA_URL")
最后一行代码使用钱包地址和元数据 URL 参数调用 mintNFT 函数。如果你想要一些 NFT 的占位符元数据,请使用此 URL:https://bafkreif4rv2kafqbmrmifwg7davpwmd4vgkehe63ryosdzajn7nnbifnfm.ipfs.nftstorage.link/
注意,你需要在 Polygon Mumbai 测试网络上有一些 MATIC才能进行此铸造交易
只需一个命令即可铸造你的 NFT!导航到终端中的项目主目录并运行命令 node mint.js。输出应如下所示:
我们可以通过检查 Polygonscan 和 OpenSea 来验证 NFT 是否已铸造:
就是这样!你已经使用 Ethers.js 铸造了一个 NFT!要了解有关 Ethers 的更多信息,你可以查看我们的其他 Web3 SDK guides 或查看 Ethers documentation。
订阅我们的 newsletter 以获取更多关于以太坊的文章和指南。如果你有任何反馈,请随时通过 Twitter 与我们联系。你也可以随时在我们的 Discord 社区服务器上与我们聊天,这里有一些你会遇到的最酷的开发人员 :)
- 原文链接: quicknode.com/guides/pol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!