ERC721实践

​ ERC721是比ERC20更复杂的标准,具有多个可选扩展名,并且分为多个合约。 OpenZeppelin合约提供了灵活的组合方式以及自定义有用的扩展。本文讲解以OpenZeppelin合约为目标对象。

构建ERC721代币合同

​ 我们将使用ERC721来跟踪游戏中的装备条目,每个条目都有各自独特的属性。 每当要奖励给玩家时,便会铸造(mint)并发送给他们。 玩家可以自由保留自己的代币,也可以与自己认为合适的其他人进行交易,就像区块链上的任何其他资产一样! 请注意,任何帐户都可以将awardItem称为铸造(mint)。 为了限制可以创建项目的帐户,我们可以添加访问控制

​ 合约如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract GameItem is ERC721 {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;

constructor() public 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;
}
}

​ ERC721合约包括了标准扩展(IERC721MetadataIERC721Enumerable)。 这就是_setTokenURI方法的来源:我们使用它来存储项目的元数据。

​ 另请注意:与ERC20不同,ERC721缺少小数,因为每个令牌都是不同的,并且无法分区。

​ 新项目示例:

1
2
3
4
> gameItem.awardItem(playerAddress, "https://game.example/item-id-8u5h2m.json")
Transaction successful. Transaction hash: 0x...
Events emitted:
- Transfer(0x0000000000000000000000000000000000000000, playerAddress, 7)

​ 查询每个项目的所有者和元数据:

1
2
3
4
> gameItem.ownerOf(7)
playerAddress
> gameItem.tokenURI(7)
"https://game.example/item-id-8u5h2m.json"

​ 此tokenURI应该解析为一个类似于以下内容的JSON文档:

1
2
3
4
5
6
{
"name": "Thor's hammer",
"description": "Mjölnir, the legendary hammer of the Norse god of thunder.",
"image": "https://game.example/item-id-8u5h2m.png",
"strength": 20
}

​ 有关tokenURI元数据JSON架构的更多信息,请参考==>https://eips.ethereum.org/EIPS/eip-721

ERC721 合约的前置功能

​ ERC721可用的预设有ERC721PresetMinterPauserAutoId。它已预设为允许Token铸造(创建),停止所有令牌传输(暂停),并允许持有人焚毁(销毁)其Token。合同使用访问控制来控制对铸造和暂停功能的访问。部署合同的帐户将被授予minter 和pauser 角色,以及默认的admin角色。

​ 无需编写任何Solidity代码即可立即部署此合同。它可以原样用于快速原型制作和测试,但也适用于生产环境。

关联内容 ==> https://willzhuang.github.io/2019/07/04/ERC20-721Token的发行-冻结-多方签名功能