1.获取ERC721协议
Openzeppelin中实现了ERC721协议,我们需要将示例代码复制下来,在remix中部署
// 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)
{
uint256 newItemId = _tokenIds.current();
_mint(player, newItemId);
_setTokenURI(newItemId, tokenURI);
_tokenIds.increment();
return newItemId;
}
}
2.执行awardItem
部署完后,remix会有很多方法,我们找到awardItem
,需要传递两个参数:address、tokenURI
tokenURI传入:图片连接
address传入:测试网钱包地址
此时,我们最简单的一个NFT就实现了
将合约地址导入到钱包资产,就可以看到我们的NFT
查看钱包中的token
另外,部署合约中还有很多方法提供,例如:转发token等
3.解析
我们可以从ERC721代码中看出,token的本质其实就是地址和数字的组合,在铸造NFT时,需要保证tokenId唯一性。
下面时ERC721的代码,我添加了一下简单的注释解释
// solidity版本号
pragma solidity ^0.8.0;
// 导入协议,remix会自动下载
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
// 定义合约,继承ERC721URIStorage
contract GameItem is ERC721URIStorage {
// 定义变量
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
// 初始化NFT名字,两个参数:NFT名字,NFT简写
constructor() ERC721("GameItem", "ITM") {}
// 定义白名单方法,接收两个参数:参与人地址,tokenURI
function awardItem(address player, string memory tokenURI)
public
returns (uint256)
{
// 获取到当前自增后的tokenId
uint256 newItemId = _tokenIds.current();
// 铸造NFT.铸造只需要提供地址和数字,所以NFT本质上就是地址和数字组合而来的
_mint(player, newItemId);
// 设置token信息
_setTokenURI(newItemId, tokenURI);
// tokenId自增,防止出现重复tokenId
_tokenIds.increment();
return newItemId;
}
}