プロキシパターンとは何ですか?

Hans-Helmut Kraus
Hans-Helmut Kraus
Ethereum smart contract auditor and security expert; 以太坊智能合约审计师与安全专家。

はい、承知いたしました。この「プロキシパターン」が一体何なのか、ざっくばらんに話しましょう。


プロキシパターン(Proxy Pattern)とは?

ねえ、君。プロキシパターンについて話そうか。この名前に怖がらないで、実はこれ、すごく分かりやすいんだ。

これは、大スターとそのマネージャーだと想像してみてくれ。

君が大スターに映画出演を依頼したいとする。直接彼の家に押しかけたりはしないよね?おそらく見つけられないだろうし。まずは彼のマネージャーに連絡を取るはずだ。

このシナリオでは:

  • :クライアント(Client)、つまりリクエストを出す人だ。
  • 大スター:リアルサブジェクト(Real Subject)、つまり実際に仕事(演技)をする人だ。
  • マネージャー:それが**プロキシ(Proxy)**だ。

君はマネージャーと協業について話し、マネージャーが君の要望を大スターに伝える。君にとっては、まるで大スターのチームと直接コミュニケーションを取っているように感じるだろう。しかし実際には、間にマネージャーが挟まっているんだ。

この「マネージャー」は何ができるんだろう?彼はただの伝言係じゃないんだ:

  1. アクセス制御(Access Control):どんな依頼でも引き受けるわけじゃない。マネージャーはまず、脚本が信頼できるか、ギャラは適切か、スケジュールに問題はないか、などをチェックしてくれる。彼のチェックを通過して初めて、リクエストは大スターの元に届く。これが「アクセス制御」だ。
  2. 機能の追加(Adding Functionality):契約を結ぶ前に、マネージャーは法務処理、メディア対応の手配、スケジュールの調整なども手伝ってくれるかもしれない。これらは大スター自身の核心的な「演技」の仕事ではなく、マネージャーが付加するサービスなんだ。
  3. 遅延ロード(Lazy Loading):大スターが海外で休暇中で、邪魔されたくない場合もあるだろう。マネージャーはまず君とすべての事柄を話し合い、契約書を確認し、最後の署名を待つことができる。スター本人の登場が必要になった時に、彼を呼び戻すんだ。こうすることで、最初からスターの貴重なリソース(時間)を占有することがなくなる。

だから、プロキシパターンの核となる考え方は:

他のオブジェクトへのアクセスを制御するために、そのオブジェクトの身代わりやプレースホルダーを提供する。

クライアント(君)はターゲットオブジェクト(スター)とやり取りしていると思っているが、実際にはずっとプロキシ(マネージャー)とコミュニケーションを取っているんだ。プロキシはターゲットオブジェクトと全く同じインターフェース(例えば、「協業について話せる」など)を提供しているため、君にとってはシームレスで透過的だ。


なぜそれが「イーサリアム」でそんなに重要なの?

さて、ではなぜこのパターンがイーサリアムでこれほど重要なのか、君の質問タグに関連する核心的なポイントについて話そう。

ご存知の通り、スマートコントラクトはイーサリアムにデプロイされると、そのコードは永久に修正不可能になる。これはまるで文字を石に刻んだようなもので、一文字でも変えたい?無理だ!

これが致命的な問題を引き起こす:もしコントラクトのコードにバグがあったり、将来的に新しい機能を追加したくなったらどうする?

手詰まりだ。新しいコントラクトを再デプロイするしかない。しかし、以前の古いコントラクト内のデータ、ユーザー、資産はどうなる?すべてのユーザーを新しいコントラクトアドレスに移行させるのか?それはまさに災害であり、面倒で安全ではない。

プロキシパターンは、この「石に刻まれた」問題を解決するために存在するんだ。

それは巧妙に一つのコントラクトを二つの部分に分解する:

  1. プロキシコントラクト (Proxy Contract)

    • このコントラクトは、君の携帯電話番号のようなものだ。決して変わらず、アドレスは固定されている。すべてのユーザーや他のコントラクトは、このアドレスとのみやり取りする。
    • このコントラクト自体にはほとんどビジネスロジックがないが、最も重要な任務はすべてのデータと状態を保管することだ(例えば、ユーザーの残高や記録など)。
    • それは「交換手」のようなもので、電話(リクエスト)を受け取ると、後ろのロジックコントラクトに転送する。
  2. ロジックコントラクト (Implementation/Logic Contract)

    • このコントラクトは、君が持っているiPhoneそのものだ。すべてのビジネスロジック(送金方法、計算方法など)を実装する責任を負う。
    • それ自体は重要なデータを一切保存しない。

アップグレードはどのように実現されるのか?

ここが面白いところだ。

もし君のiPhone 13(ロジックコントラクトV1)にバグがあったり、もっと機能の強いiPhone 14(ロジックコントラクトV2)に買い替えたいとしたら、携帯電話番号を変える必要があるだろうか?

必要ない!

君は店に行って新しい携帯電話(新しいロジックコントラクトV2をデプロイする)を買うだけでいい。そして、君の「プロキシコントラクト」(あの変わらない携帯電話番号)に一つのことを伝えるんだ:

「おい、もう古い携帯電話にはかけるなよ。すべての着信はこの新しい携帯電話に転送してくれ!」

この操作は通常、プロキシコントラクト内の upgradeTo() 関数を呼び出し、ロジックコントラクトのアドレスを更新することによって行われる。