polygon NFT开发教程
polygon NFT开发教程
- 1、初始化hardhat项目
- 2、设置Polygon环境
- 3、编写NFT智能合约
- 4、测试NFT合约
- 5、mint nft通证
以太坊的手续费费目前还是天文数字,因此第2层解决方案得到了蓬勃发展。以太坊最著名和最常用的第2层解决方案之一是Polygon(以前的Matic)。在这篇文章中,我们将创建一个基于IPFS去中心化存储并运行在Polygon二层网络上的的NFT通证。Polygon具有出色的性能和成本优势,可实现智能合约部署和交易。当需要在以太坊主链与二层之间转移资产时,Polygon使此操作变得容易。
1、初始化hardhat项目
我们使用Hardhat来处理项目配置和部署任务。Hardhat与Truffle一样提供了一套可以简化以太坊开发的工具。由于Polygon是与Etherem EVM兼容的第2层,因此我们可以采用与以太坊几乎相同的方式将Hardhat与Polygon结合使用。
在计算机上打开一个终端,然后创建一个新的项目文件夹polygon-nfts:
mkdir polygon-nfts
进入该目录运行以下命令初始化一个新的Hardhat示例项目以开始我们的工作:
npm install --save-dev hardhat
npx hardhat
第二个命令将引导你完成一些配置工作。选择示例项目选项,然后接受之后显示的所有默认选项。完成该过程后,项目文件夹中将包含一些新文件。在代码编辑器中打开整个项目文件夹,让我们看一下目录内容:
polygon-nfts
|- contracts|- Greeter.sol
|- scripts|- sample-script.js
|- test|- sample-test.js
|- .gitignore
|- hardhat.config.js
|- package-lock.json
|- package.json
因为我们创建的是示例项目,所以项目目录下有三个文件夹:
- contracts
- scripts
- test
contracts文件夹包含一个示例合约Greeter.sol。scripts文件夹包含一个简单的脚本文件,该脚本可读取代码并进行部署。test目录下的测试文件可以部署并调用我们的合同。很简单的东西,但是这是一个很好的起点,接下来让我们看看如何把Polygon加进去。
2、设置Polygon环境
在继续下面操作之前,我们获取一些MATIC通证。因此,第一步是确保你有一个以太坊钱包。只需访问Metamask的网站,安装扩展程序,然后按照创建新钱包的过程进行即可。当然,如果你已经有了钱包,则可以跳过此步骤。
创建钱包后,我们需要获取钱包的私钥。该密钥对于部署NFT合同并与第2层链进行交互是必不可少的。在Metamask扩展中,可以通过单击钱包帐户旁边的三点菜单图标来导出私钥:
选择 帐户详细信息 / Account Details,然后就可以导出私钥了。拥有私钥后,还需要做两件事:
- 在polygon-nft项目的根目录下创建一个名为.env的文件,加入PRIVATE_KEY=YOUR_EXPORTED_PRIVATE_KEY。 注意替换YOUR_EXPORTED_PRIVATE_KEY为你的实际私钥。
- 在项目的.gitignore文件中,添加一行.env,这将确保你不会意外地将.env文件提交给源代码管理 并泄露你的密钥。
由于使用了环境变量文件,因此我们需要在项目中安装另一个依赖项,以使其更易于使用这些变量。从项目目录的根目录运行以下命令:
npm i dotenv
现在让我们去测试网Faucet中获取一些MATIC通证。你可以把钱包地址粘贴到提供的字段中,选择MATIC通证,然后选择Mumbai网络:
提交后,系统会要求你进行确认。这样你地钱包很快就会收到MATIC通证了。
现在让我们更新hardhat.config.js
文件,以便告知hardhat我们正在使用Polygon网络。在第一条require语句上方的文件顶部,添加:
require('dotenv').config();
const PRIVATE_KEY = process.env.PRIVATE_KEY;
上面的代码标明我们将使用该dotenv程序包提取环境变量。第二行是创建一个变量,该变量引用在.env文件中为私钥存储的环境变量的值。
接下来,我们需要在文件中找到module.exports对象。它可能仅包含Solidity版本的定义。让我们用以下代码替换之前的module.exports:
module.exports = {defaultNetwork: "matic",
networks: {hardhat: {},matic: {url: "https://rpc-mumbai.maticvigil.com",accounts: [PRIVATE_KEY]}},solidity: {version: "0.7.3",settings: {optimizer: {enabled: true,runs: 200}}},paths: {sources: "./contracts",tests: "./test",cache: "./cache",artifacts: "./artifacts"},mocha: {timeout: 20000}
}
看起来内容很多,不过实际上没那么复杂。上面的代码告诉hardhat我们在使用Polygon网络、RPC地址以及私钥。除此之外,就是一些容易理解的配置信息了。
在我们继续之前,最好测试下配置。让我们运行以下命令将Greeter.sol合约部署到Polygon测试网:
npx hardhat run scripts/sample-script.js --network matic
上面的命令声明了要运行的hardhat脚本以及要连接的网络,matic网络是我们在hardhat.config.js文件中定义的。稍等片刻就可以在终端看到如下输出:
Compiling 2 files with 0.7.3
Compilation finished
successfullyGreeter deployed to:0x790a1c9a212A13Fce5C1cfA4904f18bD3540E1e8
你的合约地址应该和我的不一样,只要你看到的和上面类似,就意味着配置文件是正常的。
我们没有运行测试,因为接下来要整个换掉合约文件,因此在这一步我们只需要测试下hardhat.config.js是否正常即可。
好了。
3、编写NFT智能合约
我们将使用OpenZeppelin来编写智能合约,该合约是基于ERC-721实现。因此我们需要安装OpenZeppelin的智能合约库。在项目根目录执行如下命令:
npm install @openzeppelin/contracts
安装好openZeppelin后,我们就可以开始编写智能合约了。打开contracts文件夹并创建一个新的文件NFT.sol,该合约文件非常简单,让我们看一下具体内容:
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyNFT is ERC721, Ownable {using Counters for Counters.Counter;using Strings for uint256;Counters.Counter private _tokenIds;mapping (uint256 => string) private _tokenURIs;
constructor() ERC721("MyNFT", "MNFT") {}
function _setTokenURI(uint256 tokenId, string memory _tokenURI)internalvirtual{_tokenURIs[tokenId] = _tokenURI;}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory){require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");string memory _tokenURI = _tokenURIs[tokenId];return _tokenURI;}
function mint(address recipient, string memory uri)public returns (uint256){_tokenIds.increment();uint256 newItemId = _tokenIds.current();_mint(recipient, newItemId);_setTokenURI(newItemId, uri);return newItemId;}
}
由于我们使用了OpenZeppelin的ERC721合约,因此只需要很少的代码。
第一行定义了我们使用的solidiy的版本。
接下来的三行代码引入所需的OpenZeppelin合约,其中ERC-721合约是最重要的。 有了这些合约,我们编写智能合约的效率就大大提高了。
接下来我们定义contract名为MyNFT,它继承自OpenZeppeline提供的ERC721和Ownable合约。
然偶定义一些变量。Counters和Strings用来帮助计数以及将数据转换为字符串,然后我们定义一个变量来保存下一个token的ID。最后,我们定义一个从通证ID到通证URI的映射表。
引入声明和变量定义完成后,我们可以开始实质性的代码了。构造函数实际上就是定义下通证名称和符号。
在最近的OpenZeppelin更新中,其ERC-721合约不再内置setTokenURI函数。这一选择 的初衷可能是减少用户部署合约的gas成本,不过我们还需要这个函数。
没关系,我们可以自己实现。这就是第一个函数的功能。函数_setTokenURI传入参数通证ID 和通证URI,然后将其添加到映射表中。
通过上述操作,我们现在可以使用tokenURI方法返回通证URI的值。这一点很重要,因为这个URI指向了NFT的全部元数据,例如名称、属性以及资产自身。我们必须确保URI保存下来并能够返回给任何对此感兴趣的人。
最后,我们需要一个mint方法,传入一个钱包地址和通证URI作为参数,新的通证将发送到接收地址。
好了,很简单的合约,对吗。
4、测试NFT合约
在第一个测试中,我们使用Polygon Mumbai测试网来测试hardhat配置文件是否正确,不过现在我们要使用hardhat的内存链来测试NFT合约。
为此,我们回到hardhat.config.js文件,暂时将defaultNetwork从matic修改为hardhat。 你也需要将config中的如下部分注释掉:
matic: {url: "https://rpc-mumbai.maticvigil.com",accounts: [PRIVATE_KEY]}
保存修改。
接下来有两件事要做。首先找到项目根目录下的artifacts文件夹并删除其中的contracts目录。然后找出项目根目录下的contracts目录并删除其中的Greeter.sol文件。
现在就只剩下NFT.sol合约了。我们还需要更新测试文件,在test目录中,打开sample-test.js文件,更新为如下内容:
const { expect } = require("chai");
describe("NFT", function() {it("It should deploy the contract, mint a token, and resolve to the right URI", async function() {const NFT = await ethers.getContractFactory("MyNFT");const nft = await NFT.deploy();const URI = "ipfs://QmWJBNeQAm9Rh4YaW8GFRnSgwa4dN889VKm9poc2DQPBkv";await nft.deployed();await nft.mint("0xd72203a26D887b60Af3a11178eF4A48BE8DecbA6", URI)expect(await nft.tokenURI(1)).to.equal(URI)});});
在上面的测试中,我们读取合约并部署,然后mint一些通证到一个假想的以太坊地址和一个通证URI。注意URI的格式。我们希望利用IPFS和Pinata来提供元数据,并希望可以利用任何IPFS网关解析该元数据,而不局限于Pinata。将URI按此格式化有助于验证元数据的解析。
上面的URI是伪造的,不过很快我们将创建一个真正的URI并使用它在Polygon网络上mint一个NFT通证。在终端输入以下命令测试合约:
npx hardhat test
我们可以编写很多像这样的测试,不过这留给你来完成了。
现在我们准备好在Polygon Mumbai测试网上mint一个通证了。
5、mint nft通证
在我们实际mint一个NFT通证之前,需要首先创建一个资产并将其pin到IPFS。 我们使用下面这个图像:
我们将利用Pinata将此文件pin到IPFS网络。点击这里 注册并登录,然后前往Pin Manager上传文件,上传完成后,就可以在Pin Manager 表中看到文件的IPFS CID,拷贝这个CID,例如QmQRDYPTprDPknn3zE2ZSpc8DjnUKfYztyaeMBYdR8GDdw,后面会用到。
我们已经上传了资产,接下来还需要上传NFT对应的元数据的JSON文件。这听起来很困难,但实际上很简单。用文本编辑器创建一个文件,内容如下:
{name: "My NFT",
description: "This is my NFT",
image: "ipfs://QmQRDYPTprDPknn3zE2ZSpc8DjnUKfYztyaeMBYdR8GDdw"}
你可以将NFT随意命名,可以提供任何描述文本。不过image属性一定要指向前面得到的CID。由于我们希望Pinata之外的IPFS网关也可以解析URI,因此使用格式:ipfs://YOUR_CID。
上述操作完成后,将文件保存为metadata.json,同样利用Pinata Pin Manager上传该文件并记录得到的IPFS CID。
接下来我们从命令行来部署NFT合约并mint一个NFT通证。让我们来修改下sample-script.js文件,首先更名为deploy-script.js,内容替换为:
const hre = require("hardhat");
async function main() {const NFT = await hre.ethers.getContractFactory("MyNFT");
const nft = await NFT.deploy();
await nft.deployed();
console.log("NFT deployed to:", nft.address);
}
main().then(() => process.exit(0))
.catch(error => {console.error(error);process.exit(1);
});
要部署到Mumbai测试网,我们需要更新hardhat.config.js文件。将默认网络改回matic, 取消matic部分的注释。
在终端执行如下命令:
npx hardhat run scripts/deploy-script.js --network matic
一切顺利的话,NFT合约将成功mint,终端的输出将包含合约地址,拷贝下来,因为后面 需要此地址来mint我们的第一个NFT通证。
为此,让我们创建一个新的脚本文件mint-script.js,并在文件中添加如下内容:
const hre = require("hardhat");
async function main() {const NFT = await hre.ethers.getContractFactory("MyNFT");const URI = "ipfs://YOUR_METADATA_CID"const WALLET_ADDRESS = "YOUR_WALLET_ADDRESS"const CONTRACT_ADDRESS = "YOUR NFT CONTRACT ADDRESS"const contract = NFT.attach(CONTRACT_ADDRESS);await contract.mint(WALLET_ADDRESS, URI);console.log("NFT minted:", contract);
}
main().then(() => process.exit(0)).catch(error => {console.error(error);process.exit(1);
});
脚本很简单,需要的参数是我们上传到Pinata的元数据的URI、以太坊钱包地址和部署的NFT合约的地址。
保存文件并在终端运行如下命令:
npx hardhat run scripts/mint-script.js --network matic
假设没有错误,我们就成功的mint了之前创建的资产的NFT通证,它已经在你的钱包中了。为证明这一点,我们创建一个新的脚本文件get-token-script.js,添加如下内容:
const hre = require("hardhat");
async function main() {const NFT = await hre.ethers.getContractFactory("MyNFT");
const CONTRACT_ADDRESS = "YOUR_CONTRACT_ADDRESS"
const contract = NFT.attach(CONTRACT_ADDRESS);
const owner = await contract.ownerOf(1);
console.log("Owner:", owner);
const uri = await contract.tokenURI(1);
console.log("URI: ", uri);
}
main().then(() => process.exit(0))
.catch(error => {console.error(error);process.exit(1);});
上面的脚本查询第一个通证的持有者,同时提取通证的URI。在终端运行如下命令:
npx hardhat run scripts/get-token-script.js --network matic
输出结果类似下面这样:
Owner: 0xd7220ab26a887a60Af3a11178eF4A48BE8DncbA6
URI: ipfs://QmZu6UUMHo2bHLiRMZCoQf7hiSmnFVVzWqnEAyF9SJwxhx
polygon NFT开发教程相关推荐
- 【区块链 | NFT | Unity3D】Unity3D NFT开发教程,unity3d开发链游教程
ethereum-unity-boilerplate包含用于快速构建 web3 游戏的 Unity 组件和挂钩.使用此 SDK, 你可以为移动.桌面.Xbox.Playstation 和其他平台构建 ...
- 【Web3 系列开发教程——创建你的第一个 NFT(6)】为 NFT 设置价格
我想作为 NFT 的创建者,你可能有意将你的 NFT 出售给你的 NFT 爱好者. 为此,我们需要为 NFT 定价,一般有两种主要的定价方式: 在智能合约内定价(本文所讲) 在 NFT 市场或平台上列 ...
- Unity 2D游戏开发教程之游戏中精灵的跳跃状态
Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却 ...
- ArcGIS Engine基础开发教程(转)
ArcGIS Engine基础开发教程(0)--目录 <ArcEngine9.3 基础开发教程>是面向初中级开发者的一份简单易用,功能全面的学习资料及参考文档.教程首先从如何来创建一个Ar ...
- OpenGl文章
Android OpenGL ES 简明开发教程
Android OpenGL ES 简明开发教程 分类:android学习笔记2011-12-14 15:04375人阅读评论(0)收藏举报 ApiDemos 的Graphics示例中含有OpenGL ...
- ArcGIS Maritime Server 开发教程(七)Maritime Server 正确的开发模式
ArcGIS Maritime Server 开发教程(七)Maritime Server 正确的开发模式 本章导读:前面几个章节已经非常细节的分析和测试了 Maritime Server 的相关功能 ...
- ArcGIS Maritime Server 开发教程(六)Maritime Service 开发技巧
ArcGIS Maritime Server 开发教程(六)Maritime Service 开发技巧 本章导读:GIS 开发人员基于 Maritime Service 开发海图应用时总会遇到与海图数 ...
- ArcGIS Maritime Server 开发教程(四)Maritime Service 开发实践
ArcGIS Maritime Server 开发教程(四)Maritime Service 开发实践 本章导读:Maritime Service 属于 MapService 的一个扩展,大部分功能继 ...
- 基于React、Typescript和Solidity的NFT完整教程
基于React.Typescript和Solidity的NFT完整教程 了解如何使用 React / Next JS.Solidity 和 Pinata(IPFS) 在以太坊上创建 NFT 市场 课程 ...
最新文章
- 不畏浮云遮望眼--离散数学和组合数学
- 数据库学习day_02:表格相关sql语句 / 表格数据相关sql语句 / sql中的数据类型 / 导入外部sql文件 / 去重.是否为null.and与or.in.[x,y]
- VTK:可视化之QuadricVisualization
- 【NetApp】NetBoot的使用方法
- 华为nova 5i Pro发布:麒麟810+4800万像素AI四摄
- windows登录linux免密码,Windows使用SSH Secure Shell实现免密码登录Linux的方法以及使用scp2命令免密码下载文件...
- 【最全】微信支付宝小程序蓝牙API开锁全流程
- Git基础:第九、十章 Git可视化工具 Git团队协作以及合并时的diff工具
- 浪潮ERP-PS异速联远程接入解决方案
- Spring整合FreeMarker生成静态页面(静态模板)
- 解决VS2003查询卡死的问题
- RAW数据格式的图片转换--常用于相机开发和图片旋转
- 微信公众号访问 ssm框架根目录下MP_verify_xxxxxx.txt的解决方法
- w ndows7防火墙文件名,大神帮你win7系统彻底关闭windows7防火墙的具体方法
- Matlab如何调整坐标轴刻度
- keras入门教程 1.线性回归建模(快速入门)
- 图像识别(二)| 图像的色彩空间
- (转)颈椎病自我治疗体操
- 【机器学习系列】【模型评价】【ROC曲线、约登指数最佳阈值】一个函数中实现约登指数计算并集成到ROC图中,给出默认阈值及最佳阈值下的混淆矩阵
- 压力传感器十大技术趋势解析