ERC1155
ERC1155是一个为了实现比以前标准更好的新通证标准。
多通证标准
ERC1155最独特的功能是它使用一个单独的智能合约一次性代表多种通证。这也就是它的balanceOf函数与ERC20及ERC777不同的原因。它有一个额外的id参数作为通证标识符以查询余额。
这点和ERC721相似,但是表中的id并没有余额的概念。ERC721的balanceOf函数关联到一个账户拥有多少不同的通证,而不是每个拥有多少个。另一方面,ERC1155账户每个通证id有非常清晰的余额。和不可替代的通证实现通过简单铸造它们中的一个。
这种方法对于有多种通证的项目会节省大量的gas费。比针对每种通证类型部署不同的合约更好。一个ERC1155通证合约可以包含所有系统状态,降低部署成本和复杂性。
批量 *** 作
因为所有状态都存储在一个合约中,就可以非常高效地在一个 *** 作中 *** 作很多通证。标准提供了两个函数:balanceOfBatch 和 safeBatchTransferFrom,使得查询多个余额和转移多种通证变得简单和花费更少的gas费。
在标准中,也包含一些非必需的函数,比如_mintBatch。
构造一个ERC1155通证合约
// contracts/GameItems.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
contract GameItems is ERC1155 {
uint256 public constant GOLD = 0;
uint256 public constant SILVER = 1;
uint256 public constant THORS_HAMMER = 2;
uint256 public constant SWORD = 3;
uint256 public constant SHIELD = 4;
constructor() ERC1155("https://game.example/api/item/{id}.json") {
_mint(msg.sender, GOLD, 10**18, "");
_mint(msg.sender, SILVER, 10**27, "");
_mint(msg.sender, THORS_HAMMER, 1, "");
_mint(msg.sender, SWORD, 10**9, "");
_mint(msg.sender, SHIELD, 10**9, "");
}
}
ERC1155合约包含可选的扩展IERC1155MetadataURI。用于查询合约的元数据。
不像ERC20那样,ERC1155没有小数字段,每个代币就不可以再分割。
以上合约部署好以后,就可以查询部署者的余额
> gameItems.balanceOf(deployerAddress,3)
也可以转移
> gameItems.safeTransferFrom(deployerAddress, playerAddress, 2, 1, "0x0")
> gameItems.balanceOf(playerAddress, 2)
1
> gameItems.balanceOf(deployerAddress, 2)
0
也可以批量转移和批量获取余额
> gameItems.safeBatchTransferFrom(deployerAddress, playerAddress, [0,1,3,4], [50,100,1,1], "0x0")
> gameItems.balanceOfBatch([playerAddress,playerAddress,playerAddress,playerAddress,playerAddress], [0,1,2,3,4])
[50,100,1,1,1]
元数据uri获取方式:
> gameItems.uri(2)
"https://game.example/api/item/{id}.json"
Uri可以包含字符串id,客户端查询时替换为实际的代币id,小写的十六进制格式,不够64位的用0填充。对于代币ID为2的可以这样查询:
https://game.example/api/item/0000000000000000000000000000000000000000000000000000000000000002.json
查询的元数据如下所示:
{
"name": "Thor's hammer",
"description": "Mjölnir, the legendary hammer of the Norse god of thunder.",
"image": "http://www.kaotop.com/file/tupian/20220606/item-id-8u5h2m.png",
"strength": 20
}
给合约发送代币
当使用safeTransferFrom做代币转移时的一个重要区别是可能收到以下消息
ERC1155: transfer to non ERC1155Receiver implementer
这就对了,这意味着接受合约还没有注册自己为ERC1155协议。
为了接收ERC1155代币我们可以继承合约ERC1155Holder。
// contracts/MyContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
contract MyContract is ERC1155Holder {
}
也可以通过onERC1155Received和onERC1155BatchReceived 函数实现更多复杂的场景应用。
预置ERC1155合约
ERC1155PresetMinterPauser,这个预置合约包含铸造和批量铸造功能,以及转移和销毁功能。合约通过使用 Access Control 控制对铸造和中止函数的访问。已部署合约的账号会授权给铸造者或者中止者角色,还有默认的管理员角色。
这个合约可以在没有任何Solidity代码的情况下用于部署,用于快速作原型或测试,当然也可以直接使用与生产环境。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)