# 手把手教程 ——Alchemy Week3 **Published by:** [RogerZ](https://paragraph.com/@rogerz-2/) **Published on:** 2022-08-16 **URL:** https://paragraph.com/@rogerz-2/alchemy-week3 ## Content Alchemy 教程目录Week1: How to Develop an NFT Smart Contract (ERC721) with Alchemy 教程 Week2: How to Build “Buy Me a Coffee“ Defi dapp with Alchemy 教程Week3: How to Make NFTs with On-Chain Metadata - HardHat and JavaScript 教程官方教程在此,也可以看 youtube 视频链接,不想看我啰嗦的可以移步。 step0 环境配置系统环境: Window10 X64编程环境: nodeJS v16.15.0 NPM v8.5.5 nodeJS 安装回头写一篇教程吧,最简单的方法可以 google nvm,比去官网下载 nodeJS 的安装包好用多了。另外 windows 系统下需要配置环境变量,不明白的可以先百度。编程IDE: VS Code VS code 下载官网,exe 的安装程序,按照提示即可step1 部署 web3 环境1. 新建文件夹 ChainBattles,在文件夹内启动 cmd,npm init -y初始化项目,获得文件 package.json。 2. 安装 hardhat,在 cmd 中输入根据提示依次 选择Create a basic sample project 选择默认路径 3. 复制下列代码,安装需要的库npm install --save-dev "hardhat@^2.9.3" "@nomiclabs/hardhat-waffle@^2.0.0" "ethereum-waffle@^3.0.0" "chai@^4.2.0" "@nomiclabs/hardhat-ethers@^2.0.0" "ethers@^5.0.0" "@nomiclabs/hardhat-etherscan@^3.0.1" 4. 安装 dotenv 库5. 安装 OpenZeppelinnpm install @openzeppelin/contracts 可以看下文件夹内的各文件,如果和以下树形图一致,那就表示环境部署没有问题了。. ├── README.md ├── contracts ├── hardhat.config.js ├── node_modules ├── package-lock.json ├── package.json ├── scripts └── test 接下来的step2,step4 需使用 VScode 打开文件夹进行编辑。step2 编写智能合约在 ./contracts/ 文件夹下新建 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 view 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 view 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 NFT to train it!"); uint256 currentLevel = tokenIdToLevels[tokenId]; tokenIdToLevels[tokenId] = currentLevel + 1; _setTokenURI(tokenId, getTokenURI(tokenId)); } } step3 申请 Alchemy 帐号并配置小狐狸钱包1. 注册 alchemy 帐号详细步骤可以回看 week1 教程的 step3。 https://www.alchemy.com/ 2. 进入 Dashboard,点击 create app。3. 依次填入 Name, Description,Chain 选择 Polygon,Network 选择 Polygon Mumbai,然后点击 CREATE APP。4. 点击 VIEW KEY,复制 HTTPS 和 API KEY 的内容5. 查看小狐狸钱包中是否有 Mumbai 测试网,如果没有可以去 chainlink.org 上添加一个,并保存私钥,第六步要用到。 6. 因为交互需要消耗 gas,所以还需通过 chainlink faucet 获取测试代币 MATIC。通过 faucet 的链接,进入申请代币即可。 https://faucets.chain.link/step4 在 Mumbai 测试网络部署合约1. 在 ./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(); 2. 编辑 ./hardhat.config.js,复制以下代码,然后保存。require("dotenv").config(); require("@nomiclabs/hardhat-waffle"); require("@nomiclabs/hardhat-etherscan"); const MUMBAI_URL = process.env.MUMBAI_URL; const PRIVATE_KEY = process.env.PRIVATE_KEY; const POLYSCAN_API_KEY = process.env.POLYSCAN_API_KEY module.exports = { solidity: "0.8.10", networks: { mumbai: { url: MUMBAI_URL, accounts: [PRIVATE_KEY] }, }, etherscan: { apiKey: POLYSCAN_API_KEY } }; 3. 新建 ./.env 文件,复制以下代码,然后保存。MUMBAI_URL=输入你的MUMBAI_URL POLYSCAN_API_KEY=输入你的POLYSCAN_API_KEY PRIVATE_KEY=输入你的私钥 4. 在 cmd 中运行 npx hardhat run scripts/deploy.js --network mumbai,返回Contract deployed to: 合约地址 至此,合约已经部署到了 Mumbai 测试网,还可以在浏览器中查看。但是合约没有开源,还没有 verify。5. 在 cmd 中运行 npx hardhat verify --network mumbai [合约地址],返回Nothing to compile Successfully submitted source code for contract contracts/ChainBattles.sol:ChainBattles at 合约地址 for verification on the block explorer. Waiting for verification result... Successfully verified contract ChainBattles on Etherscan. https://mumbai.polygonscan.com/address/合约地址#code 看到 successfully 即 verify 成功,再回到 mumbai polygonscan 上看,已经有绿勾了。step5 通过合约Mint NFT1. 在合约页面中,选择 Contract —> Write Contract —> Connect to Web3,在弹出的 Metamask 窗口点击下一步,最后连接。2. 在 mint 方法下,点击 write 并在弹出的 Metamask 窗口内确认。3. 在 testnet.opensea.io 中可以查看 NFT 已经在钱包中。step6 通过合约train NFT这是一个动态的 NFT,回到合约页面中,找到 train 方法,输入自己所持有 NFT 的 tokenId(第一个输入1),再点击 write 并在弹出的 Metamask 窗口内确认。在 testnet.opensea.io 中可以查看 NFT ,点击 refresh metadata 按钮后,再刷新页面,Levels 变成了 1。step7 在官网提交任务并 claim NFT在官方申请网址中提交对应的信息。 https://alchemyapi.typeform.com/roadtoweekthree 在 mintkudos 网址中 claim Alchemy 的 NFT,通常需要一天至一周可以获得 allowlist 资格。 https://mintkudos.xyz/claim/674 ## Publication Information - [RogerZ](https://paragraph.com/@rogerz-2/): Publication homepage - [All Posts](https://paragraph.com/@rogerz-2/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@rogerz-2): Subscribe to updates