如何使用Ethers.js 在Polygon上铸造NFT

本文介绍了如何使用Ethers.js库在Polygon区块链上铸造NFT。

概述

本指南演示了如何使用 Ethers.js 库在 Polygon 区块链上铸造 NFT,以及一个已部署在 Polygon Mumbai 测试网络上的 ERC-721 代币。通过从本指南中学习到的信息,你将更好地理解如何使用 Ethers.js 与其他智能合约进行交互。

前提条件

  • 已安装 Node.js
  • 已安装 Ethers.js (版本 5<=)
  • 文本编辑器
  • 终端
  • Polygon Mumbai 上的 MATIC 代币 (你可以在 QuickNode Multi-Chain Faucet 获取一些)

什么是 Ethers.js?

Ethers.js 是一个完整的以太坊库,是用 Javascript 实现的钱包。由于其高效的代码库、易用性和编写良好的文档,它最近已成为 dApp 开发人员的首选库。

Ethers.js 有几个不同的模块。本指南将使用 Providers(提供者)、Signers(签名者)、Contract Interact(合约交互)和 Utility(实用工具)模块。

  • Providers(提供者)- 用于访问区块链数据的只读抽象。
  • Signers(签名者)- 以太坊账户的抽象
  • Contract Interaction(合约交互)- 智能合约的抽象
  • Utilities(实用工具)- 应用程序开发人员的有用工具(即,将十六进制转换为数字)
  • 其他库 - Ethers ASM Dialect, Hardware Wallets(硬件钱包)(例如,Ledger)
  • Experimental(实验性的)- 实验性功能

智能合约回顾

作为提醒,“铸造 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 关键字使该函数可以从合约外部访问。

该函数执行以下操作:

  1. 它声明一个名为 tokenIduint256 变量,并使用当前的 token ID 计数器值对其进行初始化。_tokenIdCounter.current() 函数调用返回当前的 token ID。
  2. 它通过调用 _tokenIdCounter.increment() 递增 token ID 计数器。这是为了确保每个 token 都有一个唯一的标识符。
  3. 它调用 _safeMint 函数,将 totokenId 作为参数传递。预计此函数会创建一个新 token 并将其转移到接收者的地址。
  4. 它调用 _setTokenURI 函数,将 tokenIduri 作为参数传递。预计此函数会为新铸造的 token 设置 token URI。

步骤 1:设置 QuickNode Polygon Endpoint

你将需要一个 API endpoint 来与 Polygon Mumbai 测试区块链通信。欢迎你使用公共节点或部署和管理你自己的基础设施;但是,如果你想要快 8 倍的响应时间,你可以将繁重的工作交给我们。在此处注册一个帐户 here

登录后,点击 Create Endpoint,然后选择 Polygon Mumbai 测试区块链。

QuickNode Endpoint

步骤 2:创建项目

是时候编写代码了!首先,打开一个终端窗口,然后导航到你想要将此项目放置到的目录。然后,运行以下命令:

mkdir mintWithEthers && cd mintWithEthers && npm init -y

接下来,我们将创建项目文件并安装所需的依赖项:

touch mint.js && touch abi.json && touch .secret && npm install ethers@5.4

请务必安装 ethers@5.4

我们的项目目录现在应如下所示:

Screenshot of project directory

我们将首先将我们的私钥粘贴到 .secret 文件中。要了解如何导出你的私钥,请查看此 MetaMask Exporting Private Key Guide

之后,我们需要检索我们要与之交互的合约的 ABI(应用程序二进制接口)。ABI 定义了用于与合约交互的方法和结构,并以 JSON 格式表示。查看此 What is an ABI? 指南以了解更多信息。

由于我们要与之交互的 NFT 智能合约部署在 Polygon 上,因此我们将导航到 Polygonscan(一个区块浏览器)并搜索此 address: 0x66e47a27241f38b8482c0ae95e55a535324f9f54。找到该页面后,点击 Contract 选项卡并向下滚动到底部以找到合约 ABI。点击复制按钮并将内容粘贴到你的 abi.json 文件中。

ABI on Polygonscan

现在是编写将与 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 的字符串)。

该函数执行以下操作:

  1. 它调用 getNonce 函数,传递 wallet 对象,并等待结果存储在 nonce 变量中。预计 getNonce 函数会返回钱包的下一个交易 nonce
  2. 它调用 getGasPrice 函数,等待结果,并将其存储在 gasFee 变量中。预计 getGasPrice 函数会返回当前的 gas 价格。
  3. 它调用 contractInstance 对象的 populateTransaction.safeMint 函数,传递 addressURI 和一个包含 gasPricenonce 属性的对象。结果存储在 rawTxn 变量中。
  4. 它使用 gas 价格和 nonce 记录一条消息。
  5. 它调用 wallet 对象的 sendTransaction 方法,传递 rawTxn 作为参数。结果存储在 signedTxn 变量中。
  6. 它等待交易被处理,将收据存储在 receipt 变量中。
  7. 它检查 receipt 对象。如果它是 truthy,该函数会记录一条带有交易哈希和区块编号的成功消息。如果它是 falsy,该函数会记录一条错误消息。
  8. 如果在上述任何步骤中发生错误,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/

步骤 3:铸造我们的 NFT

注意,你需要在 Polygon Mumbai 测试网络上有一些 MATIC才能进行此铸造交易

只需一个命令即可铸造你的 NFT!导航到终端中的项目主目录并运行命令 node mint.js。输出应如下所示:

log of mint script

我们可以通过检查 Polygonscan 和 OpenSea 来验证 NFT 是否已铸造:

Transaction reciept on polygon

Our minted NFT on OpenSea

结论

就是这样!你已经使用 Ethers.js 铸造了一个 NFT!要了解有关 Ethers 的更多信息,你可以查看我们的其他 Web3 SDK guides 或查看 Ethers documentation

订阅我们的 newsletter 以获取更多关于以太坊的文章和指南。如果你有任何反馈,请随时通过 Twitter 与我们联系。你也可以随时在我们的 Discord 社区服务器上与我们聊天,这里有一些你会遇到的最酷的开发人员 :)

  • 原文链接: quicknode.com/guides/pol...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。