本文へ移動

プロキシコントラクト

プロキシコントラクトは、プロキシのアドレスと状態を維持したまま、呼び出しを実装コードへ転送します。プロキシ方式の仕組みと、アップグレード、ストレージ、管理者に関するリスクを解説します。

更新日

教育目的の参考情報であり、投資助言ではありません。投資により損失が生じる可能性があります。

直接の答え

プロキシコントラクトとは、別のコントラクト(通常は実装コントラクトまたはロジックコントラクトと呼ばれます)へ呼び出しを転送する仲介コントラクトです。一般的な EVM の設計ではプロキシが delegatecall を使用するため、実装のコードはプロキシのコンテキストで実行され、状態と残高はプロキシのアドレスに残ります。

この間接層により、システムはユーザー向けアドレスを固定したまま実装を変更できます。また、多数のプロキシがコードを共有する場合は、デプロイ費用を抑えられます。ただし、プロキシが自動的にアップグレード可能になるわけではありません。単一の実装を永続的に参照する最小プロキシもあれば、実装またはビーコンを変更するための制御された仕組みを持つアップグレード可能プロキシもあります。

したがって、ユーザーは現在の実装と、それを変更できる権限の両方を評価する必要があります。プロキシのバイトコードが検証済みであるだけでは、明日どのコードが実行されるかは分かりません。

仕組み

呼び出しがプロキシに届くと、フォールバック経路が呼び出しデータを実装へコピーまたは転送します。delegatecall では address(this) はプロキシを指し、ストレージの読み書きはプロキシに作用し、元の msg.sendermsg.value は維持されます。その後、プロキシは実装の返却データを返すか、実装とともにリバートします。

プロキシのメタデータはアプリケーションの状態と同じストレージ空間を共有するため、標準化されたスロットは偶発的な衝突の回避に役立ちます。ERC-1967 は実装アドレス、ビーコンアドレス、任意の管理者用スロットを定義し、それらの値が変わった際のイベント発行を推奨しています。この標準はプロキシを調査しやすくしますが、それだけでアップグレードが安全になるわけではありません。

一般的な設計では、アップグレード権限を異なる場所に置きます。

  • トランスペアレントプロキシ:プロキシが管理用呼び出しと通常のユーザー呼び出しを区別し、一般には独立した管理者コントラクトを利用します。
  • UUPS プロキシ:アップグレードロジックは実装内にあり、実装は変更を承認し、想定されたアップグレードインターフェースとの互換性を保つ必要があります。
  • ビーコンプロキシ:プロキシはビーコンに実装を問い合わせます。一つのビーコンを変更すると、それに従うすべてのプロキシに影響する可能性があります。
  • 最小クローン:多数の小さなプロキシが共有コードへ委譲し、多くの場合、アップグレード経路は一切ありません。

ユーザー残高を保持し、実装 A に委譲するボールトプロキシを考えます。ユーザーはプロキシアドレスを通じて預け入れ、実装 A のコードがプロキシのストレージにある残高記録を更新します。

その後、ガバナンスが ERC-1967 の実装スロットを実装 B に変更します。プロキシアドレスと記録済み残高は移動しませんが、以後の呼び出しでは実装 B のコードが実行されます。B がストレージレイアウトを維持し、意図したルールを実装していれば、ユーザーは同じアドレスで新しい動作を利用できます。

B がストレージ変数を並べ替えたり、認可チェックを省いたり、アップグレード権限者が制御する出金経路を追加したりすると、同じアップグレードで会計が壊れたり資産が危険にさらされたりします。したがって実務では、単にプロキシかどうかではなく、誰がどの遅延と検証の下で実行経路を変更できるかを確認します。

リスク

  • アップグレード鍵の侵害:管理者、マルチシグ、またはガバナンス手続きによって、悪意あるコードや欠陥コードが導入される可能性があります。
  • ストレージレイアウトの非互換:変数の順序、型、継承を変更すると、新しいコードが既存の状態を誤読または上書きするおそれがあります。
  • 初期化の失敗:コンストラクターはプロキシのストレージを初期化しません。初期化保護がない、または再実行できると、別のアカウントが特権ロールを取得する可能性があります。
  • 呼び出し経路の予想外な動作:関数セレクターの衝突、管理者専用ルーティング、予期しないビーコンにより、実行経路が表示されたインターフェースと異なる場合があります。
  • 共有アップグレードの影響範囲:一つのビーコンまたは実装に関する決定が、多数のコントラクトインスタンスを同時に変更する可能性があります。

資産を預け入れたり承認を付与したりする前に、現在の実装またはビーコンをオンチェーンで特定し、アップグレード権限とタイムロックを確認し、検証済みソースとストレージ互換性を調べ、該当する場合は最近の UpgradedBeaconUpgradedAdminChanged イベントを確認します。実行経路は変わり得るため、最初の審査後も監視が必要です。

よくある誤解

  • 「プロキシは意味のある状態を保持しない。」delegatecall では、ロジックが別のアドレスから提供されても、アプリケーションの状態と多くの場合の資産はプロキシに属します。
  • 「実装が検証済みなら、システムはトラストレスである。」アップグレード鍵、ガバナンス、ビーコン、初期化、将来の実装は引き続き信頼モデルの一部です。
  • 「すべてのプロキシはアップグレードできる。」クローンなどの固定プロキシは一つの実装へ永続的に委譲することがあります。アップグレード可能性は、具体的な設計と認可コード次第です。

関連トピック

出典

ナビゲーション

Wiki を検索...