
検証済みコントラクト、プロキシ、そして誰も触れないアップグレード鍵
ブロックエクスプローラーには Contract Source Code Verified という緑のチェックマークがあり、途方もない数の人がそれを「このコントラクトは安全だ」と読んでいます。
それはそういう意味ではありません。もっと狭く、もっと有用な何かを意味しており、その二つを取り違えることこそ、慎重な人がやがて、決して同意しなかったはずのものを承認してしまう道筋なのです。
「検証済み」が実際に証明していること
コントラクトはバイトコードとして配備されます――機械の命令列であり、実務上は読めません。検証とは、元のソースコードをアップロードし、宣言されたコンパイラの版と設定でそれをコンパイルすると、その住所にすでに置かれているバイトコードとぴったり一致する、とエクスプローラーに確認させる行為です。
主張はそれだけです。あなたが読んでいるソースは、本当に動いているソースだ。
これは本物の、値打ちのある保証です。これがなければ、ある企画の GitHub に載っている見栄えのよいコードが、あなたの取引がこれから触れるものと何か関係があるのかどうか、知りようがありません。
けれども、それが言っていないことすべてに目を向けてください。検証は監査ではありません。そのコードが正しいか、不具合を抱えているか、関数名がほのめかすようなことを少しでもしているか――誰も評価していません。claimRewards という名の関数が残高の全部を配備者へ送るコントラクトも検証済みでありえますし、その検証はまったく正直です。盗みこそがコードの言うとおりの働きである、と忠実に証明してくれるのですから。
検証済みとは読めるという意味であって、信用に値するという意味ではありません。 問いを「これは何なのか」から「いま読んだものを理解しているか」へ移してくれる。それは前進ですが、二つ目の問いにあなたの代わりに答えてはくれません。
逆もまた大切です。未検証のコントラクトは悪意の証拠ではありません――正当な配備の多くが検証まで手が回らないままです。しかしそれは、誰も――あなたが使うどんな道具も、警告してくれたかもしれないどんな研究者も――これから関わる相手を読めない、ということです。それを警戒するのは理に適っています。
そしてプロキシが事態を悪くする
ここで足場がずれます。そして、たいてい語られないのがこの部分です。
あなたが関わる、ある程度の規模のコントラクトのほとんどは、単体のコントラクトではありません。プロキシです。プロキシはあなたが目にする住所であり、残高も、許容額も、状態も、データはすべてそこが抱えています。けれども論理はほとんど持ちません。代わりに、あらゆる呼び出しを別の実装コントラクトへ転送し、そのコントラクトの言うとおりに実行するだけです。
理由はアップグレード可能性です。不変のコントラクトは手当てができないので、不具合は永久で、欠けている機能はいつまでも欠けたままです。プロキシを新しい実装へ向け直せば、利用者全員に移行をお願いすることなく、不具合を直し改良を届けられます。直せない不具合でどれだけの価値が失われてきたかを思えば、これは擁護できる設計上の選択です。
そこには見落としやすい帰結があります。エクスプローラーでプロキシを引いて「検証済み」と出ているとき、あなたが検証したのは転送の論理であって、ふるまいではありません。 あなたのお金がどうなるかを実際に決めているコードは実装の住所に住んでおり、エクスプローラーがそれを目立つ形で見せるとは限らず、そしてそれは差し替えられます。
ですから本当の問いは、はじめから「このコントラクトは検証済みか」ではありませんでした。こうです。
このコントラクトのふるまいを誰が、どれだけ速く変えられるのか。
管理鍵こそが実際の安全模型
アップグレード可能なコントラクトには必ず、アップグレードを実行できる誰かがいます。今のコードがどれほど良かろうと、その権限こそが安全模型です。
幅は、憂慮すべきものから理に適ったものまであります。
単一の外部所有アカウント。 誰かの機械に載った一本の秘密鍵が、あなたの資金を抱えるコントラクトの論理を入れ替えられます。それが騙し取られ、盗まれ、あるいは持ち主が強要されれば、コントラクトは攻撃者の望むものになります。この仕立ては、あるべき頻度よりも多く見かけます。
マルチシグ。 複数の署名者が同意しなければなりません。格段に良い――単一障害点が消えます――とはいえ、署名者が何人で、本当に独立した人々なのか、それとも同じ組織の四台のノートパソコンなのかは、知っておく値打ちがあります。
タイムロックの後ろのマルチシグ。 アップグレードはチェーン上で予告され、固定の遅延――多くは二十四時間から七十二時間――を経てはじめて実行できます。意味があるのはこれです。あなたの立場をまるごと変えるからです。変更の予告を受け取り、効力が生じる前に引き揚げる窓が与えられます。タイムロックは悪意あるアップグレードを止めません。それを生き延びられるものにします。
アップグレードの道がまったくない。 コントラクトは不変です。予測可能性は最大、不具合が見つかったときの手立てはゼロ。正当な選択であり、たいていはそれに賭けられるだけ長く実地で鍛えられた仕組みが選びます。
どれかが自動的に正しいということはありません。けれども「鍵一本」と「マルチシグ+二日の遅延」の差は、誰も間違えないことを願う立場と、間違いが起きたときに動く時間がある立場との差です。
なぜこれがとりわけ承認に噛みつくのか
ここは、あなたが実際に折々している行いとつながる部分です。
トークンの承認を与えるとき、あなたはトークンを動かす権限をある住所に与えています。コードの一片ではなく、住所にです。承認はトークン側のコントラクトの記憶領域に置かれ、期限なく残り続けます。
その住所がアップグレード可能なプロキシなら、あなたのトークンを動かす資格を持つ論理は、あなたが承認したあとで、あなたの関与もあなたの新たな署名もなしに差し替えられます。調べたのは一つのもの、さらされ続けるのは別のものです。
だからこそ、使わなくなった承認を取り消すという常々の助言は、見た目より重い。あるコントラクトに不具合が見つかるかどうか、だけの話ではありません。アップグレード可能なコントラクトへの無制限の許容額は、あなたがそれを開けたままにしているあいだずっと、アップグレード鍵を握る者へ与えた許可なのだ、という話です。
これは取引のシミュレーションの、最も鋭い限界でもあります。署名の前にシミュレートすることは、現在の状態と現在の実装に対して取引が何をするかを教えてくれます。本当に有用であり、そして同じ承認が来月何を許すことになるかは教えられません。
SSP が見せるもの、そしてどこで止まるか
SSP Key が承認を提示するとき、生の十六進数を見せるのではなく呼び出しデータを解読します。標準的な ERC-20 のセレクタ――approve、transfer、transferFrom、increaseAllowance、setApprovalForAll――を認識し、平明な言葉で描き出します。無制限の許容額に印を付けることも含めて。コードでは 2^255 以上のあらゆる額がそれと定義されています。
この解読器は意図して控えめです。自身の冒頭注記が、これは表示層専用だと述べています。署名される中身を決して変えず、閉じる側へ倒れて失敗します。未知のセレクタ、誤った長さ、崩れた十六進数、標準でない住所の詰め方――いずれも何も返さず、「詳細」の裏に生の十六進数を置いた汎用の動作へ退きます。自信満々に当て推量して外すより、分からないと認めるほうを選ぶのです。トークンの記号と小数桁は、端末内の登録簿から確かに分かるときだけ添えられ、決して推し量りません。
さて正直な境界です。この解読器にはプロキシという概念がありません。 実装コントラクトという考えは、そのどこにも存在しません。「あなたは 0xABC… に無制限の USDC 許容額を与えようとしています」と、正しく明瞭に告げることはできます。そして、0xABC がプロキシであること、そのアップグレード鍵を誰が握っているか、来週にはふるまいがまるで別物になりうることは、告げられません。
これは手落ちというより、どの財布の解読器にも越えられない境界です。解読は目の前の呼び出しを描きます。相手方がアップグレード可能かどうか、誰がそれを治めているかは、より広い世界の性質であり、別途確かめるほかありません。自信ありげな承認画面に、備えていない網羅性をほのめかさせるより、境界を言葉にするほうを私たちは選びます。
重要なものを承認する前の、実際的な確認
検証されているか。 されていないなら、あなたが頼っているのは評判だけだと理解してください。
プロキシか。 エクスプローラーはこれを表示します――プロキシの注記や「Read as Proxy」という項目を探してください。あるなら、意味を持つコードは実装のほうです。
誰がアップグレードでき、遅延はあるか。 一覧の中で最も値打ちのある問いであり、ほとんど誰も尋ねない問いです。これを考え抜いた企画は文書に残します。考えていない、あるいは言わない企画は、それ自体で何かを告げています。
その承認は無制限である必要があるか。 たいていは要りません。実際に使うつもりの額を承認すれば、そのコントラクトが後に何になろうと、さらされる範囲はきっかりそこまでに区切られます。
済んだら取り消すこと。 開いたままの許容額は常設の許可であり、あなたの注意より長生きします。
行う値打ちのある頭の調整は小さく、けれども多くを変えます。検証は、いま何のコードが動いているかを教えます。アップグレード可能性は、明日何が動くかを誰が決めるのかを教えます。危険のほとんどは二つ目の問いに住んでおり、差し出される安心のほとんどは一つ目にしか応えていません。


