LoginSignup
0

More than 1 year has passed since last update.

CordaにおけるReference Stateの活用方法(デモンストレーション編)

Last updated at Posted at 2022-06-21

まえがき

今回、Reference State(以下Ref.State)に関する細かな動作確認を行うため調査を行いました。
調査にあたりましてサンプルプログラムを作成しました。コード解説編とデモンストレーション編の2部編成でお届けしたいと思います。本記事はRef.Stateについて詳しく知りたいCordaに精通していらっしゃるエンジニアの方やセールスの方を対象としております。 Cordaについて詳しく知りたい方は R3公式ドキュメント株式会社digglueさんの記事 をご覧ください。また、Cordaの概念であるUTXOモデルについて知りたい方は、こちらの解説記事 をご覧ください。

自己紹介

SBI R3 Japan株式会社にインターンでお邪魔している井本翔太と申します。現在、都内の大学に通いながらエンジニアとして働かせていただいています。昨年からブロックチェーンに興味を持ち始め、その仕組みや活用方法を学ぶ過程でCordaと出会いました。私にとってCordaは社会にブロックチェーンという存在を浸透させる上で大きな役割を果たすと考えております。   

調査内容(再掲)

改めて調査内容の確認です。
調査1:Ref.Stateをトランザクションに含め、コントラクトで検証可能か
調査2:あるノードで発行したRef.Stateのバックチェーンを別のノードで確認できるか
調査3:消費済みのRef.Stateをトランザクションに含められるか

調査結果について(再掲)

調査1,2については要望を満たすことができましたが、調査3はエラーが出力されました。  
調査3で出力されたエラーについては後ほど説明したいと思います。
※調査1,2と調査3では実装が異なるため、サンプルプログラムは2つ作成しました。

サンプルプログラムについて(再掲)

サンプルプログラムはSBI R3 Japan株式会社が提供しております Corda trainingのコードにAddressState(住所録)をRef.Stateとして加えました。Corda trainingで扱うプログラムはIOU(借用証書)の発行(Issue)、譲渡(Transfer)、返済(Settle)に関するプログラムになります。今回は必要最低限の機能を実装するためにRef.Stateの実装対象をIssueのみに絞りました。

デモンストレーション手順

前提条件としてデモンストレーションの実行はCordaのNode Terminal Windowで行いました。

要望1(Node Terminal Window: ParticipantAで実行)

1. PublishFlow.javaを実行して、AddressStateを発行する。
2. MoveFlowを実行して、AddressStateを更新する。
3. IOUIssueFlowを実行して、IOUを発行。この時、SignedTransactionIDを記録
4. トランザクションの詳細を調べるため、run internalFindVerifiedTransaction txnId: Transaction-ID or Hashというコマンドを実行。引数に手順3で記録したSignedTransactionIDを指定する。
5. referencesという項目に記載されているtxhashがMoveFlow実行後に表示されるハッシュ値と一致するか確認

要望2(Node Terminal Window: ParticipantBParticipantCで実行)

1. IOUTransferFlow.javaでIOUのトランザクションをParticipantBからParticipantCに渡す。
2. ParticipantCのNode Terminal Windowsにてrun internalFindVerifiedTransaction txnId: ~を実行し、付随されているAddressStateのハッシュ値を確認する。
3. 再びrun internalFindVerifiedTransaction txnId: ~を実行し、手順2で確認したハッシュ値を引数に指定する。InputStateに関する項目でハッシュ値を確認する。
4. 再びrun internalFindVerifiedTransaction txnId: ~を実行し、手順3で確認したハッシュ値を引数に指定する。InputStateに関する項目が空白になっていれば、別ノードでAddressStateのバックチェーンが確認できた事になります。

要望3(Node Terminal Window: ParticipantAで実行)

1.PulishFlowを実行し、AddressStateを発行
2.MoveFlowを実行し、AddressStateを更新
3.IOUIssueFlowを実行。この時、SignedTransactionIDを記録。
4.run internalFindVerifiedTransaction txnId: ~を実行。引数には手順3で記録したSignedTransactionIDを指定
5.referencesという項目に記載されているtxhashがPublishしたAddressStateと一致するか確認

調査結果

調査1: Ref.Stateをトランザクションに含め、コントラクトで検証可能か

  • PublishFlow
    PublishFlowの実行結果です。issuerがParticipantAaddressがshinjuku(新宿) というAddressStateを発行しました。以下に実行結果を示します。
    publish.png
    ref=8C7EF4~が発行したAddressStateのハッシュ値になります。
  • MoveFlow
    MoveFlowの実行結果になります。新しいaddressをroppongi(六本木) としAddressStateを更新しました。以下に実行結果を示します。
    move.png
    ref=8169C4~が更新したAddressStateのハッシュ値になります。
  • IOUIssueFlow
    IOUIssueFlowの実行結果になります。
    IOUIssue.png
    ※SignedTransactionID=081209B~は次の手順で使用するため必ず記録します。
  • コマンド
    続いて、AddressStateがIOUIssueのトランザクションに含まれている事を確認します。確認には
    run internalFindVerifiedTransaction txnId: ~というコマンドを使用します。この時、LinearIdを調査2で使用するため記録します。 以下に実行結果を示します。※添付図は一部カットしています。
    IOU_internalFindVerified.png
    コマンドの引数は先ほど記録したIOUIssueのSignedTransactionID=081209B~です。「references:」という項目に注目するとMoveしたAddressStateのハッシュ値(8169C4~)と一致 することが分かります。したがって、Ref.State(AddressState)はトランザクションに含めることができると判明しました。

調査2: あるノードで発行したRef.Stateのバックチェーンを別のノードで確認できるか

  • IOUTransferFlow
    IOUTransferFlowの実行結果になります。引数にはLinearIdが必要になるため、調査1でトランザクションの詳細を調べた時にLinearIdを記録する必要があります。ここでは、IOUIssueのトランザクションをParticipantBからParticipantCへ渡します。
    IOUTransfer_from_participantB.png
    SignedTransactionId=870F57~は必ず記録します。
  • コマンド
    続いて、ParticipantCでAddressStateのバックチェーンをトレースします。先ほど記録したSignedTransactionIdを引数に指定し、run internalFindVerifiedTransaction txnId: ~を実行します。以下に結果を示します。※添付図は一部カットしています。
    internalFind_1_participantC.png
    「referencese:」という項目からAddressState(addressはroppongi)のハッシュ値を確認します。そして、run internalFindVerifiedTransaction txnId: を実行します。以下に結果を示します。※添付図は一部カットしています。
    internalFind_2_partcipantC.png
    赤枠からaddressがroppongiのAddressStateはtxhash=8C7EF4~というAddressState(addressはshinjuku)をinputStateとして使用している事が分かります。再び同様に、run internalFindVerifiedTransaction txnId: ~を実行します。※添付図は一部カットしています。
    internalFind_end_participantC.png
    赤枠からinputの項目が空であることが分かります。したがって、PublishしたAddressStateまでトレースできたことを意味します。

調査3: 消費済みのRef.Stateをトランザクションに含められるか

基本的な手順は調査1と同様です。

  • PublishFlow
    最初にsuginami(杉並区)のAddressStateを発行しました。赤色の下線部がハッシュ値です。
    3_move_hash.png

  • MoveFlow
    次にAddressStateをsuginamiからnakano(中野区)に更新しました。赤色の下線部がハッシュ値です。
    3_publish_hash.png

  • IOUIssueFlow
    コード解説編 にて、このIOUIssueFlowは1つ前のAddressStateを含める処理が記述されています事を確認しました。実行結果を以下に示します。3_iouIssue.png
    previousHashという項目と先ほどのPublishFlowの実行結果からvaultQueryを用いた処理で1つ前のAddressStateが発見できている事が分かります。しかし、赤色の下線部からNotaryの処理で止まっている事が確認できます。

  • ParticipantAのログ
    先ほどNotaryの処理で止まっていたためParticipantAのログを確認します。すると以下のエラーメッセージが出力されていました。
    調査3_error_message.png
    事項でエラーの発生原因について解説したいと思います。

調査3のエラーについて

先ほどエラーメッセージを直訳すると「一つもしくは複数のStateまたはReference Stateは他のトランザクションの中で既にインプットとして使われた」という意味です。このエラーの原因として、Moveする段階で最初にPublishしたAddressState(=1つ前のRef.State)がInputStateとして使われた事をNotaryが記録する事 が考えられます。詳しい説明のためにCDLを再掲します。
CDL.png
上記のCDLからMoveFlowを実行する際には、PublishしたAddressStateがInputStateとして使われていることが分かります。調査3ならsuginamiのAddressStateを消費して、nakanoのAddressStateを作成しています。 image.png
suginamiのAddressStateが消費済みという事実はNotaryに記録されます。したがって、IOUIssueのトランザクションにsuginamiのAddressState(1つ前のAddressState)を含めようとするとNotaryはNGを出します。
image.png
調査3が実現不可能な理由についてご理解いただけましたでしょうか?

サンプルプログラムのURL

調査1,2のサンプルプログラムです。
https://github.com/ShotaIMO/investigation-of-ReferenceState
調査3のサンプルプログラムです。
https://github.com/ShotaIMO/investigation-of-Previous-ReferenceState

サンプルプログラム作成にあたって、ご協力いただいたSBI R3 Japan株式会社のエンジニアチームの皆様
ありがとうございました。

終わりに

以上が調査結果の報告になります。皆様のRef.Stateに対する理解が深まれば幸いです。Cordaにご興味のある方はSBI R3 Japan株式会社へ直接ご連絡いただければ幸いです。Ref.StateRに関する新たな調査も始動しておりますので、また記事にしたいと思います。ご一読ありがとうございました。

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