热点新闻
快速实现一个标准的NFT合约(实操篇)
2024-12-31 07:34  浏览:757  搜索引擎搜索“错改B2B”
温馨提示:信息一旦丢失不一定找得到,请务必收藏信息以备急用!本站所有信息均是注册会员发布如遇到侵权请联系文章中的联系方式或客服删除!
联系我时,请说明是在错改B2B看到的信息,谢谢。
展会发布 展会网站大全 报名观展合作 软文发布

前言

本文借助openzeppelin库编写一个标准的NFT合约,从开发,测试,到部署上链全部流程。注意:ERC20标准的同质化代币和ERC721标准的非同质化代币的区别 需要metadata,要把信息上传到ipfs上,文中会有详细操作的步骤;

同质化代币和非同质化代币程序层面的区别

  • ERC20:mapping(address=>uint)//地址指向余额
  • ERC721:mapping(uint=>address)//id指向地址

开发

合约功能说明:铸造,销毁,权限控制:只有项目方可铸造,

// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import {ERC721Burnable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; import {ERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import {ERC721URIStorage} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; contract BoykaNFT is ERC721, ERC721Enumerable, ERC721URIStorage, ERC721Burnable, Ownable { uint256 private _nextTokenId; constructor(address initialOwner) ERC721("BoykaNFT", "BNFT") Ownable(initialOwner) {} //铸造nft 说明:地址,metadata function safeMint(address to, string memory uri) public onlyOwner { uint256 tokenId = _nextTokenId++; _safeMint(to, tokenId); _setTokenURI(tokenId, uri); } // The following functions are overrides required by Solidity. function _update(address to, uint256 tokenId, address auth) internal override(ERC721, ERC721Enumerable) returns (address) { return super._update(to, tokenId, auth); } function _increaseBalance(address account, uint128 value) internal override(ERC721, ERC721Enumerable) { super._increaseBalance(account, value); } function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { return super.tokenURI(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable, ERC721URIStorage) returns (bool) { return super.supportsInterface(interfaceId); } }

测试

步骤:

  1. 在beforeEach中部署合约
  2. 拿到合约实例在describe调用相关方法验证

const {ethers,getNamedAccounts,deployments} = require("hardhat"); const { assert,expect } = require("chai"); describe("NFT",async()=>{ let NFT;//合约 let firstAccount//第一个账户 let secondAccount//第二个账户; //关于makedata的获取通过filebase工具生成的 let mekadata='https://zygomorphic-magenta-bobolink.myfilebase.com/ipfs/QmQT8VpmWQVhUhoDCEK1mdHXaFaJ3KawkRxHm96GUhrXLB'; beforeEach(async()=>{ await deployments.fixture(["nft"]); firstAccount=(await getNamedAccounts()).firstAccount; secondAccount=(await getNamedAccounts()).secondAccount; const nftDeployment = await deployments.get("BoykaNFT"); NFT = await ethers.getContractAt("BoykaNFT",nftDeployment.address);//已经部署的合约交互 }) describe("NFT",async()=>{ it("铸造一个nft",async()=>{ //const owner = await NFT.owner(); await NFT.safeMint(firstAccount,mekadate); }) }) }) //执行指令:部署nft合约到sepolia链上并铸造一个nft,成功后可以在opensea测试网上预览部署的nft npx hardhat test --network sepolia

部署

  1. 通过部署插件部署合约
  2. 拿到合约地址,通过verify来验证合约是否部署成功

module.exports=async ({getNamedAccounts,deployments})=>{ let confirmations=5;//等待的区块数 const {deploy,log} = deployments; const {firstAccount,secondAccount} = await getNamedAccounts(); const BoykaNFT=await deploy("BoykaNFT",{ from:firstAccount, args: [firstAccount],//参数:权限账号 log: true, wait/confirm/iations: /confirm/iations,//等待的区块数 }) //打印部署合约的地址 console.log('nft合约',BoykaNFT.address) await hre.run("verify:verify", { address: BoykaNFT.address, constructorArguments: [firstAccount], }); }; module.exports.tags = ["all", "nft"]; //执行指令:把合约部署到sepolia链上 npx hardhat deploy --network sepolia

文件配置

  • 定义网络节点
  • 通过定义别名获取钱包地址

# 在hardhat.config.js require("@nomicfoundation/hardhat-toolbox"); require("@nomicfoundation/hardhat-verify");//验证合约 require('hardhat-deploy');//部署插件 require("dotenv").config();//使用此包读取.env文件的常量 const ALCHEMY_API_KEY=process.env.ALCHEMY_API_KEY;//在infura中创建项目会自动生成 const PRIVATE_KEY=process.env.PRIVATE_KEY; const PRIVATE_KEY_1=process.env.PRIVATE_KEY_1; const ETHERSCAN_API_KEY=process.env.ETHERSCAN_API_KEY//ETHERSCAN_API可以在ETHERSCAN浏览器网站注册 module.exports = { solidity: "0.8.28", networks:{ localhost: { url:'http://127.0.0.1:8545/', chainId: 31337, }, sepolia:{ url: `https://sepolia.infura.io/v3/${ALCHEMY_API_KEY}`,//使用infura 创建项目会生成对应的api_key accounts: [PRIVATE_KEY,PRIVATE_KEY_1]//对应的账号的私钥,账号1和账号2 chainId: 11155111 } }, etherscan: { apiKey: { sepolia: ETHERSCAN_API_KEY } }, namedAccounts: { firstAccount: { default: 0 }, secondAccount: { default: 1 } },//可以用别名获取账号节点 } # 详细的配置可以在hardhat官网查看

关于铸造NFT时metadata生成

使用filebase网站把matadata存储到ipfs上

把cattle.jpg和cattle.json文件上传到ipfs上

关于cattle.json 实例:

{ "description": "This is the zodiac sign chicken",//关于nft的描述 "external_url":"https://openseacreatures.io/3", "image":"ipfs://QmWH3hY6J31Hcf61aM6A9cCVArKSfh8E4mYbL9yg68kUx8",//指向的图片的url "name":"chicken",//nft的名字 "attributes": [ { "trait_type": "Background", "value": "Blue" }, { "trait_type": "Eyes", "value": "Black" }, { "trait_type": "Mouth", "value": "Smile" } ]//关于属性的设置 }

如图所示




屏幕截图 2024-12-28 001841.png

工具

使用openSea网站查看合约是否部署成功

在openSea测试网上链接自己的钱包,可以查看到自己铸造的所有的项目

部署成功如图:




屏幕截图 2024-12-27 235740.png

总结

以上就是从开发测试到部署的全流程,NFT和同质化代币最主要的区别就是多了metadata上传到ipfs上的操作;

发布人:900a****    IP:124.223.189***     举报/删稿
展会推荐
让朕来说2句
评论
收藏
点赞
转发