ERC-1178: 多类别代币标准
Authors | Albert Chon <achon@stanford.edu> |
---|---|
Created | 2018-06-22 |
Discussion Link | https://github.com/ethereum/EIPs/issues/1179 |
简单概述
多类别同质化代币的标准接口。
摘要
此标准允许在智能合约中实现多类别同质化代币(以下简称 “MCFTs”)的标准 API。此标准提供跟踪和转移 MCFT 所有权的基本功能。
动机
目前,没有标准支持具有多个类别的代币。在现实世界中,在许多情况下,定义同一代币的不同类别将是合适的(例如,区分公司的优先股/普通股/限制股)。然而,今天的代币标准无法支持这种细微差别。ERC-20 代币合约定义的所有代币都是一个类别,而 ERC-721 代币合约为每个单独的代币创建一个类别(由 token_id 定义)。ERC-1178 代币标准提出了一种新标准,用于在一个代币合约中创建多个类别的代币。
旁注:从理论上讲,虽然可以使用 ERC-721 代币中代币结构体的属性来实现具有类别的代币,但在实践中,对于任何非平凡的应用来说,实现此目的的 gas 成本都非常高。
规范
ERC-20 兼容性(部分)
name
function name() constant returns (string name)
可选 - 建议实现此方法以增强与钱包和交易所的可用性,但接口和其他合约不能依赖于此方法的存在。
返回此合约管理的 MCFT 集合的名称。- 例如 "My Company Tokens"
。
class name
function className(uint256 classId) constant returns (string name)
可选 - 建议实现此方法以增强与钱包和交易所的可用性,但接口和其他合约不能依赖于此方法的存在。
返回此合约管理的 MCFT 类别的名称。- 例如 "My Company Preferred Shares Token"
。
symbol
function symbol() constant returns (string symbol)
可选 - 建议实现此方法以增强与钱包和交易所的可用性,但接口和其他合约不能依赖于此方法的存在。
返回一个简短的字符串符号,引用此合约中管理的所有 MCFT 集合。例如 “MUL”。此符号应该很短(建议 3-8 个字符),没有空格字符或换行符,并且应该仅限于大写拉丁字母(即英语中使用的 26 个字母)。
totalSupply
function totalSupply() constant returns (uint256 totalSupply)
返回此合约当前跟踪的所有 MCFT 的总数。
individualSupply
function individualSupply(uint256 _classId) constant returns (uint256 individualSupply)
返回此合约当前跟踪的 _classId
类别的 MCFT 总数。
balanceOf
function balanceOf(address _owner, uint256 _classId) constant returns (uint256 balance)
返回分配给地址 _owner
的 _classId
代币类别的 MCFT 数量。
classesOwned
function classesOwned(address _owner) constant returns (uint256[] classes)
返回合约中地址 _owner
拥有的 MCFT 的 _classId
数组。
注意:
pragma experimental ABIEncoderV2
支持返回数组
基本所有权
approve
function approve(address _to, uint256 _classId, uint256 quantity)
授予地址 _to
许可,使其拥有 ID 为 _classId
的 MCFT 的 quantity
数量。如果 balanceOf(msg.sender, _classId) < quantity
,或者如果 _classId
不代表此合约当前跟踪的 MCFT 类别,或者如果 msg.sender == _to
,则此方法必须 throw
。
对于给定的地址和 _classId
,在任何给定时间只能有一个地址 “拥有许可”。使用新地址和 _classId
调用 approve
会撤销对先前地址和 _classId
的许可。使用 0 作为 _to
参数调用此方法会清除任何地址和指定 _classId
的许可。
除非调用者试图在没有待处理许可时清除许可,否则成功完成此方法必须发出 Approval
事件(如下定义)。特别是,如果 _to
地址为零并且存在一些未完成的许可,则必须触发 Approval 事件。此外,如果 _to
已经是当前批准的地址并且此调用没有其他影响,则必须触发 Approval 事件。(即,”重申” 现有许可的 approve()
调用必须触发一个事件。)
transfer
function transfer(address _to, uint256 _classId, uint256 quantity)
当且仅当 quantity == balanceOf(msg.sender, _classId)
时,才将 ID 为 _classId
的 quantity
个 MCFT 的所有权分配给 _to
。成功的转移必须触发 Transfer
事件(如下定义)。
此方法必须将所有权转移给 _to
或 throw
,不能有其他结果。失败的原因包括(但不限于):
msg.sender
不是_classId
的quantity
数量代币的拥有者。_classId
不代表此合约当前跟踪的 MCFT 类别
一个符合标准的合约必须允许当前所有者将代币 “转移” 给自己,作为在事件流中确认所有权的一种方式。(即,如果 balanceOf(msg.sender, _classId) >= balance
,则 _to == msg.sender
是有效的。)此 “no-op 转移” 必须被视为成功的转移,因此必须触发 Transfer
事件(_from
和 _to
的地址相同)。
高级所有权和交换
function approveForToken(uint256 classIdHeld, uint256 quantityHeld, uint256 classIdWanted, uint256 quantityWanted)
允许一个代币的持有者允许另一个人(或智能合约本身)批准以其指定的汇率将其一类的代币换成另一类的代币的交换(有关更多详细信息,请参见示例实现)。这等效于在市场中发布竞标。
function exchange(address to, uint256 classIdPosted, uint256 quantityPosted, uint256 classIdWanted, uint256 quantityWanted)
允许个人填写现有竞标(请参见上面的函数)并完成将其一类的代币换成另一类的交换。在示例实现中,除非调用者已经批准该合约转移其代币,否则此函数调用应失败。当然,可以创建一个实现,其中调用此函数隐式地假定批准并且一步完成转移。
transferFrom(address from, address to, uint256 classId)
假设已授予批准,则允许第三方启动从 from
到 to
的代币转移。
事件
Transfer
当 MCFT 所有权通过任何机制转移时,必须触发此事件。
此外,创建新的 MCFT 必须为每个新创建的 MCFT 触发 Transfer 事件,_from
地址为 0,_to
地址与新 MCFT 的所有者匹配(可能是智能合约本身)。删除(或销毁)任何 MCFT 必须触发 Transfer 事件,_to
地址为 0,_from
地址为 MCFT 的所有者(现在的原所有者!)。
注意:_from == _to
的 Transfer 事件是有效的。有关详细信息,请参见 transfer()
文档。
event Transfer(address indexed _from, address indexed _to, uint256 _classId)
Approval
每次成功调用 approve(_to, _classId, quantity)
时,必须触发此事件(除非调用者试图在没有待处理许可时清除许可)。
event Approval(address indexed _owner, address indexed _approved, uint256 _classId)
理由
当前的局限性
当我尝试创建不同类别的同质 ERC-721 代币(自相矛盾)时,我受到了这个项目的设计的激励,但由于必须单独创建每个代币并在有效的数据结构中维护它们以进行访问而遇到了 gas 限制。使用一个人可以在 Metamask(一种流行的 web 钱包)上通过交易发送的最大 gas 量,我只能在耗尽所有 gas 之前创建大约 46 个 ERC-721 代币。这种经历促使了多类别同质代币标准的创建。
向后兼容性
采用 MCFT 标准提案不会造成向后兼容性问题,因为它定义了代币创建的新标准。该标准尽可能地遵循 ERC-721 的语义,但由于多类别同质代币和非同质代币之间的根本差异,它不能完全与之兼容。例如,ERC-721 代币标准中的 ownerOf
、takeOwnership
和 tokenOfOwnerByIndex
方法无法在此标准中实现。此外,balanceOf
、approve
和 transfer
的函数参数也不同。
实现
一个示例实现可以在这里找到
版权
版权和相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Albert Chon <achon@stanford.edu>, "ERC-1178: 多类别代币标准 [DRAFT]," Ethereum Improvement Proposals, no. 1178, June 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1178.