前言
"ERC1400"是新提案的證券型代幣的標(biāo)準(zhǔn)膜蠢,新標(biāo)準(zhǔn)主要是把token的互換性(fungible)結(jié)合證券相關(guān)的業(yè)務(wù)場景堪藐,設(shè)計(jì)了一套通用接口。
標(biāo)準(zhǔn)制定了代幣持有人的余額分離成多個(gè)分片(tranche)的能力狡蝶。tranche是一種以債務(wù)為基礎(chǔ)的投資結(jié)構(gòu)庶橱。這些證券將具有不同期限的,投資風(fēng)險(xiǎn)或高或低的tranche組合成一個(gè)整體贪惹,以達(dá)到降低投資者的風(fēng)險(xiǎn)苏章,提供長期投資的目的。例如奏瞬,你可能有一筆貸款轉(zhuǎn)付證券枫绅,其中包括5到30年期的高風(fēng)險(xiǎn)和低風(fēng)險(xiǎn)的轉(zhuǎn)付證券,基于ERC1400標(biāo)準(zhǔn)的代幣將支持這種投資方式硼端。
我們先了解ERC777標(biāo)準(zhǔn)并淋,ERC777是ERC20的加強(qiáng)版,旨在加強(qiáng)用戶的控制權(quán)限珍昨,具體有:
- 隨交易發(fā)送可以附帶描述數(shù)據(jù)县耽,以供某些業(yè)務(wù)場景使用
- 設(shè)置一些轉(zhuǎn)賬限制,如黑名單
- 支持一些高級(jí)交易
無論是ERC20還是ERC777镣典,每個(gè)單位的token都是相同的兔毙,并無附加屬性,屬于fungible token(同質(zhì)化代幣/可互換代幣)兄春。ERC721標(biāo)準(zhǔn)的代幣澎剥,每個(gè)token均有不同的ID,不同ID可以有不同的解釋赶舆,屬于no-fungible token(非同質(zhì)化代幣哑姚,不可互換代幣)
ERC1410標(biāo)準(zhǔn)的代幣屬于Partially-Fungible Token (部分可互換代幣)托酸,將 ERC20/ERC777 中不存在解釋屬性的余額纯趋,附加額外的信息蓬抄,從而劃分成不同的部分陷遮,就可以做一些操作上的限制(例如:某些操作只限定于指定tranche的token揩慕,某些操作優(yōu)先消耗指定tranche的token)
ERC1400則是繼承ERC1410標(biāo)準(zhǔn)抄课,增加了證券相關(guān)業(yè)務(wù)會(huì)使用到的函數(shù):證券增發(fā)厢破,相關(guān)法律文件存儲(chǔ)等峭沦。
先前一些證券型代幣的合約大多是在ERC20標(biāo)準(zhǔn)的基礎(chǔ)上蒸辆,通過維護(hù)一個(gè)或多個(gè)以太坊地址集合征炼,對(duì)這部分地址做出了劃分:是否通過kyc,是否處于鎖定期等躬贡,來進(jìn)行轉(zhuǎn)賬上的限制谆奥。這些都是在地址層面做出不同的解釋。而ERC1400對(duì)token本身做了不同解釋拂玻,以適用于更復(fù)雜的證券相關(guān)業(yè)務(wù)場景酸些。
ERC1400則是繼承ERC1410, 加上了證券相關(guān)功能會(huì)使用的函數(shù)(發(fā)行證券檐蚜,法律文件等)魄懂。
Security Token Standard
- eip: ERC1400
- 標(biāo)題: Standard for Security Tokens
- 作者: Adam Dossa (@adamdossa), Pablo Ruiz (@pabloruiz55), Fabian Vogelsteller (@frozeman), Stephane Gosselin (@thegostep)
- 狀態(tài): Draft
- 類型: Standards Track
- 范疇: ERC
- 創(chuàng)建于: 2018-09-09
- 需要: ERC-777, ERC-1066
Motivation
通過指定一套標(biāo)準(zhǔn)的接口,加速發(fā)行和管理以太坊上的證券闯第,通過該接口所有相關(guān)方可以查詢和操作證券型代幣市栗。
證券型代幣與其他代幣用例存在重大差異,鏈上與鏈下參與者的交互更加復(fù)雜咳短,有著相當(dāng)嚴(yán)格的監(jiān)管審查填帽。
證券型代幣應(yīng)該能夠?qū)?biāo)任何資產(chǎn)類別,在任何司法管轄區(qū)內(nèi)發(fā)型和管理咙好,并遵守相關(guān)的監(jiān)管限制篡腌。
Requirements
將證券的發(fā)行,交易和生命周期事件遷移到公共賬本上需要采用標(biāo)準(zhǔn)的方式對(duì)證券勾效,其所有權(quán)及其在鏈上的屬性進(jìn)行建模嘹悼。
經(jīng)證券型代幣生態(tài)中各方討論后,編寫了如下的要求:
- 必須有一個(gè)標(biāo)準(zhǔn)的接口來查詢一筆轉(zhuǎn)賬交易是否成功层宫,失敗的話則返回原因杨伙。
- 必須能夠強(qiáng)制轉(zhuǎn)賬以應(yīng)對(duì)法律訴訟或資金回收。
- 必須發(fā)布用于發(fā)行和贖回的標(biāo)準(zhǔn)事件卒密。
- 必須能將一些數(shù)據(jù)附加到代幣持有者余額的子集上缀台,例如特殊股東權(quán)利或是轉(zhuǎn)賬限制的數(shù)據(jù)。
- 必須能根據(jù)離線數(shù)據(jù)哮奇,鏈上數(shù)據(jù)和轉(zhuǎn)賬的參數(shù)在轉(zhuǎn)賬時(shí)修改元數(shù)據(jù)膛腐。
- 可能需要將簽名數(shù)據(jù)傳遞到轉(zhuǎn)賬交易中睛约,以便于在鏈上驗(yàn)證。
- 不應(yīng)該限制可以代表司法管轄區(qū)內(nèi)的資產(chǎn)類別范圍哲身。
- 應(yīng)該兼容ERC20和ERC777標(biāo)準(zhǔn)辩涝。
Structure
ERC-1400: Security Token Standard
ERC-w: Semi-Fungible Token
ERC-w-1: Tranche metadata schema
ERC-x: Permissioned Token Transfers (canSend() and status codes)
ERC-y: Token Metadata (set/getDocument)
ERC-z: Optional Security Token features
Forced transfers
Permanent end to Issuance
Trading Halts
Batched transfers
Semi-Fungible Token
-
1410 Partially-Fungible Token (部分可互換代幣)
Permissioned Token Transfers
-
1400 Security Token Standard (證券型代幣標(biāo)準(zhǔn))
-
1404 Simple Restricted Token Standard (簡單的受限代幣標(biāo)準(zhǔn))
Abstract
有許多類型的證券雖然代表相同的標(biāo)的資產(chǎn),但需要有與之相關(guān)的差異化數(shù)據(jù)勘天。
這些額外的元數(shù)據(jù)隱含地使這些證券不可置換怔揩,但實(shí)際上這些數(shù)據(jù)通常應(yīng)用于證券的一個(gè)子集而不是單個(gè)證券。將令牌持有者的余額劃分為各個(gè)部分的能力脯丝,每個(gè)部分具有單獨(dú)的元數(shù)據(jù)商膊,在 Partially-Fungible Token 部分中進(jìn)行了說明。
例如宠进,代幣持有人的余額可以分為兩部分:在首次發(fā)行期間發(fā)行的代幣和通過二級(jí)市場交易得到的代幣晕拆。
證券代幣合同可以引用該元數(shù)據(jù)去應(yīng)用額外的邏輯來決定轉(zhuǎn)賬是否有效,并確定一旦轉(zhuǎn)賬到接收方賬戶中材蹬,這些代幣所關(guān)聯(lián)的原數(shù)據(jù)实幕。
這些條件可能與正在轉(zhuǎn)賬的證券代幣關(guān)聯(lián)的元數(shù)據(jù)有關(guān)(即它們是否受制于鎖定期),證券發(fā)送方和接收方的身份(即他們是否通過了KYC流程堤器,是否是經(jīng)認(rèn)可的昆庇,或是發(fā)行方的附屬公司)或者是與具體轉(zhuǎn)賬無關(guān)的原因,而是設(shè)定在代幣的級(jí)別上(即代幣合同強(qiáng)制執(zhí)行投資人數(shù)量的上限闸溃,或任何單一投資人持有的百分比上限)整吆。
對(duì)于ERC20/ERC777代幣而言,balanceOf
和allowance
方法提供了一個(gè)在執(zhí)行轉(zhuǎn)賬之前檢查轉(zhuǎn)賬是否可能成功的方法圈暗,轉(zhuǎn)賬在鏈上或是鏈下都可以執(zhí)行掂为。
對(duì)于標(biāo)的證券的代幣而言,這個(gè)標(biāo)準(zhǔn)引入了一個(gè)函數(shù)canSend
员串,當(dāng)失敗的原因更加復(fù)雜的時(shí)候勇哗,它提供了一種更通用的方法來實(shí)現(xiàn)這一目的。還引入了一個(gè)用于整個(gè)轉(zhuǎn)賬行為的函數(shù)(即包括同轉(zhuǎn)賬一起發(fā)送的任意數(shù)據(jù)和證券的接收方)
為了提供同true或false相比更加豐富的信息寸齐,會(huì)返回一個(gè)字節(jié)返回碼欲诺。這使得我們能夠說明轉(zhuǎn)賬失敗的原因,或者至少是失敗原因的類別渺鹦。查詢文檔的能力和對(duì)轉(zhuǎn)賬成功的預(yù)期會(huì)包含在 Security Token 部分中說明扰法。
#1410
- Partially-Fungible Token
一個(gè) Partially-Fungible Token 允許將元數(shù)據(jù)關(guān)聯(lián)到代幣持有者余額當(dāng)中的一部分上面。這些部分的余額稱為 tranches (tranche毅厚,實(shí)際上是一個(gè)法語單詞意為“切片”或“部分”塞颁。在投資界,用來描述可以被分割成并賣給投資者的小額證券。)祠锣,并由bytes32_tranche
鍵來建立索引酷窥,該鍵可以同鏈上或鏈下的元數(shù)據(jù)相關(guān)聯(lián)。
Sending Tokens
代幣轉(zhuǎn)賬始終具有關(guān)聯(lián)的源tranche和目標(biāo)tranche伴网,以及通常的轉(zhuǎn)賬數(shù)量和發(fā)送方/接收方的地址蓬推。
getDefaultTranches
為了提供對(duì)ERC777的兼容性,實(shí)現(xiàn)需要決定在執(zhí)行ERC777發(fā)送函數(shù)時(shí)要使用哪一個(gè)tranche澡腾。
這個(gè)函數(shù)返回在此情況下使用的tranches沸伏。例如,一個(gè)證券型代幣可以返回byte32("unrestricted")
tranche, 或者使用一小組可能的tranches的簡單實(shí)現(xiàn)动分,可以返回與代幣持有者相關(guān)聯(lián)的所有tranches毅糟。
返回值可以為空,這意味著沒有默認(rèn)的tranche(因此ERC777的發(fā)送函數(shù)將拋出錯(cuò)誤)刺啦,或者返回多個(gè)tranches留特,在這種情況下纠脾,ERC777的發(fā)送函數(shù)應(yīng)該按照順序循環(huán)遍歷這些tranches玛瘸,直到指定數(shù)量的代幣已經(jīng)成功轉(zhuǎn)賬。
function getDefaultTranches(address _tokenHolder) external view returns (bytes32[]);
setDefaultTranches
允許為指定的地址設(shè)置默認(rèn)的tranches苟蹈,將會(huì)在ERC777的發(fā)送函數(shù)執(zhí)行時(shí)使用到這些設(shè)置糊渊。
這個(gè)函數(shù)可以供所有代幣持有人自行調(diào)用,或僅限于那些實(shí)現(xiàn)了某些必要行為的持有人慧脱。
function setDefaultTranche(bytes32[] _tranches) external;
balanceOfByTranche
除了有查詢所有tranches下總的代幣余額的balanceOf
渺绒,也要有查詢某個(gè)特定tranche下代幣余額的函數(shù)。
function balanceOfByTranche(bytes32 _tranche, address _tokenHolder) external view returns (uint256);
sendByTranche
通過拓展ERC777標(biāo)準(zhǔn)并提供一個(gè)默認(rèn)的tranche(通過getDefaultTranches
函數(shù)獲取)菱鸥,就可以發(fā)送代幣了(從默認(rèn)的tranches)宗兼。要從一個(gè)特定的tranche來發(fā)送代幣的話,可以使用sendByTranche
函數(shù)氮采。
例如殷绍,一個(gè)有權(quán)限的代幣可以使用tranche元數(shù)據(jù)來強(qiáng)制執(zhí)行如下的轉(zhuǎn)賬限制:
-
_tranche
值 - 與
_tranche
值相關(guān)聯(lián)的任何額外數(shù)據(jù)(例如,可能與_tranche
關(guān)聯(lián)的鎖定時(shí)間戳) - 與代幣的發(fā)送方或接收方相關(guān)聯(lián)的任何細(xì)節(jié)(例如鹊漠,他們的身份信息已經(jīng)創(chuàng)建)
- 轉(zhuǎn)賬的代幣數(shù)量(比如主到,它是否遵守任意按天或者基于其他時(shí)間周期的轉(zhuǎn)賬數(shù)量限制)
-
_data
參數(shù)允許調(diào)用者提供與轉(zhuǎn)賬相關(guān)的任何附加的授權(quán)或詳細(xì)信息(例如,來自一個(gè)被允許對(duì)轉(zhuǎn)賬行為進(jìn)行授權(quán)的授權(quán)實(shí)體的簽名數(shù)據(jù))
其它的用例包括通過把先前的持有者與目標(biāo)tranches關(guān)聯(lián)起來躯概,跟蹤代幣的出處登钥。
如果轉(zhuǎn)賬代幣因某種原因失敗,這個(gè)函數(shù)必須拋出錯(cuò)誤娶靡。
當(dāng)從特定的tranche上轉(zhuǎn)賬代幣時(shí)牧牢,了解這些代幣的鏈上的(即不僅是通過一個(gè)響應(yīng)的事件)目標(biāo)tranche是有用的。目標(biāo)tranche將會(huì)由這個(gè)函數(shù)的實(shí)施來決定,并依據(jù)用例而有所不同塔鳍。
這個(gè)函數(shù)在轉(zhuǎn)賬成功時(shí)必須觸發(fā)一個(gè)SentByTranche
事件度陆。
function sendByTranche(bytes32 _tranche, address _to, uint256 _amount, bytes _data) external returns (bytes32);
function sendByTranches(bytes32[] _tranches, address[] _tos, uint256[] _amounts, bytes _data) external returns (bytes32);
redeemByTranche
允許代幣持有者贖回(銷毀)代幣。
必須從代幣總量和代幣持有人賬戶里扣除已銷毀或已贖回的代幣献幔。銷毀代幣應(yīng)該像發(fā)送代幣一樣懂傀,受到相同條件的限制。每次此函數(shù)被調(diào)用時(shí)蜡感,必須觸發(fā)RedeemedByTranche
事件蹬蚁。
function redeemByTranche(bytes32 _tranche, uint256 _amount, bytes _data) external;
tranchesOf
代幣持有者可以把他們的余額拆分成多個(gè)部分(tranches) —— 此函數(shù)將返回與特定代幣持有者地址關(guān)聯(lián)的所有tranches。
function tranchesOf(address _tokenHolder) external view returns (bytes32[]);
Operators
操作者可以獲得以下授權(quán):
- 所有的代幣持有人和tranches(
defaultOperators
繼承自ERC777標(biāo)準(zhǔn)) - 一個(gè)特定tranche的所有代幣持有人(
defaultOperatorsByTranche
) - 一個(gè)特定代幣持有人(
isOperatorFor
繼承自ERC777標(biāo)準(zhǔn))的所有tranches(當(dāng)前的和以后的) - 一個(gè)特定代幣持有人的特定的一個(gè)tranche(
isOperatorForTranche
)
defaultOperatorsByTranche
此函數(shù)返回默認(rèn)的由所有代幣持有人和一個(gè)特定tranche授權(quán)的操作者集合郑兴。
function defaultOperatorsByTranche(bytes32 _tranche) external view returns (address[]);
authorizeOperatorByTranche
允許一個(gè)代幣持有人去為他的某個(gè)指定tranche的代幣設(shè)置一個(gè)操作人犀斋。
每次調(diào)用此函數(shù)時(shí),必須觸發(fā)AuthorizedOperatorByTranche
事件
function authorizeOperatorByTranche(bytes32 _tranche, address _operator) external;
revokeOperatorByTranche
允許一個(gè)代幣持有人撤銷其某個(gè)特定tranche的代幣的操作人情连。
注意 —— 操作人可能會(huì)通過defaultOperatorsByTranche
或defaultOperators
保留對(duì)該代幣持有人和tranche的授權(quán)叽粹。
每次調(diào)用此函數(shù)時(shí),必須觸發(fā)RevokedOperatorByTranche
事件却舀。
function revokeOperatorByTranche(bytes32 _tranche, address _operator) external;
isOperatorForTranche
返回某個(gè)特定地址是否是給定代幣持有人和tranche的操作人虫几。
如果地址是上述任何類別下的操作人,則應(yīng)該返回TRUE挽拔。
function isOperatorForTranche(bytes32 _tranche, address _operator, address _tokenHolder) external view returns (bool);
operatorSendByTranche
允許操作人代表代幣持有人發(fā)送證券型代幣辆脸。
此函數(shù)應(yīng)該返回接收方的bytes32 _tranche
。
如果是在鏈下生成的話螃诅,接收方的bytes32 _tranche
可以在bytes _data
中定義啡氢。
如果此函數(shù)被一個(gè)缺少由isOperatorForTranche
定義的合適授權(quán)的地址調(diào)用的情況下,必須回退术裸。
此函數(shù)在成功發(fā)送代幣后必須觸發(fā)一個(gè)SentByTranche
事件倘是。
function operatorSendByTranche(bytes32 _tranche, address _from, address _to, uint256 _amount, bytes _data, bytes _operatorData) external returns (bytes32);
function operatorSendByTranches(bytes32[] _tranches, address[] _froms, address[] _tos, uint256[] _amounts, bytes _data, bytes _operatorData) external returns (bytes32[]);
operatorRedeemByTranche
允許一個(gè)操作人代表代幣持有人銷毀或贖回代幣。
必須從代幣供應(yīng)總量和代幣持有人賬戶中扣除被銷毀或贖回的數(shù)量袭艺。銷毀代幣應(yīng)該同發(fā)送代幣一樣搀崭,收到相同的條件限制。每次調(diào)用此函數(shù)時(shí)必須觸發(fā)RedeemedByTranche
事件匹表。
function operatorRedeemByTranche(bytes32 _tranche, address _tokenHolder, uint256 _amount, bytes _operatorData) external;
Interface
/// @title ERC-PFT Fungible Token Metadata Standard
/// @dev See https://github.com/SecurityTokenStandard/EIP-Spec
interface IERCPFT is IERC777 {
function getDefaultTranches(address _tokenHolder) external view returns (bytes32[]);
function setDefaultTranche(bytes32[] _tranches) external;
function balanceOfByTranche(bytes32 _tranche, address _tokenHolder) external view returns (uint256);
function sendByTranche(bytes32 _tranche, address _to, uint256 _amount, bytes _data) external returns (bytes32);
function sendByTranches(bytes32[] _tranches, address[] _tos, uint256[] _amounts, bytes _data) external returns (bytes32[]);
function operatorSendByTranche(bytes32 _tranche, address _from, address _to, uint256 _amount, bytes _data, bytes _operatorData) external returns (bytes32);
function operatorSendByTranches(bytes32[] _tranches, address[] _froms, address[] _tos, uint256[] _amounts, bytes _data, bytes _operatorData) external returns (bytes32[]);
function tranchesOf(address _tokenHolder) external view returns (bytes32[]);
function defaultOperatorsByTranche(bytes32 _tranche) external view returns (address[]);
function authorizeOperatorByTranche(bytes32 _tranche, address _operator) external;
function revokeOperatorByTranche(bytes32 _tranche, address _operator) external;
function isOperatorForTranche(bytes32 _tranche, address _operator, address _tokenHolder) external view returns (bool);
function redeemByTranche(bytes32 _tranche, uint256 _amount, bytes _data) external;
function operatorRedeemByTranche(bytes32 _tranche, address _tokenHolder, uint256 _amount, bytes _operatorData) external;
event SentByTranche(
bytes32 indexed fromTranche,
bytes32 toTranche,
address indexed operator,
address indexed from,
address indexed to,
uint256 amount,
bytes data,
bytes operatorData
);
event AuthorizedOperatorByTranche(bytes32 indexed tranche, address indexed operator, address indexed tokenHolder);
event RevokedOperatorByTranche(bytes32 indexed tranche, address indexed operator, address indexed tokenHolder);
event RedeemedByTranche(bytes32 indexed tranche, address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
event IssuedByTranche(bytes32 indexed tranche, address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
}
Notes
ERC20 / ERC777 Backwards Compatibility (向后兼容ERC20/ERC777標(biāo)準(zhǔn))
為了保持向后兼容ERC20/ERC777(以及其它可互換代幣標(biāo)準(zhǔn))门坷,必須去定義在執(zhí)行一個(gè)transfer
/send
操作時(shí)(即未指定tranche時(shí)),應(yīng)該使用哪一個(gè)或者哪幾個(gè)tranche袍镀。
如果函數(shù)實(shí)現(xiàn)保證每個(gè)代幣持有人盡可能的tranches的數(shù)量默蚌,則迭代代幣持有人的所有tranches(通過tranchesOf
)是合理的。
代幣創(chuàng)建者必須為所有的代幣持有人指定一個(gè)或多個(gè)默認(rèn)的供ERC20/ERC777標(biāo)準(zhǔn)下函數(shù)使用的tranche苇羡。每個(gè)代幣持有人或者其所有tranches的代幣余額的操作者绸吸,可以更改代幣持有人的默認(rèn)tranche。代幣持有人去更改他們的默認(rèn)tranche的能力允許他們更改顯示在還未兼容ERC_PFT的ERC20/ERC777錢包中的tranche。
以下是對(duì)ERC777標(biāo)準(zhǔn)函數(shù)的實(shí)現(xiàn)描述:
-
send()
必須使用getDefaultTranche()
來獲取默認(rèn)的tranche锦茁。 -
opratorSend()
必須使用getDefaultTranche()
獲取默認(rèn)的tranche攘轩。 -
REDEEM()
必須使用getDefaultTranche()
來獲取默認(rèn)的tranche。 -
opratorRedeem()
必須使用getDefaultTranche()
獲取默認(rèn)的tranche码俩。 -
balanceOf()
必須計(jì)算指定代幣持有人的所有tranche的余額總量度帮。 -
totalSupply()
必須返回被該合約跟蹤的所有代幣總量。 -
defaultOperators()
必須查詢可以操作所有地址和tranches的操作人列表稿存。 -
authorizeOperator()
必須對(duì)msg.sender
的所有tranches授權(quán)一個(gè)操作人笨篷。 -
revokeOperator()
必須撤銷先前對(duì)msg.sender
的所有tranches授權(quán)的操作人。 -
isOperatorFor()
必須查詢_operator
是否是_tokenHolder
所有tranches的一個(gè)操作人瓣履。 - 事件
Minted()
和IssuedByTranche()
必須在代幣供應(yīng)總量有任何增長時(shí)觸發(fā)率翅。 - 事件
Burned()
和RedeemedByTranche()
必須在代幣供應(yīng)總量有任何減少時(shí)觸發(fā)。 - 事件
AuthorizedOperator()
必須由authorizeOperator()
觸發(fā)袖迎。 - 事件
RevokedOperator()
必須由revokeOperator()
觸發(fā)冕臭。
#1400
- Security Token
Methods
getDocument / setDocument
這些函數(shù)用于管理與代幣關(guān)聯(lián)的一個(gè)文檔庫。這些文件可以是法律文件或者是其他參考資料燕锥。
文檔與短名稱(表示為一個(gè)bytes32
)相關(guān)聯(lián)辜贵,并且可以選擇有一個(gè)同其鏈上相關(guān)聯(lián)的文檔內(nèi)容的哈希值。
function getDocument(bytes32 _name) external view returns (string, bytes32);
function setDocument(bytes32 _name, string _uri, bytes32 _documentHash) external;
canSend
證券轉(zhuǎn)讓可能由于多種原因失敗脯宿,例如:
- 代幣發(fā)送方或接收方的身份信息念颈。
- 對(duì)轉(zhuǎn)賬的特定代幣的限制(即與轉(zhuǎn)讓代幣相關(guān)tranche的限制)
- 對(duì)代幣總體狀態(tài)相關(guān)的限制(即投資人總數(shù))
該標(biāo)準(zhǔn)提供了一個(gè)鏈上函數(shù),用于決定轉(zhuǎn)賬是否能成功连霉,并返回指示轉(zhuǎn)賬失敗原因的詳細(xì)原因。
這些規(guī)則可以由智能合約還有鏈上數(shù)據(jù)來定義嗡靡,或者依賴可以表示對(duì)轉(zhuǎn)賬進(jìn)行授權(quán)的sendByTranche
函數(shù)(例如跺撼,聲明轉(zhuǎn)賬有效性的轉(zhuǎn)賬代理的簽名信息)返回的部分_data
。
此函數(shù)將會(huì)返一個(gè)遵循ERC-1066標(biāo)準(zhǔn)的ESC (Ethereum Status Code讨彼,以太坊狀態(tài)碼)歉井,還有一個(gè)可以用于定義程序指定原因碼及額外詳細(xì)信息(例如,執(zhí)行發(fā)送操作的轉(zhuǎn)賬限制無效)的bytes32
參數(shù)
此函數(shù)也會(huì)以與sendByTranche
類似的方式返回所轉(zhuǎn)賬代幣的目標(biāo)tranche
function canSend(address _from, address _to, bytes32 _tranche, uint256 _amount, bytes _data) external view returns (byte, bytes32, bytes32);
issuable
一個(gè)證券型代幣發(fā)行人可以指定此代幣的發(fā)行已結(jié)束(即哈误,不能鑄造或發(fā)行新的代幣)
如果代幣在issuable()
返回的是false哩至,今后只能返回false。
function issuable() external view returns (bool);
issueByTranche
此函數(shù)在增長代幣供應(yīng)總量時(shí)必須被調(diào)用蜜自。
在調(diào)用時(shí)菩貌,此函數(shù)必須觸發(fā)IssuedByTranche
事件。
function issueByTranche(bytes32 _tranche, address _tokenHolder, uint256 _amount, bytes _data) external;
Interface
/// @title ERC-ST Fungible Token Metadata Standard
/// @dev See https://github.com/SecurityTokenStandard/EIP-Spec
interface IERCST is IERCPFT {
function getDocument(bytes32 _name) external view returns (string, bytes32);
function setDocument(bytes32 _name, string _uri, bytes32 _documentHash) external;
function issuable() external view returns (bool);
function canSend(address _from, address _to, bytes32 _tranche, uint256 _amount, bytes _data) external view returns (byte, bytes32, bytes32);
function issueByTranche(bytes32 _tranche, address _tokenHolder, uint256 _amount, bytes _data) external;
}
Notes
Forced Transfers
可能是法規(guī)要求發(fā)行人或受信任的第三方保留代表投資人轉(zhuǎn)賬代幣的權(quán)利重荠。因此箭阶,ERC-ST規(guī)范取代ERC-PFT,因?yàn)椴坏迷试S代幣持有人撤銷默認(rèn)的操作人。
Restricted Transfers
相比實(shí)用型代幣仇参,證券型代幣的轉(zhuǎn)賬可能因?yàn)槎喾N原因而失敗嘹叫,而實(shí)用型代幣通常僅要求發(fā)送方有足夠的余額。
這些條件可能與被轉(zhuǎn)賬的證券型代幣的元數(shù)據(jù)有關(guān)(即它們是否受制于鎖定周期)诈乒,代幣發(fā)送方和接收方的身份及資格(即他們是否已經(jīng)通過了KYC罩扇,是否是可信任的或是發(fā)行方的附屬機(jī)構(gòu)),或者出于與特定轉(zhuǎn)賬無關(guān)的原因怕磨,而是出于監(jiān)管下證券層面的原因(即證券強(qiáng)制執(zhí)行投資者的最大數(shù)量和單一投資者持有百分比的最高上限)暮蹂。
對(duì)于實(shí)用型代幣(ERC20/ERC777標(biāo)準(zhǔn)的),balanceOf
和allowance
函數(shù)提供了一種方式用以在執(zhí)行轉(zhuǎn)賬操作前檢查轉(zhuǎn)賬是否可能成功癌压,可以在鏈上或鏈下執(zhí)行仰泻。
該標(biāo)準(zhǔn)引入了一個(gè)函數(shù)canSend
,它提供了一種更通用的方法來查詢發(fā)送代幣能否成功滩届。它接收一組參數(shù)集侯,參數(shù)可能包括簽名數(shù)據(jù),并返回關(guān)于交易成功或失敗的原因字節(jié)碼帜消。
注意——調(diào)用canSend
的結(jié)果可能會(huì)根據(jù)鏈上狀態(tài)(包括區(qū)塊高度或時(shí)間戳)和鏈下預(yù)言機(jī)發(fā)生改變棠枉。因此,在作為不修改任何狀態(tài)的視圖函數(shù)被調(diào)用之后泡挺,它不能保證將來的轉(zhuǎn)賬一定會(huì)成功辈讶。
Identity
在許多司法管轄區(qū),一方能否接收和發(fā)送證券型代幣依賴于該方身份的特征娄猫。例如贱除,在一方有資格購買或出售特定的證券之前,絕大多數(shù)的司法管轄區(qū)都要求具有某種程度的 KYC/AML 流程媳溺。另外月幌,一方可能被分類到投資人資格類別(比如,合格的投資人和購買者)悬蔽,并且他們的公民身份也可以告知與其證券相關(guān)聯(lián)的限制扯躺。
多種身份標(biāo)準(zhǔn)(比如ERC725,Civic蝎困,uPort)可用于捕獲某一方的身份數(shù)據(jù)录语,以及集中管理的其他方法(例如,維護(hù)一個(gè)經(jīng)KYC批準(zhǔn)的地址白名單)禾乘。這些身份標(biāo)準(zhǔn)的共同之處是以太坊地址(可以是一方的錢包地址或者身份合同)澎埠,因此canSend
函數(shù)可以使用證券型代幣的發(fā)送方和接收方的地址作為確定是否符合資格要求身份的代理。
除此之外盖袭,該標(biāo)準(zhǔn)并未強(qiáng)制要求任何特定的身份識(shí)別方法失暂。
Reason Codes
為了改善代幣持有人的體驗(yàn)彼宠,canSend
必須依據(jù)下面指定的ERC-1066標(biāo)準(zhǔn)應(yīng)用程序特定狀態(tài)代碼返回成功或失敗的原因字節(jié)碼。具體的實(shí)現(xiàn)還可以將任意數(shù)據(jù)以bytes32
的形式返回弟塞,以提供原因碼以外的額外的信息
Code | Reason |
---|---|
0xA0 |
Transfer Verified - Unrestricted |
0xA1 |
Transfer Verified - On-Chain approval for restricted token |
0xA2 |
Transfer Verified - Off-Chain approval for restricted token |
0xA3 |
Transfer Blocked - Sender lockup period not ended |
0xA4 |
Transfer Blocked - Sender balance insufficient |
0xA5 |
Transfer Blocked - Sender not eligible |
0xA6 |
Transfer Blocked - Receiver not eligible |
0xA7 |
Transfer Blocked - Identity restriction |
0xA8 |
Transfer Blocked - Token restriction |
0xA9 |
Transfer Blocked - Token granularity |
On-chain vs. Off-chain Transfer Restrictions
確定一個(gè)證券型代幣能否被發(fā)送的規(guī)則是可以自動(dòng)執(zhí)行的(例如凭峡,對(duì)證券投資人的最大數(shù)量限制),或者需要一些鏈下的輸入(比如决记,經(jīng)紀(jì)人對(duì)交易的明確批準(zhǔn))摧冀。為了方便線下的情況,sendByTranche
和canSend
函數(shù)接收一個(gè)額外的_data
參數(shù)系宫,該參數(shù)可以由批準(zhǔn)方簽名并用于驗(yàn)證傳輸索昂。
此規(guī)范超出了本標(biāo)準(zhǔn)的范圍,具體的實(shí)現(xiàn)也是特定的扩借。