# Alchemy第三周任务

By [Untitled](https://paragraph.com/@0x160877bcaf77644e55d051c487721190a55b1010) · 2022-08-20

---

1.2获取免费的 Matic 以部署NFT 智能合约 我们去到mumbaifaucet.com获取测试币，输入我们的地址获取测试币即可

10-20 秒后，会看到 MATIC 出现在 Metamask 钱包中。

2.1项目设置

新建一个文件夹用于此次项目的搭建
================

mkdir ChainBattled cd ChainBattled

安装yarn并查看版本
===========

npm install -g yarn yarn --version yarn add hardhat

初始化项目
=====

npx hardhat init

现在我们需要安装OpenZeppelin包来访问ERC721 智能合约我们将使用该标准作为模板来构建我们的 NFT 智能合约。

yarn add @openzeppelin/contracts 2.2修改 hardhat.config.js 文件 将我们的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 } }; 2.3开发智能合约 在 contracts 文件夹中，创建一个新文件并将其命名为“ChainBattles.sol”。

与往常一样，我们需要指定SPDX-Licence-Identifier、pragma ，并从OpenZeppelin导入几个库，我们将用作智能合约的基础，合约内容如下：

// 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),"The tokenId does not exist"); require(\_isApprovedOrOwner(msg.sender, tokenId),"You are not the owner of the NFT"); tokenIdToLevels\[tokenId\] += 1; \_setTokenURI(tokenId, getTokenURI(tokenId)); } } 我们在上面将合约全部完善了，也新增了 4 个不同的功能：

\*\*generateCharacter：\*\*生成和更新我们 NFT 的 SVG 图像 \*\*getLevels：\*\*获取 NFT 的当前级别 \*\*getTokenURI ：\*\*获取 NFT 的 TokenURI \*\*mint:\*\*到 mint - 当然 \*\*train：\*\*训练 NFT 并提高其等级 3.使用链上元数据智能合约部署 NFT 首先，让我们在项目的根文件夹中新建一个 .env 文件，并添加以下变量：

TESTNET\_RPC="" PRIVATE\_KEY="" POLYGONSCAN\_API\_KEY="" 然后，导航到alchemy.com并创建一个新的 Polygon Mumbai 应用程序：

单击新创建的应用程序，复制 API HTTP URL，并将 API 作为“ TESTNET\_RPC ”值粘贴到我们在上面创建的 .env 文件中。

打开您的Metamask钱包，点击三个点菜单 > 帐户详细信息 > 并将您的私钥复制粘贴为..env

最后，继续Polygon,并创建一个新帐户，登录后，进入个人资料菜单并单击 API Keys，如果没有则需要新建一个：

现在将 Api-Key 令牌复制粘贴为 .env 中的“ POLYGONSCAN API\_KEY ”值。最终结果如下：

在部署我们的智能合约之前的最后一步，我们需要创建部署脚本。

3.1创建部署脚本 我们将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(); 3.2编译和部署智能合约 当我们把脚本写好后，编译智能合约，只需在项目内的终端中运行以下命令：

npx hardhat compile 如果一切按预期进行，你将在 artifacts 文件夹中看到已编译的智能合约。

现在，让我们在运行的 Polygon Mumbai 链上部署智能合约

npx hardhat run scripts/deploy.js --network mumbai 如果一切正常你将在页面看到合约的地址

3.3在 Polygon Scan 上检查智能合约 复制刚刚部署的智能合约的地址，去测试polygon网络，然后\*\*在搜索栏中粘贴智能合约的地址。\*\*进入智能合约页面后，单击“合约”选项卡。你会注意到合约代码不可读：

这是因为我们还没有验证我们的代码。

为了验证我们的智能合约，我们需要回到我们的项目，并在终端中运行以下代码：

npx hardhat verify --network mumbai 合约地址
========================================

npx hardhat verify --network mumbai 0x2A9C54F7711d12aE72b9ECefEA2ce4c497595b9b 后续也可以通过测试polygon网络提供的验证过的，如果你解决了下面的报错，可以和武哥一起交流下

报错信息：

Error in plugin @nomiclabs/hardhat-etherscan: Failed to send contract verification request. Endpoint URL: [https://api-testnet.polygonscan.com/api](https://api-testnet.polygonscan.com/api) Reason: read ECONNRESET 通过网站添加方法，点击立即验证即可：

3.4通过多边形扫描与您的智能合约交互 现在智能合约已经通过验证，[mumbai.polygonscan.com](http://mumbai.polygonscan.com) 将在其附近显示一个绿色小勾：

然后寻找“min​​t”函数并点击Write：

这将打开一个 Metamask 弹出窗口，要求支付 gas 费用，单击签名按钮。恭喜！您刚刚铸造了您的第一个动态 NFT - 让我们转移到 OpenSea 测试网来现场查看它。

4.在 OpenSea 上查看您的动态 NFT 复制智能合约地址，[前往testnet.opensea.com](http://xn--testnet-s00l549g.opensea.com)，并将其粘贴到搜索栏中：

如果一切正常，现在应该会看到您的 NFT 显示在 OpenSea 上，其中包含动态图像、标题和描述。

4.1更新动态 NFT 图像训练 NFT 导航回测试.polygons网络，点击合约标签 > 写合约并寻找“train”功能。

插入您的 NFT 的 ID - 在这种情况下为“1”，因为我们只铸造了一个，然后单击写入：

然后回到testnets.opensea.com并刷新页面：

以上就是第三周的任务了，大家别忘记了填写表格完成哦，表格页面在下方：

Week Three - Road to Web3 Project Submission

---

*Originally published on [Untitled](https://paragraph.com/@0x160877bcaf77644e55d051c487721190a55b1010/alchemy)*
