Neutrinoで働くブロックチェーンエンジニアのブログ

渋谷の専門特化コワークNeutrinoに入居してブロックチェーンエンジニアとして働いています。元丸の内。(Neutrino運営企業とは直接関係ありません)

Ethereumトークン標準「ERC1400 Security Token Standard」の提案

f:id:naomasabit:20180930203532j:plain

セキュリティトークンが盛り上がっていますが、今月「ERC-1400: Security Token Standard」としての提案がEthereum Improvement Proposal上で行われました。なお、この提案はFinalizeされていないため、ERCではなくEIP1400になります。

また、EIP1400は議論中のため、内容が変わることがあります。2018年9月30日時点で議論されている内容を大まかにまとめました。

github.com

セキュリティトークンとは

こちらの記事でわかりやすく書かれています。

venturebeat.com

ユーティリティトークンはサービスの利用などで扱われますが、セキュリティトークンは有価証券と同じような使い方として、出る利益や所有を価値の裏付けとして扱います。

従来の有価証券の置き換えとして利用するために、証券法などの規制に準ずると見なされています。

セキュリティトークンの範囲がどのようなものなのか、配当を出したらセキュリティトークンなのか、裏付けが何であればセキュリティトークンであるのかなどは明確に定義されていません。

証券的な性質を持つものが現在セキュリティトークンとして呼ばれているように見えます。

EIP1400で定義されているセキュリティトークンの要件

  • MUST要件

    • 譲渡が成功したか、失敗したならその理由を照会するための標準的なインターフェースをもつ
    • 法的措置や資金回収のために強制的に譲渡することができなければならない
    • 発行と償還のための標準的なインターフェースを備える
    • 特別な株主権限や譲渡制限など、トークン所有者の残高の区分にメタデータを添付ができる
    • オフチェーンデータ、オンチェーンデータ、および転送のパラメータに基づいて、転送時にメタデータを変更できる
  • MAY要件

  • SHOULD NOT
    • 表明されている管轄区域にわたる資産クラスの範囲を制限してはならない
  • SHOULD要件
    • ERC20とERC777との互換性を持つ

前提知識 - トランシェとは

トランシェは金融用語であり、この言葉を前提にEIPではディスカッションが進められています。

社債や株式など複数のものを組み合わせて一つにした金融商品について、利回りやリスクで区分したものがトランシェというらしいです。

証券化において、リスクや条件の異なる証券を設定する場合、そのリスクや利回り等の条件の程度により区分することをトランチングといい、区分された各部分をトランシェといいます。 例えば社債の場合、各トランシェを優先社債、劣後社債の2区分とするトランチングや優先社債、中間の社債(メザニン社債)、劣後社債の3区分とするトランチング等があります。

トランシェ(Tranche)|不動産ジャパン用語集より

トランシェは優先劣後構造を持ち、上位トランシェほどキャッシュフローを先に享受し、発生した損失は後で被る仕組みとなっています。この為、下位になるほど損失のリスクが高くなり、トランシェ間のリスクの差は利回りの差に反映されることになります。

CMBS(商業不動産担保証券)とは | PIMCOより

f:id:naomasabit:20180930202009p:plain

図にするとおそらくこのような形ではないかと思います。この辺りは金融の人間ではないため、より詳しい方がいらっしゃったら定義を教えていただければ幸いです。

セキュリティトークンにメタデータが必要な理由-EIP1400のAbstractより

EIP1400ではメタデータが必要であると述べています。直感的には、有価証券についてその証券を表す説明や要素が必要とは感じますが、より具体的な例が挙げられています。

EIP1400のAbstractの引用を見ながら考えて行きます。

There are many types of securities which, although they represent the same underlying asset, need to have differentiating data tied to them. This additional metadata implicitly renders these securities non-fungible, but in practice this data is usually applied to a subset of the security rather than an individual security. The ability to partition a token holder's balance into tranches, each with separate metadata is addressed in the Partially-Fungible Token section. For example a token holder's balance may be split in two: Those tokens issued during the primary issuance, and those received through secondary trading.

多種類の証券があり、同じ資産を表しても関連づけられたデータを区別する必要がある。メタデータは証券をnon-fungible(代替不可能)なものとして扱う。メタデータは通常ここの証券ではなく証券の区分化された対象について適用される。

トークンホルダーの残高をトランシェに分割する機能はPartially-Fungible Tokenセクションで詳述するが、例えば、トークンホルダーの残高は、一次発行と二次取引で受け取ったものとで2つに分けられる。

ここでは、同じトークンでも、発行のステージによって区別したい場合にメタデータが必要であると述べています。

おそらく発行ステージによっては何らかの優先条項があったりすることが想定されているかと思います。

Security token contracts can reference this metadata in order to apply additional logic to determine whether or not a transfer is valid, and determine the metadata that should be associated with the tokens once transferred into the receiver's balance.

Transfers of securities can fail for a variety of reasons in contrast to utility tokens which generally only require the sender to have a sufficient balance. These conditions could be related to metadata of the securities being transferred (i.e. whether they are subject to a lock-up period), the identity of the sender and receiver of the securities (i.e. whether they have been through a KYC process, whether they are accredited or an affiliate of the issuer) or for reasons unrelated to the specific transfer but instead set at the token level (i.e. the token contract enforces a maximum number of investors or a cap on the percentage held by any single investor).

セキュリティトークコントラクトは有価証券の譲渡が有効かどうかを判定するためのロジックを利用する際に、このメタデータを利用する。

証券の譲渡は単純な残高不足以外のいろいろな理由で失敗する。

・ロックアップの対象期間外

・有価証券引受人者の身元による理由(KYCプロセスを経ているかどうか、受け渡しなどを認定された者か、発行者の関係者かなど)

・最大の投資家数や単一の投資家が保有する割合の上限を設定でき、その上限を超えるなど

メタデータは、証券譲渡がシステム的にだけでなく、業務的、法的な意味合いでも問題なく譲渡できるかを定義するために利用されるとしています。コントラクトでこの処理を行うことで、トラストレスに譲渡の有効性確認を実行できると考えられます。

function定義

提案では、ERCとしての関数の定義も掲載されています。

  • Partially-Fungible Tokenに関するfunction
  • オペレーターに関係するfunction
  • セキュリティトークンに関係するfunction

として3種類の分割で掲載しています。それぞれ以下に示します。

Partially-Fungible Tokenに関するfunction定義

トークンホルダーの残高をトランシェに分割する機能として、提案されています。

関数名 説明 定義
getDefaultTranches balanceOfを通じてトランシェ全体の総残高を照会するだけでなく、特定のトランシェの残高を決定する必要があるかもしれません。 function getDefaultTranches(address _tokenHolder) external view returns (bytes32);
setDefaultTranches トークンホルダーは、バランスをいくつかのパーティション(トランシェ)に分割することができます。この機能は、特定のトークンホルダーアドレスに関連付けられているすべてのトランシェを返します。 function setDefaultTranche(bytes32 _tranches) external;
balanceOfByTranche トランシェの残高を取得する function balanceOfByTranche(bytes32 tranche, address tokenHolder) external view returns (uint256);
sendByTranche デフォルトのトランシェから他のトランシェへトークンを送る function sendByTranche(bytes32 tranche, address to, uint256 amount, bytes data) external returns (bytes32);
redeemByTranche トークンホルダーがトークンを償還できるようにする。 function redeemByTranche(bytes32 tranche, uint256 amount, bytes _data) external;
tranchesOf トークンホルダーは残高をいくつかのトランシェに分割できる function tranchesOf(address _tokenHolder) external view returns (bytes32);

オペレーターに関係するfunction定義

オペレーター、として資産を運用する人を設定するfunctionが提案されています。 オペレーターは以下のどれかから証券を動かす権限を付与されます。

  • トークンホルダーとトランシェ(defaultOperators inherited from ERC777)
  • あるトランシェの全てのトークンホルダー(defaultOperatorsByTranche)
  • あるトークンホルダー全てのトランシェ(現在と未来)
  • あるトークンホルダーのあるトランシェ(isOperatorForTranche)
関数名 説明 定義
defaultOperatorsByTranche あるトランシェのデフォルトのオペレータを返却する function getDefaultTranches(address _tokenHolder) external view returns (bytes32);
authorizeOperatorByTranche あるトランシェのトークンについて、トークンホルダーはオペレーターを設定できる。 function authorizeOperatorByTranche(bytes32 tranche, address operator) external;
revokeOperatorByTranche あるトランシェのトークンについて、トークンホルダーはオペレーターを解除できる。 function revokeOperatorByTranche(bytes32 tranche, address operator) external;
isOperatorForTranche あるトランシェのホルダーのオペレーターであるかどうかを返す。上の4つのパターンいずれかに該当するならTrueを返す function isOperatorForTranche(bytes32 tranche, address operator, address _tokenHolder) external view returns (bool);
operatorSendByTranche トークンホルダーの代わりにオペレーターがセキュリティトークンを送金できるようにする function function operatorSendByTranche(bytes32 tranche, address from, address to, uint256 amount, bytes data, bytes operatorData) external returns (bytes32);
or
function operatorSendByTranches(bytes32 tranches, address froms, address tos, uint256 amounts, bytes data, bytes operatorData) external returns (bytes32[]);
operatorRedeemByTranche トークンホルダーの代わりにオペレーターがセキュリティトークンを償還できるようにする function operatorRedeemByTranche(bytes32 tranche, address tokenHolder, uint256 amount, bytes operatorData) external;

セキュリティトークンに関係するfunction定義

セキュリティトークン基本機能としてのfunctionが定義されています。

関数名 説明 定義
getDocument ドキュメントを取得する function getDocument(bytes32 _name) external view returns (string, bytes32);
setDocument ドキュメントを設定する。これらの文書は、法的文書またはその他の参考資料とすることができる function setDocument(bytes32 name, string uri, bytes32 _documentHash) external;
canSend 譲渡できるかの確認。不能であれば譲渡不可能の理由を返す function canSend(address from, address to, bytes32 tranche, uint256 amount, bytes _data) external view returns (byte, bytes32, bytes32);
issuable 新規発行可能かを確認する function issuable() external view returns (bool);
issueByTranche 新規発行。総供給量を増加させるときには必ずこの関数が呼ばれる function issueByTranche(bytes32 tranche, address tokenHolder, uint256 amount, bytes data) external;

今後の議論について

現在、EIP1400はissueを変えてEIP1410、EIP1411で議論が継続されております。WEBコールなどでも議論がされる予定です。

概ね好意的な反応が多いですが、トランシェについての実装などが複雑になってしまうなども指摘されており、標準化のためにシンプルなものにする方が良いという意見なども出ております。

影響の大きいトピックだと思いますので、今後も見守って行きたいと思います。

github.com

github.com