720 / 736OVFL

Value Overflow Incident

ブロック 74 638 の値オーバーフロー事件

Value Overflow Incident は 2010年8月15日の重大なコンセンサス障害である。ブロック 74 638 の取引が 64 ビット加算のオーバーフローを利用し、二つの巨大な出力を検証に通して、採掘中の枝に 2^64 satoshi を余分に加えた。

不具合は暗号技術や発行スケジュールではなく、検証ルールの実装にあった。各出力は正の値だったが、その合計がオーバーフローして負の値になった。その結果、入力とこの負の合計との差が手数料として扱われた。バージョン 0.3.10 は個々の出力と累計額に上限を設け、修正後の分岐への再編成によって、不正なブロックは現在につながる履歴から除外された。

2010年8月15日、開発者の Jeff Garzik は奇妙なブロック 74 638 を報告した。トランザクション 1d5e512a9723cbef373b970eb52f1e9598ad67e7408077a82fdac194b65333c9 は、0.50 BTC の入力を一つ消費し、巨額の出力を二つ生成していた。当時の printblock の記録によると、それぞれの出力は 92 233 720 368.54275808 BTC だった。この不具合を悪用したトランザクションの作成者は、確実には特定されていない。公開記録が示すのはトランザクションのデータであり、作成者の身元や動機ではない。 [1]

当時の Bitcoin は金額を satoshi 単位の符号付き64ビット整数で扱っていた。各出力の整数値は正で、int64 の最大値をわずかに下回っていた。16進数の記録 0x7ffffffffff85ee0 も、その値を裏付けている。しかし、二つを足した 18 446 744 073 708 551 616 satoshi は表現可能な範囲を超え、オーバーフローによって −1 000 000 satoshi になった。旧版の検証処理は、この負の合計を入力と比較して受け入れてしまった。署名が破られたのではなく、計算上の不具合だった。議論の最初に掲載された JSON の数値は小数点以下の末尾が異なるため、ここでは printblock と16進数の記録の両方で確認できる整数値を使って正確に計算している。 [1]

出力の合計が −0.01 BTC になったため、入力の 0.50 BTC との差から、見かけ上 0.51 BTC の手数料が生まれた。その結果、マイナーは基本報酬の50 BTCではなく、coinbase で 50.51 BTC を受け取った。消費された入力を差し引き、coinbase の過剰分も加えると、この二つの巨額出力によって不正な分岐上の供給量は正確に 18 446 744 073 709 551 616 satoshi 増えた。これは 2^64 satoshi、つまり 184 467 440 737.09551616 BTC に当たる。この数字は、二つの出力を単純に足した値ではない。 [2]

コミュニティーは時間圧力の中で公開対応した。Lfm は深刻なバグと呼び、Gavin Andresen は各出力を 2100万 BTC と比較する迅速な検査を提案し、Satoshi Nakamoto はより広い修正を公開した。負または過大な出力を拒否し、加算ごとに過大な累計額も拒否する。Satoshi は新しい有効な分岐が不正な分岐により早く追いつき、置き換えられるように、採掘の一時停止も求めた。 [2]

Satoshi は 2010年8月15日のフォーラム時刻 23:48 にバージョン 0.3.10 を告知した。Garzik の報告から約五時間四十分後だった。更新ノードは悪用取引とブロック 74 638 を無効とし、最後の共通有効ブロック上に構築した。当時の告知は後に良い枝が悪い枝を追い越したと述べ、更新クライアントは blockchain ファイルを手動削除せず自動再編成できた。 [3]

中央のデータベースで過去のブロックを書き換えたわけではない。当時は二つの履歴が競合していた。旧版のノードは元のルールに従って問題のブロックを受け入れた。一方、修正済みのノードはそれを拒否し、最後の有効な先行ブロックにつながる作業だけを受け入れた。修正後の分岐により多くの Proof of Work が積み重なると、ネットワークはそちらを採用し、過剰発行を含むブロックは現在につながる履歴から外れた。決め手となったのは、利用者とマイナーによる新しいルールの導入と、その後に行われた作業であり、一人の管理者の命令ではなかった。 [3]

当時追加された保護処理は、現在の Bitcoin Core にも残っている。CheckTransaction は、負の値の出力、MAX_MONEY を超える出力、MoneyRange の範囲外になる累計額を拒否する。加算するたびに検査することで、比較前に合計がオーバーフローするのを防いでいる。ソースコードのコメントには CVE-2010-5139 が明記されている。一方、入力の重複を調べる別の検査には、これとは異なる事件である CVE-2018-17144 への言及がある。 [4]

この事件は、2100万枚という上限が、ハッシュだけで守られる魔法の定数ではないことを示している。上限を実際に守るのは、厳密な検証ルールとその正しい実装だ。監査では、各値の範囲、安全な加算、coinbase と手数料、検査の順序、境界値を使ったテスト、独立した実装同士の一致まで確認する必要がある。この歴史は、初期コミュニティーが素早く不具合を修正できたことと、当時の対応が少数の開発者やマイナー、そして人同士の直接の調整に強く依存していたことの両方を伝えている。 [5]

理解を深めるには、この項目とあわせて次もお読みください Bitcoin Core, コンセンサスルール, トランザクション, UTXO, Reorg, Soft Fork.

01有効な Bitcoin に 1840億 BTC が存在したことはあるか?

悪用ブロックにより、当時採掘された不正な分岐には短時間存在した。修正ノードがその枝を拒否し、有効な分岐が再編成したため、巨大出力は現在の現在採用されている blockchain や UTXO 集合に含まれない。ただし事件自体はブロックと当時の対応で記録されている。

02事件は 2100万枚の上限を永久に破ったのか?

現在受け入れられる履歴では違う。修正されたコンセンサス規則が誤ブロックを拒否し、出力は再編成で消えた。ただし上限が正しい検証と実際に動くソフトウェアに依存し、文書の記述だけでは供給を強制できないことを示した。

DOC · 001BitcoinTalk — Strange block 74638一次資料 DOC · 002BitcoinTalk — overflow bug SERIOUS一次資料 DOC · 003BitcoinTalk — Version 0.3.10, block 74638 overflow patch一次資料 DOC · 004Bitcoin Core — current CheckTransaction overflow checks文書 DOC · 005CVE — CVE-2010-5139文書
改訂日: 一次資料を優先 · 投資助言ではありません