簡単なブロックチェーンをつくる(その5 プルーフオブワーク)

 新しいブロックを生成するための条件として,ブロックのハッシュ値に条件を設ける.何度もブロックのハッシュを計算させ,ハッシュ値がある条件を満たした場合に限りブロックを生成する.今回はこの原型をつくる.

 ブロックのハッシュ値は sha256 を使っているので256ビット(32バイト)である.これを一つの巨大な数とみなし,この数がある指定した数以下になることをブロック生成の条件とする.ここでは32バイト値の上位2バイトが0であるという条件を設ける.すなわちブロックのハッシュを計算してみて

0000d49f91f2cf6662177fcec869c5cf89feee162a91d49a67d419f537bedc39

のようになればOKである.0000 ではなく 00000 になる条件を置けばさらにブロックの生成は困難になる(時間がかかる).

import hashlib, json
from time import time

# ハッシュ値の上4文字が0000となるノンスを見つける
difficulty = 4
target = "0000"

# ダミーブロック作成
nonce = 0
prev_block_hash =  hashlib.sha256("hoge".encode()).hexdigest()
block = {
    'index': 1,
    'tiemstamp': time(),
    'tx_list': [{'sender': 'Yamada', 'recipient': 'Sato', 'amount': 23}],
    'nonce': nonce,
    'prev_block_hash': prev_block_hash
}

# プルーフオブワーク
# nonceは0から1ずつ増やす
while True:
    hash = hashlib.sha256(json.dumps(block, sort_keys=True).encode()).hexdigest()
    if hash[:difficulty] == target:
        prev_block_hash = hash
        break
    nonce += 1
    block['nonce'] = nonce

print("nonce:", nonce)
print("hash:", prev_block_hash)

何度か実行すると,ノンスはかなり変動することがわかる.

nonce: 1954
hash: 00002e4e132b4259019b1cb8d5aa1b538644f1a9ab8bc1d0ffec8a3bd442ccb2

nonce: 70000
hash: 0000d47aedcf7626f1cf5ea82ff773021e5ed524d85755ededc558ed81892fde

nonce: 59104
hash: 0000f3d5131bfbbdea4c07fc1d691ec6ceb1b34aadf162348c51fa04415565e9

nonce: 8375
hash: 00007bf5d40f956adc0941602f7d6c699cb693574609769360bdf9fda36c9129