Subscribe to Untitled
Subscribe to Untitled
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers
1.2获取免费的 Matic 以部署NFT 智能合约 我们去到mumbaifaucet.com获取测试币,输入我们的地址获取测试币即可
10-20 秒后,会看到 MATIC 出现在 Metamask 钱包中。
2.1项目设置
mkdir ChainBattled cd ChainBattled
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 0x2A9C54F7711d12aE72b9ECefEA2ce4c497595b9b 后续也可以通过测试polygon网络提供的验证过的,如果你解决了下面的报错,可以和武哥一起交流下
报错信息:
Error in plugin @nomiclabs/hardhat-etherscan: Failed to send contract verification request. Endpoint URL: https://api-testnet.polygonscan.com/api Reason: read ECONNRESET 通过网站添加方法,点击立即验证即可:
3.4通过多边形扫描与您的智能合约交互 现在智能合约已经通过验证,mumbai.polygonscan.com 将在其附近显示一个绿色小勾:
然后寻找“mint”函数并点击Write:
这将打开一个 Metamask 弹出窗口,要求支付 gas 费用,单击签名按钮。恭喜!您刚刚铸造了您的第一个动态 NFT - 让我们转移到 OpenSea 测试网来现场查看它。
4.在 OpenSea 上查看您的动态 NFT 复制智能合约地址,前往testnet.opensea.com,并将其粘贴到搜索栏中:
如果一切正常,现在应该会看到您的 NFT 显示在 OpenSea 上,其中包含动态图像、标题和描述。
4.1更新动态 NFT 图像训练 NFT 导航回测试.polygons网络,点击合约标签 > 写合约并寻找“train”功能。
插入您的 NFT 的 ID - 在这种情况下为“1”,因为我们只铸造了一个,然后单击写入:
然后回到testnets.opensea.com并刷新页面:
以上就是第三周的任务了,大家别忘记了填写表格完成哦,表格页面在下方:
Week Three - Road to Web3 Project Submission
1.2获取免费的 Matic 以部署NFT 智能合约 我们去到mumbaifaucet.com获取测试币,输入我们的地址获取测试币即可
10-20 秒后,会看到 MATIC 出现在 Metamask 钱包中。
2.1项目设置
mkdir ChainBattled cd ChainBattled
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 0x2A9C54F7711d12aE72b9ECefEA2ce4c497595b9b 后续也可以通过测试polygon网络提供的验证过的,如果你解决了下面的报错,可以和武哥一起交流下
报错信息:
Error in plugin @nomiclabs/hardhat-etherscan: Failed to send contract verification request. Endpoint URL: https://api-testnet.polygonscan.com/api Reason: read ECONNRESET 通过网站添加方法,点击立即验证即可:
3.4通过多边形扫描与您的智能合约交互 现在智能合约已经通过验证,mumbai.polygonscan.com 将在其附近显示一个绿色小勾:
然后寻找“mint”函数并点击Write:
这将打开一个 Metamask 弹出窗口,要求支付 gas 费用,单击签名按钮。恭喜!您刚刚铸造了您的第一个动态 NFT - 让我们转移到 OpenSea 测试网来现场查看它。
4.在 OpenSea 上查看您的动态 NFT 复制智能合约地址,前往testnet.opensea.com,并将其粘贴到搜索栏中:
如果一切正常,现在应该会看到您的 NFT 显示在 OpenSea 上,其中包含动态图像、标题和描述。
4.1更新动态 NFT 图像训练 NFT 导航回测试.polygons网络,点击合约标签 > 写合约并寻找“train”功能。
插入您的 NFT 的 ID - 在这种情况下为“1”,因为我们只铸造了一个,然后单击写入:
然后回到testnets.opensea.com并刷新页面:
以上就是第三周的任务了,大家别忘记了填写表格完成哦,表格页面在下方:
Week Three - Road to Web3 Project Submission
No activity yet