Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hyperledger FabricアプリケーションとChaincodeの開発

gakumura
October 25, 2022

Hyperledger FabricアプリケーションとChaincodeの開発

2021/12/8 Blockchain GIG#11でしゃべった内容
→2022/10/25 Blockchain GIG特別編 HLF集中講義#3 Hyperledger FabricのアプリとChaincodeの開発 でリバイズ
Hyperledger Fabricのクライアントアプリケーション、Chaincodeを開発する際に知っておきたいこと

gakumura

October 25, 2022
Tweet

More Decks by gakumura

Other Decks in Technology

Transcript

  1. Hyperledger Fabric
    アプリケーションとChaincodeの開発
    Blockchain GIG特別編 HLF集中講義#3
    中村 岳
    クラウド事業統括/クラウド・エンジニアリング統括/ソリューション・アーキテクト本部
    2022/10/25

    View Slide

  2. Copyright © 2022 Oracle and/or its affiliates
    2
    中村 岳
    Twitter @gakumura
    はてなブログ @gakumura
    …主にHyperledger Fabric関連
    • 現職:ソリューションエンジニア@日本オラクル
    • 担当:Oracle Blockchain Platform、
    Blockchain Table
    • 前職:金融決済系SIerでパッケージ開発
    • SWIFT、CLS、日銀ネット関連の銀行間決済システム

    View Slide

  3. Hyperledger Fabricをベースにエンタープライズ利用向けPaaSとオンプレミスで提供
    • 数ステップで構築完了、GUIコンソールで管理・運用も容易
    • エンタープライズグレードの耐障害制、堅牢性
    • マルチクラウド、ハイブリッドクラウド、
    オープンなネットワーク構成が可能
    • Oracle独自の付加価値:
    • State DBとしてBerkeley DBを利用:パフォーマンスとクエリ利便性向上
    • 多機能なREST API:スマートコントラクトの利用を容易に
    • 台帳のデータをRDBに複製:大量照会、分析、データ統合
    • スマートコントラクトを容易に開発:付属の開発ツールでアセット仕様からコードを自動生成
    • 複数ChannelのアトミックトランザクションとXA対応:複数Channelでの更新のアトミックな実行
    や、ローカルのDB、MQなどとのグローバルトランザクションをサポート
    Oracle Blockchain Platform
    Copyright © 2022 Oracle and/or its affiliates
    東京DCからも
    サービス提供中
    3

    View Slide

  4. • 10/11(火): Hyperledger Fabric(再)入門
    • コンポーネントやトランザクションフローなど基本を解説
    • 10/18(火):Hyperledger Fabricのネットワーク設計
    • ブロックチェーンネットワークの設計の考え方、進め方を解説
    • 10/25(火):Hyperledger FabricアプリとChaincodeの開発
    • クライアントアプリケーションとChaincodeの開発方法を解説
    • 11/1(火):Oracle Blockchain Platformを用いたHLFアプリ開発
    • Oracle Blockchain Platformならではのメリット、開発方法を解説
    集中講義シリーズ
    Copyright © 2022 Oracle and/or its affiliates
    4

    View Slide

  5. • Chaincodeの開発
    • クライアントアプリケーションの開発
    • 整合性あれこれ
    ※なお、文中のHLF=HyperLedger Fabric
    資料の内容
    Copyright © 2022 Oracle and/or its affiliates
    5

    View Slide

  6. Copyright © 2022 Oracle and/or its affiliates
    Chaincodeの開発
    6

    View Slide

  7. • 所謂「スマートコントラクト」をHLFではChaincodeと呼んでいる
    • 別にコントラクト=契約を表現していなくてもよい(契約を表現していてもよい)
    • 単に「台帳の読み書きのロジック」と考えるとわかりやすい
    • 「RDBにおけるストアドプロシージャのようなもの」という説明もある
    • 台帳(のデータ)の更新の唯一の手段である
    • Chaincodeの関数がトランザクションの実行単位である
    • Chaincodeを経由せずに台帳を更新する(適切な)手段はない
    • 台帳の参照についてはいくつかバイパス手段がある
    • ブロックを直接見る、State DBを直接見る、外部DBに複製したデータを見る
    • ユーザーが開発する通常のChaincode(→User Chaincode)の他に、Chaincodeライフサイ
    クルやChannel設定などに関連したロジックを担うプリセットのSystem Chaincodeが存在する
    • System Chaincodeについては通常特に意識しないでOKなので本資料では触れず、以降で
    はUser Chaincodeのみの話をします
    Chaincodeとは何か?
    Copyright © 2022 Oracle and/or its affiliates
    7
    Client App
    Fabric SDK
    Peerノード
    Ledger
    Chaincode

    View Slide

  8. • 各々が自身のPeerにInstallした後に、Channelで有効化することで実行可能に
    • 有効化の手続きはv1.x系とv2.x系で異なる(v2.x系ではオペレーションが一層分権化)
    • バージョンアップ可能:Chaincodeはバージョンアップできるため、稼働後も修正や改善が可能
    • 新バージョンで旧バージョンのChaincodeが書いたレコードにもアクセスできる
    Chaincodeのライフサイクル
    Copyright © 2022 Oracle and/or its affiliates
    8
    Install
    有効化 Upgrade
    新バージョンの
    Install
    各Orgで行う
    ローカルな
    オペレーション
    ネットワークの
    オペレーション
    新バージョン
    稼働

    View Slide

  9. 運用上重要なものを含むが、Chaincodeの開発自体にはあまり関係ないかも
    項目 内容
    有効化とアップグレードの分
    権化
    v1.4系ではChaincodeの有効化およびアップグレードを単一のOrgのオペレーションで行っていた。そのため、Chaincode
    のパラメータ(Endorsement PolicyやPrivate Data Collection、Init関数の引数など)に他のOrgが関われなかった。
    v2.x系の新ライフサイクルでは、パラメータ内容を含む有効化&アップグレードオペレーションについて、予め複数のOrgから
    の承認が必要になった。
    パラメータ設定更新方法の
    改善
    Chaincodeをインストールし直さなくてもEndorsement PolicyとPrivate Data Collectionのを更新することが可能に
    なった。
    パッケージ概念の追加 v1.x系でのChaincode IDとバージョンの概念に加え、インストールモジュールの実体を指すパッケージ概念が追加された
    (パッケージを単位としてインストールするようになった)。
    また、インストールされた同一のパッケージを元に複数のChaincodeインスタンスを別のChaincode ID/バージョンを付与
    し、別のパラメータで同一Channelで稼働させることが可能になった。
    ローカルカスタマイズが可能に v2.x系では、各OrgでインストールするChaincodeのロジック内容(→パッケージの内容)が必ずしも一致していなくても
    よくなった。これにより、自Orgのみが使う参照用の関数の追加など、ローカルなカスタマイズを行うことができるようになった。
    Chaincode稼働環境の
    柔軟化
    v1.x系ではChaincodeインスタンスはPeerごと×Chaincode(&バージョン)ごとに作成されるDockerコンテナ上で稼
    働していた。v2.x系ではDockerコンテナ以外の稼働環境も選ぶことができるようになり、また、必ずしもPeerごとの単位で
    はなく、外部サービスのかたちで稼働させて複数Peerから共用することができるようになった。
    参考:v2.x系でのChaincode関連の主要な変更
    Copyright © 2022 Oracle and/or its affiliates
    9

    View Slide

  10. • Chaincode開発言語の選択肢:Node.js、Go、Java
    • これらの言語で用意されたFabric Chaincode SDKを利用してChaincodeを実装
    する
    • できることは基本的には変わらないので、お好みで選択
    • いずれかのAPIを選択して実装する
    • fabric-contract-api(後から追加された高レベルAPI、現在の推奨)
    • fabric-shim(初期から存在する低レベルAPI)
    • 多くの場合、Chaincodeはそれほど複雑にも大規模にもならない
    • Ethereumにおけるスマコン(ERC、Open Zeppelin、etc.の学習が必須&デー
    タの持ち方と扱い方のお作法がだいぶ特殊)とは事情はかなり異なるので、イメージ
    に引きずられない
    • まずはHLFのGitHubのサンプルコーナー
    (https://github.com/hyperledger/fabric-samples)にあるChaincodeをい
    ろいろ眺めてみることを推奨
    Chaincodeの実装
    Copyright © 2022 Oracle and/or its affiliates
    10
    Peerノード
    Ledger
    Chaincode
    fabric-contract-api
    Client App
    Fabric SDK

    View Slide

  11. • Chaincode内に実処理を記述した関数を複数実装し、クライアントがトランザクションでどの関数を利用するかを指定
    して呼び出すことになる
    • 関数の分岐はどちらのAPIを利用しているかによって書き方が異なる
    • fabric-shimを利用している場合、invoke()関数が単一のエントリーポイントになっており、invokeの処理の中
    で実処理を担う関数の呼び出しに分岐させる
    invoke(実処理関数名, [引数の配列]) {
    if (実処理関数名 == hoge) {hoge([引数の配列])}
    if (実処理関数名 == fuga) {fuga([引数の配列])}
    ...
    }
    • fabric-contract-apiを利用している場合invoke()関数は不要で、実処理を担う関数の呼び出し分岐まで
    API側でやってくれる
    • Init()という名前で初期化関数を実装しておく必要がある
    • Chaincodeの有効化とアップグレードのトランザクションの中で呼び出される
    • Init()内ではChannelの台帳のセットアップ的なことをやってもよいし、何もやらなくてもよい
    Chaincodeの実装お作法
    Copyright © 2022 Oracle and/or its affiliates
    11

    View Slide

  12. Peer
    Peerノードが保持する分散台帳の1コピー
    復習:Hyperledger Fabricにおける「台帳」
    12
    • 台帳は以下ふたつの要素から構成される

    Blockchain:履歴
    • トランザクションの履歴が格納される
    ハッシュチェーンで連結されたブロックのファイル
    • 追記オンリーで蓄積していく
    World State:状態
    • 各Keyに対する現在(最新)バージョンの値を保持
    • レコードは更新、削除が可能
    (履歴はBlockchainに残っている)
    • State DBと呼ばれるDBに格納される
    Ledger
    Peer
    Ledger
    Peer
    Ledger
    Peer
    Ledger
    Copyright © 2022 Oracle and/or its affiliates

    View Slide

  13. 台帳に保存される「現在の値(ステート)」とそれを保持するデータベース
    World StateはKey-Valueストアで、Valueには任意の文字列やバイナリを格納可能
    • ChaincodeはWorld StateからKeyのValueを読み出し、書き込むことで
    台帳上のデータに対してのビジネスロジックを表現する
    • State DBと呼ばれるデータベースに保持される
    通常のHLFではState DBにはLevelDBかCouchDBを選択可能
    • LevelDB:シンプルなデータ構造を扱う場合向き(例:口座番号がKey/残高がValue)
    • Keyを指定するステート検索しかできない(単一指定or範囲指定)
    • CouchDB:複数の属性を持つValueを扱いやすい
    • JSON形式でValueを格納すると、Attributeを条件に指定して検索できる(リッチクエリ)
    • LevelDBに比べると低速な点、Phantom Read問題に係る制約には留意
    復習:World StateとState DB
    13 Copyright © 2022 Oracle and/or its affiliates

    View Slide

  14. ある程度柔軟なデータ構造を扱え、State DBによる検索の表現能力もそこそこ
    復習:World Stateで扱うデータ構造の例
    Copyright © 2022 Oracle and/or its affiliates
    14
    Key:口座番号 Value:残高
    1020345 10,000,000
    1020346 56,400
    Key:アセット種別とID Value:アセット情報
    car^aaa111 {“color”:”red”, “price”:10000, “owner”:”Bob”, “drive”:”front”}
    car^bbb222 {“color”:”blue”, “price”:30000, owner”:”Alice”, “drive”:”AWD’}
    bike^xyz345 {“color”:”green”, “price”:30000, owner”:”Alice”, “CC”:”1800’}
    シンプルなKey-Value構造:口座
    複合キーとJSONを用いたKey-Value構造:アセット台帳
    Keyの値を指定してValueを読み取る/書き込む
    複合キーの利用や
    Key値の範囲指定のクエリも可
    State DBにCouchDBを使いValueをJSONにしておくと
    リッチクエリが使える
    (例:ownerがAliceのアセットを全件取得)

    View Slide

  15. • Chaincodeを実装する際に利用する主な機能はSDKのChaincodeStubクラスにまとまっている
    • このクラスの内容(関数)を抑えておけば基礎の学習はだいたいOK
    • Go/Java/Node.jsのSDKで細かい関数の有無、関数名に差異(ここではNode.js基準で記載)があるが、実質的にで
    きることは同等。Node.jsのドキュメントは説明が多くてわかりやすい。
    • 以下によく使う主要なものを抜粋して記載
    Chaincode SDKの主要な機能①
    Copyright © 2022 Oracle and/or its affiliates
    15
    カテゴリ 関数 説明
    引数 getArgs クライアントから渡された引数を取得する
    getTransient TransientMap(Transactionに載らない=Blockchain上に値が記録されない特殊
    な引数)として渡された引数を取得する
    トランザクション情報 getTxTimeStamp クライアントから渡されたTransactionのタイムスタンプを取得する
    getTxID クライアントから渡されたTransactionのID(ランダムなGUID)を取得する
    getMspId トランザクション発行者(クライアント)の所属Organizationを取得する
    getCreator トランザクション発行者のアイデンティティを取得する

    View Slide

  16. • 台帳操作系の機能のうち主要なものは以下(World Stateへの操作についてはPrivate Data用に同等の機能が存在するが、こ
    こでは一律割愛)
    • いずれも特に難しいところはないが、参照系はRead-Set Validationとの絡みで更新トランザクション内での利用に制約がつくもの、
    注意が必要なものがある点は留意(後述)
    Chaincode SDKの主要な機能②
    Copyright © 2022 Oracle and/or its affiliates
    16
    カテゴリ 関数 説明
    World Stateの
    更新
    putState 指定したKey、ValueのレコードをWorld Stateに書き込む(Keyが既にあればValueを上書きす
    る)
    deleteState 指定したKeyのレコードをWorld Stateから削除する
    台帳の参照 getState 指定したKeyのValueをWorld Stateから取得する
    getStateByRange StartKey~EndKeyで指定した範囲のKeyのレコードをWorld Stateから検索し取得する
    getStateByPartial
    CompositeKey
    複合Keyを持たせたレコードについて、複合Keyの前部分を指定し、前方一致でWorld Stateから
    検索し取得する
    getQueryResult State DBのデータベース実装が対応している構文でクエリを渡し、World Stateの検索結果のレコー
    ドを取得する(例:CouchDBを利用→JSONリッチクエリ)
    getHistoryForKey 指定したKeyについての履歴(過去から現在のバージョンのValue、TxIDとTimeStamp)を
    Blockchainから取得する

    View Slide

  17. • ChaincodeはEndorsement Phaseの中で呼び出されてPeerノー
    ドにより実行される
    • クライアントアプリケーションからPeerにChaincode実行依頼
    (Transaction Proposal)を送付
    • Chaincode関数の引数はここで渡す
    • PeerノードがChaincodeを実行し署名を付けて結果
    (Endorsement)を返却
    • 関数のレスポンスとRWSetが含まれる
    • クライアントはEndorsement Policyで定められた必要な分の
    Endorsementを収集する
    →Chaincodeは通常、複数のOrganizationの複数のPeerで冗長に
    実行される
    • Peerの処理リソースはネットワークの共有資産
    • Chaincodeの処理コストには敏感になったほうが良い
    復習:トランザクションの中でのChaincodeの使われ方
    Copyright © 2022 Oracle and/or its affiliates
    17

    View Slide

  18. • 台帳上のデータを参照したいが台帳を更新する意図がない場合、クライアントアプリはEndorsement(に含まれるレ
    スポンス)だけ受け取れば良いのでEndorsement Phaseまででトランザクションを終わらせる(Ordererに
    Transactionメッセージを送信しない)
    • Fabric SDKにクエリ用APIとして用意されている
    • この場合冗長に実行させる必要はなく、ひとつのPeerにTransaction Proposalを送れば良い
    • v2.x系で可能になったローカルカスタマイズと組み合わせるといろいろ便利なこともできる
    • なお、参照した事実だけ記録するためにそのままOrdering Phaseまで進めることもできる
    • 参照はした(→Read-Setアリ)が更新しなかった(→Write-Setナシ)トランザクションとしてBlockchainに
    残る
    • 参照の記録はクライアントアプリ次第なので、
    強制できない点には留意
    Tips: Chaincodeで台帳の参照だけを行う(更新を行わない)
    Copyright © 2022 Oracle and/or its affiliates
    18

    View Slide

  19. 指針として、Chaincodeに何もかもやらせようとせず、できるだけシンプルなものに留めておいたほうがよい→Chaincodeに必須でないも
    の、向いていないものはクライアントアプリケーションロジックや、台帳データ複製先のデータベースで引き取る
    やるべき
    • Chaincodeに必須なのはWorld StateとPrivate Dataの更新に関連する機能
    • 更新の中で必要な参照機能(条件評価など)を含む
    • 基本的な(それほど複雑でない、規模の大きくない)クエリの機能もあって良い
    やらないべき
    • Chaincodeは複雑でコストの重い処理、広い範囲のデータを一括で読み書きする処理にはあまり向いていない
    • Endorsementでは複数Peerでロジックが冗長に実行される
    • State DBはRDBと同じようには使えない…大規模集計、分析は得意ではない
    • トランザクションフローの仕組み上、1トランザクションに大量のRWSetが含まれると他のトランザクションと衝突しやすく、結果的に
    処理性能に問題が発生しやすい
    • 必要な場合はバッチとして切り出し時間を区切るなどして他のトランザクションに影響を与えないように工夫する
    何をChaincodeのロジックとして持っておくべきか?
    Copyright © 2022 Oracle and/or its affiliates
    19

    View Slide

  20. • 前述の「複雑でコストの重い処理、広い範囲のデータを一括で読み書きする処理」以外にもChaincodeロジックの設
    計あるいは実装にあたって注意が必要な以下の点を説明していく
    Chaincodeロジックの注意点
    Copyright © 2022 Oracle and/or its affiliates
    20
    項目 要点
    非-決定性ロジック 実行したPeer間で結果がバラバラになり得るロジックは作り込んではいけない
    外部情報の参照(オラクル) Chaincodeから台帳の外部にある情報を見に行くのは難しい
    Read My Writes 今書いたValueはまだコミットされてないので読めない
    更新トランザクション内での
    一部クエリ機能の利用制約
    一部のクエリ(World State、Private Data、Blockchainの検索)機能はValidationで検
    出されない不整合を起こし得るので更新トランザクションの中での利用には注意が必要
    Chaincode内Chaincode呼び出し Chaincode内から別のChaincodeを呼び出せるが、同一Channelでない場合は安全でな
    い、呼び出し先のChannelの更新もできない
    同一レコードについての
    更新スループット追及上の限界
    トランザクションフローにおけるRead-Set Validationの関係で、同一のレコードを高密度で
    更新するユースケースが苦手

    View Slide

  21. ステートマシン
    • 現在の状態(State)と入力条件によって次の状態に遷移
    • 入力条件とはたとえば処理内容(e.g. 起動する、停止する、値を増やす/減らす)や、処理内容に対して外部か
    ら与えられる引数(e.g. いくつ値を増減する)
    非-決定性
    Staten
    Staten+1
    入力(処理)X
    Copyright © 2022 Oracle and/or its affiliates
    21

    View Slide

  22. 分散台帳とステートマシン
    • ノードそれぞれが持つ台帳は独立したステート
    • それぞれのノード上でトランザクションを処理してステートが遷移
    • 分散/独立しているが一致したステートを実現するのが分散台帳
    非-決定性
    Staten
    Staten+1
    Tx
    ノード
    Staten
    Staten+1
    Tx
    ノード
    Staten
    Staten+1
    Tx
    ノード
    Staten
    Staten+1
    Tx
    ノード
    Copyright © 2022 Oracle and/or its affiliates
    22

    View Slide

  23. スマートコントラクトとステートの一致
    分散/独立したステートを一致させるにはどうすればよいか?
    前提として、ステートを更新する方法、条件を予め合意し共有しておく
    • 予め合意していることをもってシステム化された「契約」とみなせるため
    スマートコントラクトと呼ばれる
    • ステートは契約の履行の結果を記した台帳ということになる
    そのうえで、全ノードで一致したステートを保持する方法はふたつ
    • 全てのノードがそれぞれスマートコントラクトを実行してステートを遷移させる
    • 一部(単一または複数)のノードでスマートコントラクトをシミュレーション実行し、
    事後状態となるステートを伝播する
    • Hyperledger Fabricのコンセンサスモデルはこちら
    非-決定性
    Copyright © 2022 Oracle and/or its affiliates
    23

    View Slide

  24. Chaincode(シミュレーション)実行のBefore/Afterの状態セット
    RWSet(Read-Write-Set)と呼ばれるトランザクションの仕組み上必要なデータと、
    クライアントアプリケーションへの返り値がChaincode実行結果には含まれている
    RWSet:Chaincodeを実行するなかでの、
    • World Stateから読み取った値があればそのKeyとバージョンのセット(Read-Set)
    • World Stateに書き込む(予定の)値があればそのKeyとValueのセット(Write-Set)
    HLFのトランザクションフロー上、以下のような意味を持っている
    • Read-Set:そのトランザクションが前提とした台帳の状態
    • Write-Set:そのトランザクションが有効となった場合に書き込む値
    復習:「Chaincode実行結果」とRWSet
    Copyright © 2022 Oracle and/or its affiliates
    24

    View Slide

  25. あるTransactionがWorld Stateから読んだレコード、書き込む(予定の)値











    復習:RWSetの例 ※バージョンの形式は単純化しており正確なものではない
    Copyright © 2022 Oracle and/or its affiliates
    25
    • K1とK2のレコードを読んでいる
    • それぞれバージョンは”1”
    • K1に”V1”という値を、K3に”V2”という値をそれぞれ
    書き込もうとしている
    • K4のレコードを削除しようとしている

    View Slide

  26. Chaincodeの決定性がなぜ必要か
    • Chaincodeにはそのインプットとして常に台帳の現在ステートとクライアントからの入力値(引数)が存在する
    • 複数ノードでそれぞれChaincodeが実行された結果に含まれる事後ステート=Write-Setが同一になっていないと
    ならない
    • 異なるWrite-Setを集めてきてもEndorsement Policyを満たさない
    • すなわち、同一インプットからは同一の事後ステートが導かれるようにしておく必要がある
    • この条件を満たすChaincodeをdeterministic(決定性の、決定的な)であると呼び、
    そうでないものをindeterministic(非-決定性の、非-決定的な)と呼ぶ
    • Chaincode内に非-決定性のロジックを作り込んではならない
    非-決定性
    Copyright © 2022 Oracle and/or its affiliates
    26

    View Slide

  27. 非-決定性ロジックの例:ランダムな値の生成
    • Chaincodeの中でGUIDの生成などのためにランダムな値を生成する処理(UUID ver4など)を
    使いたくなるが、当然複数ノード間で一致しなくなるのでNG
    • 代替としてステート内にシードを用意しておき、そこから決定的に生成する処理を利用する(UUID ver3など)、ある
    いはクライアント側で生成してから渡す
    非-決定性
    P
    L
    CC
    P
    L
    CC

    Copyright © 2022 Oracle and/or its affiliates
    27

    View Slide

  28. 非-決定性ロジックの例:ノードのローカル日時の利用
    • Chaincode内でノードのローカル日時を取得して利用するのは、
    他のノードと必ずしも一致しなくなるのでNG
    • 時刻同期が不完全なことによるズレ
    • Chaincodeの実行タイミングのズレ
    • 「現在」の日時はクライアント側で決定してから渡すしかない
    • ⇨クライアント側で任意の値を渡すことができる(不正の余地がある)
    • これはつまり、特別な手段を講じない限り「現在」日時はコンセンサスの外部ということ
    非-決定性
    P
    L
    CC
    P
    L
    CC

    12:00:00 12:01:23
    Copyright © 2022 Oracle and/or its affiliates
    28

    View Slide

  29. 日時に関する補足
    非-決定性
    Copyright © 2022 Oracle and/or its affiliates
    • ブロック内のトランザクションデータ(トランザクション
    履歴)として保存されているタイムスタンプもクライ
    アントアプリケーションで決定しているもの
    • 必ずしもクライアントが正しいタイムスタンプを渡すと
    も限らない
    • トランザクション履歴を利用する際には、順序付け
    などにこのタイムスタンプを使用してはならない
    29

    View Slide

  30. 非-決定性ロジックの例:オンチェーンデータの外部に存在する情報の利用
    • Chaincodeから(クライアントから渡されるもの以外の)オンチェーンデータ外部の情報を取得しようとすると、各ノード
    で個別に取得した結果が一致することを保証するのは困難
    • Chaincodeの実行タイミングによって違う値が返ってくる、あるいは取得できない可能性
    • 外部ハッキングあるいはノード所有者によって不正な値を取得させられてしまう可能性
    • なお、ノードのローカル時刻も「台帳の外部に存在する情報」の一種
    非-決定性
    P
    L
    CC
    P
    L
    CC

    天気予報
    60
    %
    40
    %
    明日の降水確率
    Copyright © 2022 Oracle and/or its affiliates
    30

    View Slide

  31. • 例えばスポーツ賭博や予測市場などのサービスをブロックチェーン/分散台帳で実現しようとしたときに、現実世界の情
    報(試合結果や値動き)が必要
    • クライアントアプリケーションから渡すことにすると、都合良く偽れてしまう
    • 不正があったことを後から追求可能ではあるので、それで問題ないユースケースならそれでよい
    • スマートコントラクトからネットワーク外部の情報にアクセスしてコンセンサス内で取得してこないとならない
    • 何も考えないで実装すると、外部サービスへのアクセスにインタラプトするMockを建ててそこから都合の良い情報を
    返す、などわりとかんたんに不正ができる
    • このような要求に対して、中立かつ信頼できるかたちでネットワーク外部の情報を提供するサービスをオラクル
    (Oracle、託宣)と呼ぶ
    • オラクルが情報を自身の署名付きで提供することで、偽装や改ざんが不能でコンセンサスに取り入れられる外部情報
    が利用できる
    • しかし署名の検証をどう行うかまで考慮が必要となるなど、オラクル利用はけっこう難しい
    安全な外部情報の利用(オラクル)
    Copyright © 2022 Oracle and/or its affiliates
    31

    View Slide

  32. • Chaincodeの中でWorld StateまたはPrivate Data Collectionにデータを書き込み(PutState/
    PutPrivateData)したあとに、同一Tx内で先程書き込んだデータを読み出そう(GetState/GetPrivateData、
    あるいは各種クエリ)としても読み出せない(反映されていない)
    • 例:{Key, Value}=K1, V1のレコードにK1, V2を上書き(PutState)してからすぐGetStateすると取得し
    たデータはK1, V1のまま
    • 理由:台帳とPrivate Dataに更新が反映されるのはValidation/Commitフェーズなので
    • それまでは更新が反映されないので、さっき書いたものが読めない…”Can’t Read My Writes”
    • 対処法は一時格納用の変数を用意するだけなので簡単だが、知らないとたまにハマるので注意
    できない:Read My Writes
    Copyright © 2022 Oracle and/or its affiliates
    32

    View Slide

  33. • HLFではValidationフェーズでのRead-Set ValidationによりMVCC(MultiVersion Concurrency Control)でのデータ整
    合性、一貫性保護を行っている
    • また、一部のレンジクエリ機能はValidation時にChaincode実行時と同じ検索条件で再実行され、結果セット(のサマリ値)が
    変わっていないことを確認している→Phantom Readが検知される
    • 対象:getState(PrivateData)ByRange,getState(PrivateData)ByPartialCompositekey
    • Chaincode内で使えるクエリ機能のうち以下はValidationの検知スコープ外の挙動が発生する可能性があるため、更新トランザ
    クション内での利用には注意が必要(基本的には使用するべきではない)
    更新トランザクション内での一部クエリ機能の利用制約
    Copyright © 2022 Oracle and/or its affiliates
    33
    クエリ機能 問題点の説明
    getHistoryForKey 履歴は読んでもRead-Setに載らないので、Validationフェーズまでにその
    Keyに更新があっても検知できない
    ※ただしgetStateと併用していれば問題ないので回避は容易
    getStateByRangeWithPagenation,
    getStateByPartialCompositeKeyWithPagenation,
    getQueryResult,
    getPrivateDataByRangeWithPagenation,
    getPrivateDataByPartialCompositeKeyWithPagenation,
    getPrivateDataQueryResult
    これらのレンジクエリ(検索結果としてゼロ~複数の結果セットを返すクエ
    リ)は共通してValidationフェーズに再実行されないため、Phantom
    Readの発生を検知できない
    →Phantom Read問題

    View Slide

  34. Tx2
    • Read-Setに含まれるKeyのバージョンが自身の現在のWorld Stateの
    それと一致しているか
    • 言い換えると、Chaincode実行時点(Endorsementフェーズ)で
    読み取ったレコードのValueが、Validation時点までに更新されてい
    ないことをチェックしている
    Read-Set Validationの必要性:
    • HLFはあるトランザクションでStateをReadする時点とWrite/Commit
    する時点が離れており、その間のロックもしていない
    • Read時点からWrite時点までにトランザクションの前提としたStateの状
    態が変わってしまうケースがある
    • i.e. 他のトランザクションによって更新
    • 前提が変わっている場合には検出してトランザクションを無効にする必要が
    ある
    復習:Read-Set Validation
    Copyright © 2022 Oracle and/or its affiliates
    34
    World State


    Key Value Version
    A 0 4
    不一致

    View Slide

  35. CouchDBでのリッチクエリでの例
    リッチクエリとは
    • HLFではState DBとして利用しているデータベース側の機能を利用し、そのデータベースネイティブのクエリ文によりWorld Stateお
    よびPrivate Dataの検索を行うリッチクエリを利用することができる
    • getQueryResult、getPrivateDataQueryResultでクエリ文を渡す
    • KeyではなくValueの内容を検索条件に使えるのが非常に強力な点…ビジネスロジックの表現力の大幅な拡張
    • どのようなリッチクエリを使えるかはState DBとして利用するデータベースに依存する
    • State DBにCouchDBを利用している場合、ValueをJSONにして格納しておくと、JSONの属性とその値を条件に指定したクエリ
    (⇨JSONリッチクエリ)が利用可能
    • 例:{“owner” : “Bob”, “color” : “Red”, “size” : “100” }というような項目を持ったmarbleアイテムに対して、owner
    がBobである、colorがRedでない、sizeが50より大きいといった条件で検索
    Phantom Read問題にかかる制約
    • リッチクエリを含む一部のレンジクエリはValidation時に再実行されない
    • 本来結果セットのレンジに入るべきレコードがEndorsement~Validationフェーズの間で追加、更新により増えていても検知
    できない(Phantom Readの発生を検知できない)
    • ロジックの意図とデータの更新結果の不整合を起こす可能性があるため、(運用上の特別な考慮をしてPhantom Readの発生
    可能性を排除できない限り)更新トランザクションで使用してはならない
    Phantom Read問題
    Copyright © 2022 Oracle and/or its affiliates
    35

    View Slide

  36. 物の所有権をHLFの台帳上で管理しており、初期状態は以下とする
    CouchDBのPhantom Read問題:事象の例①
    Key: Item ID Value: JSON形式
    Item1 {“owner” : “Alice”, “color” : “Blue”, “size” : “50” }
    Item2 {“owner” : “Bob”, “color” : “Red”, “size” : “100” }
    Item3 {“owner” : “Carol”, “color” : “Yellow”, “size” : “80” }
    • この状態からふたつの更新トランザクションを間を置かずに発行する
    – Tx1
    :Carolの持ち物をすべてAliceに譲渡する…ownerがCarolのものをAliceに更新する
    – Tx2
    :Aliceの持ち物をすべてBobに譲渡する…ownerがAliceのものをBobに更新する
    • State DBとしてCouchDBを使用しており、Owner値による更新すべきレコードの抽出にはリッチクエリを使用する前提とす

    Copyright © 2022 Oracle and/or its affiliates
    36

    View Slide

  37. まずCarolの持ち物をすべてAliceに譲渡したのちにAliceの持ち物をすべてBobに譲渡したいので、Tx
    1
    とTx
    2
    の実行後の
    期待される結果は以下
    CouchDBのPhantom Read問題:事象の例②
    しかしCouchDBではPhantom Read問題により以下の結果になる場合がある
    Item ID Owner初期状態 中間状態(Tx1後) 結果(Tx2後)
    Item1 Alice Alice Bob
    Item2 Bob Bob Bob
    Item3 Carol Alice Bob
    Item ID Owner初期状態 中間状態(Tx1後) 結果
    Item1 Alice Alice Bob
    Item2 Bob Bob Bob
    Item3 Carol Alice Alice
    取りこぼし
    Copyright © 2022 Oracle and/or its affiliates
    37

    View Slide

  38. トランザクションが以下の時系列で処理されると意図しない結果が発生する
    • Tx
    1
    のEndorsementをE
    1
    、ValidationをV
    1、
    Tx
    2
    も同様にE
    2
    とV
    2
    とし、OrderingをOと表記
    CouchDBのPhantom Read問題:事象の例③
    E1
    E2
    O V2
    V1
    Item ID 初期状態~V1前まで V1後 V2後
    Item1 Alice Alice Bob
    Item2 Bob Bob Bob
    Item3 Carol Alice Alice
    Copyright © 2022 Oracle and/or its affiliates
    38

    View Slide

  39. • V
    2
    でAliceの持ち物であるにもかかわらず、Item3の取りこぼしが生じている
    • Tx
    2
    でのリッチクエリ結果にはItem3が含まれておらず、したがってRead-Set ValidationにItem3は含まれず取りこ
    ぼしは検知できない
    • このようなパターンの不整合を検知するにはValidationフェーズでのレンジクエリの再実行が必要
    CouchDBのPhantom Read問題:事象の例③
    E1
    E2
    O V2
    V1
    Item ID 初期状態~V1前まで V1後 V2後
    Item1 Alice Alice Bob
    Item2 Bob Bob Bob
    Item3 Carol Alice Alice
    Copyright © 2022 Oracle and/or its affiliates
    39
    V2 Validation

    View Slide

  40. 単一ChannelでのChaincode呼び出し
    • 単一Channel上で複数Chaincodeを稼働させることが(ふつうに)可能
    • ただし、あるChaincodeが台帳/Private Data Collectionに書き込んだレコードは、そのChaincodeからしか直接アクセスで
    きない
    • Chaincode A on Channel Xが書き込んだレコードは、Chaincode B on Channel Xからは直接にはアクセスできない
    • World State/Private Dataだけでなく、Blockchainから取得できるキー履歴、トランザクション履歴の参照にもこの制約が
    ある
    • Chaincodeから同一Channel内で稼働する別のChaincodeを呼び出すことが可能
    • Chaincode A on Channel X⇒Chaincode B on Channel Xは可能
    • Chaincode A on Channel XがChaincode B on Channel Xが書き込んだレコードを参照/更新したいときは、
    Chaincode Bを経由すれば参照/更新できる
    • ただし、実行するPeerには呼び出し元と呼び出し先両方のChaincodeがInstallされていることが必要
    • 管理が煩雑になるので再利用性の理由のみなどでのChaincode分割は推奨しない
    • 単一Channel上であれば複数のChaincodeが絡んでも単一トランザクションとなり、RWSetも共有している
    Chaincode内Chaincode呼び出し
    Copyright © 2022 Oracle and/or its affiliates
    40

    View Slide

  41. DogCC
    例:複数種類のトークンを扱う場合
    • 複数種類のトークンをひとつのChaincodeでまとめて管理することもできる
    • 例①:ひとつのChaincode内で複数種類のNFTを扱い、互いに交換可能にする
    • 例②:ひとつのChaincode内でNFTとFTを扱い、DVP(Delivery Versus Payment)をやる
    • トークンごとに分けても良い
    • この場合、異種トークンの交換は専用のChaincodeを作り、そこから各トークンのChaincodeを呼ぶ
    41 Copyright © 2022 Oracle and/or its affiliates
    SuperTokenChaincode
    DogNFT CatNFT PericaFT
    交換ロジック
    Dog
    ロジック
    Cat
    ロジック
    Perica
    ロジック
    ExchangeChaincode
    交換ロジック
    DogNFT
    Dog
    ロジック
    CatCC
    CatNFT
    Cat
    ロジック
    PericaCC
    PericaFT
    Perica
    ロジック

    View Slide

  42. 別ChannelのChaincode呼び出しに関わる制約
    • ChaincodeはChannelごとにインスタンス化(Instantiate)され稼働しており、呼び出し(Invoke)する際もChannelを指定
    して呼び出し実行させる
    • あるChannelでInvokeされたChaincodeから他のChannel上のChaincodeを呼び出し、台帳(およびPrivate Data)を参
    照することは可能だが、呼び出し先のChannelの台帳の更新を実行することはできない
    • Chaincode A on Channel XからChaincode B on Channel Yを呼び出してChannel Yの台帳をクエリした結果を
    Chaincode Aから利用することは可能だが、Channel Yの更新は不可ということ
    • Channelごとに台帳が存在する、つまりChannelが異なれば別の台帳であり、ステートおよびトランザクションは共有していないという
    ことに留意が必要
    • 整合性、一貫性を担保する仕組みはChannelごとにしか用意されていない/機能しない
    • Chaincodeから他のChannelのChaincodeを呼び出してクエリした際にタイミングマターが生じ、複数Peer間でのクエリ結果が
    異なる可能性がある
    Chaincode内Chaincode呼び出し
    Copyright © 2022 Oracle and/or its affiliates
    42

    View Slide

  43. • Chaincodeは台帳(のデータ)の更新の唯一の手段である
    • Chaincodeは台帳のデータを通じた複数組織間のコミュニケーションのメッセージングインターフェース
    であり、同時に台帳のデータ構造定義とデータに対してのロジックを担う
    • Chaincode SDKを通じて実装する
    • 開発言語はNode.js、Go、Javaが選べる
    • ChaincodeのSDKはそれほど難しくない
    • 多くの場合、Chaincodeはそれほど複雑にも大規模にもならない
    • 向いていない、できない、知らないとハマるなど、Chaincodeロジックの設計あるいは実装にあたって
    注意が必要な点は抑えておく
    Chaincodeまとめ
    Copyright © 2022 Oracle and/or its affiliates
    43
    Client App
    Fabric SDK
    Peerノード
    Ledger
    Chaincode

    View Slide

  44. Copyright © 2022 Oracle and/or its affiliates
    クライアントアプリケーションの開発
    44

    View Slide

  45. • HLFの種々の機能を利用するアプリケーションのこと……
    だが、主にはHLFのトランザクションを使うアプリケーションをクライアントアプリケーションと
    呼んでいる(→トランザクションの主体である)
    • トランザクションにおいて以下の役割を担う
    • Peerノードに対してChaincode実行を依頼する
    • Peerノードから返ってきたEndorsementを集める
    • Ordering ServiceにTransaction(メッセージ)を送付する
    • クライアントアプリケーションは一般にHLFとのインタラクション以外にも色々と役割を持たさ
    れるが、そのあたりは一般のアプリケーション開発の範疇なのでここではあまり触れない
    クライアントアプリケーションとは?
    Copyright © 2022 Oracle and/or its affiliates
    45
    Client App
    Fabric SDK
    Peerノード
    Ledger
    Chaincode
    証明書

    View Slide

  46. 凡例
    D社
    C社
    B社
    A社
    ノード
    コンソーシアム型ブロックチェーンの一般的な概観
    Copyright © 2022 Oracle and/or its affiliates
    SC L
    ノード
    SC L
    ノード
    SC L
    ノード
    SC L
    アプリ
    ブロックチェーン
    プラットフォーム
    アプリ
    オペレーター
    他システム
    SC スマート
    コントラクト
    L 台帳
    A社の所管するシステムの範囲
    アプリ
    アプリ
    46
    ブロックチェーンノードは
    コンソーシアム内で分散して
    所有/管理/運用

    View Slide

  47. ノード
    ノード
    ブロックチェーンノード
    エンタープライズでのブロックチェーンを利用したシステムのイメージ
    Copyright © 2022 Oracle and/or its affiliates
    47
    台帳
    スマート
    コントラクト
    アプリ
    ケーション
    データベース
    既存
    データベース
    ユーザー
    アプリ連携
    データ統合
    ブロックチェーンと同内容
    のデータをDBに複製
    BIツール
    ERP、SCM等
    基幹システム
    ERP、SCM等
    基幹システム
    ERP、SCM等の
    基幹システムや
    他アプリケーション
    既存
    データベース
    既存
    データベース
    トランザクション発行
    47

    View Slide

  48. • クライアントアプリケーションは通常、Fabric SDKを用いて実装する
    • Fabric SDKはNode.js版とJava版が正式リリース
    • Node.js版:fabric-network パッケージを用いる…高レベルなAPI、現在の推奨
    • 低レベルなAPIはfabric-common パッケージ
    • Java版:Hyperledger Fabric Gateway SDK for Javaを用いる…高レベルなAPI、現在の推奨
    • 低レベルなAPIはHyperledger Fabric SDK for Java
    • Node.js版とJava版のSDKでは細かい機能の有無や粒度、実装お作法などはだいぶ異なっているが、実質的にでき
    ることはおおよそ同じ(※のはず…)
    • アプリケーション設計、実装にあたっての抽象的な概念(設計要素)は共通しているので、ここではその要素の話を
    していく
    クライアントアプリケーションの実装
    Copyright © 2022 Oracle and/or its affiliates
    48

    View Slide

  49. • クライアントアプリケーションは自身のOrganizationに所属するものだけではなく、他Organizationに所属する
    PeerやOrdererともメッセージをやり取りする
    • 大前提としてネットワーク的にアクセス可能であること(疎通)が必要
    • 認証のためにお互いにHLFのネットワーク上のアイデンティティが必要
    • ネットワークコンポーネントの存在、所在の認識が必要
    クライアントアプリケーションとHLFネットワークコンポーネントの関わり
    Copyright © 2022 Oracle and/or its affiliates
    49

    View Slide

  50. Fabric SDKの主要要素:Wallet
    Copyright © 2022 Oracle and/or its affiliates
    50
    from: https://hyperledger-fabric.readthedocs.io/ja/latest/developapps/wallet.html
    • クライアントアプリケーションが用いるHLFネットワーク上のユーザーアイデンティティの(抽象的な)ストア
    • 秘密鍵/証明書ペアにIDラベルを付けてWalletに追加し、以降そのIDラベルによってWalletからアイデンティティを用いる
    • ファイルシステムWallet、インメモリWallet、CouchDB Walletの形態から選べる
    • 秘密鍵をHSMに格納することも可
    • 秘密鍵/証明書ペアの作成/発行は
    Fabric CA Clientなどで予めやっておく
    (Walletのスコープ外)

    View Slide

  51. • クライアントからHLFのネットワークコンポーネント(Peer、Ordererなど)に対してメッセージを送る際に、「どこにいるどのコンポーネ
    ントにメッセージを送信するか」を抽象化して管理してくれる要素
    • あるChannelのあるChaincodeのトランザクションを実行したい場合、Channel参加有無、Chaincodeインストール有無や
    Endorsement PolicyなどによってTransaction Proposal送信先のPeerの使い分けが必要で、Gatewayがそのあたりを
    やってくれる
    • ネットワークコンポーネントからクライアントアプリケーションへのメッセージ受け取り(Eventなど)も管理してくれる
    • Connection Profileの設定(YAMLまたはJSONで記述)に基づいて動作する
    • 動的なConnection Profile:最小限の設定を記述しておき、PeerのService Discovery機能により動的にネットワーク
    構成情報(トポロジーやノードの死活、Channel参加有無、Endorsement Policy、Private Data Collection参加有
    無など)を取得する
    • 静的なConnection Profile:上記の全てのネットワーク構成情報を予め記載しておく
    • クライアントアプリケーションはTransaction Proposal(Chaincode実行依頼)送信先をGatewayの動的な制御に任せ
    ることもでき、ネットワークの構成情報を取得したうえで自身で細かく指定することもできる
    • 現状ではトランザクションの中で触るPrivate Data CollectionやCollection-Level/State-Levelの細かい
    Endorsement Policyまでは動的には考慮してくれない模様なので、そのあたりを使う場合自身で指定してやる必要アリ
    Fabric SDKの主要要素: Gateway
    Copyright © 2022 Oracle and/or its affiliates
    51

    View Slide

  52. • トランザクションの一連のプロセスを抽象化し実行してくれる
    • EndorsementフェーズでのPeerへのTransaction Proposalメッセージの送信~Endorsementの収集
    • OrderingフェーズでのOrdering ServiceへのTransactionメッセージの送信
    • Validationフェーズでのトランザクション結果のEventメッセージ受け取り
    • 前提としてWallet(および用いるユーザーアイデンティティ)、Gatewayの構成をしたうえでContractを用いてトランザクションを実
    行する
    • 台帳の更新を行うトランザクション用の関数と、クエリ用の関数が用意されている
    • 【Node.js】submitTransaction/【Java】createTransaction
    …台帳の更新とValidation結果の取得まで行う
    • 【共通】evaluateTransaction
    …Chaincodeの実行結果レスポンスの取得まで(台帳は更新されない)
    Fabric SDKの主要要素: Contract
    Copyright © 2022 Oracle and/or its affiliates
    52

    View Slide

  53. public static void main(String[] args) throws IOException {
    // Load an existing wallet holding identities used to access the
    network.
    Path walletDirectory = Paths.get("wallet");
    Wallet wallet = Wallets.newFileSystemWallet(walletDirectory);
    // Path to a common connection profile describing the network.
    Path networkConfigFile = Paths.get("connection.json");
    // Configure the gateway connection used to access the network.
    Gateway.Builder builder = Gateway.createBuilder()
    .identity(wallet, "user1")
    .networkConfig(networkConfigFile);
    // Create a gateway connection
    try (Gateway gateway = builder.connect()) {
    // Obtain a smart contract deployed on the network.
    Network network = gateway.getNetwork("mychannel");
    Contract contract = network.getContract("fabcar");
    // Submit transactions that store state to the ledger.
    byte[] createCarResult = contract.createTransaction("createCar")
    .submit("CAR10", "VW", "Polo", "Grey", "Mary");
    System.out.println(new String(createCarResult,
    StandardCharsets.UTF_8));
    // Evaluate transactions that query state from the ledger.
    byte[] queryAllCarsResult =
    contract.evaluateTransaction("queryAllCars");
    System.out.println(new String(queryAllCarsResult,
    StandardCharsets.UTF_8));
    } catch (ContractException | TimeoutException | InterruptedException
    e) {
    e.printStackTrace();
    }
    }
    Java Gateway SDKを用いた実装サンプル:
    Copyright © 2022 Oracle and/or its affiliates
    53
    from: https://hyperledger.github.io/fabric-gateway-java/release-2.2/

    View Slide

  54. // Connect to a gateway peer
    const connectionProfileJson = (await
    fs.promises.readFile(connectionProfileFileName)).toString();
    const connectionProfile = JSON.parse(connectionProfileJson);
    const wallet = await Wallets.newFileSystemWallet(walletDirectoryPath);
    const gatewayOptions: GatewayOptions = {
    identity: '[email protected]', // Previously imported identity
    wallet,
    };
    const gateway = new Gateway();
    await gateway.connect(connectionProfile, gatewayOptions);
    try {
    // Obtain the smart contract with which our application wants to interact
    const network = await gateway.getNetwork(channelName);
    const contract = network.getContract(chaincodeId);
    // Submit transactions for the smart contract
    const args = [arg1, arg2];
    const submitResult = await
    contract.submitTransaction('transactionName', ...args);
    // Evaluate queries for the smart contract
    const evalResult = await
    contract.evaluateTransaction('transactionName', ...args);
    // Create and submit transactions for the smart contract with transient
    data
    const transientResult = await
    contract.createTransaction(transactionName)
    .setTransient(privateData)
    .submit(arg1, arg2);
    } finally {
    // Disconnect from the gateway peer when all work for this client identity
    is complete
    gateway.disconnect();
    }
    Node.js fabric-network-apiを用いた実装サンプル:
    Copyright © 2022 Oracle and/or its affiliates
    54
    from: https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.html

    View Slide

  55. • クライアントアプリケーションは通常、Fabric SDKを用いて実装する
    • Fabric SDKはNode.js版とJava版が正式リリース
    • 凝ったことをやろうとしなければSDKがよしなにやってくれる部分が多く、HLFでのトランザクション実行部分の実装は
    さほど難しくない
    • Connection Profile設定の用意、ユーザーアイデンティティ(CAを利用した秘密鍵/証明書の作成)の用意
    は必要
    • 前提としてHLFの構造、要素(アイデンティティ、Channel、Private Dataなど)とトランザクションフローの
    しっかりとした理解は必要
    クライアントアプリケーションのFabric SDKを利用した実装まとめ
    Copyright © 2022 Oracle and/or its affiliates
    55

    View Slide

  56. Copyright © 2022 Oracle and/or its affiliates
    整合性あれこれ
    56

    View Slide

  57. ノード
    ノード
    エンタープライズ領域でのユースケースの
    クライアントアプリケーションのイメージ
    Copyright © 2022 Oracle and/or its affiliates
    台帳
    Chaincode
    アプリ
    ケーション
    データベース
    既存
    データベース
    API
    ユーザー
    アプリ連携
    データ統合
    データ複製
    集計・分析
    ERP、SCM等
    基幹システム
    ERP、SCM等
    基幹システム
    ERP、SCM等
    基幹システム
    既存
    データベース
    既存
    データベース
    HLF
    トランザクション
    57

    View Slide

  58. • クライアントアプリケーション自体のビジネスロジック、UIなどの実装がもちろん必要
    • 多くの場合、自身のローカルなデータストアを持つことになる
    • アプリケーションユーザーの認証…HLFのネットワークアイデンティティとは別の層(HLFでは一般的にエンドユーザーごとにネット
    ワークアイデンティティを割り当てることはしない)
    • 必要に応じて台帳からデータベースへのデータの複製を行う
    • 集計、分析をデータベース上で行えるようになり、データの活用可能性が向上
    • データ統合も容易になる
    • 別アプリケーション/システムとの連携
    • エンタープライズのユースケースでは多くの場合、ERPやSCM、基幹システムとの連携が必要
    • APIやインテグレーションツールを通じたアプリケーション連携
    • 既存データとのデータ統合
    • 関係先が増えると、HLF上のデータ(トランザクション)との整合性の考慮も必要に…
    • ChaincodeロジックおよびHLFトランザクション部分よりも、それ以外の側面のほうが開発ボリュームの割合は恐らくだいぶ大きくな

    • ので、一般的な(エンタープライズ領域の)アプリケーション/システム開発のスキルも重要
    クライアントアプリケーションのHLFトランザクション以外の役割
    Copyright © 2022 Oracle and/or its affiliates
    58

    View Slide

  59. アプリ自身のデータベース、社内の別システム、複数のChannelなどなど……
    アプリケーションはしばしば複数のデータストアを扱う
    Copyright © 2022 Oracle and/or its affiliates
    59
    アプリ
    RDB
    社内の
    別システム
    Peer
    他参加者
    アプリ
    Peer
    他参加者
    アプリ
    Peer
    Channel X
    Channel Y
    Channel Z

    View Slide

  60. • 単独Channelでの更新トランザクションはHLFの機能で整合性を保護できる
    • しかし、アプリケーションから見て以下のようなケースで複数データストアを扱っている場合、それらの間の整合性保護は
    HLFでは担保できないので、アプリケーション側で作りこむ必要がある
    • アプリケーションが個別に持つデータストアと台帳を同時に更新したい場合
    • 複数Channelの台帳を同時に更新したい場合
    HLFのトランザクションと複数データストアの整合性保護
    Transaction Scope
    Transaction Scope
    Copyright © 2022 Oracle and/or its affiliates
    60

    View Slide

  61. • 基本的には分散システムでのデータストア間の整合性を保護する方法に準じる
    • 2PC/3PCは使えないのでSagaパターン、補償トランザクションなどで対応
    • 最も難しいのはタイムアウト障害のハンドリング:複数データストアで共通に持つKeyを用意して冪等&リトライ可
    能になるように設計しておくとベター
    • ブロックチェーンならではの注意すべきところは他参加者がいるところ
    • 他参加者が台帳の更新を受けて直ちにアクションを取っても問題ないようにする必要
    • 他参加者も同時にトランザクションを仕掛けていても整合性が崩れないようにしておく
    複数データストア利用時の整合性保護の方式
    Copyright © 2022 Oracle and/or its affiliates
    61

    View Slide

  62. • 基本的には個別データストア→台帳の順序がおすすめ
    • オフチェーンの個別データストアは取り消しなどの手当がしやすく、他参加者にも伝わらない
    • 個別データストアでの更新が成功してから(成功する確証が取れてから)台帳の更新トランザクションを発行する
    • 個別データストア側の更新をロールバックできるならベター
    • 先にRDB側でトランザクション発行しホールド
    • HLFのトランザクションが確定(valid/committed)したらコミット
    • Proposalでエラーになるか、Validationフェーズでinvalidになったらロールバック
    • ロック長時間化による性能劣化の可能性には留意
    ケース①:台帳&個別データストアを同時に更新したい
    Transaction Scope
    Copyright © 2022 Oracle and/or its affiliates
    62

    View Slide

  63. 正常系
    Copyright © 2022 Oracle and/or its affiliates
    63

    View Slide

  64. 異常系①:Proposalでエラー
    Copyright © 2022 Oracle and/or its affiliates
    64

    View Slide

  65. 異常系②:Validationでエラー
    Copyright © 2022 Oracle and/or its affiliates
    65

    View Slide

  66. ・なんらかの理由によりValidation結果のPeer Event
    が取れなかったパターン
    ・場合によってはRDBでロールバックせずにコミットしちゃう
    のもありかも
    異常系③:Validation結果不明
    Copyright © 2022 Oracle and/or its affiliates
    66

    View Slide

  67. • 複数Channelに同時にトランザクションを発行すると結果が出る順序がまちまちになったりしてハンドリングが難しくなる
    ため、基本的に直列に順次発行する
    • Ch1にTx発行⇒Ch1成功⇒Ch2にTx発行⇒…
    • 参加者の間でChannelの更新順序を合意しておくことがベター(場合によってはデッドロック状態回避のために必
    須)
    • 更新順序は規約、マナー、慣行ではなくシステム的に作り込めると安全
    • Ch1で削除したときに生成されるIDをCh2に登録時に入力する、など
    ケース②:複数Channelを同時に更新したい
    Transaction Scope
    moveOut(Item1)
    outKey
    moveIn(Item1,outKey)
    Copyright © 2022 Oracle and/or its affiliates
    67

    View Slide

  68. 複数Channelで順次Txを行った場合にも…
    • 後に回したほうのChannelで更新が行えなかった場合の手当ては検討しておく必要がある
    • Ch1からCh2にアセットを移動しようとしたが、Ch2に追加できなかったためCh1に復活、など
    • いわゆる補償トランザクション
    • Ch2に追加できなかった原因次第で対応を分ける、とすると他参加者に混乱が生じる可能性があるため、常にいった
    んは一定の対応をとることにしたほうがシンプル
    • 最低限、中途半端な状況になっていることを発見できるようにしておく
    ケース②:複数Channelを同時に更新したい
    Transaction Scope
    moveOut(Item1)
    outKey
    moveIn(Item1,outKey)
    undo(moveOut,Item1,outKey)
    Copyright © 2022 Oracle and/or its affiliates
    68

    View Slide

  69. 【PR】Oracle Blockchain Platformの
    REST APIでの複数Channel間アトミックトランザクションのサポート
    • 2フェーズコミットを用いたアトミックトランザクションをサポート
    • セットに含めた全てのトランザクションが揃ってコミット(反映)、
    またはロールバック(撤回)される
    • Hyperledger Fabricを用いるうえで課題となりがちな
    複数Channel間での更新の整合性担保を容易に
    • 例:Channel1でNFTの所有者を更新しつつ、
    Channel2で代金としてコインの残高を移転
    • REST ProxyのatomicTransactionsエンドポイントを使用
    • Fabric SDK/gRPCでアトミックトランザクションを行いたい
    場合は、後述のXAライブラリを利用
    69 Copyright © 2022 Oracle and/or its affiliates
    クライアント
    アプリケーション
    REST Proxy
    Channel 1
    REST API:
    atomicTransactions [
    {Ch1でのTx1},
    {Ch2でのTx2}
    ]
    {Ch1でのTx1}
    Channel 2
    {Ch2でのTx2}
    アトミック
    Blockchain

    View Slide

  70. 【PR】Oracle Blockchain Platformの
    XA対応によるグローバル分散トランザクションのサポート
    • 分散トランザクションの標準であるX/Open XAに対応し、
    Oracle Blockchain PlatformをXAリソースとして扱えるように
    • 分散トランザクションの一部としてブロックチェーンのトランザクションを
    実行することが可能
    • 2フェーズコミットにより、セットでのコミットまたはロールバック
    • エンタープライズで求められるデータ整合性の担保が容易に実装可能
    • 複数Channel間でのアトミックトランザクション
    • データベース、メッセージキューなど他のXA対応リソースとのアト
    ミックなトランザクション
    • クライアントアプリケーションをJavaで実装し、OBPXAResource、
    OBPXADataSource、OBPXAConnectionなどのライブラリを用いる
    ことで利用可能
    70 Copyright © 2022 Oracle and/or its affiliates
    Ch1 Ch2 MQ DB
    Blockchain 他のXAリソース
    クライアントアプリケーション
    Tx Managerライブラリ
    OBP XA
    ライブラリ
    他XAリソース
    ライブラリ
    トランザクションマネージャ
    Tx Tx Tx Tx
    アトミック

    View Slide

  71. Copyright © 2022 Oracle and/or its affiliates
    まとめ
    71

    View Slide

  72. • 10/11(火): Hyperledger Fabric(再)入門
    • コンポーネントやトランザクションフローなど基本を解説
    • 10/18(火):Hyperledger Fabricのネットワーク設計
    • ブロックチェーンネットワークの設計の考え方、進め方を解説
    • 10/25(火):Hyperledger FabricアプリとChaincodeの開発
    • クライアントアプリケーションとChaincodeの開発方法を解説
    • 11/1(火):Oracle Blockchain Platformを用いたHLFアプリ開発
    • Oracle Blockchain Platformならではのメリット、開発方法を解説
    集中講義シリーズ
    Copyright © 2022 Oracle and/or its affiliates
    72

    View Slide

  73. Orderer
    Organization配下にPeer、Orderer、CAのコンポーネントとクライアントアプリケーション
    Hyperledger Fabricネットワークの概観図
    Peer
    Client
    App
    CA
    Chain
    Code Ledger
    Orderer
    A社
    Orderer
    Peer CA
    Chain
    Code Ledger
    Orderer
    Orderer
    Orderer
    Peer
    Chain
    Code Ledger
    CA
    Orderer
    CA
    Orderer
    Peer
    Chain
    Code Ledger
    B社 D社
    C社
    Client
    App
    Client
    App
    Client
    App
    Copyright © 2022 Oracle and/or its affiliates
    Hyperledger Fabric完全に理解した!!
    73

    View Slide

  74. Thank you
    Copyright © 2022 Oracle and/or its affiliates
    74

    View Slide

  75. View Slide