2021/12/8 Blockchain GIG#11でしゃべった内容 →2022/10/25 Blockchain GIG特別編 HLF集中講義#3 Hyperledger FabricのアプリとChaincodeの開発 でリバイズ Hyperledger Fabricのクライアントアプリケーション、Chaincodeを開発する際に知っておきたいこと
Hyperledger FabricアプリケーションとChaincodeの開発Blockchain GIG特別編 HLF集中講義#3中村 岳クラウド事業統括/クラウド・エンジニアリング統括/ソリューション・アーキテクト本部2022/10/25
View Slide
Copyright © 2022 Oracle and/or its affiliates2中村 岳Twitter @gakumuraはてなブログ @gakumura…主にHyperledger Fabric関連• 現職:ソリューションエンジニア@日本オラクル• 担当:Oracle Blockchain Platform、Blockchain Table• 前職:金融決済系SIerでパッケージ開発• SWIFT、CLS、日銀ネット関連の銀行間決済システム
Hyperledger Fabricをベースにエンタープライズ利用向けPaaSとオンプレミスで提供• 数ステップで構築完了、GUIコンソールで管理・運用も容易• エンタープライズグレードの耐障害制、堅牢性• マルチクラウド、ハイブリッドクラウド、オープンなネットワーク構成が可能• Oracle独自の付加価値:• State DBとしてBerkeley DBを利用:パフォーマンスとクエリ利便性向上• 多機能なREST API:スマートコントラクトの利用を容易に• 台帳のデータをRDBに複製:大量照会、分析、データ統合• スマートコントラクトを容易に開発:付属の開発ツールでアセット仕様からコードを自動生成• 複数ChannelのアトミックトランザクションとXA対応:複数Channelでの更新のアトミックな実行や、ローカルのDB、MQなどとのグローバルトランザクションをサポートOracle Blockchain PlatformCopyright © 2022 Oracle and/or its affiliates東京DCからもサービス提供中3
• 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 affiliates4
• Chaincodeの開発• クライアントアプリケーションの開発• 整合性あれこれ※なお、文中のHLF=HyperLedger Fabric資料の内容Copyright © 2022 Oracle and/or its affiliates5
Copyright © 2022 Oracle and/or its affiliatesChaincodeの開発6
• 所謂「スマートコントラクト」を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 affiliates7Client AppFabric SDKPeerノードLedgerChaincode
• 各々が自身のPeerにInstallした後に、Channelで有効化することで実行可能に• 有効化の手続きはv1.x系とv2.x系で異なる(v2.x系ではオペレーションが一層分権化)• バージョンアップ可能:Chaincodeはバージョンアップできるため、稼働後も修正や改善が可能• 新バージョンで旧バージョンのChaincodeが書いたレコードにもアクセスできるChaincodeのライフサイクルCopyright © 2022 Oracle and/or its affiliates8Install有効化 Upgrade新バージョンのInstall各Orgで行うローカルなオペレーションネットワークのオペレーション新バージョン稼働
運用上重要なものを含むが、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 affiliates9
• 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 affiliates10PeerノードLedgerChaincodefabric-contract-apiClient AppFabric SDK
• 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 affiliates11
PeerPeerノードが保持する分散台帳の1コピー復習:Hyperledger Fabricにおける「台帳」12• 台帳は以下ふたつの要素から構成される+Blockchain:履歴• トランザクションの履歴が格納されるハッシュチェーンで連結されたブロックのファイル• 追記オンリーで蓄積していくWorld State:状態• 各Keyに対する現在(最新)バージョンの値を保持• レコードは更新、削除が可能(履歴はBlockchainに残っている)• State DBと呼ばれるDBに格納されるLedgerPeerLedgerPeerLedgerPeerLedgerCopyright © 2022 Oracle and/or its affiliates
台帳に保存される「現在の値(ステート)」とそれを保持するデータベース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 DB13 Copyright © 2022 Oracle and/or its affiliates
ある程度柔軟なデータ構造を扱え、State DBによる検索の表現能力もそこそこ復習:World Stateで扱うデータ構造の例Copyright © 2022 Oracle and/or its affiliates14Key:口座番号 Value:残高1020345 10,000,0001020346 56,400Key:アセット種別と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のアセットを全件取得)
• Chaincodeを実装する際に利用する主な機能はSDKのChaincodeStubクラスにまとまっている• このクラスの内容(関数)を抑えておけば基礎の学習はだいたいOK• Go/Java/Node.jsのSDKで細かい関数の有無、関数名に差異(ここではNode.js基準で記載)があるが、実質的にできることは同等。Node.jsのドキュメントは説明が多くてわかりやすい。• 以下によく使う主要なものを抜粋して記載Chaincode SDKの主要な機能①Copyright © 2022 Oracle and/or its affiliates15カテゴリ 関数 説明引数 getArgs クライアントから渡された引数を取得するgetTransient TransientMap(Transactionに載らない=Blockchain上に値が記録されない特殊な引数)として渡された引数を取得するトランザクション情報 getTxTimeStamp クライアントから渡されたTransactionのタイムスタンプを取得するgetTxID クライアントから渡されたTransactionのID(ランダムなGUID)を取得するgetMspId トランザクション発行者(クライアント)の所属Organizationを取得するgetCreator トランザクション発行者のアイデンティティを取得する
• 台帳操作系の機能のうち主要なものは以下(World Stateへの操作についてはPrivate Data用に同等の機能が存在するが、ここでは一律割愛)• いずれも特に難しいところはないが、参照系はRead-Set Validationとの絡みで更新トランザクション内での利用に制約がつくもの、注意が必要なものがある点は留意(後述)Chaincode SDKの主要な機能②Copyright © 2022 Oracle and/or its affiliates16カテゴリ 関数 説明World Stateの更新putState 指定したKey、ValueのレコードをWorld Stateに書き込む(Keyが既にあればValueを上書きする)deleteState 指定したKeyのレコードをWorld Stateから削除する台帳の参照 getState 指定したKeyのValueをWorld Stateから取得するgetStateByRange StartKey~EndKeyで指定した範囲のKeyのレコードをWorld Stateから検索し取得するgetStateByPartialCompositeKey複合Keyを持たせたレコードについて、複合Keyの前部分を指定し、前方一致でWorld Stateから検索し取得するgetQueryResult State DBのデータベース実装が対応している構文でクエリを渡し、World Stateの検索結果のレコードを取得する(例:CouchDBを利用→JSONリッチクエリ)getHistoryForKey 指定したKeyについての履歴(過去から現在のバージョンのValue、TxIDとTimeStamp)をBlockchainから取得する
• 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 affiliates17
• 台帳上のデータを参照したいが台帳を更新する意図がない場合、クライアントアプリは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 affiliates18
指針として、Chaincodeに何もかもやらせようとせず、できるだけシンプルなものに留めておいたほうがよい→Chaincodeに必須でないもの、向いていないものはクライアントアプリケーションロジックや、台帳データ複製先のデータベースで引き取るやるべき• Chaincodeに必須なのはWorld StateとPrivate Dataの更新に関連する機能• 更新の中で必要な参照機能(条件評価など)を含む• 基本的な(それほど複雑でない、規模の大きくない)クエリの機能もあって良いやらないべき• Chaincodeは複雑でコストの重い処理、広い範囲のデータを一括で読み書きする処理にはあまり向いていない• Endorsementでは複数Peerでロジックが冗長に実行される• State DBはRDBと同じようには使えない…大規模集計、分析は得意ではない• トランザクションフローの仕組み上、1トランザクションに大量のRWSetが含まれると他のトランザクションと衝突しやすく、結果的に処理性能に問題が発生しやすい• 必要な場合はバッチとして切り出し時間を区切るなどして他のトランザクションに影響を与えないように工夫する何をChaincodeのロジックとして持っておくべきか?Copyright © 2022 Oracle and/or its affiliates19
• 前述の「複雑でコストの重い処理、広い範囲のデータを一括で読み書きする処理」以外にもChaincodeロジックの設計あるいは実装にあたって注意が必要な以下の点を説明していくChaincodeロジックの注意点Copyright © 2022 Oracle and/or its affiliates20項目 要点非-決定性ロジック 実行したPeer間で結果がバラバラになり得るロジックは作り込んではいけない外部情報の参照(オラクル) Chaincodeから台帳の外部にある情報を見に行くのは難しいRead My Writes 今書いたValueはまだコミットされてないので読めない更新トランザクション内での一部クエリ機能の利用制約一部のクエリ(World State、Private Data、Blockchainの検索)機能はValidationで検出されない不整合を起こし得るので更新トランザクションの中での利用には注意が必要Chaincode内Chaincode呼び出し Chaincode内から別のChaincodeを呼び出せるが、同一Channelでない場合は安全でない、呼び出し先のChannelの更新もできない同一レコードについての更新スループット追及上の限界トランザクションフローにおけるRead-Set Validationの関係で、同一のレコードを高密度で更新するユースケースが苦手
ステートマシン• 現在の状態(State)と入力条件によって次の状態に遷移• 入力条件とはたとえば処理内容(e.g. 起動する、停止する、値を増やす/減らす)や、処理内容に対して外部から与えられる引数(e.g. いくつ値を増減する)非-決定性StatenStaten+1入力(処理)XCopyright © 2022 Oracle and/or its affiliates21
分散台帳とステートマシン• ノードそれぞれが持つ台帳は独立したステート• それぞれのノード上でトランザクションを処理してステートが遷移• 分散/独立しているが一致したステートを実現するのが分散台帳非-決定性StatenStaten+1TxノードStatenStaten+1TxノードStatenStaten+1TxノードStatenStaten+1TxノードCopyright © 2022 Oracle and/or its affiliates22
スマートコントラクトとステートの一致分散/独立したステートを一致させるにはどうすればよいか?前提として、ステートを更新する方法、条件を予め合意し共有しておく• 予め合意していることをもってシステム化された「契約」とみなせるためスマートコントラクトと呼ばれる• ステートは契約の履行の結果を記した台帳ということになるそのうえで、全ノードで一致したステートを保持する方法はふたつ• 全てのノードがそれぞれスマートコントラクトを実行してステートを遷移させる• 一部(単一または複数)のノードでスマートコントラクトをシミュレーション実行し、事後状態となるステートを伝播する• Hyperledger Fabricのコンセンサスモデルはこちら非-決定性Copyright © 2022 Oracle and/or its affiliates23
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実行結果」とRWSetCopyright © 2022 Oracle and/or its affiliates24
あるTransactionがWorld Stateから読んだレコード、書き込む(予定の)値復習:RWSetの例 ※バージョンの形式は単純化しており正確なものではないCopyright © 2022 Oracle and/or its affiliates25• K1とK2のレコードを読んでいる• それぞれバージョンは”1”• K1に”V1”という値を、K3に”V2”という値をそれぞれ書き込もうとしている• K4のレコードを削除しようとしている
Chaincodeの決定性がなぜ必要か• Chaincodeにはそのインプットとして常に台帳の現在ステートとクライアントからの入力値(引数)が存在する• 複数ノードでそれぞれChaincodeが実行された結果に含まれる事後ステート=Write-Setが同一になっていないとならない• 異なるWrite-Setを集めてきてもEndorsement Policyを満たさない• すなわち、同一インプットからは同一の事後ステートが導かれるようにしておく必要がある• この条件を満たすChaincodeをdeterministic(決定性の、決定的な)であると呼び、そうでないものをindeterministic(非-決定性の、非-決定的な)と呼ぶ• Chaincode内に非-決定性のロジックを作り込んではならない非-決定性Copyright © 2022 Oracle and/or its affiliates26
非-決定性ロジックの例:ランダムな値の生成• Chaincodeの中でGUIDの生成などのためにランダムな値を生成する処理(UUID ver4など)を使いたくなるが、当然複数ノード間で一致しなくなるのでNG• 代替としてステート内にシードを用意しておき、そこから決定的に生成する処理を利用する(UUID ver3など)、あるいはクライアント側で生成してから渡す非-決定性PLCCPLCC≠Copyright © 2022 Oracle and/or its affiliates27
非-決定性ロジックの例:ノードのローカル日時の利用• Chaincode内でノードのローカル日時を取得して利用するのは、他のノードと必ずしも一致しなくなるのでNG• 時刻同期が不完全なことによるズレ• Chaincodeの実行タイミングのズレ• 「現在」の日時はクライアント側で決定してから渡すしかない• ⇨クライアント側で任意の値を渡すことができる(不正の余地がある)• これはつまり、特別な手段を講じない限り「現在」日時はコンセンサスの外部ということ非-決定性PLCCPLCC≠12:00:00 12:01:23Copyright © 2022 Oracle and/or its affiliates28
日時に関する補足非-決定性Copyright © 2022 Oracle and/or its affiliates• ブロック内のトランザクションデータ(トランザクション履歴)として保存されているタイムスタンプもクライアントアプリケーションで決定しているもの• 必ずしもクライアントが正しいタイムスタンプを渡すとも限らない• トランザクション履歴を利用する際には、順序付けなどにこのタイムスタンプを使用してはならない29
非-決定性ロジックの例:オンチェーンデータの外部に存在する情報の利用• Chaincodeから(クライアントから渡されるもの以外の)オンチェーンデータ外部の情報を取得しようとすると、各ノードで個別に取得した結果が一致することを保証するのは困難• Chaincodeの実行タイミングによって違う値が返ってくる、あるいは取得できない可能性• 外部ハッキングあるいはノード所有者によって不正な値を取得させられてしまう可能性• なお、ノードのローカル時刻も「台帳の外部に存在する情報」の一種非-決定性PLCCPLCC≠天気予報60%40%明日の降水確率Copyright © 2022 Oracle and/or its affiliates30
• 例えばスポーツ賭博や予測市場などのサービスをブロックチェーン/分散台帳で実現しようとしたときに、現実世界の情報(試合結果や値動き)が必要• クライアントアプリケーションから渡すことにすると、都合良く偽れてしまう• 不正があったことを後から追求可能ではあるので、それで問題ないユースケースならそれでよい• スマートコントラクトからネットワーク外部の情報にアクセスしてコンセンサス内で取得してこないとならない• 何も考えないで実装すると、外部サービスへのアクセスにインタラプトするMockを建ててそこから都合の良い情報を返す、などわりとかんたんに不正ができる• このような要求に対して、中立かつ信頼できるかたちでネットワーク外部の情報を提供するサービスをオラクル(Oracle、託宣)と呼ぶ• オラクルが情報を自身の署名付きで提供することで、偽装や改ざんが不能でコンセンサスに取り入れられる外部情報が利用できる• しかし署名の検証をどう行うかまで考慮が必要となるなど、オラクル利用はけっこう難しい安全な外部情報の利用(オラクル)Copyright © 2022 Oracle and/or its affiliates31
• 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 WritesCopyright © 2022 Oracle and/or its affiliates32
• 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 affiliates33クエリ機能 問題点の説明getHistoryForKey 履歴は読んでもRead-Setに載らないので、ValidationフェーズまでにそのKeyに更新があっても検知できない※ただしgetStateと併用していれば問題ないので回避は容易getStateByRangeWithPagenation,getStateByPartialCompositeKeyWithPagenation,getQueryResult,getPrivateDataByRangeWithPagenation,getPrivateDataByPartialCompositeKeyWithPagenation,getPrivateDataQueryResultこれらのレンジクエリ(検索結果としてゼロ~複数の結果セットを返すクエリ)は共通してValidationフェーズに再実行されないため、PhantomReadの発生を検知できない→Phantom Read問題
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 ValidationCopyright © 2022 Oracle and/or its affiliates34World StateKey Value VersionA 0 4不一致
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 affiliates35
物の所有権を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 affiliates36
まずCarolの持ち物をすべてAliceに譲渡したのちにAliceの持ち物をすべてBobに譲渡したいので、Tx1とTx2の実行後の期待される結果は以下CouchDBのPhantom Read問題:事象の例②しかしCouchDBではPhantom Read問題により以下の結果になる場合があるItem ID Owner初期状態 中間状態(Tx1後) 結果(Tx2後)Item1 Alice Alice BobItem2 Bob Bob BobItem3 Carol Alice BobItem ID Owner初期状態 中間状態(Tx1後) 結果Item1 Alice Alice BobItem2 Bob Bob BobItem3 Carol Alice Alice取りこぼしCopyright © 2022 Oracle and/or its affiliates37
トランザクションが以下の時系列で処理されると意図しない結果が発生する• Tx1のEndorsementをE1、ValidationをV1、Tx2も同様にE2とV2とし、OrderingをOと表記CouchDBのPhantom Read問題:事象の例③E1E2O V2V1Item ID 初期状態~V1前まで V1後 V2後Item1 Alice Alice BobItem2 Bob Bob BobItem3 Carol Alice AliceCopyright © 2022 Oracle and/or its affiliates38
• V2でAliceの持ち物であるにもかかわらず、Item3の取りこぼしが生じている• Tx2でのリッチクエリ結果にはItem3が含まれておらず、したがってRead-Set ValidationにItem3は含まれず取りこぼしは検知できない• このようなパターンの不整合を検知するにはValidationフェーズでのレンジクエリの再実行が必要CouchDBのPhantom Read問題:事象の例③E1E2O V2V1Item ID 初期状態~V1前まで V1後 V2後Item1 Alice Alice BobItem2 Bob Bob BobItem3 Carol Alice AliceCopyright © 2022 Oracle and/or its affiliates39V2 Validation
単一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 affiliates40
DogCC例:複数種類のトークンを扱う場合• 複数種類のトークンをひとつのChaincodeでまとめて管理することもできる• 例①:ひとつのChaincode内で複数種類のNFTを扱い、互いに交換可能にする• 例②:ひとつのChaincode内でNFTとFTを扱い、DVP(Delivery Versus Payment)をやる• トークンごとに分けても良い• この場合、異種トークンの交換は専用のChaincodeを作り、そこから各トークンのChaincodeを呼ぶ41 Copyright © 2022 Oracle and/or its affiliatesSuperTokenChaincodeDogNFT CatNFT PericaFT交換ロジックDogロジックCatロジックPericaロジックExchangeChaincode交換ロジックDogNFTDogロジックCatCCCatNFTCatロジックPericaCCPericaFTPericaロジック
別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 affiliates42
• Chaincodeは台帳(のデータ)の更新の唯一の手段である• Chaincodeは台帳のデータを通じた複数組織間のコミュニケーションのメッセージングインターフェースであり、同時に台帳のデータ構造定義とデータに対してのロジックを担う• Chaincode SDKを通じて実装する• 開発言語はNode.js、Go、Javaが選べる• ChaincodeのSDKはそれほど難しくない• 多くの場合、Chaincodeはそれほど複雑にも大規模にもならない• 向いていない、できない、知らないとハマるなど、Chaincodeロジックの設計あるいは実装にあたって注意が必要な点は抑えておくChaincodeまとめCopyright © 2022 Oracle and/or its affiliates43Client AppFabric SDKPeerノードLedgerChaincode
Copyright © 2022 Oracle and/or its affiliatesクライアントアプリケーションの開発44
• HLFの種々の機能を利用するアプリケーションのこと……だが、主にはHLFのトランザクションを使うアプリケーションをクライアントアプリケーションと呼んでいる(→トランザクションの主体である)• トランザクションにおいて以下の役割を担う• Peerノードに対してChaincode実行を依頼する• Peerノードから返ってきたEndorsementを集める• Ordering ServiceにTransaction(メッセージ)を送付する• クライアントアプリケーションは一般にHLFとのインタラクション以外にも色々と役割を持たされるが、そのあたりは一般のアプリケーション開発の範疇なのでここではあまり触れないクライアントアプリケーションとは?Copyright © 2022 Oracle and/or its affiliates45Client AppFabric SDKPeerノードLedgerChaincode証明書
凡例D社C社B社A社ノードコンソーシアム型ブロックチェーンの一般的な概観Copyright © 2022 Oracle and/or its affiliatesSC LノードSC LノードSC LノードSC Lアプリブロックチェーンプラットフォームアプリオペレーター他システムSC スマートコントラクトL 台帳A社の所管するシステムの範囲アプリアプリ46ブロックチェーンノードはコンソーシアム内で分散して所有/管理/運用
ノードノードブロックチェーンノードエンタープライズでのブロックチェーンを利用したシステムのイメージCopyright © 2022 Oracle and/or its affiliates47台帳スマートコントラクトアプリケーションデータベース既存データベースユーザーアプリ連携データ統合ブロックチェーンと同内容のデータをDBに複製BIツールERP、SCM等基幹システムERP、SCM等基幹システムERP、SCM等の基幹システムや他アプリケーション既存データベース既存データベーストランザクション発行47
• クライアントアプリケーションは通常、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 affiliates48
• クライアントアプリケーションは自身のOrganizationに所属するものだけではなく、他Organizationに所属するPeerやOrdererともメッセージをやり取りする• 大前提としてネットワーク的にアクセス可能であること(疎通)が必要• 認証のためにお互いにHLFのネットワーク上のアイデンティティが必要• ネットワークコンポーネントの存在、所在の認識が必要クライアントアプリケーションとHLFネットワークコンポーネントの関わりCopyright © 2022 Oracle and/or its affiliates49
Fabric SDKの主要要素:WalletCopyright © 2022 Oracle and/or its affiliates50from: https://hyperledger-fabric.readthedocs.io/ja/latest/developapps/wallet.html• クライアントアプリケーションが用いるHLFネットワーク上のユーザーアイデンティティの(抽象的な)ストア• 秘密鍵/証明書ペアにIDラベルを付けてWalletに追加し、以降そのIDラベルによってWalletからアイデンティティを用いる• ファイルシステムWallet、インメモリWallet、CouchDB Walletの形態から選べる• 秘密鍵をHSMに格納することも可• 秘密鍵/証明書ペアの作成/発行はFabric CA Clientなどで予めやっておく(Walletのスコープ外)
• クライアントから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の主要要素: GatewayCopyright © 2022 Oracle and/or its affiliates51
• トランザクションの一連のプロセスを抽象化し実行してくれる• EndorsementフェーズでのPeerへのTransaction Proposalメッセージの送信~Endorsementの収集• OrderingフェーズでのOrdering ServiceへのTransactionメッセージの送信• Validationフェーズでのトランザクション結果のEventメッセージ受け取り• 前提としてWallet(および用いるユーザーアイデンティティ)、Gatewayの構成をしたうえでContractを用いてトランザクションを実行する• 台帳の更新を行うトランザクション用の関数と、クエリ用の関数が用意されている• 【Node.js】submitTransaction/【Java】createTransaction…台帳の更新とValidation結果の取得まで行う• 【共通】evaluateTransaction…Chaincodeの実行結果レスポンスの取得まで(台帳は更新されない)Fabric SDKの主要要素: ContractCopyright © 2022 Oracle and/or its affiliates52
public static void main(String[] args) throws IOException {// Load an existing wallet holding identities used to access thenetwork.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 connectiontry (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 | InterruptedExceptione) {e.printStackTrace();}}Java Gateway SDKを用いた実装サンプル:Copyright © 2022 Oracle and/or its affiliates53from: https://hyperledger.github.io/fabric-gateway-java/release-2.2/
// Connect to a gateway peerconst connectionProfileJson = (awaitfs.promises.readFile(connectionProfileFileName)).toString();const connectionProfile = JSON.parse(connectionProfileJson);const wallet = await Wallets.newFileSystemWallet(walletDirectoryPath);const gatewayOptions: GatewayOptions = {identity: '[email protected]', // Previously imported identitywallet,};const gateway = new Gateway();await gateway.connect(connectionProfile, gatewayOptions);try {// Obtain the smart contract with which our application wants to interactconst network = await gateway.getNetwork(channelName);const contract = network.getContract(chaincodeId);// Submit transactions for the smart contractconst args = [arg1, arg2];const submitResult = awaitcontract.submitTransaction('transactionName', ...args);// Evaluate queries for the smart contractconst evalResult = awaitcontract.evaluateTransaction('transactionName', ...args);// Create and submit transactions for the smart contract with transientdataconst transientResult = awaitcontract.createTransaction(transactionName).setTransient(privateData).submit(arg1, arg2);} finally {// Disconnect from the gateway peer when all work for this client identityis completegateway.disconnect();}Node.js fabric-network-apiを用いた実装サンプル:Copyright © 2022 Oracle and/or its affiliates54from: https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.html
• クライアントアプリケーションは通常、Fabric SDKを用いて実装する• Fabric SDKはNode.js版とJava版が正式リリース• 凝ったことをやろうとしなければSDKがよしなにやってくれる部分が多く、HLFでのトランザクション実行部分の実装はさほど難しくない• Connection Profile設定の用意、ユーザーアイデンティティ(CAを利用した秘密鍵/証明書の作成)の用意は必要• 前提としてHLFの構造、要素(アイデンティティ、Channel、Private Dataなど)とトランザクションフローのしっかりとした理解は必要クライアントアプリケーションのFabric SDKを利用した実装まとめCopyright © 2022 Oracle and/or its affiliates55
Copyright © 2022 Oracle and/or its affiliates整合性あれこれ56
ノードノードエンタープライズ領域でのユースケースのクライアントアプリケーションのイメージCopyright © 2022 Oracle and/or its affiliates台帳Chaincodeアプリケーションデータベース既存データベースAPIユーザーアプリ連携データ統合データ複製集計・分析ERP、SCM等基幹システムERP、SCM等基幹システムERP、SCM等基幹システム既存データベース既存データベースHLFトランザクション57
• クライアントアプリケーション自体のビジネスロジック、UIなどの実装がもちろん必要• 多くの場合、自身のローカルなデータストアを持つことになる• アプリケーションユーザーの認証…HLFのネットワークアイデンティティとは別の層(HLFでは一般的にエンドユーザーごとにネットワークアイデンティティを割り当てることはしない)• 必要に応じて台帳からデータベースへのデータの複製を行う• 集計、分析をデータベース上で行えるようになり、データの活用可能性が向上• データ統合も容易になる• 別アプリケーション/システムとの連携• エンタープライズのユースケースでは多くの場合、ERPやSCM、基幹システムとの連携が必要• APIやインテグレーションツールを通じたアプリケーション連携• 既存データとのデータ統合• 関係先が増えると、HLF上のデータ(トランザクション)との整合性の考慮も必要に…• ChaincodeロジックおよびHLFトランザクション部分よりも、それ以外の側面のほうが開発ボリュームの割合は恐らくだいぶ大きくなる• ので、一般的な(エンタープライズ領域の)アプリケーション/システム開発のスキルも重要クライアントアプリケーションのHLFトランザクション以外の役割Copyright © 2022 Oracle and/or its affiliates58
アプリ自身のデータベース、社内の別システム、複数のChannelなどなど……アプリケーションはしばしば複数のデータストアを扱うCopyright © 2022 Oracle and/or its affiliates59アプリRDB社内の別システムPeer他参加者アプリPeer他参加者アプリPeerChannel XChannel YChannel Z
• 単独Channelでの更新トランザクションはHLFの機能で整合性を保護できる• しかし、アプリケーションから見て以下のようなケースで複数データストアを扱っている場合、それらの間の整合性保護はHLFでは担保できないので、アプリケーション側で作りこむ必要がある• アプリケーションが個別に持つデータストアと台帳を同時に更新したい場合• 複数Channelの台帳を同時に更新したい場合HLFのトランザクションと複数データストアの整合性保護Transaction ScopeTransaction ScopeCopyright © 2022 Oracle and/or its affiliates60
• 基本的には分散システムでのデータストア間の整合性を保護する方法に準じる• 2PC/3PCは使えないのでSagaパターン、補償トランザクションなどで対応• 最も難しいのはタイムアウト障害のハンドリング:複数データストアで共通に持つKeyを用意して冪等&リトライ可能になるように設計しておくとベター• ブロックチェーンならではの注意すべきところは他参加者がいるところ• 他参加者が台帳の更新を受けて直ちにアクションを取っても問題ないようにする必要• 他参加者も同時にトランザクションを仕掛けていても整合性が崩れないようにしておく複数データストア利用時の整合性保護の方式Copyright © 2022 Oracle and/or its affiliates61
• 基本的には個別データストア→台帳の順序がおすすめ• オフチェーンの個別データストアは取り消しなどの手当がしやすく、他参加者にも伝わらない• 個別データストアでの更新が成功してから(成功する確証が取れてから)台帳の更新トランザクションを発行する• 個別データストア側の更新をロールバックできるならベター• 先にRDB側でトランザクション発行しホールド• HLFのトランザクションが確定(valid/committed)したらコミット• Proposalでエラーになるか、Validationフェーズでinvalidになったらロールバック• ロック長時間化による性能劣化の可能性には留意ケース①:台帳&個別データストアを同時に更新したいTransaction ScopeCopyright © 2022 Oracle and/or its affiliates62
正常系Copyright © 2022 Oracle and/or its affiliates63
異常系①:ProposalでエラーCopyright © 2022 Oracle and/or its affiliates64
異常系②:ValidationでエラーCopyright © 2022 Oracle and/or its affiliates65
・なんらかの理由によりValidation結果のPeer Eventが取れなかったパターン・場合によってはRDBでロールバックせずにコミットしちゃうのもありかも異常系③:Validation結果不明Copyright © 2022 Oracle and/or its affiliates66
• 複数Channelに同時にトランザクションを発行すると結果が出る順序がまちまちになったりしてハンドリングが難しくなるため、基本的に直列に順次発行する• Ch1にTx発行⇒Ch1成功⇒Ch2にTx発行⇒…• 参加者の間でChannelの更新順序を合意しておくことがベター(場合によってはデッドロック状態回避のために必須)• 更新順序は規約、マナー、慣行ではなくシステム的に作り込めると安全• Ch1で削除したときに生成されるIDをCh2に登録時に入力する、などケース②:複数Channelを同時に更新したいTransaction ScopemoveOut(Item1)outKeymoveIn(Item1,outKey)Copyright © 2022 Oracle and/or its affiliates67
複数Channelで順次Txを行った場合にも…• 後に回したほうのChannelで更新が行えなかった場合の手当ては検討しておく必要がある• Ch1からCh2にアセットを移動しようとしたが、Ch2に追加できなかったためCh1に復活、など• いわゆる補償トランザクション• Ch2に追加できなかった原因次第で対応を分ける、とすると他参加者に混乱が生じる可能性があるため、常にいったんは一定の対応をとることにしたほうがシンプル• 最低限、中途半端な状況になっていることを発見できるようにしておくケース②:複数Channelを同時に更新したいTransaction ScopemoveOut(Item1)outKeymoveIn(Item1,outKey)undo(moveOut,Item1,outKey)Copyright © 2022 Oracle and/or its affiliates68
【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 ProxyChannel 1REST API:atomicTransactions [{Ch1でのTx1},{Ch2でのTx2}]{Ch1でのTx1}Channel 2{Ch2でのTx2}アトミックBlockchain
【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 affiliatesCh1 Ch2 MQ DBBlockchain 他のXAリソースクライアントアプリケーションTx ManagerライブラリOBP XAライブラリ他XAリソースライブラリトランザクションマネージャTx Tx Tx Txアトミック
Copyright © 2022 Oracle and/or its affiliatesまとめ71
• 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 affiliates72
OrdererOrganization配下にPeer、Orderer、CAのコンポーネントとクライアントアプリケーションHyperledger Fabricネットワークの概観図PeerClientAppCAChainCode LedgerOrdererA社OrdererPeer CAChainCode LedgerOrdererOrdererOrdererPeerChainCode LedgerCAOrdererCAOrdererPeerChainCode LedgerB社 D社C社ClientAppClientAppClientAppCopyright © 2022 Oracle and/or its affiliatesHyperledger Fabric完全に理解した!!73
Thank youCopyright © 2022 Oracle and/or its affiliates74