Etherscan verified ソース汚染 — なぜ「verified」は「バイトコード」ではないのか

確度: 概ね確度あり 更新 2026-06-03 要再確認 2026-12-03 出典 4 機械翻訳
#security#smart-contract#verification#etherscan#sourcify#bytecode
目次

Wiki ルート

このエントリは セキュリティ の配下にある。実地の対応物として スマートコントラクト bytecode フォレンジック — 三層 verify 技術 と併せて読み、表示されているソースが本物であっても 次の implementation がそうではないケースについては プロキシ・アップグレード可能コントラクトの rug パターン — admin のアップグレード権限がバックドアになる と併せて読むとよい。

[!info] TL;DR 緑色の “Contract Source Code Verified” バッジは、ブロックエクスプローラが何らかのソースを再コンパイルし、デプロイされているものと一致する バイトコードを得たことを意味する — 通常はコメント、変数名、メタデータの差異を許容する。それはソースが良性であること、それがプロキシの 拘束力ある ロジックであること、あるいは一致がバイト単位で厳密であることを意味し ない。バッジを安全性の証明として扱うことが信頼のギャップであり、「verified ソース汚染」はそれを悪用する技術の総称である。グラウンドトゥルースは、レンダリングされたソースペインではなく、オンチェーンのバイトコードとアップグレードグラフである。

「verified」が実際に主張すること

検証は、提出されたソースを宣言されたコンパイラ設定の下で再コンパイルし、その出力をデプロイされたバイトコードと比較する。その主張の強さはツールと一致の種類によって異なる:

一致の種類何が保証されるか何が保証され ない
Full / exact match (Sourcify)デプロイされたバイトコードが、付加されたメタデータハッシュを 含めて 再コンパイル結果とバイト単位で等しい — つまり正確なソースバイトが固定される意図については何も。良性に見えるソースでも依然として悪意あり得る
Partial match (Sourcify) / 典型的なエクスプローラの “verified”ランタイムの挙動が一致し、メタデータハッシュ領域 を除いて バイトコードが等しいコメント、変数名、ソースパス、その他のメタデータフィールドが、著者が実際にコンパイルしたものと異なり得る
Unverifiedソースに関する主張は一切なし

Solidity コンパイラは、コントラクトメタデータの IPFS ハッシュをバイトコードに付加する。そのハッシュは正確なコンパイルのフィンガープリントである。Full match はそれをチェックするが、多くのエクスプローラの “verified” フローはチェックしない。したがって partial-match バッジは、同じ挙動にコンパイルされる一方で 名前とコメントが安全に見えるよう編集された ソースと整合する — その装飾的なレイヤーこそがまさに汚染の表面である。

バッジが捕捉しない汚染技術

  • プロキシによる間接化。 verified なコントラクトはプロキシであり、それが委譲する implementation は別途(未)検証であり得て、差し替え可能である — プロキシ・アップグレード可能コントラクトの rug パターン — admin のアップグレード権限がバックドアになる を参照。ユーザーはプロキシのソースを読むが、ロジックは implementation で実行される。
  • メタデータ領域の編集。 partial match の下では、コメントと識別子は制約されない。同情を誘う命名(SafeVaultonlyTrustedRelayer)は、レビュアーが読み飛ばす挙動を覆い隠し得る。
  • コンストラクタ vs ランタイムの混同。 検証はランタイムバイトコードを対象とする。コンストラクタ時の作用や immutable は過小検査されやすい。
  • 「既知の良いフォークのように見える」。 監査済みの上流に似せてレンダリングされながら、レッドラインの領域で乖離しているソース — まさに Fork and Rebrand プロジェクトの五層監査フレームワーク が捕捉するために作られた失敗モード(Layer 1 上流 diff、Layer 3 バイトコードフィンガープリント)。

バッジのクロスチェック(公開・再現可能)

  1. デプロイされたランタイムバイトコード(eth_getCode(addr, "latest"))を取得し、いかなる比較の前にも末尾のメタデータハッシュを除去する。
  2. 提出されたソースを、宣言された solc バージョンと optimizer 設定でローカルに再コンパイルし、(1) と diff する。メタデータ除去後に空でない diff があれば、それは強いシグナルである。
  3. ソースのコメント/名前がレビューにとって重要な場合、partial match よりも full/exact match(例: Sourcify)を優先する。
  4. 対象がプロキシの場合、ERC-1967 スロットから implementation を解決し それ を検証してから、Upgraded(address) イベントから過去の implementation を列挙する。
  5. 未検証コードのセレクタレベルのチェックについては、4 バイトのディスパッチャを復元しセレクタを逆引きする — スマートコントラクト bytecode フォレンジック — 三層 verify 技術 における Layer 2 の技術。

なぜこれが重要か

バッジで十分な場合

  • 実際にソースを読んだ、非プロキシでイミュータブルなコントラクトにおける full/exact 一致 — 主張は強く、ロジックは変化し得ない。
  • 最悪ケースの影響が無視できる、低リスクの read-only/view コントラクト。

関連

ソース