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進行反饋。