Alert Source Discuss
⚠️ Draft Standards Track: ERC

ERC-7803: 用于账户抽象的 EIP-712 扩展

改进 EIP-712 以支持智能合约帐户。

Authors Francisco Giordano (@frangio)
Created 2024-10-08
Discussion Link https://ethereum-magicians.org/t/erc-7803-eip-712-extensions-for-account-abstraction/21436
Requires EIP-712

摘要

本 ERC 改进了 EIP-712 签名,通过以下方式更好地支持智能合约帐户:1) 引入签名域,作为在跨帐户共享私钥时防止重放攻击的一种方式,以及 2) 允许 dapps 和钱包协调将用于验证签名的方法。

动机

签名域

诸如 ERC-1271ERC-6492 等标准使智能合约帐户 (SCA) 能够生成应用程序无需了解帐户抽象规则即可验证的签名。这对于应用程序来说是一个重要的原语,因为帐户所有者能够授权第三方代表其行事,而无需与链交互。

智能合约帐户可能由密码学密钥“拥有”,这些密钥的签名用于授权帐户的使用。密钥和帐户之间不一定存在一对一的映射,因为单个密钥可能控制多个帐户,因此必须小心防止跨帐户的重放攻击。这是通过将签名绑定到特定帐户来完成的。

EIP-712 引入了一种方案,可以将签名绑定到验证域,该域对应于将验证签名的协议合约。重用此机制以将签名额外绑定到智能合约帐户的域会产生大量的复杂性和攻击面(请参阅 ERC-7739),以及帐户可组合性方面尚未解决的问题(控制其他 SCA 的 SCA)。除了验证域之外,本 ERC 还引入了签名域,以原生方式使钱包能够生成具有重放保护的智能合约帐户签名。

身份验证方法

ERC-1271 是一个最小且非常通用的接口,非常有效。它要求在需要验证签名时,合约代码已经部署,因此 ERC-6492 扩展了 ERC-1271 以支持该用例。将来可能需要开发其他方法。

目前,各个协议对这些方法的支持不足,并且是帐户抽象路线图的主要痛点。在支持 ERC-1271 的地方,不一定统一使用它,特别是某些合约在调用 isValidSignature 之前尝试 ECRECOVER,而另一些合约则相反,这将导致 EIP-7702 之后语义大相径庭。

本 ERC 通过允许 dapps 传达协议合约支持的签名类型(即,将使用哪些身份验证方法以及按什么顺序)来解决此问题。

规范

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

通过 JSON-RPC (eth_signTypedData) 或客户端库发出的类型化数据签名请求将扩展以下可选属性:

  • signingDomains
  • authMethods

这些新属性与现有属性(即 typesprimaryTypedomainmessage)一起使用。

响应请求返回的签名可以是任何大小,并且在没有 authMethods 的情况下,必须将其不透明地处理,因为签名的类型未知。

signingDomains

此属性是智能合约帐户域的数组。数组的每个成员都是一个对象,包含以下键:

  • types:与 EIP-712 types 格式相同的对象,但至少包含一个 EIP712Domain 键。
  • domain:一个对象,对于 types 中描述的 EIP712Domain 类型是有效的。

从右到左,数组列出了签名者最终通过其控制“最外层”签名域(即,首先列出的域)的帐户链。

例如:

  1. dapp 通过 JSON-RPC 请求连接帐户的 EIP-712 签名。signingDomains 为空或未定义。
  2. 连接的帐户是一个多重签名,因此它从其签名者请求 EIP-712 签名,将多重签名的域添加到 signingDomains 的前面,该签名现在是长度为 1 的数组。
  3. 其中一个签名者使用由硬件钱包中保存的 ECDSA 密钥控制的智能合约帐户,因此他们的钱包从硬件钱包请求 EIP-712 签名,将智能合约帐户的域添加到 signingDomains 的前面,该签名现在是长度为 2 的数组。
  4. 签名者在其硬件钱包中验证签名的内容。他们能够看到他们正在代表其智能合约帐户(最接近的签名域)签署一条用于特定 dapp 域的消息,作为多重签名的成员(最远的签名域)。

编码要签名的数据

在存在 signingDomains 的情况下,帐户应根据以下递归过程编码要签名的消息:

  • encodeForSigningDomains(signingDomainSeparators : [𝔹²⁵⁶], verifyingDomainSeparator : 𝔹²⁵⁶, message : 𝕊) =
    • 如果 signingDomainSeparators = [first, ...others]: "\x19\x02" ‖ first ‖ encodeForSigningDomains(others, verifyingDomainSeparator, message)
    • 如果 signingDomainSeparators = []: encode(domainSeparator, message), 其中 encode 由 EIP-712 定义。

signingDomainSeparatorssigningDomains 中包含的域的哈希数组,按照相同的顺序,根据 EIP-712 的 hashStruct 计算得出。

authMethods

此属性是受支持的签名身份验证方法的数组,按验证域尝试它们的顺序排列。

数组的每个成员都是一个对象,包含以下键:

  • id:标识该方法的字符串。它可以是:
    • ECDSA:由外部拥有帐户进行的 ECDSA 签名。
    • ERC-{n}:由 ERC 指定的标准类型的签名。n 不得用零填充。
  • parameters(可选):方法特定的参数数组。

JSON Schema

{
  type: 'object',
  properties: {
    types: {$ref: '#/$defs/EIP712Types'},
    primaryType: {type: 'string'},
    domain: {type: 'object'},
    message: {type: 'object'},
    signingDomains: {
      type: 'array',
      items: {$ref: '#/$defs/EIP712Types'}
    }
    authMethods: {
      type: 'array',
      items: {
        type: 'object',
        id: {type: 'string'},
        parameters: {type: 'array'},
        required: ['id'],
      },
    }
  },
  required: ['types', 'primaryType', 'domain', 'message'],
  $defs: {
    EIP712Types: {
      type: 'object',
      properties: {
        EIP712Domain: {type: 'array'},
      },
      additionalProperties: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            name: {type: 'string'},
            type: {type: 'string'}
          },
          required: ['name', 'type']
        }
      },
      required: ['EIP712Domain']
    }
  }
}

理由

向后兼容性

安全考虑

需要讨论。

版权

CC0 下放弃版权和相关权利。

Citation

Please cite this document as:

Francisco Giordano (@frangio), "ERC-7803: 用于账户抽象的 EIP-712 扩展 [DRAFT]," Ethereum Improvement Proposals, no. 7803, October 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7803.