Security Token(證券型代幣)標(biāo)準(zhǔn) -- ERC1400/ERC1410

前言

"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)限珍昨,具體有:

  1. 隨交易發(fā)送可以附帶描述數(shù)據(jù)县耽,以供某些業(yè)務(wù)場景使用
  2. 設(shè)置一些轉(zhuǎn)賬限制,如黑名單
  3. 支持一些高級(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代幣而言,balanceOfallowance方法提供了一個(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ì)通過defaultOperatorsByTranchedefaultOperators保留對(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)的),balanceOfallowance函數(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))摧冀。為了方便線下的情況,sendByTranchecanSend函數(shù)接收一個(gè)額外的_data參數(shù)系宫,該參數(shù)可以由批準(zhǔn)方簽名并用于驗(yàn)證傳輸索昂。

此規(guī)范超出了本標(biāo)準(zhǔn)的范圍,具體的實(shí)現(xiàn)也是特定的扩借。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末椒惨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子潮罪,更是在濱河造成了極大的恐慌康谆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫉到,死亡現(xiàn)場離奇詭異沃暗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)何恶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門孽锥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人细层,你說我怎么就攤上這事惜辑。” “怎么了今艺?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵韵丑,是天一觀的道長。 經(jīng)常有香客問我虚缎,道長,這世上最難降的妖魔是什么钓株? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任实牡,我火速辦了婚禮,結(jié)果婚禮上轴合,老公的妹妹穿的比我還像新娘创坞。我一直安慰自己,他們只是感情好受葛,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布题涨。 她就那樣靜靜地躺著偎谁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪纲堵。 梳的紋絲不亂的頭發(fā)上巡雨,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音席函,去河邊找鬼铐望。 笑死,一個(gè)胖子當(dāng)著我的面吹牛茂附,可吹牛的內(nèi)容都是我干的正蛙。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼营曼,長吁一口氣:“原來是場噩夢啊……” “哼乒验!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蒂阱,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤锻全,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蒜危,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虱痕,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年辐赞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了部翘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡响委,死狀恐怖新思,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赘风,我是刑警寧澤夹囚,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站邀窃,受9級(jí)特大地震影響荸哟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瞬捕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一鞍历、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肪虎,春花似錦劣砍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽香嗓。三九已至,卻和暖如春装畅,著一層夾襖步出監(jiān)牢的瞬間靠娱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工洁灵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饱岸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓徽千,卻偏偏與公主長得像苫费,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子双抽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容