リエントランシー攻撃の技術的な原理は何か、コントラクト操作の「順序」がなぜそれほど重要なのか?リエントランシーの根本的な脆弱性は、スマートコントラクトが資金を転送した後に自分の台帳を更新することにあります——この操作順序が悪用の機会を生みます。正しいアプローチ:まず台帳を更新し(ユーザーの残高をゼロに設定)、それからユーザーに資金を転送します。脆弱なパターン:ユーザーに資金を転送し、転送完了後に台帳を更新します。問題:EthereumのCall()メソッドはコントラクトに支払うとき、ETHを受け取った瞬間に受取コントラクトのフォールバック関数を実行できます。攻撃者のフォールバック関数が元のコントラクトのwithdrawを再び呼び出します——この時点で台帳はまだ更新されていないので残高チェックがまた通ります。
The DAO攻撃とは何か、なぜそれほど重要だったのか?The DAO(分散型自律組織)は2016年のイーサリアム上のクラウドファンディングスマートコントラクトプロジェクトで、当時約1億5,000万ドル相当のETHを調達しました。2016年6月、攻撃者はThe DAOの引き出しコントラクトのリエントランシー脆弱性を悪用して繰り返し引き出し、最終的に約360万ETH(当時約6,000万ドル相当)を転送しました。イーサリアムコミュニティはハードフォーク(ブロックチェーンの状態を変更)して盗まれたETHをDAO投資家に強制返却するかどうかという根本的な選択に直面しました。今日のイーサリアム(ETH)の由来であり、ハードフォークを認めなかった少数派は元のチェーンを維持し——これがイーサリアムクラシック(ETC)の由来です。
リエントランシー攻撃をどう防ぐか?検証済みのパターンは何があるか?いくつかの標準的な防衛アプローチ。第一に、Checks-Effects-Interactions(CEI)パターン:最も基本的で重要な防衛原則。コントラクトの関数はこの順序で実行すべきです:Checks(まずすべての条件チェック)→ Effects(すべての内部状態を更新)→ Interactions(最後に外部コントラクトやアドレスと対話、送金など)。第二に、ReentrancyGuard(ミューテックスロック):OpenZeppelinが標準のReentrancyGuardモジュールを提供しています——本質的にはブール値のミューテックスロックで、関数実行中に「ロック済み」に設定し完了後にアンロックします。第三に、生のcall()を避ける:transfer()とsend()はデフォルトで2,300 Gasのみ転送します——複雑なロジックのフォールバックを実行するには不十分です。
リエントランシー攻撃以外に一般的なスマートコントラクトの脆弱性タイプは何か?同様に重要なスマートコントラクトの脆弱性タイプをいくつか知っておきたい。整数オーバーフロー/アンダーフロー:Solidity 0.8の自動オーバーフロー保護前、数値計算は「ラップアラウンド」できました——残高偽造に悪用されました。安全でない外部呼び出し:外部コントラクトを呼び出すとき、戻り値を不正確に処理すると攻撃者が実行フローを制御できます。ロジックエラー:技術的な脆弱性でなくビジネスロジックの設計エラー。フラッシュローン攻撃:フラッシュローンの瞬間的な巨大流動性を使って1つのトランザクション内で市場やオラクル価格を操作します。
擬似コードを使ってリエントランシー攻撃の完全なフローを説明しましょう。各アドレスの残高を記録するbalancesマッピングを持つシンプルなイーサリアムの預金/引き出しコントラクトを想像してください。
脆弱なwithdraw関数:先に送金し、後で残高を更新します。
攻撃者はフォールバック関数を持つ悪意のあるコントラクトをデプロイします:ETHを受け取った瞬間にvictim.withdraw()を再度呼び出します。
攻撃のフロー:攻撃者がvictim.withdraw()を呼び出す→残高チェックが通る→コントラクトが攻撃者にETHを送る→フォールバックがトリガーされて再びwithdrawを呼び出す→この時点で残高はまだ更新されていないのでチェックがまた通る→ループ。
修正されたCEIバージョン:balances[msg.sender] = 0を先に行い、その後.call{value: ...}を行います。1行の順序変更で攻撃全体がブロックされます。
リエントランシーはスマートコントラクト設計の根本的なエンジニアリングのトレードオフを明らかにします:外部呼び出し(別のアドレスやコントラクトへの資金転送)と状態更新の間の順序。直感的な「先に送金、後で記録」のアプローチはビジネスロジックを明確にしますが、リエントランシーリスクを導入します。CEIの「先に記録、後で送金」のアプローチはビジネスロジックとしてやや直感に反しますが、リエントランシー問題を完全に排除します。このトレードオフには明確なコンセンサスの答えがあります——常にCEIを使う。しかしそれはスマートコントラクトのコードのセキュリティと直感的なビジネスロジックが時に微妙な衝突を持つことを思い出させます。