解くのは大変で、確認は一瞬
プルーフ・オブ・ワーク(作業証明)とは、ブロックを足す前に、手間のかかる計算をさせる決まりです。計算には時間がかかりますが、答えが正しいかの確認は、一瞬で済みます。
4桁の数字の南京錠で考えます。開けるには最大1万通りを試しますが、開いたかどうかは、見れば分かります。
このレッスンのゴール
メモ
採掘には手間がかかり、確認は軽い理由を説明することができる。
キーワード
| ことば | いみ |
|---|---|
| ナンス | 条件に合うまで、ブロックに足して変える数 |
| 難易度 | ハッシュ値の先頭に並べるゼロの数 |
| 採掘 | 条件に合うナンスを探す作業。マイニングとも呼ぶ |
| プルーフ・オブ・ワーク | 手間をかけたことを示す、確かめやすい証拠 |
| 試行回数 | ナンスを試した回数 |
学生が入力するセルは、このプレビューでは空白です。
ナンスを変えて、ハッシュ値を探す
決まりは「ハッシュ値の先頭に、ゼロが難易度の数だけ並ぶこと」です。ブロックの中身は変えられないので、ナンスという数だけを0、1、2と増やします。
ナンスが変わるたびに、ハッシュ値は別の値になります。当たるまで試し続ける作業が、採掘です。
Python でナンスを探す
import hashlib
DIFFICULTY = 2
data = "hello"
nonce = 0
while True:
digest = hashlib.sha256((data + str(nonce)).encode()).hexdigest()
if digest.startswith("0" * DIFFICULTY):
break
nonce = nonce + 1
print("ナンス", nonce, "ハッシュ値", digest[:10])
# DIFFICULTY を 3 に変えて、もう一度実行しましょう。
# 見つかるまでの試行が、ずっと増えます。
ラボで4つの難易度を試す
次の Run は、同じブロックを難易度1から4まで採掘します。表示は英語で、difficulty は難易度、nonce はナンス、tries は試行回数、hash はハッシュ値の先頭です。ブロックも出発点も決まっているので、答えはいつも同じです。
難易度1から4を採掘する
docker exec jupyter python3 steps/mine.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
例: ゼロが増えると、試行が増える
| 難易度 | 平均の試行回数 | ラボの試行回数 |
|---|---|---|
| 1 | 16 | 15 |
| 2 | 256 | 835 |
| 3 | 4096 | 7992 |
| 4 | 65536 | 109028 |
学生が入力するセルは、このプレビューでは空白です。
ゼロが1つ増えると、16倍になる
ハッシュ値の1桁は16通りなので、ゼロが1つ増えるごとに、平均の試行は16倍になります。表の左は計算した平均で、右はラボの結果です。
採掘は運にも左右されるので、実際の回数は平均より多くも少なくもなります。でも、増え方の勢いは変わりません。
確認はハッシュを1回計算するだけ
採掘は何千回も計算しますが、確認はたった1回です。ナンスを入れたブロックのハッシュ値を計算し、先頭のゼロの数を見るだけで済みます。
次の Run は、さきほど見つけたナンス227で、その1回の計算をします。表示は先頭10文字で、001b92541e になります。
ナンス227を1回で確かめる
docker exec jupyter python3 -c "import hashlib; print(hashlib.sha256(b'hello227').hexdigest()[:10])"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
「難易度を上げると、確認も同じだけ大変になる」と考える人がいます。確認は、難易度にかかわらず、ハッシュを1回計算するだけです。大変になるのは、ナンスを探す側だけです。
なぜ、わざわざ手間をかけるのか
古いブロックを書き換えると、そのブロックも、その先のブロックも、採掘し直す必要があります。1つ直すだけで何千回もの計算が要るので、改ざんは割に合いません。
手間は、書き換えにかかる費用になります。これが、採掘の目的です。