ERC1155
ERC1155
多代币标准
简介
用于多种代币管理的合约标准接口。 单个部署的合约可以包括同质化代币、非同质化代币或其他配置(如半同质化代币)的任何组合。
多代币标准是什么?
它的目的很单纯,就是创建一个智能合约接口,可以代表和控制任何数量的同质化和非同质化代币类型。 这样一来,ERC-1155 代币就具有与 ERC-20 和 ERC-721 代币相同的功能,甚至可以同时使用这两者的功能。 它改进了 ERC-20 和 ERC-721 标准的功能,提升了效率并纠正了实现中的明显错误。
功能
批量传输
通过一次合约调用传输多种资产
就是不单是一种代币可以传输,很多种代币都可以传输
来看看,他与ERC20传输合约的比较
// ERC-20 |
ERC-1155 中唯一的区别是我们将值作为数组传递,同时也传递了 ids 数组。 例如,给出 ids=[3, 6, 13] 和 values=[100, 200, 5],传输结果将是
- 将 id 3 的 100 个代币从 _from 传输到 _to。
- 将 id 6 的 200 个代币从 _from 传输到 _to。
- 将 id 13 的 5 个代币从 _from 转移到 _to。
在 ERC-1155 中,我们只有 transferFrom,没有 transfer。 要像常规的 transfer一样使用它,只需将 “from” 地址设为调用该函数的地址。
批量余额
在一次调用中获取多个资产的余额
相应的 ERC-20 balanceOf 调用同样具有支持批处理的相应函数。 还是做个对比
// ERC-20 |
调用余额查询更简单的是,我们可以在单次调用中获取多个余额。 参数中传递所有者帐户数组和代币的 id 数组。
例如,对于给出的 _ids=[3, 6, 13] 和 _owners=[0xbeef…, 0x1337…, 0x1111…],返回值将为:
[ |
批量审批
审批同一地址的所有代币
还是来看一下ERC115
// ERC-1155 |
审批过程与 ERC-20 略有不同。 这里不是批准特定金额,而是通过 setApprovalForAll 函数设置操作帐户为已批准或未批准。
查看当前的审批状态可以通过 isApprovedForAll 完成。 如你所见,要么全部批准,要么不批准。 不能定义要批准代币的数量,甚至代币类型。
这是考虑到简洁性而故意设计的。 你只能批准一个地址的所有代币。
接受钩子
接受钩子的代币函数
function onERC1155BatchReceived( |
基于 EIP-165(opens in a new tab) 的协议支持,ERC-1155 只支持智能合约的接收钩子函数。 钩子函数必须返回一个事先预定义的 4 字节值,这个值被指定为:bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
当接收合约返回这一值时,意味着合约知道如何处理 ERC-1155 代币并接受转账。 太好了,代币不会再卡在合约中了!(这里可能会是漏洞,比如点击这个题就是使用到了钩子,让代币困在合约中)
安全转账
现在我们来看一下最重要的规则:
1,调用者必须获得批准才能从 _from 的帐户地址消费代币,或者调用者帐户地址必须与 _from 的帐户地址相同。
2,在以下情况下,转账调用将回退
- _to 地址为 0;
- _ids 的长度与 _values 的长度不同;
- _ids 中代币持有者的任何余额低于发送给接收者的相应 _value 金额。出现任何其他错误。
注意:包括钩子在内的所有批处理函数也均作为非批处理的版本存在。 这样做是为了提高燃料效率,考虑到只转移一种资产可能仍然是最常用的方式。 简洁起见,我们没有在这里介绍这些非批处理的版本,包括安全转账规则。 名称是相同的,只需移除 ‘Batch’。
接口
IERC1155接口,接口中定义了六个函数
- balanceOf():单币种余额查询,返回account拥有的id种类的代币的持仓量。
- balanceOfBatch():多币种余额查询,查询的地址accounts数组和代币种类ids数组的长度要相等。
- setApprovalForAll():批量授权,将调用者的代币授权给operator地址。。
- isApprovedForAll():查询批量授权信息,如果授权地址operator被account授权,则返回true。
- safeTransferFrom():安全单币转账,将amount单位id种类的代币从from地址转账给to地址。如果to地址是合约,则会验证是否实现了onERC1155Received()接收函数。
- safeBatchTransferFrom():安全多币转账,与单币转账类似,只不过转账数量amounts和代币种类ids变为数组,且长度相等。如果to地址是合约,则会验证是否实现了onERC1155BatchReceived()接收函数。(重点)
如果ERC1155TOKEN的接收者receiver是一个合约地址,那么接收者必须要实现该接口。
该接口有两个函数:(前提是接收者是合约地址):
- onERC1155Received:这个函数是在调用 ERC1155的 safeTransferFrom()和 _mint()时,接收者的该函数会被调用,并按要求返回指定的值 bytes4(keccak256(“onERC1155Received(address,address,uint256,uint256,bytes)”))。
- onERC1155BatchReceived:这个函数时在调用 ERC1155的 safeBatchTransferFrom()时,接收者的该函数会被调用,并按要求返回指定的值 bytes4(keccak256(“onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)”))
如果我们不按要求返回一个指定值,那么代币就会转移不出来,困在合约中。