出展
Technical Reference Contents
- Introduction
- System
- Cryptography
- Trees
- Accounts and Addresses
- Transactions
- Blocks
- Blockchain
- Disruptor
- Unconfirmed Transactions
- Partial Transactions
- Network
- Reputation
- Consensus
- Finalization
- Time Synchronization
- Messaging
1. Introduction
- Symbolに影響を与えた基本原理
- トラストレス
- 高性能
- 階層構造
- ブロックチェーンベースのDLTプロトコル
- いくつかのDLTプロトコルも検討したがブロックチェーンのプロトコルの方がよりリアルなトラストレス性を持つものとして選択された
- どのノードもチェーンの完全なコピーをダウンロードして、いつでも独立して検証できる
- 十分なハーベスト能力を持つノードならりーどーなしに常にブロックを作ることができる
- Symbolは確率的なブロックファイナライズと決定論的なブロックファイナライズの両方をサポートしている
- 決定論的ファイナライズでは、プロトコルに決してロールバックできないチェックポイントを設定できるメカニズムが含まれている。これにより深いロールバックが発生する可能性があるが、より強力な保証が得られる
- トラストレスを重視する一環として、NEMから以下の様な機能が追加された
- ブロックヘッダ: トランザクションデータなしで同期でき、チェーンの整合性を検証できる
- トランザクションマークルツリーはブロックにトランザクションが含まれているかを暗号学的に証明できる
- レシートは、間接的に引き起こされる状態変化の透明性を高める
- 状態証明は、ブロックチェーン内の特定状態をトラストレスな形で検証することができる
- Symbolでは単一のサーバ実行ファイルがあり、様々なプラグインや拡張機能を使ってカスタマイズできる
- ネットワーク毎に3つの基本構成があるが、特定の拡張機能を有効または無効にすることで、さらにカスタマイズされたハイブリッドな構成が可能
- 3つの基本構成
- Peer: ネットワークのバックボーンとブロック生成を担うノード
- API: データをMongDBに保存してクエリを容易にし、Node.jsのRESTサーバと組み合わせて使用できるノード
- Dual: PeerとAPIの両方の役割を担うノード
- 強固なネットワークは多くのピアノードと十分な数のAPIノードをもち、クライアントからのリクエストに応えることがきる。
- コアブロックとトランザクションパイプラインをディスラプターパターンに基づいて構築し、可能な限り並列処理を行うことで、一般的なブロックチェーンと比較して、1秒あたりのトランザクション数を増やすことができる。
1.1 Network Fingerprint
- 各ネットワークには、以下の様な固有のフィンガープリントがある
- Network Identifire - ネットワーク間で共有可能な1バイトの識別子。ネットワークに対応する全てのアドレスは、この値を最初のバイトとして持つ必要がある(※1)
- Generation Hash Seed - ネットワーク上でグローバルに一意でなければならない32バイトのランダムな値。この値はハッシュ化や署名の前にトランザクションデータに付加され、リプレイ攻撃を防ぐ(※2)
※1: アドレスはメインネットではN
から始まり、テストネットではT
から始まる
※2:
- メインネット:
57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6
- テストネット:
7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836
2. System
- Symbolではネットワークレベルと個々のノードレベル両方で高いカスタマイズ性をサポートしている
- ネットワーク全体の設定はネットワークで指定され、ネットワーク内全てで同じでないといけない
- ノード固有の設定はノードごとに設定することが可能
- Symbolはチューリング完全なスマートコントラクトをサポートせず、プラグイン/拡張アプローチを使用するように設計している
- スマートコントラクトは柔軟性を高めることができるが、エラーが発生しやすくなる
- プラグインモデルはブロックチェーン上で実行できる操作を限定しているので、結果的に攻撃対象が小さくなる。無限にある演算セットより、離散的な演算セットの方がシンプルにパフォーマンスを最適化できる。
2.1 Transaction plugins
- ネットワークを形成する全てのノードは、同じトランザクションとプロセスを正確にサポートしなければならない。それによって、ブロックチェーンの状態が全てのノードで共有できる。
- ネットワークがサポートするトランザクションの形式はトランザクションプラグインで定義され、全てのノードでによってロードされる。
- プラグインセットに対する全ての変更、追加、削除は全てのネットワークノード間で同期される必要がある。ネットワークノードの一部だけが変更を受け入れた場合は、そのグループだけがフォークした状態になる。
- プラグインは動的にリンクされた独立のライブラリで下記の様なエントリーポイントを持つ
extern "C" PLUGIN_API
void RegisterSubsystem(
catapult::plugins::PluginManager& manager);
);
- PluginManagerは、configurationに含まれているパラメータにアクセスし、プラアグインを初期化する。このPluginManagerクラスを通して、後述のリストの中から必要なものを登録する。
- Transaction
- Caches
- Handlers
- Diagostics
- Validators
- Observers
- Resolvers
2.2 Symbol Extensions
- コンセンサスに影響を与えない範囲のオプション機能を提供する
- ノード毎に提供する機能を設定できる
- 拡張機能は、それぞれ独立した動的にリンクしたライブラリで下記の様なエントリポイントを持つ
extern "C" PLUGIN_API
void RegisterExtenstion(
catapult::extensions::ProcessBootstrap& bootstrap);
- プラグラインとして提供できるものは以下の通り
- Service - 診断用のカウンターを追加したり、APIを定義したり、タスクスケジューラにタスクを追加したりできる
- Subscription - ブロックチェーンイベントを購読することができる。ブロックや未承認トランザクションなどの変更を検知することができる
2.3 Server
Symbolの最も単純な構成は、シングルサーバーである。ネットワークに必要なトランザクションプラグインと、ノード運用者によって選択されたSymbol拡張機能がロードされ、サーバを初期化する。
Symbolはdataディレクトリに全ての情報を保存する。
保存される情報は以下のものがある
- Block Versioned Directories - ブロック情報、ブロックに含まれているトランザクションなど
- audit - 監査ファイル
- importance - 重要アカウントの情報を含むバージョンファイル
- logs - ログファイル
- spool - サブスクリプション通知が書き込まれる。サーバーからブローカーへ送り出すキューとして利用される
- state - 要約されたデータやキャッシュデータなど独自のストレージファイルを格納している
- statedb - RocksDBファイルが保存される
- transfer_message - ノードの委任ハーベストのリクエスト情報が保存される
- commit_step.dat - コミットプロセスの最新のステップを保存する。主にリカバリ用。
- index.dat - ディスクに保存されているブロック数のカウンター
- proof.index.data - ディスクに保存されているファイナライズ証明の数のカウンター
- voting_status.dat- ノードが最後に送信したファイナライズのメッセージを格納
2.3.1 Cache Database
- RocksDBにキャッシュデータが保存される
- 検証可能な状態にするのに必要
- 例) ハーベスト可能な高価値アカウントのリストが保存されている
2.4 Broker
- ブローカープロセスは、並列性を犠牲にすることなく、より複雑なSymbolの動作を追加することができる。
- ブローカーはサブスクライバを登録し、それらのサブスクライバに転送されるイベントに反応することを目的としている。
- ブローカーはspoolディレクトにの変更を監視して、イベント通知をサブスクライバに転送する
- brokerからDBに通知を送り、それによってDB拡張が最新の状態を反映するなどに使われる。
- spoolディレクトリは一方通行のメッセージキューとして機能する。サーバがメッセージを書き込み、ブローカーが読み込む。逆は行わない。これはパフォーマンスを低下させないために行われている。
2.5 Recovery
- リカバリのプロセスがどのように行われているか記載されている(省略)
2.6 Common Topologies
- SymbolのほとんどのノードはPeer、API、Dualの3つのカテゴリに分類される。これらは同じサーバープロセスが使われる。唯一の違いはどのエクステンションをロードするかの違いだけである。
- Peerノード: 軽量ノード。他のノードと同期して新しいブロックをハーベストするのみの最低限の役割のみを持っている
- APIノード: 他のノード同期はするが、新しいブロックの生成は行わない。複数署名を必要とするアグリゲートトランザクションの処理をすることができ、これを完了させるための署名を集めることができる。MongoDbにデータを記録する。そのためにブローカープロセスを必要とする。遅延を最小限にするためREST APIも含まれている。
- Dualノード: PeerノードとAPIノードを組み合わせたもの
3. Cryptography
- Symbolでは楕円曲線暗号(ECC)に基づく暗号を使用している。
- SymbolではEd25519デジタル署名アルゴリズムを使用している
- Symbolでは、このアルゴリズムが64バイトの短い署名を生成して、高速な署名検証をサポートしている点が重要である。
3.1 Public/Private Key Pair
- Ed25519に基づく秘密鍵から公開鍵の導出方法を説明(省略)
3.2 Signing and Verification
- Ed25519に基づく署名とその検証方法を説明(省略)
3.2.1 Batch Verification
- 大量の署名を処理する場合は、バッチ検証を用いて、検証の高速化を図っている
- バッチ検証でその式が成り立たない場合、個々の署名を検証して不正を見つけ出すようにしている。
3.3 Verifiable Random Function
- 検証可能な乱数関数(VRF)は公開鍵と秘密鍵のペアを用いて疑似乱数値を生成する。
- 秘密鍵の所有者だけが予測されない値を生成できる。
- 公開鍵によってその値が関連付けられた秘密鍵によって生成されたものかを検証することが可能。
- SymbolではECVRF-EDWARDS25519-SHA512-TAIを使用している
補足
- 委任ハーベストのセキュリティ強化に使われている
3.4 Voting Key List
- ファイナライゼーションに参加する投票者(ノード)は、ルート投票キー(投票用のkeyを作るための鍵)が投票できるエポック(フファイナライズの単位)の範囲を指定する必要がある。
- ルート投票キーをアナウンスする前に、投票者は投票キーのリストを作成する必要がある。
- リストの構成は簡略化されたBellare-Miner[BM99]の構成にほぼ基づいている。
- このリストの各キーは1つのエポックに結びついており、最終処理が次のエポックに進むと消去される。
- これによりある程度の前方秘匿性が確保される。攻撃者が投票キーのリストを入手しても、完了したエポックを修正したり、否認したりすることはできない
- 投票キーのリンク用のトランザクションを投げる前に投票キーのリストを作成し、全てのキーを作成したらルート投票キーを破棄する。
4. Trees
- Symbolでは、トラストレスな軽量クライアントのために、ツリー構造を利用している。
- マークルツリーを使えば、クライアントノードは暗号化された情報の中に、あるデータが含まれているかどうか確認できる。
- パトリシアツリーは、あるデータが含まれているのか含まれていないのかを確認できる。
5. Accounts and Addresses
- Symbolは、トランザクションの機密性、真正性、責任遂行性を保証するために、楕円曲線暗号を用いる。
- アカウントは、アドレスによって一意に定義され、その大部分は署名にも使用される公開鍵から生成する(逆変換はできない)
- それぞれのアカウントは、ネットワークによってトランザクションが承認されたときに発生する状態変更とリンクしている。
- この状態変更はネットワーク全体で共有されるが、ひとつまたは複数の公開鍵を含んでいる場合と、公開鍵を持たない場合がある。
5.1 Address
- デコード済みのアドレスは、24バイトの長さをもつ値であり、以下の3つのパートから構成される
- ネットワークバイト
- メインネット(N)、テストネット(T)
- 署名用公開鍵の160bitハッシュ
- 3バイトのチェックサム
- ネットワークバイト
5.1.1 Address Derivation
- 公開鍵を256bitのSHA3にて変換する
- さらに、160-bit RIPEMED_160方式によってハッシュ化する
- ネットワークバージョン(1バイト)をRIPMED_160ハッシュの前に付け加える
- 結果を256-bit SHA3によってハッシュ化し、最初の3バイトをチェックサムとして取り出し
- ステップ3とステップ4によって得られたチェックサムを結合する
- 得られた結果をBase32によってエンコードする
5.1.2 Address Alias
- アドレスは、1つ以上のエイリアスを持つことができる。
- ドメインみたいなもの ex) daoka -
TCLQE7-OW6ZDL-DES2WV-5ORL23-B74OO4-PQCFUK-GZA
- ドメインみたいなもの ex) daoka -
- アドレスと関連のある全てのトランザクションは、公開鍵から作られたアドレスとアドレスエイリアスの両方をサポートする。
5.1.3 Intentional Address Collision
- 2つの異なる署名用公開鍵が、同一のアドレスを生成してしまう可能性はあり得る。
- そのようなアドレスに価値のあるアセットが保有されていてかつ、他の公開鍵に紐付けられていなかった場合のみ、攻撃者はそのアカウントからアセットを引き出す事ができる。
- しかし、そのような攻撃をするには攻撃者は秘密鍵と公開鍵の組み合わせを以下の条件で見つけなければならない
- 公開鍵のSHA3-256のハッシュが同時にrepemd-160が生成する160ビットのハッシュでも同一のものを生成するようにしないといけない。
- SHA3-256のハッシュ化は128ビットの長さのセキュリティを持つため、SHA3-256の衝突が見つかることは数学上まずありえない
- Symbolのアドレスとビットコインのアドレス生成方法の類似性より、このようなSymbolアドレスの衝突の可能性は、ビットコインのそれち同等と考えられる。
6. Transactions
- トランザクションはグローバルチェーンの状態を変更する命令である。
- それらはアトミック(分割不能単位)として処理され、そを集積したものがブロックに書き込まれる。
- トランザクションの一部でも処理に失敗した場合、チェーンの状態はトランザクション試行前の状態にリセットされる。
- ベーシックトランザクションは単一の操作を表し、単一の署名が必要になる。
- アグリゲートトランザクションはベーシックトランザクションを複雑に組み合わせることができ、アトミックに実行できる。
- 個々の操作のアトミック性のみを保証するシステムと比較して、柔軟性が高い。
- 開発者は新しい言語を学ぶ必要もなくカスタムメイドなコントラクトの実装をゼロからする必要なく、バグの発生も少ないはずである。
6.1 Basic Transaction
- ベーシックトランザクションは暗号技術的に検証可能なデータと検証不可能なデータの両方で構成される
- 検証可能なデータは全て連続した一塊になっており、トランザクション署名者によって署名される。
- 検証不可能なデータは無視されるか、検証可能なデータから確定的に計算可能である。
- 検証不可能なヘッダフィールドは以下のものを含む
- Size - トランザクションのバイト数
- Signature - 署名
- SignerPublicKey - 署名者の公開鍵
- Reserved - パディング
- すべてのトランザクションタイプのバイナリレイアウトはSymbolのオープンソーススキーマ言語で指定されている
6.2 Aggregate Transaction
- アグリゲートトランザクションはベーシックトランザクションと同じ「検証不可能なヘッダ」を持ち、この部分は同じように処理される
- アグリゲートトランザクションにはフッターにも検証不可能なデータが存在し、埋め込みトランザクションと共同署名が連なる形になっている。
- アグリゲートトランザクションは、必要とされる全ての共同署名と一緒にネットワークに投入することもできる。その場合は、「完了」したと判断され、特別な工程なしに他のトランザクションと同様に処理される。
- Aggregate Complete Transaction
- APIノードは、完全ではない共同署名がなされた、債権付きアグリゲートトランザクションを受け入れることもできる。
- トランザクションの発行者は、期限が切れる前に全ての共同署名が集められた場合のみ返金される債権を発行しなければならない。これによりAPIノードは共同署名を集める作業を行う。作業は必要な数の署名が集まるか、期限切れになるまで行われる。
- TransactionHashはアグリゲートトランザクションの最も重要なフィールドである。これは、アグリゲートトランザクションに埋め込まれた全てのトランザクションハッシュのマークルルートハッシュとなる。埋め込まれた複数のトランザクションは自然な順番でソートされ、マークルツリーが作られる。その結果がルートハッシュとなり、TransactionHashとして検証可能なデータの一部として組み込まれる。
6.2.1 Embedded Transaction
- 埋め込みトランザクションは、アグリゲートトランザクションの中に内包されるトランザクションのことである。
- ベーシックトランザクションと比較した場合、ヘッダは少し小さいがトランザクションに関連するデータとしては同じものが含まれる。
- 共同署名のデータが別の場所にまとめて置かれるため、署名がなく、MaxFeeとDeadlineも上位のアグリゲートトランザクションに記述されるため省略される。
6.2.2 Cosignature
- 共同署名は、バージョンと、公開鍵とそれに対応する署名のペアで構成される。
- 共同署名はアグリゲートトランザクションの最後に追加されていく。
- 共同署名は複数の当事者が関与するアグリゲートトランザクションを暗号学的に検証するために使用する
- 他のトランザクションと同様、アグリゲートトランザクションはまずベーシックトランザクションとしての検証を受ける
- 次に全ての共同署名が、署名検証を受ける。
- 共同署名者はアグリゲートトランザクションのデータに対してでなく、アグリゲートトランザクションデータのハッシュに対して署名検証を行えばよい。
6.3 Transaction Hashes
- 各トランザクションには、エンティティハッシュとマークルコンポネントハッシュの2つの関連するハッシュがある。
- エンティティハッシュは取引を一意に識別するもので、同じ取引の複数回の確認を防ぐために使用される。
- マークルコンポネントハッシュはトランザクションハッシュを計算するときに使う。
- トランザクションのエンティティハッシュは次のハッシュとして計算される
- transaction Signature
- Transaction Signer Public key
- Network Generation Hash Seed
- Transaction vetifiable data
- 確認されたすべてのトランザクションは一意のエンティティハッシュが必要
- アグリゲートトランザクションのエンティティは連署とは独立している
- これにより、同一のアグリゲートトランザクションが異なる有効な連署で複数回確認されるのを防ぐ
- 通常取引のマークルコンポネントハッシュは、そのエンティティハッシュと同一である。
- アグリゲートトランザクションのマークルコンポネントハッシュはそのエンティティハッシュに、その連署の全ての公開鍵を連結したものをハッシュとして計算する。
- これによりトランザクションハッシュには、アグリゲートトランザクションの確認を許可した全ての連署が反映される
7. Blocks
- ブロック内のレイアウトはアグリゲートトランザクションと似ている
- アグリゲートトランザクションと同様に検証不可能なヘッダをもち、それを使って検証作業をするようになっている
- ブロックヘッダの後ろには検証不可能なフッタとトランザクションデータが続いていく
- ベーシックトランザクションが連続しているところがアグリゲートトランザクションと違う部分
7.1 Block Fields
- Height - ブロックの連番
- Timestamp - ジェネシスブロックからの経過時間
- Difficulty - ブロック難度
- GenerationHashProof - ブロックハーベスターのVRF秘密鍵によって作られたVRF証明。次のハーベスターを予測不可能にするのに使われる
- PreviousBlockHash - 1つ前のブロックハッシュ値
- TransactionHash - ブロックに含まれるトランザクションの個々のハッシュ値から作ったマークルルートハッシュ
- ReceiptHash - ブロックを処理する際に生成されるレシートのハッシュ値から作ったマークルルートハッシュ
- StateHash - ブロックを処理した後のブロックチェーンの状態をハッシュ化したもの
- BeneficiaryAddress - ブロック報酬の一部を受益する権利をもつ受益者のアカウント。ブロックをハーベストしたノードの所有者によって記入される
- FeeMultiplier - 手数料倍率
7.1.1 Importance Block Fields
- 重要度計算の行われるブロックには検証可能な追加情報を含む拡張フッタがある。
- VotingEligibleAccountsCount - 次の重要度グループを対象とするファイナライズエポックにおいて投票権を持つアカウント数
- HarvestingEligibleAccountsCount - ハーベスト可能な残高以上の残高をもつアカウントの数。これは不適格アカウントの数が除外されていないため、実際にハーベスト可能なアカウント数はこれよりは少なくなる
- TotalVotingBalance - 次の重要度グループを対象とするファイナライズエポックにおいて投票権をもつ全てのアカウントの残高の合計
- PreviousImportanceBlockHash - 前の重要ブロックのハッシュ
7.2 Receipts
- ブロックを実行する間に、0個またはそれ以上のレシートが発行される。
- レシートはクライアントへの何らかの働きかけがきっかけとなって起きる、状態遷移についての情報であり、状態遷移という複雑なフロックチェーン内の変化をクライアントが簡単に知ることができるためにある。
- 例) ネームスペースの期限切れ情報や、ハーベスト報酬の額を知ることができる
- トランザクションが走らない状態遷移を記録するものと理解するとよい
- レシートは3つのタイプに分類される。
- トランザクション
- アドレス解決
- モザイク解決
7.2.1 Receipt Source
- 処理されるブロックの各部分には、2つの部分からなるブロックスコープのIDが割り当てられる
7.2.2 Transaction Statement
トランザクション明細書は、発行元が同じレシートを束ねて作られる。それぞれの明細にはレシート発行元と、一つ以上のレシートが記述されている。その結果、それぞれの発行元毎に、レシートを発行した場合には、必ず対応するトランザクション明細書を作ることになる。
7.2.3 Resolution Statements
- Resolution Statementsはエイリアス(ネームスペースとの関連)の解決結果を調査するのに使える。
- 一つのブロックの中でエイリアスの参照先を変更してもクライアントがそれを解決できるようになる。
- Statementは2種類あり、モザイクとアドレスを参照する2タイプのエイリアスに対応する
7.2.4 Receipts Hash
- ブロックのレシートハッシュを計算するために、ブロックに含まれる全ての明細書が集められる。そして全ての明細書のハッシュからマークル木が構成される。
- クライアントは、ある明細(のハッシュ)が、特定のブロック内で生成されたかどうかを確かめるためには、マークル検証すればよい。
7.3 State Hash
- Symbolは、ブロックチェーン全体の状態は複数タイプの状態保持リポジトリに保管している。
- ex) アカウント状態、マルチシグ状態...
- リポジトリ毎にパトリシアツリーが作られ、1つのハッシュにまとめられ、ハッシュはそれぞれにリポジトリの状態の指紋のようなものになる。
- N個のリポジトリとそれに対応するN個のハッシュがネットワーク全体の指紋として扱われるが、これを全てブロックヘッダに格納するのはあまり好ましくない
- そのため全てのリポジトリハッシュは結合され、そのハッシュが状態ハッシュとして計算される。
7.5 Block Hashes
- 各ブロックには1つの関連づけられたハッシュ(エンティティハッシュ)があり、このハッシュによってブロックを一意に識別し、同じブロックが複数回処理されるのを防ぐ
- ブロックのエンティティハッシュは次のハッシュとして計算される
- Block Signature
- Block SignerPublicKey
- Block (header) verifiable data
8. Blockchain
8.1 Block Difficulty
- ジェネシスブロックは、ブロック難度の初期値として10^14と言う値をもつ。その後のブロック難度は10^13〜10^15の間に制限される
- 新しいブロックのブロック難度は、直近に承認された複数のブロックの難度と時刻によって決められる。
- 上記式により、目標とするブロック生成時間にブロック生成時間に近づくようになっている
- 新しいブロック難度が5%以上変化する場合は、5%の変化に制限される
- セルフィッシュハーベスティングを防いでいる
8.2 Block Score
ブロックのスコアはブロック難度と1つ前のブロックが生成されてから、そのブロック生成までにかかった時間(秒)から計算される
8.3 Block Generation
- 新しいブロックを生成することをハーベストと呼ぶ。
- ハーベストするアカウントはそのブロックに含まれているトランザクション手数料を得ることができる。
- アカウントは、以下の条件を全て満たしたときに、ハーベストする権利を与えられる
- 直近にインポータンス計算されたブロック高におけるインポータンススコアがゼロでないこと
- ネットワークによって設定されている最低ハーベスト残高を上回る残高があること
- ネットワークによって設定されている最大ハーベスト残高より下回る残高であること
- VRF公開鍵が設定されていること
- アカウント所持者は残高をもつアカウントの秘密鍵を外部に保持されないために、他のアカウントにインポータンスを委譲することができる。
- ハーベストアカウントが得る手数料は、ネットワークの設定によって決められる。
- インフレーションの設定があれば、ブロック生成に対してインフレーションブロック報酬が上積みされる
- ハーベスト報酬の分配が設定されている場合は、ノードを運用しているアカウントによって報酬の一部が回収される
- それぞれのブロックには手数料倍率が設定される。
- これによって、ブロックに含まれる全てのトランザクションによって支払われる手数料が決定される
- ノード所有者は最低手数料倍率を設定することができ、その料率はそのノードによってハーベストされる全てのブロックに適用される。
- 下記の式を満たすトランザクションだけが、ノードがハーベストするときにブロックに書き込まれる
- ノードは3種類の設定の中からどのようなトランザクションを選択するかの戦略を決めることができる
- oldest - 古いトランザクションから取り込まれる。最もパフォーマンスがよい戦略
- maximize-fee - ひとつのブロックに含まれるトランザクション手数料の合計が最大になる設定
- minimize-fee - 最も少ない最大手数料を設定されたトランザクションを優先する。理論的には手数料無料のトランザクションも取り込むことができる。
- ネームスペースやモザイクのレンタル手数料は、一定するのブロック数までの範囲の手数料倍率の中央値に連動するようになっている
8.4 Block Generation Hash
- ブロックのジェネレーションハッシュは、前のブロックのジェネレーションハッシュとブロックに書き込まれたVRF証明から、新しいハッシュを生成する
- ジェネレーションハッシュを、VRFによってランダムで予測不可能な値にできる。
- これにより、次のジェネレーションハッシュをそのジェネレーションハッシュから予測不可能にすることで、次のハーベストアカウントを予測できないようにできる
8.5 Block Hit and Target
- そのアカウントが、ある時刻(t)にハーベストをする権利を持つかどうかの判定は、以下の2つの数値を比較する
- hit: ブロック毎の目標値
- target: ハーベストアカウント毎に設定される力量。前のブロック生成から経過した時間と共に増大する
- hit < targetになった時にそのアカウントはブロックを生成できるようになる。
- target値は時間と共に増大するので、いつかはブロックが生成さえっる
- targetの計算方法
- hitの計算式 gh...はアカウント毎のジェネレーションハッシュ値
簡略化して
- hit地は指数関数的な分布をしている。よって、インポータンスを多くのアカウントに分散しても新しいブロック生成にかかる影響はない
8.6 Automatic Delegated Harvester Detection
- 委任ハーベストのリクエスト時に委任先ノードに送られるメッセージのフォーマット
- ノードは設定した数まで委任アカウントを受け入れ可能
- ポリシーは先着順かインポータンス順で決めることができる
- 委任ハーベスターの情報はharvesters.datと言うファイルに記録され、一度許可をうけたアカウントの情報はサーバを再起動しても消えない
8.7 Block Synchronization
- ブロックチェーンの同期は、分散型のコンセンサスを維持する上で最も重要で、ローカルノードは定期的に他のノードにチェーンについて問い合わせをする。
- 問い合わせ先のノードが自分より高いスコアのチェーンを提示したときは、ローカルノードは自分の持つチェーンのハッシュと比較することによって、直近の共通ブロックを見つけ出す。そのようなブロックが見つかった場合には、設定が許す範囲で問い合わせ先のノードからできる限り多くのブロックを取り寄せる
もし、取り寄せたブロックチェーンが有効なものであれば、ローカルノードは自分のチェーンをそれと置き換え、無効なものであれば、それを拒絶しそのノードが失敗しているとみなす
14. Consensus
- Symbolはトークンフォルダーよりもトークンユーザを尊重する改良型PoSアルゴリズムを使う
- より多くの資産を持つアカウントの方が、多くのトランザクションを生み出し、より多くのノードを動かしていればゲームを有利に進められて、その結果報酬も多くなる。
- 重要度はnetwork:importanceGrouping設定のブロック数ごとに再計算される。
- トランザクションやノードスコアによるインポータンスの上昇は一時的でnetwork:importanceGroupingで定められたブロック数の5倍のブロックが生成される間までである
14.1 Weighting Algorithm
- 最低ハーベスト残高以上の残高を持つアカウントはインポータンス計算に参加する高価値アカウントと呼ばれる。
- 高価値アカウントであることはブロック生成に関与できるアカウントの必須要件である。
- アカウントのインポータンススコアは、3つの要素に分解される。ステーク、トランザクション、ノード
- アカウントAのステークスコア(SA)は高価値アカウント全体が保有する通貨量に対するアカウントAが持つ通貨量の割合。BAをアカウントAが保有する通貨量とするとアカウントAのステークスコアは次のようになる
- トランザクションスコア(TA)は、一定期間内に、高価値アカウント全体が支払った手数料に対する、アカウントAが支払った手数料が占める割合である。FeesPaid(A)をAが期間Pの間に支払った手数料とすると、TAは以下の式で表される
- ノードスコア(NA)はアカウントAが、一定期間Pに受益者となった回数の、高価値アカウント全体が受益者となった総回数に対する割合である。BeneficiaryCount(A)を、Aが受益者となった回数とすると、NAは以下の様になる
- トランザクションスコアとノードスコアをアクティビティスコアと呼ぶ
- この中でトランザクションスコアは80%の重み付け、ノードスコアは20%の重み付けがされる
- アクティビティスコアはアカウントの残高(ステーク)によって、貢献度が変化する。ステークが大きくなるほどアクティビティの寄与度は小さくなる。
- これによって、残高が少ないアカウントでも残高が多いアカウントに対抗できるようになり、多少なりともPoSが持つ富めるものがさらに富むと言う法則を多少なりとも緩和できる。
- アクティビティスコアは直近のインポータンス計算においてこうか値であったアカウントのみで計算される。
- インポータンスの再計算までは新しいデータは作業ボックス(working bucket)に入れられる。インポータンス計算が更新される度にシフトし、古いものから取り除かれ、新しいボックスが作られ、最大でも5回のインポータンス計算でしか用いられない
- そのためアクティビティスコアは速やかに更新される
- network:totalChainImportance はネットワークに存在する全てのアカウントに分配されたインポータンススコアの総量となる。
- あるアカウントAのインポータンスI'Aは以下の様に計算される
最終的なインポータンススコアIAは一つ前のI'Aと新しいI'Aのどちらか小さい方が選ばれる。これはステーク分割攻撃への対策である。
14.2 Sybil Attack
- シビル攻撃とは、攻撃者が複数のIDを持ち、桁外れな大きさの影響力を与えたり、何らかの利益を得ようとする行為。
- Symbolにおいてはインポータンスを不正に上げようとする試みが該当する
- インポータンススコアの各項目(ステーク、トランザクション、ノード)はそのような攻撃に対する抵抗力を持つ必要がある。
- アクティビティスコアの底上げ率は、ステークによって減少するため、アカウントの残高を複数のアカウントに分散することで、平均の減少率を小さくできる。アカウント分割の前後で、トランザクションなどの活動量が変化しないと仮定すると、分割によって合計のインポータンスは高くなる。
- この効果は既に織り込み済みで、善意の行動を引き出すためである。
- なぜならインポータンスを底上げするにはトランザクションのなどの活動が必須だから。
- トランザクションスコアがキープされることは、複数のアカウントからトランザクションを生成して、手数料を支払おうとするモチベーションに繋がる
- ノードスコアがキープされることはさらに多くのノードを立ち上げてネットワークを拡大するモチベーションに繋がる
14.3 Nothing at Stake Attack
- PoSコンセンサスアルゴリズムに共通する脆弱性。ブロック生成コストが非常に小さい場合に起こりえる。攻撃パターンは2種類ある。
- 1つは攻撃者を除く全てのハーベスターが、全てのフォークしたチェーンでハーベストを行う場合である。
- フォークしたチェーンが2本だと仮定すると、攻撃者が一方のチェーンで支払いを実行し、もう一方のフォークチェーンでハーベストを開始する。攻撃者が十分な量のインポータンスを持っていれば、攻撃者が支払いをしたフォークチェーンよりもインポータンスを使ってハーベストしたフォークチェーンの方が優位となり、より高いチェーンスコアを獲得する。(ここでは、攻撃者が一人であるか、全ての攻撃者が結託して、支払いが行われたチェーンでハーベストを中止すると仮定する)その結果、攻撃者の支払いは、メインチェーンには書き込まれず、攻撃者に差し戻される。
- Symbolにはこの攻撃に対して3つの防衛策がある
- 1つ目は、攻撃者が優位になるようなフォークチェーンを作り出すのに、限られた時間、network:maxRollbackBlocksしか与えられていないことである。
- 2つ目は、nothing stake攻撃を成功させるにはかなりの量のインポータンスを持っていないといけない。
- 3つ目はこの攻撃が成功した場合、通貨の価値が下がるということである。攻撃者以外のハーベスターが全てのフォークチェーンでハーベストすることがこの攻撃では必要だが、利益を最大化したいハーベスター達は一本のチェーンでハーベストを行うとするだろう。その結果、攻撃者の目的は達成しない
- もう一つの攻撃パターンは、一人の攻撃者が全てのフォークチェーンでハーベストし、どのチェーンがメインになろうとも全ての手数料を獲得しようとする場合である。攻撃者はジェネシスブロックの次のブロックから始まる全てのフォークチェーンでハーベストすることが可能である。そして、最も多くの手数料が獲得できるチェーンを探す。ブロックの承認は確率的に行われるため、理論的には攻撃者は全てのブロックをハーベストするような「完璧な」チェーンを作り出すこともできる。
- ほとんどの理論上のnothing at stake攻撃は理想化されたブロックチェーンを仮定しており、攻撃に対抗するプロトコルレベルの安全策については考慮していない。しかし、現実にはこのような攻撃は攻撃者が持っている資産が十分でないと成立しない。先に述べた防衛策がこの場合にも当てはまる。加えてブロック難度の変化量が最大でも5%までと決まっているため、攻撃者のチェーンが優位性を得るためには時間がかかり、秘密裏にチェーンを伸ばそうにも最初期に大きなタイムラグが発生し、攻撃者のチェーンが高いスコアを達成することが困難になる。
14.4 Fee Attack
- 最低ハーベスト残高分の残高しか持っていないスモールアカウントの場合、2回のインポータンス計算の間に大きな手数料を伴ったトランザクションを送ると、次の再計算間隔(359ブロック)の間に1回のハーベストが期待できる程度までインポータンスを上げることができ、ラージアカウントのように振る舞うことができ、再計算期間毎に自分がハーベストするブロックに高額な手数料を送り込むことができるようになり、ブロックをハーベストできる確率が上がることによる報酬が支払ったコストを上回ることが期待される。
- が、複数のアカウントが同時に同じことを試みようとするとその効率は悪化する。またこの攻撃ができるアカウント数にも限りがあり、現実的な攻撃方法ではない。
15. Finalization
- CAPの定理によると、ネットワークに障害や分断があれば、分散型システムは「一貫性」か「可用性」のどちらかを選ばないといけない
- BFTシステムの多くは一貫性を重視してネットワーク停止のリスクを許容しようとする。
- 可用性を持つシステムの場合は、返ってきた値が同じであるという保証はなく、システムが複数の値を取ることを許容しないといけない。PoWやNXT型PoSを採用したシステムの多くはこの可用性を重視して稼働して、最終的には合意を得る設計をした。
- Symbolでは一貫性よりも可用性を重視しているが、オリジナルのコンセンサスシステムの上にファイナリティを実現するガジェットを追加することができる。このガジェットはブロック生成やコンセンサス形成と独立して稼働する。
- ガジェットを使用するアプローチはPolkadotが使っているGRANDOPAに習って設計された。