ビットコイン

Proof of Workの仕組み

今日は、ビットコインシステムを支えるブロックチェーンの要ともいえるProof of Workの仕組みについて説明します。

Proof of Workとはコンセンサスアルゴリズム(合意の方法)の一種です。また、Proof of Work をそのまま直訳すると「仕事の証明」という意味になります。

合意の方法であり仕事の証明でもあるProof of Workと、ビットコインシステムとはどうつながるのでしょうか。

ビットコインシステムにおけるProof of Workとは、ブロック生成のための「答え」を見つける作業です。その「答え」を見つけるためには膨大な計算が必要で、答えを見つける=それだけの仕事をしたという証明になるのです。そしてその「答え」を見つけたマイナーがブロックを追加することができ、報酬を得るというルールが全ノードで合意されています。

ブロックの構成

「答」を見つける作業の内容を説明する前に、ブロックチェーンを形成するブロックの内訳について説明します。

全体の構成

ブロックは以下の構成になっています。

ブロックは、大きく分けるとサイズ、ヘッダとトランザクション の3つのセクションから構成されています。トランザクションの内訳はこちらを参照してください。

Block Headerの構成

Block Headerは、下記の図のブルーの項目で構成されています。

〇Version
ブロックチェーンのソフトウェアのバージョンです。

〇Previous Block Hash
今作っているブロックの一つ前のブロック内のBlock HeaderにNonceを追加してSHA256アルゴリズムで2回ハッシュして算出した値です。

〇Merkle Root
このブロックに含まれるトランザションを要約してハッシュ化した値です。この方法であれば、トランザクションの量が膨大でも、最終的にまとめたものは1つのハッシュ値となるため、サイズを大幅に小さくすることができます。

例)トランザクションが4つの時のMerkle Rootの作り方を以下に示します。

1.トランザクションAをSHA256アルゴリズムで2回ハッシュしてHash Aを算出します。
2.HashAとHashBをペアとして、Hash AとHash Bを連結したものをSHA256で2回ハッシュ。
Hash ABとなります。
3.Hash ABとHash CDをペアとして、Hash ABとHash CDを連結したものをSHA256で2回ハッシュ。
Hash ABCDとなります。これが最終のMerkle Rootとなります。

〇Timestamp
ブロックを生成する時間をTimestampとして記録します。時間を明確化することによって、その時点で確かにこのブロックが存在していたことの証明となります。

〇Difficult Target
ビットコインシステムでは、1つのブロック生成から次のブロック生成まで、約10分間の間隔を保つように設定されています。このDifficult Targetは、この約10分間を維持するために設定されたBlock Hash生成の難易度です。
この値は固定ではなく、この約10分間隔が維持されるように調整されます。
というのも、マイニングのためのコンピュータの性能は日々アップしていて、前の機種では10分かかった計算が新しいものでは8分、5分と短縮されることもあり得るからです。生成までに常に10分間ほど必要になるように、計算の難易度も上げていきます。

では、管理者がいないP2Pシステムで誰がそんなことを決めているのでしょうか。それは、システムに参加するすべてのノードが自動的に行うのです。直近の2016ブロックの生成にかかった時間を測定し、それが20160分(10分×2016ブロック)より多いか少ないかで、次の2016ブロック生成のDifficult Targetの値を設定します。

〇Nonce
Block Hashの計算に使う数字です。Block Hashの計算には、Block HeaderにこのNonceの数字を加えたものをSHA256でダブルハッシュ化し、その数値がDifficult Targetの値より小さくなる必要があります。この値を計算によって算出します。

Proof of Workにおける「答え」とは

今回のブログの冒頭で、「Proof of Workとは、ブロック生成のための「答え」を見つける作業」と書きました。この「答え」は、Block Hash値です。

ブロック生成において、一番大変なのが、BlockHashの値を算出することです。というのも、Difficulty Targetという条件が課されているからです。
条件をクリアするまでに、天文学的回数の計算量をこなさないとHash値を算出できない設定になっていて、そこに近道はありません。

マイナーが答えを算出する具体的な手順は以下の通りです。

1.マイナーはBlock Headerの中身を準備します。
2.Block HeaderにNonceを足したものにSHA256で2回ハッシュします。
このとき算出された値がDifficulty Target(難易度)で設定された値より小さければ、そのHash値はOKですが、その値が大きいと、NGです。
3.マイナーはDifficulty Targetの設定より小さいHash値がでるまで、Nonceを変えて、延々計算を続けます。
4.難易度の条件を満たしたHash値を算出できるNonceを見つけることができたら、ブロック生成は成功です。
例)下記はブロック#592832のBlock Hash値です。
ハッシュ:0000000000000000000ce9d6c0d9b9c8c3bdc9c686cc3df50d3eb98564f39ffd
ナンス:1718824172
難易度は簡単に言うと、頭に「0を〇個つけるHash値にすること」とも言えます。上記では、「0」が19個ついています。このHash値を算出するために、Nonceを1回ごとに変えて計算。最終的に「1718824172」で、難易度をクリアするBlock Hash値を算出することができました。
5.マイナーは全ノードにブロック生成を通知します。
Proof of Workは終了です。マイナーはすぐに次のブロック生成に取り掛かります。

現在の技術では改ざん不可能なシステムを確立

ビットコインシステムのブロックチェーンは、ほぼ改ざん不可能といわれていますが、改ざん不可能にしているのが、Block Hash値です。そしてこのBlock Hash値がブロック同士をつなぐチェーンの役割を果たしています。

ブロックチェーンは、ブロックがつながった分散型台帳です。ただつながっているだけでなく、下記の図にあるように、常に前のBlock Headerのダブルハッシュ値が含まれていて、データ自体が前のブロックとつながっているのです。

もし、前のブロックのたった1つのトランザクションの内容を改ざんしたとしましょう。
すると、
Merkle Rootの値が変わる

Nonceの値が変わる(Block Headerの内容が変わるため)

Block Hash値が変わる

次のブロックのPrevious Block Hash値が変わる
ということになり、また、Proof of Workを一からやり直す必要があります。そのブロックにとどまらず、次のブロック、その次のブロックと延々計算のやり直しが必要になるのです。1つのブロックのデータを作るだけでも、膨大な計算が必要になるのに、それ以上の計算をしないと改ざんは成立しません。とても割の合わない作業になってしまうのです。正しい方法で新しいブロックを生成したほうが、改ざんするより確実にビットコインの報酬と手数料を獲得することができます。
つまり、ビットコインシステムのブロックチェーンは、改ざんするより新たなブロックを生成するほうが得になるシステムになっているのです。

参考文献
「ビットコイン: P2P電子通貨システム」 Satoshi Nakamoto  日本語版 英語版
ビットコインとブロックチェーン」 アンドレアス・М・アントノプロス NTT出版
「ブロックチェーン」 岡嶋裕史 講談社ブルーバックス