4

EIP-3074:提升以太坊用户体验

 3 years ago
source link: https://learnblockchain.cn/article/2661
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
EIP-3074:提升以太坊用户体验 | 登链社区 | 深入浅出区块链技术

EIP-3074:提升以太坊用户体验

EIP 3074 为以太坊带来了很多新的可能。AUTHAUTHCALL 使得外部账户能够将账户的控制权授予智能合约调用者,从而实现批量事务和赞助事务等新的事务类型。然而,该 EIP 也极大地改变了事务在以太坊上的运作方式,因此在主网上激活该 EIP 之前,我们需要更深入地思考其安全性。

如果你是以太坊上的活跃用户,那么你大概率会持有一些 (ERC 20)代币,用来与以太坊生态中的各种 DeFi 项目进行交互。但是,这么做的前提是你必须持有 ETH,因为 ERC 20 代币无法用来支付以太坊的手续费。另外,在向智能合约发送代币时,你通常需要执行两个事务:一个用来许可 目标合约使用你的代币,另一个用来将代币转移 到目标合约中。

EIP-3074 可以让智能合约 代表 外部账户(就是普通的以太坊地址)发送事务,从而解决了上述乃至更多问题。

EIP 3074 引入了 AUTHAUTHCALL 这两个 EVM 指令。第一个指令基于 ECDSA 签名设置环境变量authorized,第二个指令则作为 authorized 发送调用。这本质上就是向智能合约授予外部账户的控制权。

1

通过 AUTHAUTHCALL EVM 指令(又称操作码),智能合约可以基于已签署消息获得一个外部账户的授权,并代替该外部账户发送事务。这带来了很多可能性,如:

  • 赞助事务(又称元事务):支付来自另一个账户的交易的 gas。这样一来,不持有 ETH 的地址也能发送代币。
  • 批量事务:通过单个调用发送多个事务。这样可以确保两个或以上的事务在同一个区块中执行,还可以降低交易费。
  • 提升用户体验:例如,你可以在单个事务中调用 approvetransferFrom

不同于现有的解决方案,EIP 3074 不需要智能合约钱包。你可以直接将事务发送给负责执行事务的调用者(invoker)。调用者是无状态的免信任型智能合约,而且不需要你事先将余额发送到智能合约。EIP 3074 也没有引入新的事务类型。从技术层面上来看,由于只引入了两种新的 EVM 指令,EIP 3074 实现起来理应更容易。

只可惜 EIP 3074 依然在审查中,而且由于种种(安全方面的)担忧,目前还不知道将于何时启用。如果你现在想要体验一把,可以使用 Puxi 测试网。在本文中,我将详细介绍 EIP 3074 的工作原理。

如果你想看一下 EIP 3074 的实际运行效果,我编写了一个(批量)事务调用者合约作为示例。点击下方链接,即可访问:

https://github.com/Mrtenz/transaction-invoker

请注意,这个合约没有经过审计,而且只是概念证明。请勿在生产环境中使用。

AUTH 和 AUTHCALL 操作码

EIP 3074 定义了两个新的操作码,可由智能合约调用:

  • AUTH0xf6)—— 基于签名和 commit(提交)提出授权的外部账户。共有 4 个输入参数:commit以及签名的 yParityrs
  • AUTHCALL0xf7) ——代替已授权的外部账户发送调用(事务) 。共有 8 个输入参数:gasaddrvaluevalueExtargsOffsetargsLengthretOffsetretLength。 与现有的CALL 操作码相似。

确认外部账户的授权需要来自该外部账户的签名消息。调用 AUTH 的智能合约可以通过消息签名复原出签名者,然后将其设置成 authorized EVM 环境变量。这样一来,该智能合约每次调用 AUTHCALL 时,调用者都会被设置成authorized地址。当被调用的智能合约调用 CALLER(例如,通过 Solidity 的 msg.sender)时,将由已授权的外部账户的地址而非调用者地址(智能合约)执行调用。

发送一个或多个事务的基本流程如下图所示:

2

  • 上图显示了 EIP 3074 的基本流程,其中调用者合约发送多个事务 -
  1. 外部账户签署授权消息;
  2. 外部账户或其他 gas 支付方将事务数据和授权消息发送给调用者合约;
  3. 调用者合约使用 AUTH 操作码执行授权,并使用 AUTHCALL 操作码发送事务。

将事务发送到合约的是谁并不重要,只要外部账户的签名是有效的即可。因此,其他人(或账户)也可以发送事务。

请注意,目前无法使用 EIP 3074 通过外部账户发送 ETH。这样做会极大地改变当前的一些重要假设,例如,检查事务是否有效。调用者需要使用自己的 ETH 余额来发送 ETH。但是,你可以将 ETH 发送给调用者,并由调用者代为发送。目前,AUTHCALL 操作码所包含的 valueExt 字段必须被硬编码成 0。将来,如果找到适当的解决方案,我们可以更改这个字段,允许调用者外部账户发送 ETH。

授权消息和 commit

为了执行授权,外部账户必须签署特定格式的消息:

0x03 || <Padded invoker address> || <Commit>

(注:|| 用作字节连接运算符。)

这个消息包含三个部分:一个魔术字节(0x03)、填充成 32 字节的调用者地址(执行authorize的智能合约的地址)以及一个 32 字节的 commit。

3

- 授权消息格式,包含一个 commit 示例 -

该 commit 描述了外部账户提交的数据,并且可以根据调用的某些属性计算得出,例如,地址、值和 nonce 的哈希值。调用者合约可以根据属性重新计算出 commit,如果这些字段都正确的话,就会执行授权。

假设我们想要发送以下事务(JSON 格式):

[
  {
    "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
    "value": 123,
    "nonce": 0
  },
  {
    "to": "0x4bbeEB066eD09B7AEd07bF39EEe0460DFa261520",
    "value: 123,
    "nonce": 1
  }
]

我们可以对这些字段进行哈希计算(例如,用确定性的方式将它们连接起来,或使用 EIP 712 之类的规范),并将得到的哈希值用作 commit。

我们可以在智能合约中提供要发送的事务和授权消息的签名,如 JSON 数据所示。合约函数就如下面这个例子所示:

function sendTransactions(Transaction[] calldata transactions, Signature calldata signature) external;

智能合约根据 transactions 重新计算 commit,并将这个 commit(连同签名一起)提供给AUTH调用。此举的目的是找回签名者的地址,如果计算得到的 commit 无效,根据签名找回的地址将是错误的,也就是说事务将失败。

调用者对 commit 的安全性负全责。你可以将 0x0 作为 commit 来签署消息,并授予智能合约对外部账户的完整访问权。前几版 EIP-3074 对 commit 的格式要求更为严格,包括重放保护等,但是后面为了提高灵活性已经将其移除。这就要求你在与调用者进行交互时必须信任对方。

局限性和安全隐患

由于能够根据签名更改 CALLER,EIP 3074 极大地改变了 EVM 的运作方式。这会为新合约和现有合约引入潜在漏洞。因此,EIP 3074 已经经过正式审计

下文解释了一些安全隐患。由于种种原因,EIP 3074 建议只与可信调用者交互。MyCrypto 等钱包界面提供可信调用者白名单功能。使用该功能的用户只能为白名单内的调用者签署授权消息。

弱 commit 和重放攻击

正如上文解释的那样,EIP 3074 没有为 commit 定义标准格式。调用者可以通过任意方式生成 commit。这意味着,调用者有责任确保 commit 的安全性,例如,抵御重放攻击。

如果 commit 不包含某种随机数,攻击者就可以轻松获取已签署的消息,再一次发送给调用者。恶意调用者完全不需要验证 commit,就可以获得外部账户的控制权。每次签署消息时,请你务必谨慎。

EIP 3074 通过将调用者的地址包含在授权消息内,提供了最基础的重放攻击保护。这样一来,恶意调用者就无法重放其他调用者的授权消息。

可升级调用者

EIP 3074 明确声明调用者程序不可升级。如果调用者程序是可以升级的,攻击者就可以部署另一个版本的调用者,在不验证 commit 的情况下授予合约对外部账户的控制权。

目前,智能合约可以使用 require(tx.origin == msg.sender) 来验证事务是否来自外部账户(而非另一个合约)。这样可以在一定程度上防止重入攻击,因为它可以防止合约调用该函数。

EIP 3074 也允许 tx.origin 成为授权消息的签名者。调用者执行的任何 AUTHCALL 都会导致 tx.origin == msg.sender 成真,即使这个调用是由智能合约执行的,因此很有可能遭到重入攻击。EIP 3074 指出:“……本 EIP 的作者并未找到任何有关这种重入攻击的例子,尽管没有进行详尽的搜索。”

EIP 3074 为以太坊带来了很多新的可能。AUTHAUTHCALL 使得外部账户能够将账户的控制权授予智能合约调用者,从而实现批量事务和赞助事务等新的事务类型。然而,该 EIP 也极大地改变了事务在以太坊上的运作方式,因此在主网上激活该 EIP 之前,我们需要更深入地思考其安全性。


原文链接: https://blog.mycrypto.com/eip-3074/
作者: Maarten Zuidhoorn
翻译&校对: 闵敏 & 阿剑


本文首发于:https://ethfans.org/posts/eip-3074-introduction-by-MyCrypto

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 19小时前
  • 阅读 ( 43 )
  • 学分 ( 3 )
  • 分类:以太坊

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK