# アーキテクチャ

# 抜粋

このドキュメントでは、高速分散アプリケーション用のブロックチェーン・ソリューションである miyabi について説明しています。 miyabi は UTXO ベースのブロックチェーンではなく、world-state ベースのブロックチェーンです。これは、各ブロックでトランザクションを実行し、それに応じて state を更新する state machine と見なすことができます。miyabi を使用することで、豊富な形式のデータが保存および処理可能となります。

miyabi は、コンソーシアム・ベースの許可されたプライベート・ブロックチェーンです。必要な資格情報を持つコンソーシアムの既知のノードとメンバーのみが特定の miyabi ネットワークに参加できます。miyabi ネットワークでは、コンセンサス・アルゴリズムを実行しているノードはコンセンサス・ノードと呼ばれます。miyabi では、コンセンサス・ノードはBFK2コンセンサス・アルゴリズムを使用して、トランザクションの内容と順序、およびブロック内での実行結果について合意します(コンセンサスを作成)。 BFK2 はビザンチン・フォルト・トレランス(BFT)を実現し、トランザクションのファイナリティを保証します。 以下のノードの miyabi がビザンチン・ノードである場合、コミットされたブロックはすべてのノードで共有され、改ざんされることはありません(ファイナリティ)。

miyabi はスマート・コントラクトもサポートしており、カスタマイズされたロジックを使用して複数のアセットを安全に交換できます。miyabi は、タイムスタンプ付きの契約が耐タンパー性があることを保証します。スマート・コントラクトの潜在的なバグを防ぐために、miyabi には 2 つのレイヤーのバリデーションがあります。最初のレイヤーでは、スマート・コントラクト・アナライザーとコンパイラーが潜在的なシンタックス・イシューをチェックします。2 番目のレイヤーには、トランザクション・タイプとタッチドデータ・タイプ(アセットなど)に応じて開始する一連のトランザクション・バリデーターがあり、トランザクションが事前定義された一連のルールに準拠しているかどうかを確認します。たとえば、資産には、タッチドデータ・アセットに対するアクセス制御をチェックする Kotowari(理)という名前の特別なバリデーターがあり、資産の移動後の残りの残高が他のチェックの中で最小値を下回らないことを確認します。

# 分散型ステートマシン

miyabi は、各ノードが参加して次の state を決定する分散型 state machine と見なすことができます。トランザクションは、ブロックチェーンの特定の state S での操作と見なすことができます。トランザクションには、state machine を state S から S' に遷移させる機能があります。 miyabi は次の特性を満たします。

  1. 同じ初期状態を共有する。
  2. 同じ順序で実行された同じトランザクション一式を共有する。
  3. 全てのノードが整合性を侵害することなく物理的に分散可能である。

miyabi のノードは同じ初期 state で始まります。ピア・ツー・ピア・ネットワークがトランザクションを受信すると、トランザクションはブロックにバンドルされて実行されます。 その後、新しいブロックがブロックチェーンに追加されます。ブロック内のトランザクションの順序とトランザクションの実行結果は、BFK2 の想定に従って一貫していることが保証されています。 BFK2 がブロックチェーンの整合性を保証しているため、各ノードのトランザクション順序には一貫性があります。最後に、決定論的トランザクション実行が実装されます。 与えられた World State とトランザクション・リストでは、すべてのノードが同じ結果を生成します。ステートマシンの構造は図 1 の通りです。

fig1
図 1. ステートマシンのコンセプト

# ノードの役割

ノードは miyabi プログラムを実行しているインスタンスで、主な機能には次があげられます:

  1. トランザクション受信
  2. 他のピア・ノードとの情報の共有(トランザクションとブロックを含む)
  3. トランザクションの実行とワールドステートの更新
  4. 公開 API と管理 API の公開
  5. コンセンサスアルゴリズムの実行(コンセンサスノードのみ)

ノードは、ユーザーが以下に関連する情報を取得するために使用できる一連の API を公開します:

  1. miyabi のメタデータ
  2. world state
  3. ブロック
  4. トランザクション

さらに、ユーザーは API を介してノードにトランザクションを送信することもできます。

ノードは、簡単なバリデーション後、受信したトランザクションを内部トランザクション・メモリストレージ(メモリプール)に格納します。メモリプールは、クライアントから受信したトランザクションを保持するメモリ内データ構造であり、新しいブロックを生成するためにノードによってまだ選択されていないものです。トランザクション上の署名のベリファイ後、トランザクションはメモリプールに追加されます。署名のベリフェケーションに失敗した場合、トランザクションはメモリプールには追加されず破棄されます。各ノードは、新しく受け取ったトランザクションとブロックをノード間で共有するためにインベントリ・プロトコルを利用します。インベントリ・プロトコルは、送信されたメッセージが最終的に受領されるのを保証します。 異なるノードのメモリプールは、それらが保持するトランザクションについて一貫している必要はありません。実際、非同期ネットワークのため、不整合は自然なものです。インベントリ・プロトコルは、ノードがメモリプールに存在しない場合に備えて、ノードに必要な特定のトランザクションがあることを確認します。 インベントリ・プロトコルの枠組みは図 2 が示している通りです。

図 2. インベントリ・プロトコルを使用したノード間の Tx 共有

ブロックを生成するために、コンセンサス・ノードの 1 つがメモリプールから一連のトランザクションを取得して実行し、ブロックの「プロポーザル」を作成します。他のノードがコンセンサスのメカニズムによってこのプロポーザルに同意する場合、プロポーザルは受け入れられ、ブロックがネットワークによって追加され、state が更新されます。ネットワークの非同期性により、受信されたトランザクションの順序とブロックに含まれるトランザクションの一貫性は保証されません。 ただし、コミットされたブロック内のトランザクションの順序は、ネットワーク全体で一貫していることが保証されています。期限切れになったトランザクションがあれば、それはメモリプールから除外されます。次のブロックには複数の候補が存在する可能性があり、このメカニズムは miyabi のコンセンサス・レイヤーによって制御されます。 ただし、新しいブロックのコンセンサス・プロセスの最後に、ネットワークは BFK2 コンセンサス・アルゴリズムのファイナリティ保証に従って同じブロックをコミットします。 図 3 が示しているのは BFK2 のスケッチです。

user_manual-consensus_algorithm
図 3. コンセンサス_アルゴリズム

確定したブロックは、インベントリ・プロトコルを介して全ノードへ伝えられます。新しいブロックを受け取ると、そのノードは内部のトランザクション全てを実行します。そしてワールドステート内の、鍵と値に基づいたテーブルを更新します。

それぞれのノードには独自のノード ID があります。これは全ノードが共有する、そのノードの公開鍵です。ノード ID に関連する秘密鍵は PKCS#12 ファイルとして保管されていて、そのパスはノードの設定ファイルに記録されています。それぞれの秘密鍵はノードによってのみアクセスされるべきです。それは、整合性と信頼性を証明するためメッセージへ署名する際に使われます。

アプリケーション・ノードは、コアノードがブロックをブロックチェーンに追加してはじめて、ローカルにブロックを追加します。 コンセンサス・メカニズムとは別に、アプリケーション・ノードはコンセンサス・ノードが実行するすべてのプロトコルを実行します。さらに、アプリケーション・ノードにはメモリプールもあり、クライアントの要求に応答できます。 アプリケーションノードは、コンセンサス作成の複雑性を増すことなく miyabi の性能を向上することができます。アプリケーションノードは通常、図 4 のような遅延を減らすために地理的に最も近いノードへアクセスします。全コンセンサスノードの集まりは、コンセンサスメンバーと呼ばれます。リストからノード ID を追加または削除するトランザクションによって、コンセンサスメンバーを変更することは可能です。従ってアプリケーションノードは、その ID がコンセンサスメンバーへ追加されれば、コンセンサスノードとして機能することができます。

user_manul-consensus_nodes_application_nodesl
図 4. コンセンサスノードとアプリケーションノード

# コンセンサスアルゴリズム: BFK2

BFK2 は miyabi のために設計されたコンセンサスアルゴリズムです。BFK2 は、miyabi のさまざまなニーズや使用事例を念頭に置きながら自社開発されています。パブリック・ブロックチェーンの既存のコンセンサス・アルゴリズムに動機付けされ、そのボトルネックを取り除く一方で、BFK2 は次の属性を実現し ています:

  1. セキュリティ:無効なプロポーザルではコンセンサスに達することができないようにします
  2. ライブネス:最終的にコンセンサスに達することができるようにします
  3. ファイナリティー:達成されたコンセンサスは取り消しまたは修正できません

ビザンチンノード数が全コンセンサスノード数の 未満という条件を満たすとき、BFK2 は上記の特性を保証します。

BFK2 はコミュニケーションに基づいたコンセンサスアルゴリズムです。そのため、最低ネットワークレイテンシーの場合でコンセンサスを得ることができます。また BFK2 は、制限されたビザンチンノードの攻撃を生き残ることもできます。N のノードがコンセンサスに参加しているため、ビザンチン・ノードの数が N/3 未満の場合、アルゴリズムは安全性を保証し、障害のあるノードの総数が N/3 未満の場合、ライブネスを保証します 。クォーラムという用語は、バリデーター・ノードの十分に大きなサブセットを指します。クォーラム間のアグリーメントは、コンセンサス・アルゴリズムの進行について強力な保証を提供します。 miyabi にのノードがあると仮定するなら、次のようになります。

ならば、となります。これは、1 つのブロックを承認するのにコンセンサスノードから 3 つの異なる署名が必要であることを意味します。従っては、BFK2 が BFT になるために必要な条件です。ビザンチンノードが考慮されない場合、BFK2 はクラッシュ障害耐性(CFT)となるようにクォーラムを調整することができます。BFK2 がクラッシュ障害のみを考慮するなら、次のようになります。

この状況では、 は BFK2 が CFT になるために必要な条件です。

# ワールドステートの構造

前述のように、miyabi ブロックチェーンは分散型 state machine を管理します。すべてのノードに共通する miyabi ブロックチェーンの state は(特定の状況により遅延しない限り)、「World State」と呼ばれます。world state の基本的な構造は、一連のテーブルです。テーブルはデータの論理グループを表し、独立した所有権、データタイプ、読み取りおよび書き込みルールを持つことができます。各テーブルは、分離されたバイナリ Key-Value ストアによってサポートされています。

ユーザーはトランザクションによってのみ world state を更新できます。 miyabi はすでに world state を変えるためのいくつかのオペレーションを定義しました。さらに、ユーザーはスマート・コントラクトを使用して、複雑なオペレーションのためにデータを変更するロジックを定義できます。 miyabi はオペレーションチェッカー kotowari を実装しています–Kotowari はインテグリティについて最小署名要件を調べます。 Kotowari の使用は、各テーブルで個別に定義されます。テーブルは、トレーサビリティのためにテーブルのデータを更新するトランザクションをログに記録できる追跡機能もサポートしています。さらに、miyabi は、スマート・コントラクトの簡易チェック用の Roslyn アナライザーを提供します。

ワールドステートのプルーフは提供可能で、これはテーブルあるいはテーブルのデータエントリの存在を検証するためにマークルツリーを使用します。miyabi はワールドステート全体の全マークルツリーを計算し、エントリが存在するプルーフとして特定エントリへのルートを提供することができます。全てのユーザーは、ルートハッシュを入手するためにエントリとプルーフを計算することができます。これは認められている特定ブロックヘッダにあるものと同じになるべきです。

# ブロックの構造

ブロックは、トランザクションとその他関連情報のコレクションです。これらのブロックは相互にリンクされ、変更不可能なブロックチェーンを形成します。 ノードのクォーラムがブロックを含めるコンセンサスに達してはじめて、ブロックはブロックチェーンに含まれます。ブロックは、ブロックチェーン内のブロックの位置である一意の整数、高さで表すこともできます。

各ブロックは、ブロックヘッダ、ブロックボディ、エビデンス(図 5)の 3 つのパーツを含んでいます。 ブロックヘッダーは、前のブロック、現在のブロックのイベント、現在のブロックのトランザクションのマークル・ルート・ハッシュ、およびトランザクション結果に関する情報をカプセル化するデータ構造です。

ブロック・ボディーは、すべてのトランザクションとそれぞれのトランザクション結果に関する情報をカプセル化するデータ構造です。また、ブロックのトランザクションの実行中にトリガーされたイベントに関する情報も含まれています。

ブロック・エビデンスは、コンセンサス・ノードによるブロックの受け入れの証拠を形成するデータ構造です。

user_manual-structure_of_block
図 5. ブロックの構造

ブロックのブロックヘッダーのハッシュは、そのブロックのブロックIDと呼ばれます。各ブロックのヘッダは、その 1 つ前に確定しているブロックの ID を 1 つ含むことになります。そのため確定しているブロックが 1 つ変更されると、そのブロックの ID が変更され、続くブロック全ての ID に影響して検知されます。ブロックチェーンの整合性は、こうして保証されます。ブロックチェーンの構造は、図 6 のように表すことができます。

user_manual-structure_of_blockchain
図 6. ブロックチェーンの構造

# トランザクションの構造

トランザクションには図 7 の構造があります。

user_manual-structure_of_transaction
Figure 7. Transaction Structure

**トランザクションのヘッダ(Transaction Header)**が含むのは、そのトランザクションの生成された時間や期限切れの時間といった、トランザクションのメタデータです。

**トランザクションのエントリ(Transaction Entry)**は、miyabi の実行コマンド用最小単位です。1 つのトランザクションは複数のエントリを持つことができます。

必要資格(Required Credentials)とは必要な公開鍵のことです。トランザクションが実行され関連する許可が求められる時、そのノードは許可された鍵と必要資格を比較しようとします。必要な権限が満たされていない場合、トランザクションは失敗します。

トランザクション用署名(Signature for Transactions)とはトランザクション ID のための署名です。整合性を保証するため、これは必要資格の署名者によって署名されるべきものです。いずれかの署名に間違いがあれば、トランザクションは拒否されます。

それぞれのトランザクションでフォーマットが検証されます。フォーマットの検証を合格しなければ、それは有効なトランザクションとして認識されません。フォーマット検証が含むのは次の事柄です:

  1. トランザクション用署名の順序が必要資格にある関連鍵の順序と同じである。
  2. 使用されている暗号化アルゴリズムに従ってトランザクションの必要資格の公開鍵とトランザクション用署名が一致する。

# トランザクションの実行

miyabi の全ノードは、ブロック内の順序に従ってトランザクションを実行します。トランザクションが複数のエントリを含む場合、トランザクション内の順序に従ってそれらは実行されます。よって、ブロック内の全てのエントリは同じ順序で実行されます。

エントリの実行とは、miyabi の最新のワールドステートを読み書きするため、特定ルールに従ってそのエントリが非直列化され実行されるという意味です。エントリが失敗するとトランザクション全体が失敗し、ワールドステートへの全ての変更が巻き戻されます。ワールドステートを更新できるのは、全てのエントリが成功したトランザクションのみです。次のテーブルは、トランザクションを実行した場合にもたらされ得るステータスを表しています。

コード ステータス 説明
-1 Pending トランザクションは未実行
0 Success トランザクションは正常に完了し、state の変化はブロックに包含後に反映されます
1 NegativeBalance (Asset固有)マイナス残高ルールに違反しました
2 ConservationBreak (Asset固有)総資産価値保全ルール違反
3 Failed トランザクションは不特定の理由で失敗しました
4 Canceled トランザクションがキャンセルされました
5 SignatureInvalid 署名が有効でないか、必要な資格情報と一致しなかったため、トランザクションは受け付けられませんでした
6 InvalidCredentials 資格情報がこのオペレーションには無効です
7 InvalidOperation トランザクション実行中に無効なオペレーションが行われました
9 Duplicate 重複したトランザクションがすでにメモリプールまたはコミットされたブロックにありました
10 Corrupted トランザクションのフォーマットが間違っています
11 InvalidLifetime トランザクションのライフタイムが無効です。
12 NoVacancy メモリプールが満タンです。
13 TimedOut (コントラクト) 実行のタイムアウト

# アクセス制御モデル

miyabi のアクセス制御モデルは、非対称暗号をベースにしています。アクセス制御が必要なワールドステートといくつかのテーブルは、許可を要する各オペレーションのために公開鍵のリストを維持しています。それらオペレーションの 1 つがエントリでトリガーされると、そのノードはトランザクションの「必要資格」がアクセス制御モデルのリストにある公開鍵を含んでいるかどうか確認します。この関係は図 8 が表す通りです。

トランザクションの他に、miyabi は特定のスマートコントラクトへの許可の付与もサポートします。その場合、スマートコントラクトの実施のみがテーブルを変更することができます。

user_manual-access_control_model
図 8. アクセス制御モデル

# 実行されたトランザクション

トランザクションが実行されると、検索のために保存されます。各ノードは最近実行されたトランザクションのキャッシュを維持し、その他のトランザクションはローカルのストレージ内でシリアルナンバーを付けられて保管されます。メモリプールから除外されていなければ、全てのトランザクションの ID は保管されます。同じトランザクションが 2 度送られると、トランザクションフィルターがそれを検知して同一トランザクションが再び実行されるのを防ぎます。効率性を高めるため、このフィルターは固定期間内に実行されたトランザクションのみを保管します。トランザクションのライフタイムが固定期間よりも長い場合、そのトランザクションは無効なライフタイムによって直接拒否されます。

# 電子署名

電子署名は非対称暗号のアプリケーションです。電子署名サービスは次の機能をサポートすべきです:

  1. 鍵ペアを作成
  2. 秘密鍵によってプレーンテキストの署名を作成
  3. 公開鍵によって署名を検証

電子署名サービスの作業の流れは図 9 の通りです。

user_manual-digital_signature
図 9. 電子署名

# 理(ことわり)

理とは、トランザクションの有効性を検証するために設計された規則一式です。理は、定義されたアセットテーブルの変更が引き起こされる度にそれらへ自動的に適用されます。理は、署名が有効な許可を持っているかどうかを確認します。そして、マイナスのアカウントがないかなどアセットテーブルの整合性を確認します。バランスの変更はゼロになるべきです。同様に、スマートコントラクトによるスマートコントラクトのオペレーションも理による確認作業を誘発します。よってスマートコントラクトがこの問題を忘れたとしても、ワールドステートが損なわれることはありません。

# miyabi へのアクセス

前述のように、全ての miyabi ノードは一般へのウェブ API サービスを提供します。これはノード間のコミュニケーションに使われるポートとは異なります。クライアントは通常ウェブ API を直接使用せず、クライアントの SDK を通してノードにアクセスします。クライアントの SDK はウェブ API の設定をラップしており、ユーザー志向の機能サービスを提供します。クライアント SDK を使用することにより、クライアントはノードからの情報取得、署名作成、トランザクション作成、トランザクション送信を簡単に行うことができます。

miyabi は、CLI サービスを提供するためにクライアント SDK をラップしている CLI プログラムも提供します。その依存関係は図 10 の通りです。

access_of_miaybi
図 10. miyabi のアクセス