分析ERC1400--STO智能合约标准

时间:2024-03-18 16:38:09

ERC1400 – 证券型Token

该Token提案主打监管功能,目的是方便用户以合法合规方式在以太坊网络发行证券

标准说明
ERC1410 (等同ERC1411)将 ERC20/ERC777 中不存在解释属性的余额,附加额外的信息,从而划分成不同的部分,就可以做一些操作上的限制。
而 ERC1400 (等同ERC1411)是对 ERC1410 标准的继承和改进。
无论是 ERC20 还是 ERC777,每个单位的 Token 都是相同的,并无附加属性,属于 fungible token(同质化代币/可互换 Token)。ERC721标准的 Token,每个 Token 均有不同的ID,不同ID可以有不同的解释,属于 no-fungible token(非同质化 Token,不可互换 Token)。
ERC1410标准的 Token 属于Partially-Fungible Token (部分可互换 Token ),将 ERC20/ERC777 中不存在解释属性的余额,附加额外的信息,从而划分成不同的部分,就可以做一些操作上的限制(例如:某些操作只限定于指定 tranche 的 Token,某些操作优先消耗指定tranche的 Token)。
ERC1400 则是继承 ERC1410 标准,增加了证券相关业务会使用到的函数:证券增发,相关法律文件存储等。
先前一些证券型 Token 的合约大多是在 ERC20 标准的基础上,通过维护一个或多个以太坊地址集合,对这部分地址做出了划分:是否通过kyc,是否处于锁定期等,来进行转账上的限制。这些都是在地址层面做出不同的解释。而 ERC1400 对 Token 本身做了不同解释,以适用于更复杂的证券相关业务场景。

ERC20 与 ERC1400 的区别

ERC20标准: 每个单位的Token都是相同的,并无附加属性,可互换,属于fungible token。在以太坊地址层面上做监管,来限制转账。

ERC1400标准: 对余额附加额外的信息,从而划分成不同的分片,部分可互换,属于Partially-Fungible Token。对Token本身做了不同解释,可以应用于更复杂的证券业务场景。

ERC1400继承自ERC1410,接口兼容ERC20/ERC777/ERC1066

分析ERC1400--STO智能合约标准

实现原理

将Token持有人的余额分离成多个分片(tranche),并由 bytes32 _tranche 键来建立索引,该键可以同链上或链下的元数据相关联。

必须实现的功能

  • 随交易发送可以附带描述数据,以供某些业务场景使用 (bytes _data,bytes _operatorData,记录在event中)
  • 证券增发(mint),相关法律文件存储(setDocument)
  • 必须有一个标准的接口来查询一笔转账交易是否成功,失败的话则返回原因(交易函数带返回值,且可监听SentTranche事件)。
  • 必须发布用于发行(Minted)和赎回(Burnt)的标准事件(合约owner才能调)。
  • 必须能将一些数据附加到代币持有者余额的子集上,例如特殊股东权利或是转账限制的数据。(在struct Tranche中增加字段,或者通过tranche到链上链下找相关联的元数据)
  • 可能需要将签名数据传递到转账交易中,以便于在链上验证。(bytes _data,bytes _operatorData,记录在event中)
  • 必须能够强制转账以应对法律诉讼或资金回收(ForceSendTranche 合约owner才能调)。
  • 必须能根据离线数据,链上数据和转账的参数在转账时修改元数据(getDefaultTranches)。
  • 设置一些转账限制,如黑名单(canSend 在_sendTranche函数内对_from和_to做判断)
  • 应该兼容ERC20和ERC777标准。

角色分类

  • owner: address类型,合约发布者
  • _owner: address类型,投资者,分片持有人
  • _operator: address类型,由_owner指定的操作者,可以操作_owner拥有的指定余额分片

合约事件

  • 发行时

    event Minted(address indexed owner, bytes32 tranche, uint256 amount, bytes data);

  • 销毁时

    event Burnt(address indexed owner, bytes32 tranche, uint256 amount, bytes data);

  • 转账,发行或者销毁时

    event SentTranche(address indexed operator, address indexed from, address indexed to, bytes32 fromTranche, bytes32 toTranche, uint256 amount, bytes data, bytes operatorData);

  • 给指定的操作者授权操作所有分片时

    event AuthorizedOperator(address indexed operator, address indexed owner);

  • 给指定的操作者授权操作指定分片时

    event AuthorizedOperatorTranche(bytes32 indexed tranche, address indexed operator, address indexed owner);

  • 取消指定的操作者操作所有分片的权限时

    event RevokedOperator(address indexed operator, address indexed owner);

  • 取消指定的操作者操作指定分片的权限时

    event RevokedOperatorTranche(bytes32 indexed tranche, address indexed operator, address indexed owner);

状态码

兼容ERC1066标准为智能合约调用提供的一组通用的状态码

  • 0x00 Failure
  • 0x01 Success
  • 0x10 Disallowed
  • 0x20 Not Found

合约函数

兼容ERC777-地址层面

  • 总余额

    function balanceOf(address _owner) external view returns (uint256)

  • 批准权限(授权所有分片)

    function authorizeOperator(address _operator) public

    function revokeOperator(address _operator) public

    function isOperatorFor(address _operator, address _owner) public view returns (bool)

兼容ERC20

  • function transfer(address to, uint256 value) public returns (bool);
  • event Transfer(address indexed from, address indexed to, uint256 value);
  • 实现方案: 遍历getDefaultTranches函数返回的tranches,直到指定数量的代币成功转账

继承ERC1410-分片层面

  • 查询拥有的分片信息

    function trancheByIndex(address _owner, uint256 _index) external view returns (bytes32)

    function tranchesOf(address _owner) external view returns (uint256) //返回拥有的分片数量

    function balanceOfTranche(bytes32 _tranche, address _owner) external view returns (uint256)

  • 按分片转账

    function _sendTranche(address _from, address _to, uint256 _amount, bytes32 _tranche, bytes _data, bytes _operatorData) internal returns (byte, bytes32)

    function sendTranche(bytes32 _tranche, address _to, uint256 _amount, bytes _data) external returns (byte, bytes32)

    function operatorSendTranche(bytes32 _tranche, address _from, address _to, uint256 _amount, bytes _data, bytes _operatorData) external returns (byte, bytes32)

    function ForceSendTranche(bytes32 _tranche, address _from, address _to, uint256 _amount, bytes _data, bytes _operatorData) external returns (byte, bytes32)

  • 批准权限(授权某个分片)

    function authorizeOperatorTranche(bytes32 _tranche, address _operator) public

    function revokeOperatorTranche(bytes32 _tranche, address _operator) public

    function isOperatorForTranche(bytes32 _tranche, address _operator, address _owner) public view returns (bool)

  • 增发

    function mint(bytes32 _tranche, address _owner, uint256 _amount, bytes _data) public returns (byte reason)

  • 销毁

    function burn(bytes32 _tranche, address _owner, uint256 _amount, bytes _data) public returns (byte reason)

额外功能

  • Document Management 法律文件存储

    function getDocument(bytes32 _name) external view returns (string, bytes32);
    function setDocument(bytes32 _name, string _uri, bytes32 _documentHash) external;

  • Transfer Validity 转账有效性验证

    function canSend(address _from, address _to, bytes32 _tranche, uint256 _amount, bytes _data) external view returns (byte, bytes32, bytes32);

  • Default Tranche Management 按顺序返回持有的所有tranches

    function getDefaultTranches(address _owner) external view returns (bytes32[]);
    function setDefaultTranche(bytes32[] _tranches) external;

参考文献