はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

今回は、Dappsとの最初の接続時に、アドレスの表示や署名など複数の操作の許可をまとめてユーザーに求めてUXを向上させる仕組みを提案しているERC2255についてまとめていきます!

以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。

他にも様々なEIPについてまとめています。

概要

ERC2255は、wallet_getPermissions および wallet_requestPermissions という2つの新しいRPCエンドポイントを導入するものです。 これらのエンドポイントは「ウォレット名前空間(wallet-namespaced)」に属し、Web3ウォレットに対してアプリケーションが必要とするユーザー権限を確認したり、取得をリクエストしたりするための標準的なインターフェースを提供します。

これにより、dApp(分散型アプリケーション)とユーザーとのやりとりにおいて、「この操作にはこの権限が必要です」という形で、まとめて分かりやすくユーザーに提示することが可能になります。

動機

現在のWeb3ウォレットは、アプリケーションが何かの操作を行おうとするたびに、都度ユーザーに確認を求める仕様になっています。 これはセキュリティを担保するためには有効ですが、ユーザー体験を著しく損ねる原因にもなっています。

facebook_permissions.png

log_in_with_apple.jpeg

例えば、多くのdAppでは以下のような確認が繰り返されます。

  • ウォレットアドレスの開示
  • ネットワークの切り替え
  • 署名の実行
  • トークンの利用許可(アローワンス)の付与
  • コントラクトへのトランザクション送信

これらの操作は、それぞれ個別に確認を求められることが多く、ユーザーにとっては煩雑でわかりづらい手順になりがちです。

しかし、Web2の世界では、OAuth2のような一括で権限をまとめてリクエストする仕組みが広く採用されています。 例えば、FacebookやAppleのログイン画面では、最初のサインイン時にまとめて複数の権限が提示され、ユーザーはそれらを1つ1つ許可または拒否できます。

ERC2255は、そうしたWeb2の慣習をWeb3にも取り入れる提案です。 例えば、最初の接続時に「このサイトはあなたのアドレスを表示し、署名を求め、トークン利用許可を得ようとしています」といった人間にとって理解しやすい形での権限提示を行い、ユーザーがその場で細かく設定できるようにします。

permissions.png

ユーザーはそれぞれの権限を個別に拒否したり、期限を設定したり、数量を制限したりすることが可能になります。 これにより、セキュリティを維持しながらもユーザー体験を大きく向上させることが期待されます。

仕様

ERC2255では、Web3ウォレットの provider(プロバイダー)APIに、2つの新しいメソッド wallet_getPermissions と wallet_requestPermissions を追加します。 これらは、Webアプリケーションがウォレットの利用者から「どの操作を許可してもらうか」を明示的に問い合わせたり、確認するための標準的なインターフェースを提供します。

これにより、アプリケーションはウォレットに対して「この操作を許可してほしい」とリクエストし、それがユーザーによって許可された場合にのみ特定の機能を実行できるようになります。 操作が許可されていない状態では、リクエストはエラーとして扱われます。

wallet_getPermissions

wallet_getPermissions メソッドは、現在のdApp(分散型アプリケーション)がすでに取得している権限の一覧を確認するために使用されます。 引数は不要で、戻り値として Permission オブジェクトの配列が返されます。

返される Permission オブジェクトは、以下の構造になっています。

typescript
interface Caveat {
  type: string;
  value: any;
}

interface Permission {
  invoker: string;
  parentCapability: string;
  caveats: Caveat[];
}
  • invoker は、そのdAppの識別に使われるURI(例: https://your-site.com)です。
  • parentCapability は、許可されているメソッドの名前(例: eth_accounts)を表します。
  • caveats は、そのメソッドの使用に付随する制限条件のリストです。

それぞれの Caveat(制限)は、型を表す type と、制限値を表す value で構成されます。 制限値の解釈は、type に依存します。

wallet_requestPermissions

wallet_requestPermissions メソッドは、dAppがウォレットに対して新しい権限をリクエストする時に使われます。 引数として PermissionRequest オブジェクトを1つ取り、成功すれば RequestedPermission オブジェクトの配列を返します。

リクエストの構造は以下のとおりです。

typescript
interface PermissionRequest {
  [methodName: string]: {
    [caveatName: string]: any;
  };
}

この構造では、例えば以下のようなリクエストが可能です。

  • メソッド名
    • eth_accounts
  • Caveat名
    • requiredMethods
  • 値
    • ["signTypedData_v3"]

つまり、「このdAppが eth_accounts を使えるようにし、その中でも signTypedData_v3 だけを許可してください」といった具体的なリクエストを行うことができます。

リクエストされたメソッドが現在の状態で制限されている場合、その呼び出しは失敗します。 そのため、まず wallet_requestPermissions を呼び出し、ユーザーの承認を得る必要があります。

なお、ユーザーがこのリクエストを拒否した場合は、エラーコード 4001(EIP1193準拠)で例外が投げられます。

wallet_requestPermissions の戻り値

このメソッドが返すのは、次のような形式のオブジェクト配列です。

typescript
interface RequestedPermission {
  parentCapability: string;
  date?: number;
}
  • parentCapability は、許可されたメソッドの名前を示します(例: eth_accounts)。
  • date はUnixタイム形式のタイムスタンプで、リクエストが受け入れられた日時を表します。
    • これは任意の値であり、含まれない場合もあります。

このように、どのメソッドに対して、いつ、どのような権限がユーザーから許可されたのかを記録・把握できるようになります。

補足

従来のWeb3ウォレットは、ユーザーの安全性を確保するため、アプリケーションからの操作ごとに確認ダイアログを表示する形式を取ってきました。 この方式は高いセキュリティを提供する一方で、ユーザーにとっては操作のたびに中断されるため、使い勝手が非常に悪いという課題があります。

ERC2255では、人間が理解しやすいかたちで、まとめて権限をリクエストする方式に移行することで、ユーザー体験の大幅な向上を目指しています。 例えば、アプリが「署名機能が使えるアカウント」などの特定の条件を持ったアカウントをリクエストできるようにすれば、ウォレットはその条件に適合するアカウントのみをユーザーに提示できます。 これは、特定の署名方式(例えば signTypedData_v3)に対応していないハードウェアウォレットなどが存在することを考慮した設計です。

このように、アプリケーションは自分たちのニーズに合った「機能を備えたアカウント」をリクエストすることができ、ウォレットはユーザーのキー管理方法やプライバシーを保護しながら、適切なアカウントのみを提示できるようになります。

テストケース

ERC2255に基づいて、wallet_requestPermissions および wallet_getPermissions の基本的な動作を確認するテスト例が紹介されています。

まず、アプリケーションが eth_accounts メソッドの利用許可をリクエストする例は以下のようになります。

javascript
provider.request({
  method: 'requestPermissions',
  params: [
    {
      'eth_accounts': {
        requiredMethods: ['signTypedData_v3']
      }
    }
  ]
});

このリクエストでは、単にアカウントの使用を求めるだけでなく、そのアカウントが signTypedData_v3 という特定の署名機能をサポートしていることを条件としています。 これは、dAppが事前に必要な機能を宣言することにより、ユーザーにとって意味のある選択を提供できる例です。 ユーザーがこれを承認すれば、対応するアカウント情報とともに Permission オブジェクトが返されます。

次に、現在の権限の一覧を確認するには、以下のように getPermissions メソッドを呼び出します。

javascript
provider.request({
  method: 'getPermissions'
});

この呼び出しにより、現在許可されているすべての権限情報(メソッドごとの使用可否やCaveat付きの条件など)が取得できます。

これらのテストケースを通じて、dAppは権限ベースの対話に適切に対応できるようになり、ユーザーは自らの意志でアクセス範囲を制御できるようになります。 これは、セキュリティとユーザビリティの両立を目指した、より洗練されたアクセス制御の仕組みといえます。

セキュリティ

SSRF(サーバーサイドリクエストフォージェリ)

ERC2255に関連するセキュリティリスクの一つに「SSRF(Server-Side Request Forgery)」があります。 これは、ウォレットがWebサイトのfaviconなどの情報を取得するために外部URLへリクエストを送信する場合に発生し得る脅威です。

SSRF攻撃とは、本来外部からアクセスできないはずのサーバー内部のネットワークリソースに対して、不正にリクエストを送らせる攻撃手法です。 例えば、ウォレットが指定されたURLに無条件でリクエストを送る仕様であると、攻撃者はウォレットに対して http://localhost:6379(ローカルにあるRedisデータベース)などの内部アドレスにアクセスさせることができるようになります。 結果として、意図しないデータの取得や改ざん、さらにはサービスの不正操作が行われる危険性があります。

このようなリスクを防ぐためには、ウォレット実装側がユーザー指定のURLに対して無条件にリクエストを送らないようにすることが重要です。 具体的には、以下のような対策が推奨されます。

  • 許可するURLスキーム(例えば https://)やポート番号(例えば 443)をあらかじめホワイトリストとして定義しておくこと。
  • localhost や 127.0.0.1、169.254.*.*(リンクローカルアドレス)など、内部ネットワークに該当するアドレスへのアクセスを禁止すること。

これらの対策を講じることで、ウォレットが悪意あるURLにアクセスさせられることを防ぎ、ユーザーのローカル環境や内部システムの安全性を確保することができます。 SSRFはWebアプリケーションでも頻出する攻撃手法であり、Web3ウォレットにおいても同様の注意が求められます。

引用

Dan Finlay (@danfinlay), Erik Marks (@rekmarks), Gavin John (@Pandapip1), "EIP-2255: Wallet Permissions System," Ethereum Improvement Proposals, no. 2255, August 2019. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2255.

最後に

今回は「Dappsとの最初の接続時に、アドレスの表示や署名など複数の操作の許可をまとめてユーザーに求めてUXを向上させる仕組みを提案しているERC2255」についてまとめてきました! いかがだったでしょうか?

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!

他の媒体でも情報発信しているのでぜひ他も見ていってください!