Proof of Stakeのシンプルな実装の簡単な説明

[mathjax]

Proof of Workの実装の簡単な説明は結構ありますが、Proof of Stakeとなるとなかなか見かけないですよね。
説明したいと思います。

Proof of Work

まずはProof of Workのシンプルな実装の簡単な説明をしましょう。

Proof of Workのシンプルな実装では、

hash(block,nonce)<target(-difficulty)

となったときにマイニングに成功するようになっています。

hash

ハッシュ関数です。例えば256bitのハッシュ関数の場合、どのようなデータも、0〜2^256-1の範囲のうちのどれかの値を出力します。関数なので、入力と出力は対応しています。また、一方向性があり、出力から入力を求める方法は総当たり以外に存在しません。

block

ビットコインの場合、
・ブロックに含まれるトランザクションのハッシュをまとめたもの(マークルルートという)
・前のブロックのハッシュ値
です。

nonce

未知な値です。これを総当たりで見つけ出すことこそがマイニングです。ハッシュ関数は一方向関数なので、①を満たすようなnonceを総当たりで見つけなければなりません。

difficulty

difficultyというパラメータは、マイニングの難易度に影響します。例えばマイナーの増加により全体のハッシュパワーが増加して、ブロックが決められたブロックタイムより早く生成される(いとも簡単に生成される)と、次から難易度を上げることになります。

そのようにした結果、ブロック生成にかかる時間はブロックタイム±誤差で安定します。

target

例えばハッシュ関数が256bitなら、targetも0〜2^256-1のうちどれかの値をとります。
条件①は言い換えれば、hashがtargetより小さくなるかどうか、です。
difficultyつまり難易度が高いほど、targetは下がります。

ハッシュ値は世界中の誰がやっても同じ結果が出るため、中央主体の存在が無くても成功したかどうかを証明することが可能となっています。

イメージ

|----------------------------------------------------------------|
0       ^target                                                  2^256-1
                       ^hash1
                                ^hash2
                           ^hash3
                                               ^hash4
                                                          ^hash5
                                        ^hash6
    ^hash7 success!

0~2^256-1の数直線をイメージします。この中にtargetがあります。

ハッシュ関数はどんなデータを入力してもこの数直線上の値のどれかを出力します。そこで、
・マークルルート
・前のブロックのハッシュ値
・とある値nonce

これら3つを合わせたデータのハッシュ値がtargetを下回るようなとある値nonceを見つける、というのがマイニングです。

Proof of Stake

Proof of Stakeの実装は、NEM technical referenceが参考になります(正確に言うとNEMはProof of Importanceですが、この文脈では説明に使えるので気にしないでください)。これを参考に紹介します。

PoSのシンプル実装では、バリデーター(NEMならハーベスター)がバリデーション(NEMならハーベスティング)に成功する条件は

hash(block)<target(-difficulty, share, time)

となります。

share

Proof of Stakeであれば、自身のステークの全体に占めるシェアです。Proof of Importanceであれば、自身の重要度が全体に占めるシェアです。当然ながら、シェアが高いほど成功しやすいです(ハッシュパワーが高いほどマイニングに成功しやすいのと同じ)。

time

前のブロックが生成されてから現在までに経った時間です。単位は主に秒となります。Proof of Workでは時がたてばハッシュパワー×時間=投入した総ハッシュパワーが増えていきますが、Proof of Stakeでは時がたって増えていくようななにかがありません。そのため、時間に応じてtargetを下げる必要があるわけです。

イメージ

|----------------------------------------------------------------|
0                                   ^hash                        2^256-1
  ^target1
    ^target2
        ^target3
              ^target4
                    ^target5
                           ^target6
                                 ^target7
                                       ^target8 success!

こちらはtargetを所与としてhashを求めるのではなく、hashを所与としてtargetがhashを上回るまで待つという感じです。

timeの単位が秒なら、1秒に一回targetを再計算します。

NEMの場合

ちなみにですが、NEM technical referenceに書いてある、NEMのハーベスティングに成功する条件は

$$ 2^{54}|ln\left(\frac{h}{2^{256}}\right)| < 2^{64}\frac{b}{d}t $$

となっています。hがハッシュ値、bがシェア、dが難易度、tが時間にあたります。

おわりです!!!