ERC721开发NFT--接口
使用https://docs.openzeppelin.com/contracts/4.x/erc721中的简单案例
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; } }
tokenId:类似于商城商品ID,从0开始
approve函数
// 将token授权给to地址
function approve(address to, uint256 tokenId) external;
函数:awardItem() 铸造token,
player:拥有者地址
tokenURI:NFT信息,可以是地址或json,
返回tokenId
function awardItem(address player, string memory tokenURI) public returns (uint256) { uint256 newItemId = _tokenIds.current(); _mint(player, newItemId); _setTokenURI(newItemId, tokenURI); _tokenIds.increment(); return newItemId; }
safeTransferFrom函数
// 转移token从from到to地址 function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external;
safeTransferFrom函数
// 转移token从from到to地址 function safeTransferFrom( address from, address to, uint256 tokenId ) external;
setApprovalForAll函数
// 授权全部token给operate地址 function setApprovalForAll(address operator, bool _approved) external;
transferFrom函数,//单个NFT转移,与safeTransferFrom()不同之处在于调用者必须自己确认_to地址能正常接收NFT,否则将丢失此NFT
function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //检查 合约调用者是否是token的拥有者或者被授权approve require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); // 转移token _transfer(from, to, tokenId); }
balanceOf函数,返回由_owner 持有的NFTs的数量
// 记录 function balanceOf(address owner) external view returns (uint256 balance);
getApproved函数,查询地址授权(单个NFT)
// 获取token的approve地址 function getApproved(uint256 tokenId) public view virtual override returns (address) { // 检查token是否存在 _requireMinted(tokenId); return _tokenApprovals[tokenId]; }
isApprovedForAll函数,查询地址授权(所有的NFT)
// 设置 给operator的授权情况 function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); }
ownerOf函数
// 获取token的拥有者地址 function ownerOf(uint256 tokenId) external view returns (address owner);
supportsInterface函数
// 是否使用了 ERC721接口 function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); }
tokenURI函数
// 获取tokenURI function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { // 检查token是否存在 _requireMinted(tokenId); // 获取baseURI string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; }
更多接口解析,请看:https://learnblockchain.cn/article/4507#_mint%E5%87%BD%E6%95%B0
// 是否使用了 ERC721接口 function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); }