IBC/TAO for Corda¶
IBC概要¶
Inter-Blockchain Communication(IBC)プロトコルは 異種のブロックチェーン同士でデータ仲介者(Relayer)を信頼することなく 通信するためのプロトコルです。 このプロトコルは以下の2レイヤーから成ります。
- TAO(Transport, Authentication and Ordering layer)プロトコル
ブロックチェーン間の通信(ハンドシェークとパケット送受信)を 実現するプロトコル
- APP(APPlication layer)プロトコル
IBC/TAOを利用してクロスチェーンのアプリケーションを実現する プロトコル群の総称
IBC/TAOでは以下の手順でパケットが送受信されます。
Srcチェーン: パケット送信
Dstチェーン: パケット受信 + ACK返信
Srcチェーンが確実にパケット送信処理を実行したことを検証
Srcチェーン: ACK受信
Dstチェーンが確実にパケット受信処理を実行したことを検証
一方でIBC/APPによって以下の手順でクロスチェーンアプリケーションが 動作します。
Srcチェーン: パケット送信 + 送信時APP処理
Dstチェーン: パケット受信 + 受信時APP処理 + ACK返信
Srcチェーンが確実にパケット送信処理を実行したことを検証
Srcチェーン: ACK受信 + ACK受信時APP処理
Dstチェーンが確実にパケット受信処理を実行したことを検証
両者を比較すると、ブロックチェーン間の相互運用性の 仕組み(ハンドシェーク・パケット送受信)はIBC/TAOで完結している ことが分かります。 両ブロックチェーン上でIBC/TAOのパケット送受信の処理に IBC/APPの処理を連動させるだけで、多様なアプリケーションの相互運用が 実現できることがIBCの特長です。
IBCを実行するための要件¶
IBCは ICS-24 でプラットフォームの詳細な要件を規定していますが、 大まかにIBCは以下のような性質をプラットフォームに要求します。
IBCが規定する状態データ(ClientState, ConsensusState, Connection, Channel, PacketCommitment, Acknowledgement等)が改ざん不能な形で記録できること
IBCが規定する状態データが、IBCが規定する規則に従い正しく状態遷移できること
IBCが規定する状態データが、IBCが規定する規則以外の方法での変更・消去が不可能であること
IBCが規定する状態データを、IDによって一意に指定して取得可能であること
取得した状態データの正しさを、プラットフォームの外で、適切なLight clientを用いて検証できること
Corda-IBCのアプローチ¶
Corda-IBCは、Cordaネットワーク同士あるいはCordaネットワークと他のブロックチェーンをIBCを用いて接続するためのフレームワークである
しかしCordaにおけるネットワーク/台帳は、それ自体はIBCが求める要件を満たしたプラットフォームにはなっていない
そこでCorda-IBCでは、Cordaによるネットワーク/台帳の全体をIBCによって接続する対象として扱うのではなく、Corda上で動作するアプリケーション(CorDapp)の内部にIBCに適合する状態と状態遷移を構成し、これをIBCによって他のブロックチェーンと接続する
課題: IDによる状態データの一意な指定¶
IBCは各種stateをIDによって一意に指定して取得可能であることを要求する
これに対してCordaにおけるstateは単純にIDによって一意に識別することは困難
もちろん或る一つのstateが不変なIDを持つようにすることは容易
例えばstate生成時にIDを付与する
以降の状態遷移ではIDが変化しないようcontractで強制すればよい
しかしCordaではネットワーク上の全てのstate間の整合性を保証するような仕組みが無いため、同じcontractに従う複数のstateが同じIDを持たないよう強制することは難しい
解決方式: Genesis-Host方式¶
概要
まずGenesisというstateを生成し、続いてこれを消費して代わりにHostという状態を生成する
この時にHostのIDの一部として、Genesisを含むトランザクションのtxidを埋め込む
notaryが二重消費の防止によってGenesisが唯一つのトランザクションにより消費されることを保証するため、これによりHostのIDの一意性も保証される
Hostを起点としてIBCの各種stateを生成することで、これらstateのIDの一意性を強制する
このHostが、Corda-IBCによって、IBCプロトコルを用いて他のブロックチェーンと接続される対象となる
Genesis state
HostのIDの一意性を得るために利用されるstate
Genesisを含むトランザクションのtxidは”baseID”としてHostに設定される
一つのnotaryの下で同じtxidを持つ複数のトランザクションを消費することは出来ないため、或るbaseIDを持つHostは唯一つであることが保証される
Host state
IBCの各種stateのID発行を集中管理するstate
IBCの各種stateは全ていずれかのHostから派生して(Hostをinputに持つトランザクションを通じて)生成する
これら全てのstateに同じbaseIDが埋め込まれるため、異なるHostに属するstateは(例えstate IDが同一でも)区別できる
Genesis-Host方式におけるIDの一意性
notaryは公開鍵によって一意に識別できる
notaryのスコープにおいて、HostはbaseIDによって一意に識別できる
Hostのスコープにおいて、各stateはIDによって一意に識別できる
したがって、notary公開鍵+baseID+stateIDの組によって、全てのIBCのstateは一意に識別できる
Corda-IBCに対するLight client¶
Light clientの内部データ
Notary公開鍵
対象Notaryを一意に識別するため
baseID
対象Hostを一意に識別するため
当該HostをLight client対象の「ブロックチェーン」と見做す。
Stateの検証方法
Proof = 検証対象stateをOutputに持つ署名済トランザクション
検証手順
当該StateがトランザクションのOutputとして含まれることを検証
当該Stateが所定baseIDを持つことを検証
トランザクションが所定Notaryに署名されていることを検証
制限: パケット受信タイムアウトの扱い¶
IBCではパケット送信の際、height単位もしくはtimestamp単位でのパケット有効期限を設定可能な仕様になっており、この有効期限を過ぎてからパケット受信をしても失敗する
Corda-IBCではheightやtimestampを定義していないため、Cordaがパケットの受信側として動作する場合、受信タイムアウトを扱うことはできない。
IBC/TAO for Corda詳細仕様¶
Ibc contract: Host part¶
States¶
-
class
Genesis
HostのbaseIDを規定するためのstate class
-
participants
: List<AbstractParty>¶ 本Genesis/Host及びそこから派生する全てのstateの共有先となるユーザのリスト
-
-
class
Host
Hostを表現するstate class
-
participants
: List<AbstractParty>¶ Genesisから引き継いだ(同一内容の)participants
-
baseId
: StateRef¶ Genesisのreference(= txhash + output index)
-
notary
: Party¶ Genesisをnotarizeするnotary
-
clientIds
: List<Identifier>¶ Host配下で作成したClientStateのIDのリスト。 同一のIDを振り出さないようにするために使う。
-
connIds
: List<Identifier>¶ Host配下で作成したConnectionのIDのリスト。 同一のIDを振り出さないようにするために使う。
-
portChanIds
: List<Pair<Identifier, Identifier>>¶ Host配下で作成したChannelのportID及びchannelIDのペアのリスト。 同一のIDペアを振り出さないようにするために使う。 異なるportで同一のchannelIDが使われることは許容する。
-
Commands¶
-
class
GenesisCreate
Genesisの作成を指示するcommand class
-
Input states
None
-
Output states
Genesis
-
Contract rules
トランザクションに他のinput/output stateが含まれていないこと
-
-
class
HostCreate
GenesisをconsumeしてHostを作成する指示のcommand class
-
Input states
Genesis
-
Output states
Host
-
Contract rules
Host.participants == Genesis.participants
Host.baseId == refOf(Genesis)
Host.notary == notaryOf(Genesis)
-
Ibc contract: Client part¶
States¶
-
class
ClientState
ICS-2のClientStateを表現するstate class
-
participants
: List<AbstractParty>¶ Hostから引き継いだ(同一内容の)participants
-
baseId
: StateRef¶ Hostから引き継いだ(同一内容の)baseId
-
id
: Identifier¶ 本ClientStateのidentifier
-
clientState
: Any¶ protobufでencodeされたClientStateの本体(対応チェーン毎に異なる)
-
consensusStates
: Map<Height, ConsensusState>¶ HandleClientCreate及びHandleClientUpdateによって与えられたheightとConsensusStateのペアの連想配列
-
Commands¶
-
class
HandleClientCreate
(msg: MsgCreateClient) ClientStateの作成を指示するcommand class
-
Input states
Host
-
Output states
Host(clientIds += 新ClientStateのID)
ClientState
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput statesがOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
HostのclientIdsに新ClientStateのIDが追加されていること
MsgCreateClientで与えられたClientState及びConsensusStateを用いて正しく作成したClientStateが出力になっていること
-
Ibc contract: Connection part¶
States¶
Commands¶
-
class
HandleConnOpenInit
(msg: MsgConnectionOpenInit) connOpenInitを指示するcommand class
-
Input states
Host
[readonly] ClientState
-
Output states
Host(connIds += 新ConnectionのID)
IbcConnection(end.state == INIT)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
HostのconnIdsに新IbcConnectionのIDが追加されていること
その他ICS-3のconnOpenInitで規定されているルールに準拠すること
-
-
class
HandleConnOpenTry
(msg: MsgConnectionOpenTry) connOpenTryを指示するcommand class
-
Input states
Host
[readonly] ClientState
[optional] IbcConnection(end.state == INIT)
ICS-3のconnOpenTryで規定されている通り、予めINIT状態のIbcConnectionを作成済みでも未作成でも良い
-
Output states
Host(connIds += 新IbcConnectionのID)
IbcConnection(end.state == TRYOPEN)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
HostのconnIdsに新IbcConnectionのIDが追加されていること
予めIbcConnection作成済みの場合は追加なし
その他ICS-3のconnOpenTryで規定されているルールに準拠すること
-
-
class
HandleConnOpenAck
(msg: MsgConnectionOpenAck) connOpenAckを指示するcommand class
-
Input states
[readonly] Host
[readonly] ClientState
IbcConnection(end.state == INIT or TRYOPEN)
ICS-3のconnOpenAckで規定されている通り、IbcConnection状態はINIT状態の場合とTRYOPEN状態の2通りが可能
-
Output states
IbcConnection(end.state == OPEN)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
ICS-3のconnOpenAckで規定されているルールに準拠すること
-
-
class
HandleConnOpenConfirm
(msg: MsgConnectionOpenConfirm) connOpenConfirmを指示するcommand class
-
Input states
[readonly] Host
[readonly] ClientState
IbcConnection(end.state == TRYOPEN)
-
Output states
IbcConnection(end.state == OPEN)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
ICS-3のconnOpenConfirmで規定されているルールに準拠すること
-
Ibc contract: Channel part¶
States¶
-
class
IbcChannel
ICS-4のChannelを表現するstate class
-
participants
: List<AbstractParty>¶ Hostから引き継いだ(同一内容の)participants
-
baseId
: StateRef¶ Hostから引き継いだ(同一内容の)baseId
-
id
: Identifier¶ 本Channelのchannel identifier
-
portId
: Identifier¶ 本Channelのport identifier
-
end
: Channel¶ protobufで自動生成したChannel
-
nextSequenceSend
: Long¶ 次回の送信パケットに使用するsequence
-
nextSequenceRecv
: Long¶ (ORDEREDの場合のみ使用する)次回の受信予定パケットのsequence
-
nextSequenceAck
: Long¶ (ORDEREDの場合のみ使用する)次回の受信予定ACKのsequence
-
packets
: Map<Long, Packet>¶ 送信済みパケットのsequenceによる連想配列
-
receipts
: Set<Long>¶ 受信済みパケットのsequenceの集合
-
acknowledgements
: Map<Long, Acknowledgement>¶ 送信済みACKのsequenceによる連想配列
-
Commands¶
-
class
HandleChanOpenInit
(msg: MsgChannelOpenInit) chanOpenInitを指示するcommand class
-
Input states
Host
[readonly] IbcConnection
-
Output states
Host(portChanIds += Pair(Channel.portId, Channel.id))
IbcChannel(end.state = INIT)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
HostのportChanIdsに新IbcChannelのportId/channelIdが追加されていること
その他ICS-4のchanOpenInitで規定されているルールに準拠すること
-
-
class
HandleChanOpenTry
(msg: MsgChannelOpenTry) chanOpenTryを指示するcommand class
-
Input states
Host
[readonly] ClientState
[readonly] IbcConnection
[optional] IbcChannel(end.state = INIT)
ICS-4のchanOpenTryで規定されている通り、予めINIT状態のIbcChannelを作成済みでも未作成でも良い
-
Output states
Host(portChanIds += Pair(Channel.portId, Channel.id))
IbcChannel(end.state = TRYOPEN)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
HostのportChanIdsに新IbcChannelのportId/channelIdが追加されていること
予めIbcChannel作成済みの場合は追加なし
その他ICS-4のchanOpenTryで規定されているルールに準拠すること
-
-
class
HandleChanOpenAck
(msg: MsgChannelOpenAck) chanOpenAckを指示するcommand class
-
Input states
[readonly] Host
[readonly] ClientState
[readonly] IbcConnection
IbcChannel(end.state = INIT or TRYOPEN)
ICS-4のchanOpenAckで規定されている通り、IbcChannel状態はINIT状態の場合とTRYOPEN状態の2通りが可能
-
Output states
IbcChannel(end.state = OPEN)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
その他ICS-4のchanOpenAckで規定されているルールに準拠すること
-
-
class
HandleChanOpenConfirm
(msg: MsgChannelOpenConfirm) chanOpenConfirmを指示するcommand class
-
Input states
[readonly] Host
[readonly] ClientState
[readonly] IbcConnection
IbcChannel(end.state = TRYOPEN)
-
Output states
IbcChannel(end.state = OPEN)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
その他ICS-4のchanOpenConfirmで規定されているルールに準拠すること
-
-
class
HandleChanCloseInit
(msg: MsgChannelCloseInit) chanCloseInitを指示するcommand class
-
Input states
[readonly] Host
[readonly] IbcConnection
IbcChannel(end.state = OPEN)
-
Output states
IbcChannel(end.state = CLOSED)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
その他ICS-4のchanCloseInitで規定されているルールに準拠すること
-
-
class
HandleChanCloseConfirm
(msg: MsgChannelCloseConfirm) chanCloseConfirmを指示するcommand class
-
Input states
[readonly] Host
[readonly] ClientState
[readonly] IbcConnection
IbcChannel(end.state = OPEN)
-
Output states
IbcChannel(end.state = CLOSED)
-
Contract rules
全てのInput/Output statesが同一のbaseIdを共有していること
全てのInput states(readonlyを除く)がOutput statesにも含まれること(IBCのstateは作成後に消去されることはないため)
その他ICS-4のchanCloseConfirmで規定されているルールに準拠すること
-