PythonでProof of Workとは何かを解説する
最近はブロックチェーンを勉強しているというのもあり、自分の勉強や理解のためとしても、ブロックチェーンのコンセンサスアルゴリズムの一種であるProof of Workが具体的に何を行っているかを解説します。
Proof ow Workの具体的な手順
1. 直前のブロックのハッシュ値をブロックヘッダに格納
2. 現在のブロック内のトランザクションデータを全てハッシュ化し、それで得られたハッシュ値をブロックヘッダに格納
3. ナンス(nonce)と呼ばれる値を乱数で決定して、ブロックヘッダに格納する
4. ブロックヘッダ自体をハッシュ化して、先頭に0が16〜17個並ぶようになるまで3の処理に戻ってナンス値を調整していく
3の部分で乱数を探すのに膨大な計算量が必要になります。とある乱数をブロックヘッダに格納してハッシュ化して、特定の値以下で無い場合は、再度乱数を決めるところまで戻って、ブロックヘッダに格納してハッシュ化して・・・を何度も繰り返します。
これで特定の値以下になるノンス値を見つけ出すことに成功すると、ブロックを生成する権限が得られます。この一連の流れをマイニングといいます。
でたらめなナンス値をいれてハッシュ化してブロックを生成したとしても、周りのマイナーにブロックを送った時点で、そのブロックは不正なブロックとして破棄されてしまいます。
Pythonのサンプルコード
実際に以下のPythonのコードで簡易的なサンプルがあるので、実際に以下のコードを動かしてみるとわかりやすいです。
今回はわかりやすさのため、上記でいう2の部分を省いています。
またハッシュ化した際の先頭の値は0が4つの値になるまで繰り返すようにしました。流石に0が16個並ぶまで処理を繰り返していたら、通常のPCではとんでもない時間がかかります。
下のコードでは、前ブロックのハッシュ値であるprevious_hashとナンス値であるnonceを結合し、その結合した文字列をハッシュ化した際に、先頭に0が4つ並ぶまでnonceを乱数で何度も生成して調整します。
from random import randint
from hashlib import sha256
previous_hash = "b9b9ee9ffc95fa4956b63b6043a99d0a8f04e0e52e687fc1958d3c6dff885f01"
#loopカウント
cnt = 1
#nonce値
nonce = str(randint(0, 1000000))
#前ブロックのハッシュ値とnonce値の結合した文字列
header = sha256(f'{previous_hash}{nonce}'.encode()).hexdigest()
while header[:4] != "0000":
text = 'loop:{}, header:{}, header[:4]:{}, nonce:{}\n'
print(text.format(cnt, header, header[:4], nonce))
nonce = str(randint(0, 1000000))
header = sha256(f'{previous_hash}{nonce}'.encode()).hexdigest()
cnt += 1
text = 'loop:{}, header:{}, header[:4]:{}, nonce:{}'
print(text.format(cnt, header, header[:4], nonce))
実際に動かしてみると、0が4つでもそこそこループして、ようやくnonce値が決定されます。
$ python proof_of_work.py
....
loop:22679, header:0000ea27e22db290e4f2163f968bfaf3ff7d58ccf1cd4ab43b3fbc4326c0eb4a, header[:4]:0000, nonce:8978
参考資料
この記事が気に入ったらサポートをしてみませんか?