はじめに
📝 本記事は、前回の記事「ブロックチェーンの『ブロック』と『チェーン』って結局なに?ハッシュで図解する」の続編です。前回はデータ構造としての改ざん検知を扱いました。
前回の記事で、ブロックチェーンが「ハッシュで前後を繋いだデータ構造」であり、途中のブロックを書き換えると後続のハッシュが芋づる式にずれるため改ざんを検知できる、という話を整理しました。
ただ、そこには続きがあります。「検知できる」ことと「書き換えられない」ことは別物だからです。検知を免れるためにチェーンを末尾まで全部書き換えてしまえばよい、という攻撃が理屈の上では残っていました。これを防いでいるのが、本記事のテーマである PoW(Proof of Work、プルーフ・オブ・ワーク) です。
PoW という言葉は仮想通貨の文脈でよく登場しますが、「膨大な計算が必要」という説明だけを読んでも、なぜ書き換えにそんなにコストがかかるのか が自分のなかで腑に落ちていませんでした。そこで本記事では、PoW の正体を「ハッシュを使った試行錯誤のゲーム」として捉え直し、最小実装で実際に手を動かしながら確かめていきます。
この記事を読むとわかること:
- PoW が何のために存在するのか(前回の「改ざん検知」から「改ざん防止」へ)
- 「先頭にゼロが N 個並ぶハッシュを探す」とはどういう作業か(nonce と難易度ターゲット)
- マイナー(採掘者)が実際に何を計算しているのか
- 「なぜ書き換えに莫大な計算コストがかかるのか」を自分の言葉で説明できる
前回記事を読んでいなくても追えるように書いていますが、「ハッシュで繋がると改ざんが検知される」という前提だけは前提知識として使います。なお本記事では、PoW 以外のコンセンサス(PoS など)や、分散ネットワークでの合意形成の細部には踏み込みません。まずは「1台のマシンの上で PoW を体験する」ことに集中します。
なぜブロック生成を「重く」するのか
PoW の仕組みに入る前に、「そもそも何のために PoW が必要なのか」をはっきりさせておきます。ここが曖昧なまま nonce やハッシュの話に進むと、手段だけ覚えて目的を見失いがちです。
前回の「宿題」: 検知できても書き換えは止められない
前回、ブロックチェーンは次のような構造で改ざんを検知できる、と整理しました。
- 各ブロックは「自分のハッシュ」を持つ
- 次のブロックは「前のブロックのハッシュ」を抱えている
- 途中のブロックを書き換えると、そのブロック以降のハッシュが全部ずれる
ここから導かれる結論は、「1個書き換えると、それ以降のすべてのブロックを書き換えないと辻褄が合わない」でした。
問題は、ここに抜け道が残っていることです。「それ以降を全部書き換えればよい」のであれば、攻撃者が本当にそれをやり切ってしまえば、検証はパスしてしまいます。ハッシュの再計算はコンピューターにとって一瞬の処理なので、数百ブロック程度であれば総当たりで押し切れてしまうかもしれません。
図1: ハッシュ計算が一瞬だと、全書き換えで検知を免れられる
つまり前回の仕組みだけでは、改ざんを「検知できる」ところまでしか到達していません。「現実的に書き換えられない」ようにするには、もう一段の工夫が必要です。
解決策: 1ブロックを作るのを「わざと重く」する
その工夫が、「1個のブロックを作る作業を、意図的に時間のかかるものにする」 ことです。
ハッシュの計算自体は一瞬で終わります。そこで、「ただハッシュを計算する」のではなく、「ある条件を満たすハッシュになるまで、何万回・何億回と計算を繰り返させる」 という縛りを加えます。この「条件を満たすハッシュを探す」作業こそが PoW であり、後の章で詳しく見ていきます。
この縛りが入ると、改ざんの難しさが一変します。仮に1ブロックを作るのに10分かかるとすると、
- 50番目のブロックを書き換えたい攻撃者は、そこから末尾までの全ブロックを作り直す必要がある
- 100ブロックのチェーンなら、51ブロック分の作り直しに 510分(約8.5時間) かかる
- その間にも、正規のチェーンには新しいブロックがどんどん追加されていく
結果として、攻撃者は正規のチェーンに永遠に追いつけません。「全部書き換えればよい」という抜け道が、「全部書き換えるには現実離れした計算量が要る」という壁に変わります。
📝 PoW は「改ざんを不可能にする魔法」ではありません。「改ざんを、割に合わないほど高コストにする」仕組みです。理論上は可能でも、現実的には引き合わない——この線引きがブロックチェーンのセキュリティの本質です。
ここまでが PoW の動機です。次の章からは、「条件を満たすハッシュを探す」とは具体的にどういう作業なのかを掘り下げます。
PoW が解く「パズル」とは
PoW の正体は、ひとことで言えば 「条件を満たすハッシュが出るまで、ハッシュ計算を繰り返す」 作業です。ここでいう「条件」とは何かを具体的に見ていきます。
条件は「先頭にゼロが N 個並ぶハッシュ」
実際のブロックチェーンで使われる条件を、本記事では分かりやすい形に単純化して、「ハッシュの先頭にゼロが N 個並んでいること」 とします。この N を 難易度(difficulty) と呼びます。
📝 これは説明用に単純化した条件です。実際の Bitcoin の条件は「ハッシュ(を256ビットの数とみなした値)が、ある『ターゲット値』以下であること」です。小さい値ほど先頭にゼロが並ぶため、「先頭にゼロが N 個」はそのおおまかな近似にあたります。ターゲット方式だと難易度をより細かく調整できる利点があります(後半の章であらためて触れます)。
たとえば前回も使った SHA-256 で、"最初の取引" というデータを記録したブロックのハッシュを計算すると、次のような64文字が得られます(ハッシュの正確な材料は次章で扱います)。
9cde87aa54319e842fa642289474b67dfbafaef739eb1c90e168335616983525
このハッシュは先頭が 9 なので、「先頭にゼロが1個並ぶ」という条件すら満たしていません。条件を満たすハッシュを得るには、入力を少しずつ変えながら、ゼロ始まりのハッシュが出るまで計算し続けることになります。
難易度3(先頭にゼロが3個)の条件を満たすハッシュは、たとえば次のようなものです。
000424646dcb0d2063830e463cbf85b2a584801981e864022cc352c8e8f79449
先頭が 000 で始まっています。このようなハッシュを「探し当てる」のが、PoW で課されるパズルです。
図2: 条件を満たすハッシュ・満たさないハッシュ(難易度3の場合)
なぜこれが良いパズルなのか: 「探すのは大変、確かめるのは一瞬」
この条件には、PoW にとって都合の良い性質が2つあります。
- 探すのは大変: ハッシュ関数は一方通行で、「こういうハッシュが欲しい」と思っても、そこから逆算して入力を作ることはできません。条件を満たす入力を見つけるには、ひたすら入力を変えて試すしかありません(総当たり)。
- 確かめるのは一瞬: いっぽうで、「あるハッシュが条件を満たすか」のチェックは、先頭のゼロの数を数えるだけです。検証する側は、ハッシュを1回計算して先頭を見るだけで済みます。
この 「探すのは大変だが、確かめるのは一瞬」 という非対称性が PoW の肝です。ブロックを作る人には膨大な計算を強い、検証する人には軽い負担しか課さない。だからこそ「作るのは重く、チェックは誰でもできる」が成立します。
難易度を1上げると、条件はどれくらい厳しくなるか
ハッシュは16進数(0〜9, a〜f の16種類の文字)で表されます。先頭の1文字が 0 になる確率は、16種類のうちの1つなので 1/16 です。
- 先頭にゼロが1個: 約 1/16
- 先頭にゼロが2個: 約 1/16 × 1/16 = 1/256
- 先頭にゼロが3個: 約 1/16 × 1/16 × 1/16 = 1/4096
- 先頭にゼロが N 個: 約 「16 の N 乗」分の1
難易度を1上げる、つまり要求するゼロを1個増やすごとに、条件を満たすハッシュの「出にくさ」は約16倍になります。これが、ブロック生成の重さを細かく調整できる仕組みの土台です。
ただし、ここまでで1つ宙に浮いている点があります。「入力を少しずつ変えて試す」と言いましたが、ブロックのデータは記録したい取引そのものなので、勝手に書き換えるわけにはいきません。では、何を変えながら試すのか。これが次の章の nonce です。
nonce:唯一動かせるダイヤル
前章の最後で「入力を少しずつ変えて試す」と言いました。しかし、ブロックのデータ(記録したい取引)も、前のブロックのハッシュも、勝手に変えるわけにはいきません。そこで PoW では、ブロックに 自由に変えてよい数字 を1つ追加します。それが nonce(ナンス) です。
nonce はハッシュを変えるためだけの数字
nonce は "number used once" に由来する、ブロックに付け足された調整用の数値です。役割は単純で、「ハッシュを計算するときの材料に混ぜる、自由に変えてよい数」 です。
PoW 付きのブロックでは、ハッシュを次の3つから計算します。
ハッシュ = SHA-256( データ + 前のハッシュ + nonce )
データと前のハッシュは固定なので、ハッシュを変えたければ nonce を変えるしかありません。そして前回見た雪崩効果により、nonce を 0 から 1 に変えるだけで、ハッシュはまったく別の値になります。
実際に、"最初の取引" というデータについて nonce を 0 から順に変えると、ハッシュは次のように毎回まるごと変わります。
nonce=0: 9cde87aa54319e842fa642289474b67dfbafaef739eb1c90e168335616983525
nonce=1: 58dce170f68a768c76f6ae4cc9d52e381e0701607d912fe0db0132c124f99e69
nonce=2: 901aa7d5c0efe53d9c6c99f08d8d7e5960d12af6ce5223930b4defcb8cf16e82
nonce=3: 19988d450436ab33240145af6cb037ea2a2c6494c40c39ec1aff91c1355c561b
nonce=4: 1c571508792ba1256e7ffb9e49dd875cf71eb68c466088c021f05c6d5355adbd
この5つはどれも先頭がゼロではないので、条件(先頭にゼロが並ぶ)を満たしていません(前章で例に挙げた 9cde87aa... は、ちょうど nonce=0 のときの値です)。条件を満たすハッシュが出るまで、nonce を回し続ける——これが PoW の作業の中身です。
図3: nonce というダイヤルを回して、条件を満たすハッシュを探す
難易度を上げると、何回回せばよいのか
"最初の取引" について、難易度(要求するゼロの数)を変えながら、条件を満たす nonce を 0 から総当たりで探すと、結果は次のようになりました。
| 難易度(先頭ゼロの数) | 期待値(平均試行回数) | 実際の試行回数 | 見つかった nonce | そのときのハッシュ(先頭) |
|---|---|---|---|---|
| 1 | 16 | 19 回 | 18 | 0dfe0bb1b7c7... |
| 2 | 256 | 650 回 | 649 | 0029b3ea93ce... |
| 3 | 4096 | 1147 回 | 1146 | 000424646dcb... |
| 4 | 65536 | 15482 回 | 15481 | 000006eef6ed... |
難易度1なら19回で見つかりましたが、難易度4では1万5千回以上の計算が必要でした。要求するゼロが増えるほど、当たりを引くまでの試行回数が跳ね上がっていきます。
期待値(平均試行回数) の列は、前章の「ゼロを1個増やすごとに約16倍出にくくなる」を数値にしたものです。先頭ゼロが N 個なら、平均しておよそ「16 の N 乗」回(16 → 256 → 4096 → 65536)試せば1回当たる、という理論値です。
ここで注意したいのは、実際の試行回数は運に左右され、期待値どおりにはならない という点です。上の表でも、難易度2は期待値256に対して650回とやや多く、難易度3・4は逆に期待値より少ない回数で当たっており、期待値の前後にばらついています。条件を満たすハッシュがいつ出るかは確率的で、運が良ければ早く、悪ければ遅く見つかります。この「宝くじのような試行錯誤」こそが採掘の正体です。
そして、見つかった nonce には重要な意味があります。「nonce = 15481 で条件を満たすハッシュが出た」という事実は、それを見つけるまでに膨大な計算を行った証拠になっています。これが Proof of Work(仕事の証明)という名前の由来です。
マイナーは何をしているのか
「マイニング(採掘)」や「マイナー(採掘者)」という言葉は、金鉱を掘るイメージから来ています。しかし実際にやっていることは、ここまで見てきた 「条件を満たす nonce を探す総当たり計算」そのもの です。何かを物理的に掘っているわけではありません。
マイナーの仕事は「ひたすらハッシュを計算する」こと
マイナーがやっていることを手順にすると、驚くほど単純です。
- 新しいブロックに入れる取引を集める
- nonce を
0,1,2, ... と変えながらハッシュを計算する - 「先頭にゼロが N 個並ぶ」条件を満たすハッシュが出たら、そのブロックを完成として発表する
前章で見たように、難易度が上がるほど 2 の試行回数は跳ね上がります。現実のブロックチェーンでは、ネットワーク全体でこの試行を 1秒間に数百 EH(エクサハッシュ。1 EH = 100京回) という桁外れの規模で回し続けています。1秒あたりに計算できるハッシュの回数を ハッシュレート と呼び、これがマイナーの「採掘能力」にあたります。
採掘は早い者勝ちの競争
マイナーは世界中に大勢いて、全員が同時に同じ「条件を満たす nonce 探し」に取り組んでいます。そして、最初に条件を満たすハッシュを見つけたマイナーだけ が、そのブロックをチェーンに追加する権利を得ます。
図4: 複数のマイナーが同じ条件を競って探す
なぜ大勢が、わざわざ電気代をかけてまでこの競争に参加するのか。それは、ブロックを追加できたマイナーには報酬が支払われる からです(この報酬の仕組みは現実のブロックチェーンの話なので、後の章で簡単に触れます)。報酬があるからマイナーが集まり、マイナーが集まるからネットワーク全体の計算能力が膨大になる、という関係になっています。
マイナーの計算能力が、そのまま改ざんの壁になる
ここで前半の動機と繋がります。「1ブロックを作るには、ネットワーク全体が競って大量の計算をしないと条件を満たせない」という状態が、そのまま改ざんへの防壁になります。
過去のブロックを1つ書き換えたい攻撃者は、前回の記事で見たとおり、そのブロック以降をすべて作り直さなければなりません。PoW のもとでは「作り直す」とは そのブロックの nonce 探しをもう一度やり直す ことを意味します。
- ブロックを1つ作り直す = 条件を満たす nonce をもう一度引き当てる(宝くじをもう一度当てる)
- それを書き換え地点から末尾まで、全ブロック分くり返す
- しかも、その間に正規のチェーンを追い越せるだけの計算速度が要る
正規のチェーンにはネットワーク全体の計算能力が注ぎ込まれています。これを1人(あるいは少数)の攻撃者が追い抜くには、ネットワーク全体に匹敵する計算能力が必要になります。これが「改ざんには莫大な計算コストがかかる」の正体です。
言葉だけでは実感が湧きにくいので、次の章で実際にミニ実装を動かし、「1個の改ざんを隠すために何回の再計算が要るのか」を数字で確かめます。
Python によるミニ実装
ここまでの内容を、最小構成の PoW 付きブロックチェーンとして Python で実装します。前回のミニ実装に nonce と難易度(採掘)を加えただけなので、差分を中心に見ていきます。
ブロックの定義(nonce と採掘を追加)
import hashlib
DIFFICULTY = 4 # 先頭にゼロがこの数だけ並ぶハッシュを探す
class Block:
def __init__(self, data: str, previous_hash: str, difficulty: int = DIFFICULTY):
self.data = data
self.previous_hash = previous_hash
self.difficulty = difficulty
self.nonce = 0
self.hash = self.mine()
def calc_hash(self) -> str:
# データ + 前のハッシュ + nonce をまとめてSHA-256でハッシュ化
body = self.data + self.previous_hash + str(self.nonce)
return hashlib.sha256(body.encode()).hexdigest()
def mine(self) -> str:
# 先頭にゼロが difficulty 個並ぶハッシュになるまで nonce を回す
target = "0" * self.difficulty
self.nonce = 0
while True:
h = self.calc_hash()
if h.startswith(target):
return h
self.nonce += 1
前回からの変更点は3つです。
-
calc_hash()のハッシュ材料にstr(self.nonce)が加わった -
mine()を追加し、条件を満たすまでnonceを1ずつ増やす - ブロック生成時、
hashを「ただ計算する」のではなく「採掘した結果」にした
target = "0" * self.difficulty は、難易度4なら "0000" という文字列です。hash がこの文字列で始まるまで nonce を回し続けます。
チェーンの検証関数(チェックが1つ増える)
def is_chain_valid(chain: list[Block]) -> bool:
for i, block in enumerate(chain):
target = "0" * block.difficulty
# チェック1: そのブロックのハッシュは、いま計算しても同じか?
if block.hash != block.calc_hash():
print(f"❌ ブロック{i}: データかハッシュが書き換えられています")
return False
# チェック2: PoW を満たしているか?(先頭ゼロが規定数あるか)
if not block.hash.startswith(target):
print(f"❌ ブロック{i}: PoW を満たしていません(先頭ゼロ不足)")
return False
# チェック3: 前のブロックとリンクが繋がっているか?
if i > 0 and block.previous_hash != chain[i - 1].hash:
print(f"❌ ブロック{i}: 前のブロックとのリンクが切れています")
return False
print("✅ チェーンは健全です")
return True
前回はチェック1(ハッシュの整合性)とチェック3(前ブロックとのリンク)の2つでした。PoW では チェック2(先頭ゼロが規定数あるか) が加わります。「ちゃんと採掘されたブロックか」を確認する関門です。
採掘してチェーンを作る
genesis = Block("最初の取引", previous_hash="0") # ブロック0(ジェネシス)
b1 = Block("AがBに100円送った", previous_hash=genesis.hash) # ブロック1
b2 = Block("BがCに50円送った", previous_hash=b1.hash) # ブロック2
chain = [genesis, b1, b2]
ブロックを作る時点で、それぞれ内部で mine() が走り、条件を満たす nonce を探します。実行すると、各ブロックの採掘にかかった試行回数が表示されます。
実行結果(シナリオ1):
=== シナリオ1: 採掘してチェーンを作る(難易度4)===
ブロック0: data='最初の取引' nonce= 15481( 15482回試行) hash=000006eef6ed...
ブロック1: data='AがBに100円送った' nonce= 99644( 99645回試行) hash=00006cdc5472...
ブロック2: data='BがCに50円送った' nonce=121103(121104回試行) hash=0000954ed529...
✅ チェーンは健全です
3つのブロックそれぞれが、先頭にゼロが4個並ぶハッシュ(000006..., 00006c..., 0000954...)を持っています。ブロック1の採掘には約10万回、ブロック2には約12万回の計算がかかりました。難易度はどれも4ですが、運によって試行回数がばらつくことも見て取れます。
改ざんを隠すには「全ブロックの再採掘」が必要
ここからが本題です。前回と同じく、ブロック1のデータを書き換えてみます。
chain[1].data = "AがBに10000円送った" # 改ざん
is_chain_valid(chain)
実行結果(シナリオ2):
=== シナリオ2: ブロック1のデータを書き換える ===
ブロック1のデータを 'AがBに10000円送った' に改ざん
保存されているハッシュ : 00006cdc5472...
再計算したハッシュ : b9a6e9af9560... ← 食い違う!
❌ ブロック1: データかハッシュが書き換えられています
データを書き換えた瞬間、保存されているハッシュ(00006cdc...)と再計算したハッシュ(b9a6e9af...)が食い違い、チェック1で検出されます。ここまでは前回と同じです。
問題は、攻撃者がこれを 隠そうとした ときです。辻褄を合わせるには、書き換えたブロック1を採掘し直し、さらにブロック1のハッシュが変わることで壊れるブロック2のリンクを貼り直して、ブロック2も採掘し直す必要があります。
# ブロック1を新しいデータで再採掘
chain[1].hash = chain[1].mine()
# ブロック1のハッシュが変わったので、ブロック2のリンクも貼り直して再採掘
chain[2].previous_hash = chain[1].hash
chain[2].hash = chain[2].mine()
実行結果(シナリオ3):
=== シナリオ3: 改ざんを隠すには再採掘が必要 ===
ブロック1を再採掘: nonce=1688(1689回試行) hash=00002808d414...
ブロック2も再採掘: nonce=129214(129215回試行) hash=0000c8610459...
改ざん1個を隠すための再採掘 合計: 130904回
✅ チェーンは健全です
たった2ブロックを書き換えるだけで、辻褄を合わせるために合計 130904回 のハッシュ計算が必要になりました。前回のミニ実装では、ハッシュを再計算するだけなので一瞬で辻褄を合わせられました。PoW を入れた途端、「辻褄合わせ」が 採掘のやり直し に変わり、現実的なコストとして跳ね上がります。
今回はわずか2ブロック・難易度4なので一瞬で終わりますが、これが何百ブロック・難易度19(現実の Bitcoin の規模)になれば、書き換えにかかる計算量は天文学的になります。「改ざんには莫大な計算コストがかかる」という言葉の中身を、数字で確認できました。
ミニ実装と現実の PoW の違い
ミニ実装で PoW の核は押さえられましたが、現実の Bitcoin などはもう少し作り込まれています。本記事の実装と現実の差を整理しておきます。
PoW まわりの違い: ミニ実装 vs Bitcoin
| 項目 | 本記事のミニ実装 | 現実の Bitcoin |
|---|---|---|
| 条件 | ハッシュの先頭にゼロが N 個 | ハッシュが「ターゲット値」以下(より細かく調整できる) |
| 難易度の調整 | 定数で固定(DIFFICULTY = 4) |
約2週間ごとに自動調整され、1ブロック約10分を維持 |
| ハッシュ関数 | SHA-256(1回) | SHA-256 を2回(SHA-256d) |
| 計算規模 | 1ブロック数万回・一瞬 | ネットワーク全体で毎秒数百 EH(エクサハッシュ)級 |
| 採掘の報酬 | なし | 新規発行コイン(ブロック報酬)+取引手数料 |
難易度は「約10分」を保つように自動調整される
本記事では難易度を 4 で固定しましたが、現実のブロックチェーンでは難易度が自動で調整されます。Bitcoin は「1ブロックの生成にかかる時間が平均で約10分」になるように、約2週間ごとに難易度を見直します。
なぜ調整が必要かというと、マイナーの数や計算能力(ハッシュレート)は時々刻々と変わるからです。
- マイナーが増えて計算が速くなる → ブロックが早く見つかりすぎる → 難易度を上げる
- マイナーが減って計算が遅くなる → ブロックがなかなか見つからない → 難易度を下げる
この自動調整により、参加者の数によらず、ブロックの追加ペースが一定に保たれます。本記事のミニ実装で「ゼロを1個増やすと約16倍重くなる」と確認した、あの難易度のダイヤルを、ネットワークが自分で回しているわけです。
報酬があるから計算能力が集まる
ミニ実装には採掘の報酬がありませんが、現実のマイナーは ブロック報酬(新しく発行されるコイン)と取引手数料 を目当てに採掘しています。
この報酬は、単なるおまけではなく、セキュリティの一部です。報酬があるからこそ世界中のマイナーが計算能力を持ち寄り、その合計の計算能力が「改ざんを追い抜くには、これだけの計算が必要」という壁の高さを決めます。報酬 → マイナーの参加 → 高いハッシュレート → 強い改ざん耐性、という循環で成り立っています。
それでも本質は同じ
これらの違いはありますが、「条件を満たすハッシュを総当たりで探させ、見つけたことを仕事の証明とする」というコアはまったく同じです。
本記事のミニ実装は、Bitcoin の PoW から自動調整や報酬といった肉付けを削った最小版です。難易度を 4 から現実規模(先頭ゼロ19個相当)に引き上げ、難易度の自動調整と報酬を加えていけば、本物の PoW に近づいていきます。
ここまでで触れなかったこと
本記事は「1台のマシンで PoW を体験する」ことに絞ったため、以下の話題は意図的に省きました。いずれも PoW の上に乗る、もう一段上のレイヤーの話です。
- 分散ネットワークと最長チェーンルール: 現実の PoW は、世界中のノードが同じチェーンを持ち合う前提で動きます。複数のマイナーがほぼ同時にブロックを見つけてチェーンが枝分かれ(フォーク)したとき、「最も多くの計算が積み上がった、最長のチェーンを正とする」というルールで合意を取ります。本記事ではチェーンを1本だけ扱いました。
- 51%攻撃: もし1人の攻撃者がネットワーク全体の過半数の計算能力を握ると、正規のチェーンを追い抜いて改ざんを成立させられる可能性が出てきます。PoW のセキュリティが「計算能力の多数決」に依存していることの裏返しです。
- 取引の確定(コンファメーション): あるブロックの後ろにブロックが積み増されるほど、それを覆すのに必要な再計算が増え、取引が「覆りにくく」なります。何ブロック積まれたら安全とみなすか、という実務的な話も省きました。
- PoS(Proof of Stake)など他のコンセンサス: PoW は大量の電力を消費します。これを避けるため、計算量ではなくコインの保有量などで「次のブロックを作る人」を選ぶ PoS という仕組みもあります。イーサリアムは PoW から PoS へ移行しました。
これらは「条件を満たすハッシュを探す」という PoW の核を理解したうえで、その先に広がるテーマです。
まとめ
ここまでの内容をまとめると、
- PoW の目的 は、前回の「改ざんを検知する」を一歩進めて、「改ざんを現実的に不可能にする」こと。1ブロックの生成を意図的に重くすることで、全書き換えという抜け道を塞ぐ
- PoW のパズル は「先頭にゼロが N 個並ぶハッシュを探す」こと。探すのは大変だが、確かめるのは一瞬という非対称性が肝
- nonce は、データも前のハッシュも変えられないなかで唯一動かせる調整用の数字。条件を満たすハッシュが出るまで nonce を回し続ける
- マイニング は、この nonce 探しを大規模に行う総当たり計算そのもの。見つけた nonce が「仕事をした証明」になる
- 改ざんのコスト は、書き換えたブロック以降を全部採掘し直す必要があることから生まれる。ミニ実装でも、2ブロックの辻褄合わせに13万回の再計算が必要だった
「膨大な計算が必要」という説明の中身は、「条件を満たすハッシュが出るまで nonce を回し続ける、運任せの総当たり」でした。改ざんを隠すにはそれを全ブロック分やり直し、しかもネットワーク全体を追い抜く速度で行う必要がある——これが「書き換えに莫大な計算コストがかかる」の正体です。
前回の「ハッシュで繋がるデータ構造」に PoW を1つ加えるだけで、改ざん耐性が「検知できる」から「割に合わない」へと跳ね上がります。ブロックチェーンの強さが、魔法ではなく地道な計算量の積み重ねで成り立っていることが見えてきます。
最後までお読みいただきありがとうございました。