Alert Source Discuss
Standards Track: Interface

EIP-2255: 钱包权限系统

用于限制对敏感方法访问的接口

Authors Dan Finlay (@danfinlay), Erik Marks (@rekmarks), Gavin John (@Pandapip1)
Created 2019-08-22
Requires EIP-1193

摘要

此 EIP 添加了两个新的钱包命名空间 RPC 端点 wallet_getPermissionswallet_requestPermissions,为请求和检查权限提供了一个标准接口。

动机

钱包负责通过适当的用户同意来协调不受信任的应用程序和用户密钥之间的交互。如今,钱包总是提示用户执行每个操作。这以巨大的用户摩擦为代价提供了安全性。我们认为,单个权限请求可以实现相同级别的安全性,并大大改善用户体验。

权限请求的模式(通常使用 Oauth2)在网络上很常见,使其成为一种非常熟悉的模式:

Facebook 权限

使用 Apple 登录

如今,许多 web3 应用程序都以一系列重复的请求开始其会话:

  • 向此站点显示您的钱包地址。
  • 切换到首选网络。
  • 签署密码学挑战。
  • 授予我们的合约代币津贴。
  • 向我们的合约发送交易。

其中许多(可能全部),以及更多(如解密),都可以概括为原始登录屏幕上的一组人类可读的权限提示,并且可以仅在需要时请求其他权限:

示例提示截图

这些权限中的每一个都可以被单独拒绝,甚至可以被_削弱_——调整以满足用户的条款(例如,登录请求可以具有用户添加的到期日期,并且代币津贴可以在请求时由用户调整)。

规范

本文档中的关键词“必须 (MUST)”,“禁止 (MUST NOT)”,“需要 (REQUIRED)”,“应该 (SHALL)”,“不应该 (SHALL NOT)”,“推荐 (RECOMMENDED)”,“可以 (MAY)”,“可选 (OPTIONAL)”应按照 RFC 2119 中的描述进行解释。

此提案向钱包的 web3 provider API 添加了两种新方法:wallet_getPermissionswallet_requestPermissions

wallet_getPermissions

wallet_getPermissions 方法用于获取当前权限的数组(默认为空)。它不带任何参数,并返回一个 Permission 对象数组。

wallet_getPermissions 返回值

返回的权限格式必须是 Permission 对象的数组,其定义如下:

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

interface Permission {
  invoker: string;
  parentCapability: string;
  caveats: Caveat[];
}

invoker 是一个 URI,用于标识当前 dapp 的来源(例如 https://your-site.com/)。术语 parentCapability 是指正在被允许的方法(例如 eth_accounts)。caveats 数组表示应用于允许方法的特定限制。Caveattype 是一个字符串,value 是一个任意 JSON 值。Caveatvalue 仅在 Caveattype 的上下文中才有意义。

wallet_requestPermissions

wallet_requestPermissions 方法用于应用程序请求其他权限。它必须接受一个参数,即 PermissionRequest 对象,并且必须返回一个 RequestedPermission 对象数组。

wallet_requestPermissions 参数

wallet_requestPermissions 方法接受一个参数,即 PermissionRequest 对象,其定义如下:

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

methodName 是正在请求其权限的方法的名称(例如 eth_accounts)。caveatName 是应用于权限的 caveat 名称(例如 requiredMethods)。caveat 值是 caveat 的值(例如 ["signTypedData_v3"])。

在发出 wallet_requestPermissions 请求并获得用户接受之前,对受限方法的尝试请求必须失败并显示错误。

如果 wallet_requestPermissions 请求被拒绝,则应按照 EIP-1193 抛出一个 code 值为 4001 的错误。

wallet_requestPermissions 返回值

wallet_requestPermissions 方法返回一个 RequestedPermission 对象数组,其定义如下:

interface RequestedPermission {
  parentCapability: string;
  date?: number;
}

parentCapability 是正在请求其权限的方法的名称(例如 eth_accounts)。date 是请求的时间戳,以 Unix 时间表示,并且是可选的。

理由

虽然目前在每个操作的基础上获得用户同意的模型具有很高的安全性,但是通过获得更广泛的用户同意可以涵盖广泛的使用类别,可以用更易于理解的方式表达,从而获得巨大的可用性提升。这种模式可以为 web3 钱包中的不同功能提供各种好处。

requestPermissions 方法可以扩展为包括与请求的权限相关的其他选项,例如,站点可以请求具有特定功能的帐户。例如,像交易所这样需要 signTypedData_v3 (某些硬件钱包不支持)的网站可能希望指定该要求。这将允许钱包仅显示兼容的帐户,同时保留用户对于如何存储其密钥的隐私和选择。

测试用例

请求权限

以下示例应提示用户批准 eth_accounts 权限,如果获得批准,则返回权限对象。

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

获取权限

以下示例应返回当前权限对象。

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

安全考虑

服务器端请求伪造 (SSRF)

如果将显示网站的网站图标,则此注意事项适用。

钱包应注意不要对 URL 发出任意请求。因此,建议钱包通过将特定方案和端口列入白名单来清理 URI。例如,一个易受攻击的钱包可能会被诱骗修改本地托管的 redis 数据库中的数据。

版权

版权及相关权利通过 CC0 放弃。

Citation

Please cite this document as:

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