【入門編】 ERC-20トークン標準の不整合(approve/transferFrom) – IoT・OT(制御システム) & ブロックチェーンセキュリティ防御ガイド

玄関の鍵が「閉まったフリ」をしていたら?ERC-20トークンの意外な盲点

こんにちは!IoTやブロックチェーンの現場で、日々泥臭くセキュリティと向き合っているリサーチャーです。

今日は、ブロックチェーンの世界で「意外と見落とされがちな、ちょっとしたボタンの掛け違い」についてお話しします。スマートコントラクトを書き始めたばかりの方なら、一度は触れる「ERC-20トークン」。その送金処理で、実は「泥棒に鍵をかけたと思ったら、鍵が空回りしていた」というような、恐ろしい事態が起こることがあるんです。

なぜそんなことが起きるのか、どうすれば安全に守れるのか。一緒に紐解いていきましょう!

—

「戻り値なし」という罠:泥棒はそこを見逃さない

ERC-20という規格は、トークンの送金や承認を行うための共通ルールです。本来なら、誰かにトークンを移す処理(transferやtransferFrom)を呼び出すと、結果として「成功したよ(true)」という合図が返ってくるはずです。

しかし、世の中には「成功したか失敗したか、何も言わずに黙り込む」という少し風変わりなトークン(USDTの一部実装など)が存在します。

家の鍵で例えると…

あなたが泥棒(攻撃者)に入られないよう、玄関の鍵をかけた場面を想像してください。

  • 正常な鍵: 「ガチャン!」と音がして、誰が聞いても「鍵がかかったな」とわかります。
  • 今回の曲者: 「鍵を回した」という動作はしたけれど、音が全く鳴らない。鍵が本当に閉まったのか、それとも空回りしたのか、外からは判断がつきません。

もし、あなたのプログラムが「音が鳴らないと鍵が閉まっていないとみなす」という設定だった場合、鍵が閉まっているのに「エラーだ!」と勘違いして、システム全体が止まってしまうかもしれません。逆に、「音が鳴らなくても閉まったことにしよう」と楽観視していると、実は鍵が開けっ放しだったことに気づかず、資産が盗まれるという悲劇が起こります。

なぜ「SafeERC20」を使うのか?

そんな不安を解消するために、先人たちはSafeERC20という「強力な助っ人」を用意してくれました。

これは、どんな癖のあるトークンが来ても、「ちゃんと確認した?」「戻り値がないなら、今の処理の正当性を別の方法でチェックしよう」と、裏で厳しく管理してくれる「セキュリティガードマン」のような存在です。

対策コード:こう書けば安心!

OpenZeppelinという、世界中の開発者が信頼しているライブラリを使うのが鉄則です。以下のように、IERC20ではなくSafeERC20をインポートして使ってみましょう。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// SafeERC20ライブラリをインポートします
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

contract MyWallet {
    using SafeERC20 for IERC20; // これだけで準備完了!

    function secureTransfer(IERC20 token, address to, uint256 amount) external {
        // 直接 transfer を呼ぶのではなく、safeTransfer を使います
        // これにより、戻り値がなくても、失敗していれば自動的にトランザクションをリバート(中断)してくれます
        token.safeTransfer(to, amount);
    }
}

このコードのポイントは、safeTransfer を使っている点です。これを使うことで、もし相手のトークンが変な挙動をしていても、ガードマンが即座に「おっと、送金できていないぞ!」と処理を止めてくれるため、無駄な事故を防ぐことができます。

—

「一歩ずつ」が最強の防犯対策

セキュリティと聞くと、難しい数式やハッキングのニュースを想像して身構えてしまうかもしれません。でも、実際の現場で起きているのは、今回のような「ちょっとした仕様の不一致」を放置したことによるミスがほとんどです。

1. 「相手(トークン)は必ずしも行儀が良いとは限らない」と疑うこと。
2. 「自分で書くより、信頼されたライブラリ(SafeERC20など)の力を借りること」。
3. 「コードの戻り値は、常に疑ってかかること」。

この3つを守るだけで、あなたのスマートコントラクトの安全性はぐっと高まります。

最初は難しく感じるかもしれませんが、まずは「safeTransfer を使う」ということから始めてみてください。一歩ずつ、泥棒に隙を見せない強固なシステムを一緒に作っていきましょう!

もし「自分の書いているコードがこれでいいのか不安…」ということがあれば、いつでも相談してくださいね。現場のリアルな視点で、また深掘りしていきましょう!

コメント

タイトルとURLをコピーしました