署名ページを自分で動かす
Vela は承認前にすべての取引をデコードしますし、その作業は本物です。けれどその作業を しているのは、その取引を組み立てたのと同じアプリです。アプリ自身、あるいはそれが あなたに届く経路が改ざんされれば、ひとつを見せて別のものに署名させられます。 Bybit で起きたのは、まさにそれです。
署名ページは、それを 2 つに割るために存在します。取引はひとつの場所から来て、 確認と署名はあなたが管理する別の場所で行われます。
それが何か
リポジトリの app-web/clearsigning というひとつのフォルダで、ウェブページでもあり
Chrome 拡張でもあります。素の HTML・CSS・JavaScript のみ。フレームワークなし、
バンドラーなし、ビルド手順なし、依存関係なし、自分からのネットワーク通信もなし。
署名リクエストを受け取っても、それに付いてきた要約を信じません。生の calldata を 自分でデコードし、ダイジェストを自分で計算し、その署名が実際に何を認可するのかを 示したうえで、はじめてパスキーを求めます。
ビルド手順がないので、読んだファイルがそのまま動くファイルです。フォルダをリポジトリ と差分比較すれば、自分が配信しているものが何なのか分かります。
どのコピーがあなたのウォレットのために署名できるか
パスキーは、作られたドメインに結び付いています。あなたの Vela の鍵は getvela.app の下に登録されており、ブラウザは relying party が getvela.app であるページにしか
それを提示しません。この 1 点が、「自分で動かす」方法のうちどれが役に立つかを決めます。
Chrome 拡張として——既存のウォレットと使うならこちらです。 フォルダがどこから
来ていても拡張の relying party は getvela.app なので、既存の鍵で署名でき、しかも
動いているコードはあなたが読み込んで確かめたフォルダそのものです。
chrome://extensionsを開き、デベロッパーモードを有効にします。- パッケージ化されていない拡張機能を読み込むで
app-web/clearsigningフォルダを選びます。 - ツールバーのアイコンから、タブでページが開きます。
自分のドメイン、あるいは localhost 上のページとして。 HTTP(S) で配信すると、
ページの relying party はそのホスト名になります。つまりそのホスト名の下に登録
された鍵で署名できるのであって、getvela.app の下に登録された鍵では署名できません。
一連の流れを端から端まで試すのに、デスクトップのフローを動かすのに、そして自分の
ドメインで作った鍵のウォレットに署名するのに向いています。既存の getvela.app の
ウォレットのために署名する方法ではありません。
cd app-web/clearsigning
python3 -m http.server 8080 # → http://localhost:8080 アプリ内のパスはすべて相対なので、既存ホストのサブディレクトリでも動きます。
ディスクから index.html を直接開く(file://)のは眺めるだけなら可能です——
オリジンがないので relying party もなく、何も署名できません。
署名の前に何をするか
- 取引を自分でデコードします。 その呼び出しが何をし、誰に、いくらなのかを calldata から——バッチの中に入れ子になった呼び出しも含めて。
- 自分で計算したダイジェストにしか署名しません。 EIP-191、EIP-712、SafeOp、
SafeMessage のダイジェストをページ内で計算し、ウォレットと同じコードである
vela-coreと突き合わせます。計算できないダイジェストは、署名ではなく拒否です。 - 要求された取引と同じものかを確認します。 サイトが求めた呼び出しが、署名される 操作の中に実際に入っていなければなりません。
- 無制限の承認を拒否します。 警告ではなく拒否し、代わりにどうすべきかを示します。
- 読めないときは読めないと言います。 責任を持てない親切そうな要約は出しません。
- アカウントのアドレスとアイデンティコンを表示し、署名を求めてきた側が渡して きた受取人の名前は表示しません。要求側が操作できるものは、落とすか、相手の主張 として明示します。
あえて持たないもの
- 編集機能はありません。 リクエストは届いた時点で固定です。署名するかしないか だけ。手数料の選択や上限額の編集は calldata を書き換えることであり、それこそ このページが防ごうとしている病です。
- 鍵の作成はできません。 署名ページはパスキーを作れません。新しい鍵を作ることは、 別のアカウントを作ることだからです。
- ネットワーク通信をしません。 取りに行くものがなければ、傍受されるものもありません。
リクエストはどう届くか
| 要求側 | 経路 |
|---|---|
| 同じブラウザ内のページ | postMessage |
| 同じブラウザ内のページから拡張へ | 拡張のポート |
| 同じマシン上のデスクトップアプリ | URL フラグメント + ループバックコールバック |
| スマートフォンや別のコンピューター | Bluetooth LE(プロトコルは実装済み。無線部分は実機で未検証) |
ワイヤーフォーマット、ダイジェスト、そして画面上の各項目がどこから来ているかの対応表
は、コードの隣の PROTOCOL.md にあります。
いつ使うか
そのアカウントが、失ったら困るお金を持ち始めた日から——そしてそれ以降、すべての署名 で。大きな額のときだけ、ではありません。小さな承認ひとつで、アカウントを空にするのに 十分な権限が渡ることがあります。特別なときだけ持ち出す署名の習慣は、本当に必要な日に 身についていません。