LoginSignup
0

Reference stateの可能性 ~課題解決編~

Last updated at Posted at 2023-03-07

前書き

今回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に問い合わせる手法を提案したいと思います。この手法により従来手法で問題となっていた未消費でも消費済みになってしまう問題を解決することができます。消費済みだった場合はエラーとしてハッシュ値が通知されます。
image.png

4章:調査について

本章では、2章で提案した方法の実現性を調査するための調査を行いました。調査項目としては以下の2つになります。

  • 調査1: Ref.stateのみのtxは作成可能か?
  • 調査2: Notaryが検知した複数のRef.stateはログにて全て検知できるか?
    ※調査のために作成したコードはこちらになります。

調査では、Corda trainingのIOU issue(発行)の処理にRef.stateを追加する処理を書き加えました。AddressStateという住所を表すstateをRef.stateとして扱い、PublishFlowでAddressStateの発行、MoveFlowでAddressStateの更新を行います。前述のStateやFlowについて詳しく知りたい方はこちらの記事をご覧ください。

調査1: Ref.stateのみのtxは作成可能か?

背景

2章で消費状況を確認したいstateをRef.stateとしてtxに含めNotaryに問い合わせる手法を提案しました。そこで、txにはRef.state以外のコンポーネント(InputStateやOutputState)は必要なのかという疑問が浮かびました。

方法

Ref.stateのみのtxを作成し、Notaryに問い合わせ、挙動を確認しました。
1. PublishFlowを実行し、AddressStateを発行します。
image.png

2. コンポーネントはRef.stateのみなので、通常のstateであるIOU stateに関する処理やコマンドはコメントアウト後、IOUIssueFlowを実行し、AddressStateをRef.stateとして含めます。
image.png
上図からIOUIssueFlowが停止していることが分かると思います。

3. IOUIssueFlowを実行したエンティティのログを見ます。
image.png
今回はParticipant Aで実行したためParticipant Aのログを開くと、"A transaction must contain at least one input or output state" というエラーが出力されています。簡潔に説明しますと、txには少なくとも1つのInputStateまたはOutputStateが必要になります。このエラーは以下のWireTransaction.ktというファイルに示されています。
image.png

結果

Ref.stateのみのtxは作成できず、少なくとも1つのInputStateまたはOutputStateが必要になります。なおこのエラーはNotaryに渡す前である自己検証の段階で検知されました。

実装検討

Ref.stateのみのtxは作成不可能であるため、以下のようにOutputState(今回はIOU state)に紐づけることにしました。
image.png

テスト

1. 先ほど同様、PublishFlowにてAddressStateを発行します。赤線のtxhashを覚えておいてください。
image.png
2. 続いて、IOUIssueFlow(コマンド等を含むIOU stateに関する処理をコメントアウト)を実行し、AddressStateをRef.stateとして含めます。赤線のSignedTransactionIdは次のステップで使用します。
image.png
3. 先ほどのSignedTransactionIdを元にRef.stateとしてAddressStateが含まれているか確認します。
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323637383431342f39303932623862392d653163612d306530612d316338352d6635363032393335333139312e706e.png

上図のreferenceという項目に、428~というtxhashが含まれています。これはステップ1で作成したAddressStateのtxhashと一致することが分かります。 したがって、先ほどのモデル図を元に作成したtxでNotaryに問い合わせることが可能になりました。

調査2: Notaryが検知した複数のRef.stateはログにて全て検知できるか?

Notaryが検知したRef.stateというのは消費済みのstateをRef.stateとした場合です。AddressStateをPublish(発行)後、Move(更新)を行うと、PublishしたAddressStateは消費済みになります。今回はこのPublishした消費済みのAddressStateをRef.stateとしてtxに複数含めたいと思います。

背景

調査1ではRef.stateの数が1つでしたが、実際には消費状況を確認したい複数のstateをRef.stateとして問い合わせた方が効率がいいのは明らかです。したがって、複数のRef.stateを含めてもエラーとなるRef.stateが全て検知できるか調査しました。

方法

消費済みのstateをRef.stateとしてtxに10個含め、Notaryに問い合わせ、挙動を確認しました。
1. PublishFlowを実行し、Ref.stateとするAddressStateを10個発行します。

PublishFlowとMoveFlowは1つのStateに対する動作になります。Ref.stateとしたいStateを10個生成・更新したい場合は、PublishFlowとMoveFlowをそれぞれ10回実行します。

image.png

上図の赤線がハッシュ値になります。この時、linearIdの399b62ca-8c0b-484a-8a84-562f6dfb005dを記録してください。また、AC5~から始まるハッシュ値を覚えておいてください。

2. 先ほど記録したlinearIdをパラメータに指定してMoveFlowを実行し、AddressStateを更新します。
image.png

3. AddressStateを10個発行し、更新した後、IOUIssueFlowを実行し、AddressStateをRef.stateとして含めます。
image.png
上図からFlowが途中で停止していることが分かると思います。

4. IOUIssueFlowを実行したエンティティのログを見る
image.png
今回は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が含まれていると指摘されています。
image.png
上図から表示制限が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を確認することができます。
image.png

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にご興味のある方はSBI R3 Japan株式会社へ直接ご連絡いただければ幸いです。ご一読ありがとうございました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0