ブロックチェーンの「ガス」とDoS攻撃:プログラムが凍りつく瞬間を回避せよ!
こんにちは!セキュリティの世界へようこそ。今日は、IoTデバイスやスマートコントラクトを開発する皆さんが、避けては通れない「ガス」と「DoS攻撃」の切っても切れない関係についてお話しします。
「ブロックチェーンって自動で動く魔法の仕組みじゃないの?」と思っているあなた。実は、プログラムの書き方一つで、自分自身のサービスを自ら破壊してしまう可能性があるのです。今日は、家の鍵に例えながら、一緒に学んでいきましょう!
—
1. 「ガス」って何?家の鍵で例えると…
ブロックチェーンの世界では、プログラムを動かすために「ガス」という燃料が必要です。これは、ガソリンスタンドで給油しないと車が動かないのと同じです。
さて、あなたの家の玄関を想像してください。
- 通常のドア: 鍵を回せばすぐに開きます(低コスト)。
- 巨大な要塞の門: 開けるために何百人もの作業員を雇い、巨大なレバーを引かなければなりません(高コスト)。
スマートコントラクトにおける「ガス代」は、この「作業員の数」です。処理が複雑であればあるほど、ガス代は高く、時間もかかります。
2. なぜ「DoS攻撃」が起きるのか?
「DoS攻撃(サービス拒否攻撃)」は、簡単に言うと「入り口を巨大な荷物で塞いで、誰も通れなくする嫌がらせ」です。
スマートコントラクトでよくあるミスは、「無限に増え続けるリスト」をループ処理することです。
// 危険なコードの例
address[] public userList; // ユーザーが数千人に増えると…
function payDividends() public {
// ユーザー全員に送金するループ
for (uint i = 0; i < userList.length; i++) {
// ここで一人ずつ送金すると、ガス代が爆発的に増える!
payable(userList[i]).transfer(100);
}
}
このコード、ユーザーが10人なら動きます。でも、1,000人になったらどうなるでしょう?
ループを回すためのガス代がブロックチェーンの上限(ブロックガスリミット)を超えてしまい、処理が途中で強制終了(エラー)してしまいます。
結果として、誰一人として配当を受け取れなくなる。「入り口が塞がった」状態、これがスマートコントラクトにおけるDoS攻撃のメカニズムです。
—
3. 泥棒から身を守るための「分割払い」戦略
では、どうすればこの「入り口の封鎖」を防げるのでしょうか。答えはシンプル、「一気にやるな、小分けにせよ」です。
家の鍵を一度に全部開けようとするから大変なのです。少しずつ開ける仕組みに変えていきましょう。
対策:Pull型支払い(Withdraw Pattern)
全員に強制的に送金する(Push)のではなく、各自が自分の分を取りに来る(Pull)ように設計を変更します。
// 安全なコードの例
mapping(address => uint) public balances; // 個人の残高を記録
// ユーザーが自分で自分の分を引き出す
function withdraw() public {
uint amount = balances[msg.sender];
require(amount > 0, "残高がありません");
balances[msg.sender] = 0; // 送金前にゼロにする(再入攻撃対策)
payable(msg.sender).transfer(amount); // 自分の分だけ送金
}
このように設計を変えるだけで、ループ処理が消え、ガス代の上限に引っかかるリスクはゼロになります。一人ひとりが自分のタイミングで鍵を開けるので、行列ができることもありません。
—
4. セキュリティリサーチャーからの教訓
現場で多くのコードを見てきましたが、初心者が陥りがちな落とし穴は「便利さを追求しすぎて、処理を詰め込みすぎること」です。
- ループ処理の回数を予測する: 「このリストはどこまで増える?」と常に自問自答してください。
- 外部呼び出しは慎重に: 外部のプログラムを呼び出す処理は、何が起きるか分かりません。タイムアウトやガス不足を考慮に入れないのは、鍵をかけずに外出するのと同じです。
- 「制限」を設計に組み込む: どうしてもループが必要な場合は、一度に処理する件数を
LIMIT = 50のように定数で縛りましょう。
まとめ:一歩ずつ対策を学んでいきましょう!
セキュリティとは、「楽観的な未来を信じつつ、最悪の事態に備えること」です。「自分のプログラムは大丈夫」と思わず、「もしこのループが100万回回ったら?」と想像してみてください。
皆さんが書くコードが、誰かの資産を守る強固な盾になることを願っています。また次回のセキュリティ講座でお会いしましょう!
コメント