如何使用IPFS和Filecoin创建NFT

2021-08-20 61

挑战1 - 部署一个 NFT 合约

工具使用

- Node.js, version 16 - NPM, version 7 - HardHat - ethereum development framework & blockchain simulator - https://hardhat.org - OpenZeppelin Contracts - base Solidity contracts - https://docs.openzeppelin.com/contracts/4.x

步骤

1. 为项目新建一个目录并输入
mkdir nft-challenge cd nft-challenge
2. 使用默认设置开启一个新的NPM项目
npm init -y
3. 安装 HardHat and OpenZeppelin 合约作为开发依赖项
npm install --save-dev hardhat @openzeppelin/contracts
4. 使用HardHat生成项目scaffold
npx hardhat
当提示安装依赖项时,接受默认值。最后你会看到如下信息:
✨ Project created ✨ Try running some of the following tasks: npx hardhat accounts npx hardhat compile npx hardhat test npx hardhat node node scripts/sample-script.js npx hardhat help
并且目录下会创建一些新文件:
ls contracts node_modules package.json test hardhat.config.js package-lock.json scripts
5. (可选)使用Git来管理你的代码
git init . git add . git commit -m 'solidity boilerplate'
6. 用你最擅长的IDE并打开项目目录
code .
点击 contracts 目录,然后打开 Greeter.sol,你将看到一个 “hello world” 合约。
7. 在合约文件中创建一个名为 ‘GameItem.sol’ 的新文件,把这个粘贴进:
// contracts/GameItem.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract GameItem is ERC721URIStorage { using Counters for Counters.Counter; Counters.Counter private _tokenIds; constructor() ERC721("GameItem", "ITM") {} function awardItem(address player, string memory tokenURI) public returns (uint256) { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _mint(player, newItemId); _setTokenURI(newItemId, tokenURI); return newItemId; } }
8. 编译智能合约
npx hardhat compile
9. 从HardHat框架中打开示例脚本
在你的编辑器中打开scripts/sample-script.js 
将 Greeter 重命名为 GameItem , greeter重命名为 gameItem。 移除该参数 到 GameItem.deploy()
最终结果中的 main 函数应该是这样的:
async function main() { // Hardhat always runs the compile task when running scripts with its command // line interface. // // If this script is run directly using `node` you may want to call compile // manually to make sure everything is compiled // await hre.run('compile'); // We get the contract to deploy const GameItem = await hre.ethers.getContractFactory("GameItem"); const gameItem = await GameItem.deploy(); await gameItem.deployed(); console.log("GameItem deployed to:", gameItem.address); }
10. 使用 hardhat 命令运行该脚本:
npx hardhat run scripts/sample-script.js GameItem deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
提示说它已经部署在这个地址上了!是不是看上去我们已经完成了?
不,还没完。默认情况下,HardHat使用ephermeral blockhain模拟器作为它的目标环境,这对于编写自动化测试很有用,但是对互动式编程不太友好。
接下来我们将启动一个本地节点,并且告诉HardHat使用它。
11. 在项目目录中打开一个新的终端,并且运行hardhat节点
npx hardhat node
12. 返回原始终端,将HARDHAT_NETWORK环境变量设置为localhost,并且重新运行该脚本
export HARDHAT_NETWORK=localhost npx hardhat run scripts/sample-script.js
脚本输出的结果大致是相同的,但是如果你查看其他的终端,你将在hardhat的输出中看到一些交易信息。

挑战 2

1. 在你的编辑器里再次打开 scripts/sample-script.js 
在合约部署完成后,尝试调用一下 awardItem 函数
const accounts = await hre.ethers.getSigners() const player = accounts[0].address const cid = 'a-fake-cid' const tx = await gameItem.awardItem(player, `ipfs://${cid}`) const receipt = await tx.wait() for (const event of receipt.events) { if (event.event !== 'Transfer') { continue } console.log('token id: ', event.args.tokenId.toString()) console.log('owner: ', event.args.to) } const uri = await gameItem.tokenURI(1) console.log('token uri:', uri)
2. 运行脚本
npx hardhat run scripts/sample-script.js

挑战 3

1. 安装nft.storage客户端
npm install nft.storage
2. 在你的编辑器中再次打开 scripts/sample-script.js 
导入client package和File constructor,引用node.js内置的 readFile
const { readFile } = require('fs/promises') const { NFTStorage, File } = require('nft.storage')
3. 创建一个新的函数来加载一张图片并保存它
async function storeNFTData() { const apiKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJnaXRodWJ8Njc4NzE1IiwiaXNzIjoibmZ0LXN0b3JhZ2UiLCJpYXQiOjE2MTYwNzM2MjMxMTksIm5hbWUiOiJkZWZhdWx0In0.RJj_mR2zwTJ1_4gpAapGdkQcw3gSUz1SMmIHgr10Xng' const client = new NFTStorage({ token: apiKey }) const filename = '../files/nft.jpg' const data = await readFile(filename) const file = new File([data], 'nft.jpg', { type: 'image/jpeg' }) console.log('sending data to nft.storage...') const metadata = await client.store({ name: 'Encode Club Demo NFT', description: 'Hello Encode Club!', image: file }) console.log('stored NFT data! metadata URL:', metadata.url) return metadata.url }
4. 使用storeNFTData方法获得 metadata URL,然后创建该token,例如下面所示:
 main函数中:
const metadataURI = await storeNFTData() const tx = await gameItem.awardItem(player, metadataURI)
作者:Eason
原文链接:https://hackmd.io/E-pMngLbReqw-TEJDhe_4Q