跳转至主要内容
Change page

ERC-1155 多代币标准

上次修改时间: @mdranger(opens in a new tab), 2023年8月15日

介绍

用于多种代币管理的合约标准接口。 单个部署的合约可以包括同质化代币、非同质化代币或其他配置(如半同质化代币)的任何组合。

多代币标准是什么?

它的目的很单纯,就是创建一个智能合约接口,可以代表和控制任何数量的同质化和非同质化代币类型。 这样一来,ERC-1155 代币就具有与 ERC-20ERC-721 代币相同的功能,甚至可以同时使用这两者的功能。 它改进了 ERC-20 和 ERC-721 标准的功能,提升了效率并纠正了实现中的明显错误。

EIP-1155(opens in a new tab) 中对 ERC-1155 代币进行了全面的描述。

前提条件

为了更好地理解这一页面的内容,我们建议你先阅读代币标准ERC-20ERC-721

ERC-1155 的功能和特点:

  • 批量传输:通过一次合约调用传输多种资产。
  • 批量余额:在一次调用中获取多个资产的余额。
  • 批量审批:审批同一地址的所有代币。
  • Hook:接收代币的钩子函数。
  • 支持非同质化代币:如果供应量仅为 1,将其作为非同质化代币处理。
  • 安全转账规则:安全转账规则集。

批量传输

批量传输与常规 ERC-20 传输非常相似。 让我们看看常规 ERC-20 transferFrom 函数:

1// ERC-20
2function transferFrom(address from, address to, uint256 value) external returns (bool);
3
4// ERC-1155
5function safeBatchTransferFrom(
6 address _from,
7 address _to,
8 uint256[] calldata _ids,
9 uint256[] calldata _values,
10 bytes calldata _data
11) external;
显示全部
复制

ERC-1155 中唯一的区别是我们将值作为数组传递,同时也传递了 ids 数组。 例如,给出 ids=[3, 6, 13]values=[100, 200, 5],传输结果将是

  1. 将 id 3 的 100 个代币从 _from 传输到 _to
  2. 将 id 6 的 200 个代币从 _from 传输到 _to
  3. 将 id 13 的 5 个代币从 _from 转移到 _to

在 ERC-1155 中,我们只有 transferFrom,没有 transfer。 要像常规的 transfer一样使用它,只需将 "from" 地址设为调用该函数的地址。

批量余额

相应的 ERC-20 balanceOf 调用同样具有支持批处理的相应函数。 作为对比,这是 ERC-20 版本:

1// ERC-20
2function balanceOf(address owner) external view returns (uint256);
3
4// ERC-1155
5function balanceOfBatch(
6 address[] calldata _owners,
7 uint256[] calldata _ids
8) external view returns (uint256[] memory);
复制

调用余额查询更简单的是,我们可以在单次调用中获取多个余额。 参数中传递所有者帐户数组和代币的 id 数组。

例如,对于给出的 _ids=[3, 6, 13]_owners=[0xbeef..., 0x1337..., 0x1111...],返回值将为:

1[
2 balanceOf(0xbeef...),
3 balanceOf(0x1337...),
4 balanceOf(0x1111...)
5]
复制

批量审批

1// ERC-1155
2function setApprovalForAll(
3 address _operator,
4 bool _approved
5) external;
6
7function isApprovedForAll(
8 address _owner,
9 address _operator
10) external view returns (bool);
显示全部
复制

审批过程与 ERC-20 略有不同。 这里不是批准特定金额,而是通过 setApprovalForAll 函数设置操作帐户为已批准或未批准。

查看当前的审批状态可以通过 isApprovedForAll 完成。 如你所见,要么全部批准,要么不批准。 不能定义要批准代币的数量,甚至代币类型。

这是考虑到简洁性而故意设计的。 你只能批准一个地址的所有代币。

接收钩子

1function onERC1155BatchReceived(
2 address _operator,
3 address _from,
4 uint256[] calldata _ids,
5 uint256[] calldata _values,
6 bytes calldata _data
7) external returns(bytes4);
复制

基于 EIP-165(opens in a new tab) 的协议支持,ERC-1155 只支持智能合约的接收钩子函数。 钩子函数必须返回一个事先预定义的 4 字节值,这个值被指定为:

1bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
复制

当接收合约返回这一值时,意味着合约知道如何处理 ERC-1155 代币并接受转账。 太好了,代币不会再卡在合约中了!

支持非同质化代币

当供应量仅为 1 时,代币本质上就是一个非同质化的代币 (NFT)。 按照 ERC-721 的标准,你可以定义一个元数据网址。 客户端可以读取并修改网址,请参阅这里(opens in a new tab)

安全转账规则

在前面的解释中,我们已经提到过一些安全转账规则。 现在我们来看一下最重要的规则:

  1. 调用者必须获得批准才能从 _from 的帐户地址消费代币,或者调用者帐户地址必须与 _from 的帐户地址相同。
  2. 在以下情况下,转账调用将回退
    1. _to 地址为 0;
    2. _ids 的长度与 _values 的长度不同;
    3. _ids 中代币持有者的任何余额低于发送给接收者的相应 _value 金额。
    4. 出现任何其他错误。

注意:包括钩子在内的所有批处理函数也均作为非批处理的版本存在。 这样做是为了提高燃料效率,考虑到只转移一种资产可能仍然是最常用的方式。 简洁起见,我们没有在这里介绍这些非批处理的版本,包括安全转账规则。 名称是相同的,只需移除 'Batch'。

延伸阅读

本文对你有帮助吗?