该文章详细介绍了EIP-7702标准及其与Nick的方法结合所带来的新型"PREP"账户。文章探讨了PREP账户的优势,例如显著降低部署成本、实现多链账户的统一等,同时也指出了一些局限性。最终提出了一种新的智能账户标准,旨在提升用户体验和技术安全性。
随着 EIP-7702 的临近,在以太坊上开发的开发者们对与 EOA 账户合作时将获得一系列新功能感到兴奋。对于 EIP-7702 如何在实践中实施,仍然存在很多困惑。EIP-7702 提供的一个特性,几乎未受到足够关注,那就是 使用 Nick 方法创建新的以太坊账户的能力。首先由以太坊的 Dror Tirosh 提到,这激发了 Biconomy 的一个小型研发团队围绕这个方法构建一种全新的账户标准。
我们将其称为“PREP”账户,因为它们是通过设置 EIP-7702 委托(代理)来部署的账户,可以证明与其地址关联的私钥并不为任何人所知。这对以下方面有重大影响:
我们已经能够取得的成就:
我们将这种方法视为未来创建新的 EVM 账户的 默认方式 的潜在候选者,因为它结合了 EOA 和智能账户的所有最佳特性。
此外,使用这种方法使团队可以相对容易地开发通用工具,这些工具适用于从 EOA 升级的账户 以及 新的 PREP 账户!目标是将这里的许多内容标准化为 EIP-,并与智能账户和钱包提供商合作,以实现以太坊和 EVM 链的更好的账户标准。
因此,我们并不将这里概述的 PREP 标准视为此提案的 最终形式 - 我们将其视为钱包、用户和开发者工具实施新账户系统的第一步。
然而,在实现这样的目标之前,Biconomy 将在 Nexus 智能账户的新版本中原生推出 PREP 支持和我们的执行环境(ERC-4337 和 MEE)。
如 这篇文章 中所解释的那样,Nick 方法 - 由 Vitalik Buterin 设想并由 Nick Johnson 首次实现,使得“无钥执行”成为可能。简而言之,Nick 方法利用 EVM 交易的 from
(发送者)参数可以从交易的其余参数中以加密方式恢复的事实来工作。
这意味着开发者可以编码任何 EVM 交易,例如“将 5 ETH 发送到 0xabcd...000”,然后 - 无需使用私钥签署该交易 - 随机生成交易签名的 r
、s
和 v
值。
然后,开发者可以使用 ecrecover
来了解此签名有效的地址。如果他们然后将 5 ETH + 执行所需的 gas 发送到该地址并广播该编码的交易 - 该交易将成功执行!从 EVM 链的角度来看 - 这是一个有效签名的交易。
这一点的极大好处在于,它使得开发者能够从不知私钥的账户中执行交易。之前提到的文章详细讲述了 Nick 方法的一些更有趣的用例,因此我们在此不做深入讨论。相反,我们将探索 EIP-7702 授权和 Nick 方法之间的相互作用。
EIP-7702 引入了 委托 对某个 EOA 的控制,至一个在链上部署的合约。通常通过部署一个 单例 合约并使用 EIP-7702 将 EOA 地址设置为该合约的 代理 来完成这一操作。区块链在本质上表现得就像该合约的代码已部署在 EOA 地址上一样。
为了设置 EIP-7702 委托,用户需要用他们的私钥签署以下格式的 授权消息:
const message = keccak(
concat(MAGIC, rlp([chain_id, address, nonce]))
)
其中:
MAGIC
是常量 0x05
,它被拼接到所有 EIP-7702 消息中。chain_id
是进行授权的链的 ID,或在消息应在所有链上有效时为 0
。address
是单例合约的 20 字节地址,我们要委托给此合约。nonce
是签署账户的当前 nonce。该消息 和 其相关联的签名(r
、s
和 y_parity
值)将被发送至新引入的 EIP-7702 交易类型的 authorizations
字段。EVM 验证 授权 且将 EOA 委托给目标智能合约地址 - 使其获得该合约的所有功能!
如果目标合约是具有 execute
函数的智能账户 - 那么这意味着 Bundlers/Relayers/Solvers 等等可以代表用户发布由该用户签署的指令。
这意味着他们可以:
虽然 EIP-7702 还有期待大幅提高以太坊及 EVM 的用户体验,但当前智能账户提供的一些(显著且被广泛采用的)功能在 EIP-7702 委托账户中并不可用。
这些限制源于用户仍旧拥有一个 EOA,它充当所有操作的 根 签署者 - 此操作可以覆盖智能账户设置的所有限制。这意味着用户无法拥有多重签名账户(因为 EOA 可以覆盖所有签署者),无法拥有时间锁账户功能(因为 EOA 可以比时间锁更快执行),无法拥有一些非常流行的跨链/互操作功能,比如资源锁(因为 EOA 可以签署比资源锁用来进行来源链 声明 过程更早的交易)等。
通过 EOA 来覆盖智能账户可以通过两种方式进行:
ERC20Permit
(ERC-2612)。这意味着用户甚至无需解除委托账户。现在我们来到了本文的核心 - 如果我们可以将一种未知私钥的账户与 Nick 方法和 EIP-7702 授权结合部署呢? 然后,由于我们不知道私钥 - 我们便 无法 覆盖智能账户的委托,也无法为转移某些代币签署 ERC20Permit
或 Permit2
消息。
这类似于正常的 CREATE2
账户部署,并具有 Nick 方法所能提供的某些独特优势 - 我们将进一步探讨这些优势。
事实证明,我们可以做到!由于 EIP-7702 的 authorization
的结构如下:
[chain_id, address, nonce, y_parity, r, s]
其中,r
、s
以及 y_parity
参数从前文展示的 EIP-7702 授权消息的签署中提取。因此,我们可以进行的操作是将授权过程 反向进行!
首先生成一个有效的 EIP-7702 授权消息哈希,使用以下值:
chain_id = 0
使此消息在所有链上有效smart_account_address
为智能账户单例合约的地址nonce = 0
由于这将是一个新部署的账户,交易的 nonce 可以为零const messageHash = keccak256(
concat([\
MAGIC_PREFIX,\
rlp([\
0, //chainId\
smart_account_address,\
0 //nonce\
])\
])
)
在编码 EIP-7702 授权消息后,通过生成随机 r
和 s
值来生成随机 ECDSA 签名。稍后我们将展示当 r
和 s
值并 非完全 随机时的一些强大新功能,但本例将假设使用随机值以简化。
附注:
s
值小于 secp256k1n/2
(根据 EIP--2),本伪代码将跳过此部分。r
和 s
(一些对不恢复地址,但很少需要超过两次尝试来寻找有效对)将恢复两个有效地址(由于椭圆曲线是对称且两个 y 坐标与任何给定的 x 坐标匹配。这通过 v
值来表示。由于我们不关心私钥,所以我们可以使用任何 v
值(27 或 28 均可))。const r = randomBytes(32)
const s = randomBytes(32) // 确保该值小于 secp256k1n/2
const v = randomSelect(27,28) // 我们不关心 v 值,因此可以使用 27 或 28
现在我们可以恢复该签名的有效签名者地址。我们将不知道该地址的私钥!
const signature = concat([r,s,v])
const recoveredAddress = recoverAddress(messageHash, signature)
现在我们已经成功从签名中恢复了地址,我们可以生成 EIP-7702 授权元组:
// 字段必须与步骤 i 中的 `messageHash` 使用的字段匹配。
const authorization = {
chain_id: 0, // chainId 为零表示消息在所有链上有效
address: smart_account_address, // 智能账户单例的地址
nonce: 0, // 由于这是一个未使用账户,nonce 可以为 0
y_parity: v, // y_parity 是 v 参数的不同名称
r: r, // 从步骤 ii 随机生成的 r
s: s, // 从步骤 ii 随机生成的 s
}
通过以此授权作为其 authorizations
数组中一项授权以及发布 EIP-7702 交易类型的交易 - 你将成功将 recoveredAddress
委托给了 smart_contract_address
!这意味着 recoveredAddress
现在是一个完全功能的智能账户! 🥳
在我们将 recoveredAddress
委托给所需的智能账户实现后,必须初始化该智能账户。这通常意味着设置账户的所有者和签名方案。可以是一个或多个 EOA 签署者,或者是 Passkey 签署者或 MPC 签署者等……初始化部分完全依赖于智能账户本身的实现。
结合 Nick 方法和 EIP-7702 带来了许多好处,甚至在 添加 PREP 特定功能 之前就已如此。
通过某些假设账户具有单一 EOA 签署者的优化 - 我们甚至可以实现更大的优化,将部署成本降至 30k gas - 超过 80*% 的成本降低*!
由于 Nick 方法与 EIP-7702 授权利用纯加密推导用户地址,并且 Nick 方法 也 可用于部署单例智能账户实施合约 - 这意味着用户在任何支持 EIP-7702 的 EVM 兼容链上将 始终 拥有相同的地址,以及任何 未来 的 EVM 兼容链!
虽然结合 Nick 方法和 EIP-7702 是一个强大的组合,但仍然存在一些需要解决的局限性:
authorizations
元组合在内存池中公开可用,一个恶意行为者可以自己执行交易 - 如果初始化函数没有得到适当保护,将其设置为账户的唯一签署者。由于在此方法中,用户必须用 chain_id = 0
签署,以使得部署能在所有 EVM 链上用同一地址 - 如果初始化方法没有得到保护,恶意攻击者可以利用该授权进行其它链的设置。这 仍然 阻止了 Nick 的 EIP-7702 方法用于多重签名、资源锁、时间锁等功能,因为没有基础设施提供者可以信任用户提出的“EOA 不存在”的声明。
authorization
中恢复地址,然后通过受保护的方法 init
来初始化智能账户(以防止之前提到的抢先交易) - 这将要求用户分别签署账户创建。好消息是,通过聪明地复用 r
和 s
参数以适应多种用途,我们已经解决了问题 i.、ii. 和 iii.!
最后,将提出一种解决问题 iv. 的方法,但此主题超出了本文的范围,并且解决 iv. 将需要比其他问题更多的努力。
考虑到 Nick 部署方法与 EIP-7702 结合的所有好处 - 我们已经分配一个研发团队以围绕该方法的 局限性 进行工作,如今 - 我们很高兴地说,我们已经解决了所有问题,同时保留了所有的好处!
该解决方案优雅、加密上安全 且 已准备在我们最新的 Biconomy Nexus 智能账户实现中发布!所以我们一步一步来:
为了确保智能账户只能使用用户设置的初始配置进行初始化(配置示例:特定 EOA 仅被允许执行交易),并且没有签署者可以被抢先交易,我们的 PREPr 智能账户实现要求将智能账户的 initData
的哈希包含在生成签名的 r
参数中。
通过将 initData
打包在 r
参数中,由于改变 r
参数将更改恢复地址,我们确保 只有一个有效的 initData
针对该特定地址。这意味着,即使其被拦截,抢先交易机器人仍然只能够以用户实际想要的初始配置初始化账户。
此外,由于 r
参数同时充当 initData
容器 和 常规 r
参数 - 通过从消息中恢复地址,用户同样允许账户初始化 - 这意味着用户无需签署任何内容即可允许账户初始化,因为授权本身已经包含所有保护。
为了证明用户不知道私钥,我们将使用一种著名的加密技巧,替换 s
参数的高位字节为某个 魔术值。如果 s
参数包含足够固定的字节,生成已知私钥的机会几乎不可能。
替换 s
中最显著的 13 字节将需要 21032^{103}2103 次操作以找到关联的私钥,这甚至会导致现有最强大的超级计算机需要大约三万亿年难以完成位。剩余的 s
参数将随机生成。
在账户初始化期间,将在 initData
中提供创建账户时用到的精确 r
、s
、v
值 - 合约将恢复地址,检查在 initData
中设置的所有者是否为从这些 r
、s
和 v
参数中恢复的地址 并 检查 s
参数是否具有魔术值前缀。
如果这些条件都为真,账户将在其存储中将 rootless
标志设置为 true。任何与该账户交互的人员都可以 验证 该账户确实是无根的。
ℹ️
该系统并非量子抵抗力,而在后量子世界中,使用 Nick 方法初始化的账户的私钥可能会被暴露。但此漏洞并不特指此账户实现,而是 EIP-7702 + Nick 方法的一般性问题。由于此方法利用了标准,因此当以太坊添加量子抗性时,此方法应进行相应调整。
通过将 initData
的哈希包含在 r
参数中,并将魔术值前缀包含在 s
值中,然后利用它恢复 EIP-7702 授权的签署者 - 我们创造了 终极 智能合约账户!
它将 EOA 的最佳特性(相同地址、纯加密推导的地址、可移植的潜力、所有链上的相同配置等)与智能账户所提供的全部功能结合在一起。通过一些简单的调整,我们解决了所有 Nick 方法部署的问题。
不仅如此,我们还使账户的部署成本降低了高达 80% 相比使用 CREATE2
方法!
在此基础上,由于该账户使用 EIP-7702 创建 新 账户,因此许多工具 (SDKs, bundlers, relayers) 可同时用于新 PREP 账户 和 通过 EIP-7702 转换的现有 EOA。
设置 r
、s
和 v
的示例伪代码:
// 例如将 '0xABC...000' 设置为账户的所有者
const initData = "0xInitData..."
// r 参数是 initData 的哈希值
const r = hash(initData)
// 魔术前缀
const magicPrefix = '646d6a0000000'
// s 以魔术值作为前缀
const s = concat(magicPrefix, randomBytes(19))
// v 可以是 27 或 28,本方法的 v 值不相关
const v = 27
即将到来的 Biconomy 的 Nexus 2.0 账户将是第一个支持 PREP 完整功能集的智能账户。随着越来越多的链将 EIP-7702 功能添加到其堆栈中,我们预计越来越多的客户将使用 PREP 账户堆栈以利用这些新功能。
Nexus 2.0 将在以太坊主网的 Pectra 合并的第一天(计划在 2025 年 3 月)时经过审计并准备投入生产(连同相关的 PREP 工具)。一旦 EIP-7702 标准被广泛采用,开发者们即可通过使用 Nexus 2.0 开始享受到 PREP 标准的好处。
Nexus 2.0 将支持:
r
参数生成初始块rootless
标志以太坊/EVM 开发者社区有一个独特的机会来设置一种新的标准化账户部署系统。
备注:虽然可移植的智能账户超出了本文的范围,但在创建新的 EVM 和以太坊账户类型的背景下提及可移植性是重要的。
PREP 账户标准为以太坊和 EVM 区块链创建了一个通用、加密确定性的账户标准。经过额外的一些工作,它有潜力成为新账户的默认部署方式,因为它继承了 EOA 的大部分好处以及所有 SCA 的好处。它还能在 仅需 来自链的 EIP-7702 支持下实现所有这些。
然而,有一个 EOA 用户深切欣赏的特性在此方法中并不可用,那就是 可移植性 - 用户可以通过导出其私钥或种子短语,将账户导入不同钱包的能力。
虽然这通常被智能账户团队视为区块链的 负面 方面,但用户行为却指出不同的现实。许多机构用户以及更复杂的零售用户将私钥和种子短语的存在看作区块链的核心 益处。如果我们想在 PREP 标准的更广泛实施上有所突破,就需要找到一种方法来实现可移植性。
为了实现可移植性,钱包需要两个关键特性:
在这两个问题中,可发现性相对较简单。由于 PREP 账户仅需其地址的初始智能账户实现和生成的 r、s、v 参数便可推导地址 - 可以向钱包提供这些参数以“发现”账户地址。通过恢复地址并检查 s
参数,钱包可以推测该账户是符合 PREP 标准的。
所有权需要通过允许钱包升级 PREP 钱包的实现以实现对新实现的控制来解决。这可以通过类似于钱包对具有先前钱包的现有 EIP-7702 委托的 EOA 设置新委托的方式进行升级。为了使这些升级与资源锁等功能兼容,获得账户所有权可以设置时间延迟。由于 PREP 账户没有关联的私钥,因此可以通过账户本身上的标准方法来实现,这可以被编码为 EIP!
然而,正如前面提到的,达成这一点的方法超出了本文的范围,并且需要广泛的行业支持来实现。在 Biconomy,我们非常乐意与所有相关方开启讨论,以使可移植性标准适用于 PREP 账户 以及 一般智能账户。
- 原文链接: blog.biconomy.io/prep-de...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!