⛓️

Ethereumのスマートコントラクト依存関係リスク ~4100万コントラクトのオンチェーン分析から見えた集中化の実態~

2025/03/28に公開

Ethereumのスマートコントラクト依存関係リスク ~4100万コントラクトのオンチェーン分析から見えた集中化の実態~

この記事は以下の論文をもとに書かれています。
https://arxiv.org/abs/2503.19548v1

TL;DR

  • Ethereum上の4100万以上のスマートコントラクトと110億件のインタラクションを分析した大規模研究によると、ブロックチェーンの「分散化」は幻想かもしれない
  • コントラクトトランザクションの59%が複数のコントラクトに関与しており、依存関係リスクが存在する
  • わずか11のデプロイヤー(0.001%)がアクティブなコントラクトの50%を制御するという極端な集中化が明らかに
  • 最も依存されている3つのコントラクトは可変(アップグレード可能)であり、エコシステム全体が変更可能なコントラクトに依存している
  • 実際のスマートコントラクトプロトコルの依存関係は公式ドキュメントよりも複雑で不透明

はじめに:ブロックチェーンの「分散化」という幻想

ブロックチェーン技術、特にEthereumのような公開チェーンの最大の売りは「分散化」である。「誰も特権的な権限を持たない」「単一障害点がない」「検閲耐性がある」といった特徴が、従来の中央集権的なシステムと比較した際の大きな利点とされている。

でも、本当にそうなのだろうか?

私は以前からEthereumのスマートコントラクトエコシステムを眺めていて、「思ったより集中化されているのではないか」という違和感を感じていた。特に、DeFiプロトコルやNFTプロジェクトなど、多くのプロジェクトが同じライブラリやコントラクトに依存している様子を見ると、そこに潜むリスクが気になっていた。

そんな中、最近発表された「スマートコントラクト依存関係リスクのオンチェーン分析:Ethereumの場合」という論文を読んで、「やっぱり!」と思わずうなってしまった。この論文は、2024年12月までのEthereum上の4100万件以上のコントラクトと110億件のインタラクションを分析した、スマートコントラクトの依存関係に関する初の大規模実証研究である。

この記事では、この論文の重要な発見を紹介しながら、Ethereumエコシステムに潜む依存関係リスクについて考えてみる。特に、スマートコントラクト開発者やDeFiユーザーにとって、これらのリスクがどのような意味を持つのかを掘り下げていく。

スマートコントラクトの基本と依存関係

まず、スマートコントラクトとその依存関係について簡単におさらいしておこう。

スマートコントラクトは、Ethereum上にデプロイされるプログラムで、一意のアドレスによって識別される。コントラクトは主に2つの方法でデプロイできる:

  1. 外部所有アカウント(EOA)を使用する方法
  2. 他のコントラクト(ファクトリーパターン)を使用する方法

特に2つ目の方法は、共通のロジックを持つ複数のコントラクトインスタンスを効率的に作成できるため、広く使われている。

スマートコントラクト間のインタラクションには、主に以下の3つのタイプがある:

  • CALL: 標準的な関数呼び出し。別々のストレージコンテキストを維持する。
  • STATICCALL: 読み取り専用の呼び出し。状態を変更できない。
  • DELEGATECALL: 呼び出し元のコンテキスト内で外部コードを実行する。アップグレード可能性に役立つが、セキュリティリスクも伴う。

これらのメカニズムにより、スマートコントラクトは相互に依存し合い、複雑なシステムを構築できるようになっている。しかし、この依存関係こそが、今回の研究で明らかになったリスクの源泉である。

驚きの発見1:コントラクトの相互依存性

論文の最初の発見は、スマートコントラクトの相互依存性に関するものだ。

2024年のデータによると、コントラクトトランザクションの59%が複数のコントラクトに関与しており、1つのトランザクションに関わるコントラクトの中央値は4つだった。つまり、多くのトランザクションが複数のコントラクトを経由して処理されているということだ。

これは何を意味するのだろうか? 簡単に言えば、あるコントラクトの脆弱性や問題が、それに依存する他の多くのコントラクトに波及する可能性があるということである。例えば、DeFiプロトコルがあるトークンコントラクトに依存している場合、そのトークンコントラクトに問題があれば、DeFiプロトコル全体が影響を受けることになる。

依存関係の例
// プロトコルAのコントラクト
function executeSwap(address tokenAddress, uint256 amount) public {
    // 外部トークンコントラクトに依存
    IERC20(tokenAddress).transferFrom(msg.sender, address(this), amount);
    // 処理の続き...
}

上記のような依存関係は、一見すると問題ないように見えるが、tokenAddressが悪意のあるコントラクトだったり、脆弱性を持つコントラクトだったりすると、予期せぬ動作を引き起こす可能性がある。

驚きの発見2:極端な集中化

次の発見は、私にとって最も衝撃的だった。

Ethereumエコシステムは極端な集中化を示しており、わずか11のデプロイヤー(全体の0.001%)がアクティブなコントラクトの2050万件(50%)を制御しているのだ。さらに、上位100のデプロイヤーを合わせると、全アクティブコントラクトの80%以上を占めている。

これは、Ethereumが「高度に分散化されたエコシステム」であるという一般的な認識とは大きく異なる。実際には、ごく少数のエンティティがコントラクトインフラに対して不均衡な影響力を持っているのだ。

特に懸念されるのは、上位10のデプロイヤーのうち8つが主にプロキシコントラクトをデプロイしていることである。プロキシコントラクトは、DELEGATECALLを使用して実装アドレスと対話する。これは、所有者が侵害された場合に大きなリスクとなる。

例えば、OpenSeaの旧Wyvernプロトコルでは、各ユーザーに個人のプロキシコントラクトが割り当てられ、それらはすべてOpenSeaのマスターキーによって制御される単一の実装コントラクトに関数呼び出しを委任していた。このマスターキーが侵害された場合、攻撃者はすべてのユーザープロキシを一度に操作し、NFTや資産を危険にさらす可能性があったのだ。

驚きの発見3:可変性のリスク

3つ目の重要な発見は、最も依存されているコントラクトの多くが可変(アップグレード可能)であるということだ。

分析によると、最も頻繁に呼び出される上位10個のコントラクトのうち、DELEGATECALLを使用するものの多くはプロキシパターンの実装コントラクトだった。特に、USDCコントラクトは過去に3回アップグレードされている(バージョン1.0からバージョン2.0、そしてバージョン2.1、2.2へ)。

これは大きなセキュリティ上の懸念事項である。トークンメンテナが侵害された場合、トークン資金全体を盗むことが可能になるからだ。

アップグレード可能なプロキシコントラクトの例
// プロキシコントラクト
contract Proxy {
    address public implementation;
    address public admin;
    
    constructor(address _implementation) {
        implementation = _implementation;
        admin = msg.sender;
    }
    
    function upgrade(address _newImplementation) external {
        require(msg.sender == admin, "Only admin can upgrade");
        implementation = _newImplementation;
    }
    
    fallback() external payable {
        // 実装コントラクトに処理を委任
        (bool success, bytes memory data) = implementation.delegatecall(msg.data);
        require(success, "Delegatecall failed");
        
        assembly {
            let returnDataSize := returndatasize()
            returndatacopy(0, 0, returnDataSize)
            switch success
            case 0 { revert(0, returnDataSize) }
            default { return(0, returnDataSize) }
        }
    }
}

上記のようなプロキシパターンは、コントラクトをアップグレード可能にするために広く使われているが、adminが侵害されると、実装コントラクトを悪意のあるものに差し替えられるリスクがある。

驚きの発見4:透明性の欠如

最後の発見は、実際のスマートコントラクトプロトコルの依存関係が、公式に文書化されているものよりも著しく複雑であるということだ。

研究者たちは、UniswapとLidoという2つの主要なDeFiプロトコルを詳細に分析した。その結果、Uniswapでは48個中17個、Lidoでは69個中27個の依存関係が文書化されていないことが判明した。

これは、Ethereumの透明性という精神を損ない、不必要な攻撃対象面を作り出している。ユーザーや開発者は、公式ドキュメントだけでは、プロトコルの全体像やリスクを正確に把握できないのだ。

開発者とユーザーへの示唆

これらの発見は、スマートコントラクト開発者とDeFiユーザーの両方にとって重要な示唆を持っている。

開発者向けの示唆

  1. 依存関係の最小化: 可能な限り、外部コントラクトへの依存を減らそう。特に、アップグレード可能なコントラクトへの依存は慎重に検討すべきである。

  2. 透明性の向上: すべてのコントラクトとその依存関係を明確に文書化しよう。ユーザーがリスクを正確に評価できるようにすることが重要だ。

  3. プロキシパターンの慎重な使用: プロキシパターンは便利だが、セキュリティリスクも伴う。管理者キーの保護や、アップグレードプロセスの透明性確保などの対策を講じよう。

より安全なアップグレードメカニズムの例
contract SaferProxy {
    address public implementation;
    address public admin;
    uint256 public upgradeTimelock;
    address public pendingImplementation;
    
    constructor(address _implementation) {
        implementation = _implementation;
        admin = msg.sender;
    }
    
    function proposeUpgrade(address _newImplementation) external {
        require(msg.sender == admin, "Only admin can propose upgrade");
        pendingImplementation = _newImplementation;
        upgradeTimelock = block.timestamp + 2 days; // 48時間の遅延
    }
    
    function executeUpgrade() external {
        require(block.timestamp >= upgradeTimelock, "Timelock not expired");
        require(pendingImplementation != address(0), "No pending implementation");
        implementation = pendingImplementation;
        pendingImplementation = address(0);
    }
    
    // fallback関数は前と同じ
}

ユーザー向けの示唆

  1. リスク認識: DeFiプロトコルを利用する際は、そのプロトコルが依存するコントラクトのリスクも考慮しよう。特に、大量の資金を預ける場合は重要だ。

  2. 分散投資: 資金を複数のプロトコルに分散させることで、単一の依存関係リスクを軽減できる。

  3. 公式ドキュメントだけに頼らない: 可能であれば、オンチェーンデータや第三者の監査レポートも参照して、プロトコルの実際の依存関係を理解しよう。

まとめ

この研究は、Ethereumエコシステムに潜む依存関係リスクを明らかにした重要な一歩である。4100万件のコントラクトと110億件のインタラクションという膨大なデータを分析することで、以下の4つの重要な洞察が得られた:

  1. コントラクトトランザクションの59%が複数のコントラクトに関与しており、依存関係リスクが存在する
  2. わずか11のデプロイヤーがアクティブなコントラクトの50%を制御する極端な集中化が見られる
  3. 最も依存されているコントラクトの多くは可変であり、エコシステム全体が変更可能なコントラクトに依存している
  4. 実際のスマートコントラクトプロトコルの依存関係は公式ドキュメントよりも複雑で不透明である

これらの発見は、Ethereumが「完全に分散化されたエコシステム」であるという一般的な認識に疑問を投げかける。実際には、少数のエンティティが不均衡な影響力を持ち、それがシステム全体のリスクとなっているのだ。

私自身、この研究結果を見て、ブロックチェーンプロジェクトに関わる際の依存関係管理の重要性を再認識した。特に、プロキシパターンを使用する場合は、そのリスクを十分に理解し、適切な対策を講じることが不可欠だと感じている。

今後、スマートコントラクトの依存関係を文書化、分析、保護するためのより良いツールとプラクティスが開発されることを期待している。それまでは、開発者もユーザーも、これらのリスクを認識し、慎重に行動することが重要だ。

以上。

CryptoAI, Inc.

Discussion