# Alchemy Road to Web3第三周:铸造 NFT并刷新元数据 **Published by:** [Licrazy](https://paragraph.com/@doger/) **Published on:** 2022-08-29 **URL:** https://paragraph.com/@doger/alchemy-road-to-web3-nft ## Content TL;DR:这周教程也是一共包括六个步骤,目的是部署一个NFT合约,并与之进行交互,刷新元数据。主要内容包括:准备/搭建环境/代码编译/部署合约/合约交互/发布与提交。 第一步、准备: 1、结合之前前序文档,创建好本周的github代码库以及同步到replit.com上。 如图,依次点击右上角github账号--“repositories”--“new”--填写“name”(随意)--“create repository”(切记勾选“add a README file”不然会是一个空库,无法导入replit) 2、登陆你的replit账号,依次点击“create”--“import”,然后选择上一步创建的代码库“magweek3”,再次点击“import from github”,完成代码的导入工作。 (注意在开始这一步之前,必须要先关联好github账号,如何关联请看之前前序) 导入完成之后,点击“DONE” 第二步、环境搭建 1、回到replit左边栏,删除掉README.md。 2、点击右侧“Shell”,创建ChainBattle目录并进入,输入mkdir ChainBattle并回车,然后输入cd ChainBattle并回车。(以下步骤的命令都是在“shell”中输入) 2、输入npm init -y并回车(中间可能会要再次回车一次)。 3、输入npm install hardhat并回车,等待安装完成,如下图所示。 4、输入npx hardhat init并回车,(中间应该需要点5次回车,多点几次也无妨😆,warn不用管)等待安装完成,如下图所示。 5、输入npm install @openzeppelin/contracts并回车,等待安装完成,如下图。 6、输入npm install @nomiclabs/hardhat-etherscan并回车,等待安装完成,如下图。 7、输入npm install @nomiclabs/hardhat-waffle并回车,等待安装完成,如下图。 8、输入npm install dotenv并回车,等待安装完成,如下图。 至此所有环境搭建已经完成,中途应该不会遇到本地环境兼容问题🏂,这就是网页端搭建的好处。 第三步、代码编译 1、打开contracts目录,把Lock.sol重命名为ChainBattles.sol。 2、将上一步重命名为ChainBattles.sol的文件里的内容替换为以下代码。 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/Base64.sol"; contract ChainBattles is ERC721URIStorage { using Strings for uint256; using Counters for Counters.Counter; Counters.Counter private _tokenIds; mapping(uint256 => uint256) public tokenIdToLevels; constructor() ERC721 ("Chain Battles", "CBTLS"){ } function generateCharacter(uint256 tokenId) public returns(string memory){ bytes memory svg = abi.encodePacked( '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 350 350">', '<style>.base { fill: white; font-family: serif; font-size: 14px; }</style>', '<rect width="100%" height="100%" fill="black" />', '<text x="50%" y="40%" class="base" dominant-baseline="middle" text-anchor="middle">',"Warrior",'</text>', '<text x="50%" y="50%" class="base" dominant-baseline="middle" text-anchor="middle">', "Levels: ",getLevels(tokenId),'</text>', '</svg>' ); return string( abi.encodePacked( "data:image/svg+xml;base64,", Base64.encode(svg) ) ); } function getLevels(uint256 tokenId) public view returns (string memory) { uint256 levels = tokenIdToLevels[tokenId]; return levels.toString(); } function getTokenURI(uint256 tokenId) public returns (string memory){ bytes memory dataURI = abi.encodePacked( '{', '"name": "Chain Battles #', tokenId.toString(), '",', '"description": "Battles on chain",', '"image": "', generateCharacter(tokenId), '"', '}' ); return string( abi.encodePacked( "data:application/json;base64,", Base64.encode(dataURI) ) ); } function mint() public { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _safeMint(msg.sender, newItemId); tokenIdToLevels[newItemId] = 0; _setTokenURI(newItemId, getTokenURI(newItemId)); } function train(uint256 tokenId)public{ require(_exists(tokenId)); require(ownerOf(tokenId)==msg.sender,"You must own this token to train it"); uint256 currentLevel=tokenIdToLevels[tokenId]; tokenIdToLevels[tokenId]=currentLevel+1; _setTokenURI(tokenId,getTokenURI(tokenId)); } } 3、在ChainBattle文件夹下新建.env文件,并在该文件内输入以下代码。 TESTNET_RPC= PRIVATE_KEY= POLYGONSCAN_API_KEY= 4、在alchemy.com里面创建(如何创建详见:之前前序)一个Polygon Mumbai网络的APP,复制其URL粘贴到.env的TESTNET_RPC=后面 将metamask钱包的新建小号私钥导出(如何导出详见:之前前序),并复制粘贴到PRIVATE_KEY=后面。 进入polygonscan.com,登陆你的账号(需要先注册这里不赘述)依次点击“API keys”-- “Add”创建一个API。 然后复制你刚才创建的那个API代码粘贴到POLYGONSCAN_API_KEY=后面,如下图红框内。 5、最后.env文件内的代码大概如下图所示。 6、打开hardhat.config.js文件,将一下代码粘贴进去,如图所示。 require("dotenv").config(); require("@nomiclabs/hardhat-waffle"); require("@nomiclabs/hardhat-etherscan"); module.exports = { solidity: "0.8.10", networks: { mumbai: { url: process.env.TESTNET_RPC, accounts: [process.env.PRIVATE_KEY] }, }, etherscan: { apiKey: process.env.POLYGONSCAN_API_KEY } }; 7、代码编译已经完成,测试一下是否编译成功。在Shell那边输入npx hardhat compile并回车(中间大概需要5次回车🚒)。 第四步、部署合约 1、添加好mumbai测试网及领取测试币。 ①进入chainlist.info,搜索mumbai,将matic测试网添加到Metamask钱包。 ②进入https://mumbaifaucet.com/,右上角登陆Alchemy账号,粘贴钱包地址,点击“Send Me Matic”获取测试币。 2、然后回到Replit,打开scripts/deploy.js,将原文替换成以下代码。 const main = async () => { try { const nftContractFactory = await hre.ethers.getContractFactory( "ChainBattles" ); const nftContract = await nftContractFactory.deploy(); await nftContract.deployed(); console.log("Contract deployed to:", nftContract.address); process.exit(0); } catch (error) { console.log(error); process.exit(1); } }; main(); 4、在Shell处输入npx hardhat run scripts/deploy.js --network mumbai并回车(中间可能会有一次回车)。 5、点击Metamask钱包三点处,然后点区块浏览器,然后弹出新新网页查看合约地址是否一致,并等待contract处是否出现✅。如若没有,则输入npx hardhat verify --network mumbai +你的合约地址,进行验证。 最终出现“successfully submit”则代表合约部署已经成功完成。 第五步、合约交互 1、切换到之前打开的合约网页上,点开Contract--Write contract--connect to web3,在弹出的钱包中点确定,连接之前对应的私钥钱包。 2、点击第4个“mint”下的write,在钱包中确认,等待交互成功。 3、前往 testnet.opensea.com ,连接我们刚才的钱包,点击profile,找到我们刚才mint的nft,点进去会发现如下图所示。 4、继续回到合约那边,选到第8个train,在框中输入1,点击write,弹出小狐狸,点确认等待链上确认成功。 5、再次回到testnet.opensea.com 刷新网页,如下图所示,可以看到0变成1了,表示该任务已经成功完成。 第六步、发布与提交 1、如图点击publish,填好description然后一直点下一步即可发布成功,保存好最后出来的那个网址,作为提交证明。 2、提交到github,提交之前记得删除.env(保险起见)。 将代码提交到github,并在你的github账号查看提交记录,复制好你的github本周代码库网址(图二红框处)作为任务提交证明。 3、任务提交https://forms.gle/DdnKrEvKzUHK4yLH9 主要是三个链接:1第四步第4点部署到合约地址,2第六步第1点获取的published地址 3第六步第2点获取的github代码库地址。 ## Publication Information - [Licrazy](https://paragraph.com/@doger/): Publication homepage - [All Posts](https://paragraph.com/@doger/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@doger): Subscribe to updates - [Twitter](https://twitter.com/Licrazy01): Follow on Twitter