找回密码
 立即注册

扫一扫,登录网站

首页 区块链生态 查看内容
  • 7699
  • 1
  • 分享到

币圈乱象终结者! 以太坊新STO方案详解

2018-11-17 22:46

来源: 区块链大本营 作者: Codefine

ERC1410技术细节剖析


ERC1410提案的核心部分是tranche,所有提供的操作接口都围绕tranche展开。每个tranche用一个key(类型为bytes32)表示,每个账户地址下可以有多个tranches。

与tranche有关的查询接口

查询某个账户下指定 tranche 的余额:
function balanceOfByTranche(bytes32 _tranche,address _tokenHolder) external view returns (uint256);

查询某个账户下所有的tranches:
function tranchesOf(address _tokenHolder) external view returns (bytes32[]);

与tranche有关的转账接口

举个例子,Alice想要用自己的账户给Bob的账户转账,那么她需要考虑如下问题:

要选取的是账户中哪个tranche?

要转到Bob账户的哪个tranche?

转账的数量是多少?

针对问题1,可以指定一个tranche,或默认的1个或多个tranches(默认tranches将在后文讲述);针对问题2,由业务逻辑决定;针对问题3,需要由接口指定。

sendByTranche:
function sendByTranche(bytes32 _tranche,address _to,uint256_amount,bytes _data) external returns (bytes32);

上述接口表示从调用者的指定tranche转指定金额到目的账户。

如果转账交易不能完成,函数必须revert;

如果转账成功,必须emit SentByTranche event;

如果转账成功但接收者的tranche与发送者的tranche不同,则必须emit ChangedTranche event;

返回值为目的账户接受此次转账的tranche;

最后一个参数_data,可以将目标tranche直接用此参数指定,或存放任何与该交易相关的数据,比如授权信息。

sendByTranches:
function sendByTranches(bytes32[] _tranches,address[] _tos,uint256[] _amounts,bytes _data) external returns (bytes32);

上述接口是sendByTranche接口的升级版本,从指定的多个tranches中,往多个目标地址进行转账。

如果转账交易不能完成,函数必须revert;

如果转账成功,必须emit SentByTranche event;

如果转账成功但接收者的tranche与发送者的tranche不同,则必须emit ChangedTranche event

sendByTranche、sendByTranches接口均为交易发起者(msg.sender)对自有账户的操作。

ERC1410基于 ERC777继承了交易员(operator)的相关概念,允许某个交易员代表某个账户持有者基于tranche进行转账。operatorSendByTranche和operatorSendByTranches就是该类型接口。

operatorSendByTranche:
function operatorSendByTranche(bytes32 _tranche,address _from,address _to,uint256 _amount,bytes _data,bytes _operatorData) external returns (bytes32);

如果一个未被授权(isOperatorForTranche)的地址调用,函数必须revert;

如果转账成功,则必须emit SentByTranche event;

如果转账成功且接收者的tranche与发送者的tranche不同,则必须emit ChangedTranche event。

operatorSendByTranches:
function operatorSendByTranches(bytes32[] _tranches,address _from,address _to,uint256[] _amounts,bytes _data,bytes _operatorData) external returns (bytes32[]);

如果一个未被授权(isOperatorForTranche)的地址调用,函数必须revert;

如果转账成功,则必须emit SentByTranche event;

如果转账成功且接收者的tranche与发送者的tranche不同,则必须emit ChangedTranche event。

默认tranche管理

setDefaultTranches:
为了保证与ERC777、ERC20的兼容性,当调用send时,需要决定从哪个或哪几个tranches中转出。为解决这个问题,可以指定某一个或某几个tranches为默认。

function setDefaultTranche(bytes32[] _tranches) external;

设置默认tranches,这样在调用send时,将从default tranches中转账。

getDefaultTranches:
function getDefaultTranches(address _tokenHolder) external view returns (bytes32[]); 

获得某个账户的默认tranches。如果返回值为空,则调用send会抛出异常。如果返回多个,则可以按照某种策略进行转出。

交易员(Operator)相关接口

交易员可以被授权操作: 

所有账户的所有tranches

所有账户的某个特定的tranche

某个特定账户的所有tranches(包括现在与未来的)

某个特定账户的特定tranche

defaultOperatorsByTranche:
function defaultOperatorsByTranche(bytes32 _tranche) external view returns (address[]);

返回具有所有账户的某个特定tranche的默认操作员列表。

authorizeOperatorByTranche:
function authorizeOperatorByTranche(bytes32 _tranche,address _operator) external;

消息发送者授权给某个交易员某个特定tranche的操作权。每次被调用,必须emit AuthorizedOperatorByTranche event。

revokeOperatorByTranche:
function revokeOperatorByTranche(bytes32 _tranche,address _operator) external;

消息发送者撤销某个交易员对某个特定tranche的操作权。每次被调用,必须emit RevokedOperatorByTranche event。

(注: 此Operator仍有可能通过defaultOperatorsByTranche或defaultOperators拥有对此tranche的操作权。)

isOperatorForTranche:
function isOperatorForTranche(bytes32 _tranche,address _operator,address _tokenHolder) external view returns (bool);

查询_operator是否是某个账户特定tranche的操作员。

兼容性

为了使新标准与ERC20/ERC777(另一个NFT标准)兼容,需要定义在transfer/send操作时,哪些tranches会被用到。ERC1410中扩展的getDefaultTranches/setDefaultTranche规则将会被用到。

function getDefaultTranches(address _tokenHolder) external view returns (bytes32[]);

function setDefaultTranche(bytes32[] _tranches) external;

token的创建者必须为所有的通证持有人定义默认的tranche(s)(使用tranchesOf),以供ERC20/ERC777相关函数使用。而每个单独的账户所有者也可以针对性的修改其默认tranche(s)。

以下行为是在实施ERC777函数中的注意点: 

send()必须调用getDefaultTranche获得默认tranche

operatorSend()必须调用getDefaultTranche获得默认tranche

burn()必须调用getDefaultTranche获得默认tranche

operatorBurn()必须调用getDefaultTranche获得默认tranche

balanceOf()必须遍历token持有者的所有tranche得到总值

totalSupply()必须计算合约中的所有token

defaultOperators()必须返回能操作所有账户与tranche的操作员列表

authorizeOperator()必须针对msg.sender的所有tranche进行授权

revokenOperator()必须撤销操作员对msg.sender所有tranche的授权

isOperatorFor()必须查询_operator是否对_tokenHolder的所有tranches具有授权

无论何种原因,如果token总量增加,必须emit两个event : Minted(),MintedByTranche()

无论何种原因,如果token总量减少,必须emit两个event : Burned(),BurnedByTranche()

authorizeOperator()必须emit AuthorizedOperator()

revokeOperator()必须emit RevokedOperator()

应用场景

ERC1410带来的部分可替换通证能力,为证券通证化带来了可能。通过关联元数据,还能带来丰富的功能逻辑和更灵活的权限控制。

证券型通证发行

对证券型通证增加元数据来实现细粒度功能控制。比如股权和投票权分离机制下,一些tranche对应股权信息,一些tranche对应投票权。

通证锁定机制。部分通证具有锁定期,比如25%锁定一年,75%锁定两年。则可以划分成三个tranches:不受限部分,受限1年部分,受限2年部分。没到达锁定期前,不能将受限Token转出到不受限制的tranche中;但是可以对相同tranche的Token进行互转。

关联公共数据到证券(比如发行者信息,KYC/AML,相关法律文件),加强通证的信息披露和合规能力。


游戏点卡控制

游戏内的道具需要用点卡购买,为吸引玩家,玩家存入10个点数(Token)赠送2个点数(此刻玩家一共获得12个点数)。但从细粒度来看,这12个点数分为两个 tranches:10个是玩家自有的,可提现但需要优先消费;2个是系统赠送的,不可提现可后消费。在智能合约内就可以实现对不同tranches的不同控制逻辑。

总结

STO的兴起,意味着区块链通证主动进入证券法的监管范围。ERC1410结合可替代通证和证券业务的特点,在技术层面将通证分割成不同的tranches(份额),不同tranches拥有不同的业务逻辑,从而赋予智能合约对通证的细粒度控制能力。

虽然ERC1410目前还处于草案阶段,需要在社区进行广泛听证、讨论后才能正式实施,但从可监管的角度来看,ERC1410依旧是证券通证化的一个良好开端,笔者团队也将持续跟进,为读者解读标准的后续进展。

参考链接

ERC 1400: Security Token Standard #1411

https://github.com/ethereum/EIPs/issues/1411

ERC 1410: Partially Fungible Token Standard #1410

https://github.com/ethereum/EIPs/issues/1410

Security Token Standard

https://github.com/SecurityTokenStandard/EIP-Spec

作者简介:Codefine好码安全团队专注于智能合约安全审计和全生命周期管理, 已为全球多家交易所、钱包、公链做过智能合约安全审计和开发管理。团队通过独有的多维审计引擎,持续为合作伙伴提供正确、安全、可用的智能合约基础设施。
版权申明:本内容来自于互联网,属第三方汇集推荐平台。本文的版权归原作者所有,文章言论不代表链门户的观点,链门户不承担任何法律责任。如有侵权请联系QQ:3341927519进行反馈。
1234
相关新闻
发表评论

请先 注册/登录 后参与评论

    回顶部