ユースケース紹介編で提示した課題をReference Stateを用いて解決する手法を提示しております。調査結果からReference Stateの可能性についてご理解いただけると考えております。
まえがき
今回Reference state(以下Ref.state)に関する可能性を追求する調査を行いました。この調査により複数のユースケースで生じていた問題を解決することができます。本記事はCorda tech meetup 冬の陣(2023年2月22日開催)における発表の中で割愛した実際のテストコードを用いた結果の提示や詳しい説明の補足部分などを行う目的で作成されました。また、ユースケース紹介編と本記事の課題解決編の2つに分かれています。
Corda tech meetup 冬の陣のイベントレポートはこちらになります。
自己紹介
SBI R3 Japan株式会社にインターンでお邪魔している大学3年の井本翔太と申します。大学進学以来ブロックチェーンに興味を持ち始め、その仕組みや活用方法を学ぶ過程でCordaと出会いました。現在は、Cordaの機能調査やデモアプリケーション修正といったエンジニア業務やプレゼン資料作成といったビジネスサイドの仕事までありがたいことに様々な業務を経験させていただいております。
3章:Reference stateを用いた解決策
さて、ユースケース紹介編で述べた課題である"消費状況を確認したいstateを問い合わせの際に消費することなく検証したい"をReference state(略称:Ref.state) を用いて解決する手法を提案したいと思います。
Ref.stateについて詳しく知りたい方はCordaのドキュメントまたはR3の記事をご覧ください。後者の記事の方が詳しく書かれています。簡単にまとめますと、Ref.stateはtxの参照情報を表し、通常のInputStateまたはOutputStateをaddReferenceState関数を利用することでRef.stateとして扱うことができます。また最大の特徴としてRef.stateは通常のstateと異なりNotaryで消費されません。
このNotaryでは消費されない特性を生かして、消費状況を確認したいstateをRef.stateとしてtxに含めNotaryに問い合わせる手法を提案したいと思います。この手法により従来手法で問題となっていた未消費でも消費済みになってしまう問題を解決することができます。消費済みだった場合はエラーとしてハッシュ値が通知されます。
4章:調査について
本章では、2章で提案した方法の実現性を調査するための調査を行いました。調査項目としては以下の2つになります。
- 調査1: Ref.stateのみのtxは作成可能か?
- 調査2: Notaryが検知した複数のRef.stateはログにて全て検知できるか?※調査のために作成したコードはこちらになります。
調査1: Ref.stateのみのtxは作成可能か?
背景
2章で消費状況を確認したいstateをRef.stateとしてtxに含めNotaryに問い合わせる手法を提案しました。そこで、txにはRef.state以外のコンポーネント(InputStateやOutputState)は必要なのかという疑問が浮かびました。
方法
Ref.stateのみのtxを作成し、Notaryに問い合わせ、挙動を確認しました。
1. PublishFlowを実行し、AddressStateを発行します。
2. コンポーネントはRef.stateのみなので、通常のstateであるIOU stateに関する処理やコマンドはコメントアウト後、IOUIssueFlowを実行し、AddressStateをRef.stateとして含めます。
上図からIOUIssueFlowが停止していることが分かると思います。
3. IOUIssueFlowを実行したエンティティのログを見ます。
今回はParticipant Aで実行したためParticipant Aのログを開くと、"A transaction must contain at least one input or output state" というエラーが出力されています。簡潔に説明しますと、txには少なくとも1つのInputStateまたはOutputStateが必要になります。このエラーは以下のWireTransaction.ktというファイルに示されています。
結果
Ref.stateのみのtxは作成できず、少なくとも1つのInputStateまたはOutputStateが必要になります。なおこのエラーはNotaryに渡す前である自己検証の段階で検知されました。
実装検討
Ref.stateのみのtxは作成不可能であるため、以下のようにOutputState(今回はIOU state)に紐づけることにしました。
テスト
1. 先ほど同様、PublishFlowにてAddressStateを発行します。赤線のtxhashを覚えておいてください。
2. 続いて、IOUIssueFlow(コマンド等を含むIOU stateに関する処理をコメントアウト)を実行し、AddressStateをRef.stateとして含めます。赤線のSignedTransactionIdは次のステップで使用します。
3. 先ほどのSignedTransactionIdを元にRef.stateとしてAddressStateが含まれているか確認します。
上図のreferenceという項目に、428~というtxhashが含まれています。これはステップ1で作成したAddressStateのtxhashと一致することが分かります。 したがって、先ほどのモデル図を元に作成したtxでNotaryに問い合わせることが可能になりました。
調査2: Notaryが検知した複数のRef.stateはログにて全て検知できるか?
背景
調査1ではRef.stateの数が1つでしたが、実際には消費状況を確認したい複数のstateをRef.stateとして問い合わせた方が効率がいいのは明らかです。したがって、複数のRef.stateを含めてもエラーとなるRef.stateが全て検知できるか調査しました。
方法
消費済みのstateをRef.stateとしてtxに10個含め、Notaryに問い合わせ、挙動を確認しました。
1. PublishFlowを実行し、Ref.stateとするAddressStateを10個発行します。
上図の赤線がハッシュ値になります。この時、linearIdの399b62ca-8c0b-484a-8a84-562f6dfb005dを記録してください。また、AC5~から始まるハッシュ値を覚えておいてください。
2. 先ほど記録したlinearIdをパラメータに指定してMoveFlowを実行し、AddressStateを更新します。
3. AddressStateを10個発行し、更新した後、IOUIssueFlowを実行し、AddressStateをRef.stateとして含めます。
上図からFlowが途中で停止していることが分かると思います。
4. IOUIssueFlowを実行したエンティティのログを見る
今回はParticipant Aで実行したためParticipant Aのログを開くと、何やらエラーが出ていることが分かります。また、一番上のハッシュ値(AC5~)を見ていただくと最初にPublishしたAddressStateのハッシュ値と一致します。 文量の都合上添付しませんでしたが、その他ハッシュ値もPublishしたAddressStateと一致します。エラーの文言としては、"One or more input states or referenced states have already been used as input states in other transactions." と出力されています。このエラーは以下のNotaryError.ktというファイルに示されています。簡潔に説明しますと消費済みのStateが含まれていると指摘されています。
上図から表示制限が5個に指定されているため、Notaryが検知したRef.stateは5つまでしか表示されません。赤枠で囲った部分が検知されたRef.stateになりますが確かに10個含めたにも関わらず5個までしか出力されていません。
結果
10個の消費済みのstateをRef.stateとして含め、Notaryに問い合わせたところ5個までしか確認できませんでした。
解決方法
実装はしていませんが、表示制限をかいくぐって全てのRef.stateを表示させる方法を考えました。先ほども述べた通り表示制限は5個なので、下図に示すよう、txに含めるRef.stateの数を最大5個とし、小分けにしてNotaryに問い合わせを行います。こうする事で理論上はNotaryに検知された全てのRef.stateを確認することができます。
5章:まとめ
今回は3つのユースケースに共通していた"特定のstateの消費状況をNotaryに問い合わせたい要望"をRef.stateを用いた手法により解決しました。提案手法の実現性を考えるために行った2つの調査の結果を以下に示します。
- 調査1: Ref.stateのみのtxは作成可能か?
- 作成不可能。最低1個以上のInputStateまたはOutputStateを含める必要あり
- 調査2: Notaryが検知した複数のRef.stateはログにて全て検知できるか?
- 最大5個まで表示可能。全てのRef.stateを確認するため、問い合わせの処理を小分けにして繰り返す手法が現状効果的
以上の調査結果から、Ref.stateで消費状況を変化させることなくNotaryへの問い合わせが可能になりました。また、この手法を実現することで、関連するtxを渡される条件であれば第三者が、そのtxとチェーンで繋がるtxの存在を検知可能になります。 ゆえに、プライバシーを確保しつつ、透明性が向上したと考えることができます。
調査で作成したコード
調査で作成したコードは私のgithubアカウントにアップロードされています。興味のある方はぜひご覧ください。またSBI R3 Japanの提供するCorda trainingのコードにRef.stateの機能を追加したので、そちらのgithubも見ていただくとより理解が深まると思います。
終わりに
課題解決編は以上になります。皆様がRef.stateがもたらす新たな可能性を感じていただけたら幸いです。
<ご質問・ご要望の例>
- Corda Portalの記事について質問したい
- ブロックチェーンを活用した新規事業を相談したい
- 企業でのブロックチェーン活用方法を教えて欲しい 等々
SBI R3 Japanインターン エンジニアリング部所属
Corda 5の技術検証や記事翻訳など多岐に渡ります
趣味:英語学習(まだまだですが…)・テニス・映画鑑賞