Alert Source Discuss
🛑 Withdrawn Standards Track: Core

EIP-2711: 赞助、过期和批量交易。

Authors Micah Zoltu (@MicahZoltu)
Created 2020-06-11
Discussion Link https://ethereum-magicians.org/t/eip-2711-separate-gas-payer-from-msg-sender/4353
Requires EIP-2718

简要总结

创建一个新的交易类型,支持赞助交易(将 gas 支付者与发送者分离)、批量交易(按顺序执行的多个交易)和过期交易(在特定时间戳之后无效的交易)。

摘要

类型编号为 2 的 EIP-2718 交易是一种新的交易类型,包括对以下内容的支持:

  1. 赞助交易:一个可选的附加签名,从中可以恢复将支付 gas 的帐户 (GAS_PAYER)
  2. 批量交易:来自同一发送者的多个交易,将按顺序执行
  3. 过期交易:一个可选的 validUntil 字段,使交易在特定时间点之后无效

动机

赞助交易

随着代币,尤其是稳定币的出现,用户通常不在帐户中持有 ETH,而他们可能在该帐户中拥有其他有价值的资产。一些用户不想暴露于 ETH 的感知波动性,而是更喜欢使用其他资产进行交易。不幸的是,由于 gas 必须用 ETH 支付,这阻止了用户在不首先使用其他方式获取一些 ETH,然后使用该 ETH 支付费用的情况下,使用他们的资产进行交易。

本 EIP 提出了一种机制,通过该机制,我们可以允许人们在无需拥有任何 ETH 的情况下进行交易,方法是允许其他人支付 gas 费用。实现 gas 费用支付的安排不在本 EIP 的范围之内,但它可以是协议外的每月订阅,付款可以在提交交易时发生,接收者可能愿意支付 gas 费用,或者它可以是由您合作的公司提供的增值免费服务。

虽然可以在单个合约层实现这些类型的机制,但此类解决方案需要几乎每个合约都进行集成,并且这些解决方案最终还取决于 gas 成本随时间的推移保持稳定,以便适当地将其烘焙到合约中,而不会使任何一方面临系统恶意参与者的风险。因此,我们认为在协议层将 GAS_PAYERmsg.sender 分离是有价值的。

批量交易

通常,EOA 可能希望执行一系列交易,并强烈保证它们按顺序发生,并且它们之间没有任何事情发生。例如,可能希望将一些代币发送到合约,然后通过另一笔交易来调用目标地址上的合约,从而使这些代币注册到他们。通过在第 1 层支持交易批处理,我们可以确保用户可以在签名时获得跨交易原子性的有力保证。

过期交易

  • 如果引入任何形式的尘埃账户清理,例如 (https://github.com/ethereum/EIPs/issues/168),则有必要引入重放保护,例如 https://github.com/ethereum/EIPs/issues/169 。具有时间重放保护消除了更改状态中 nonce 行为的需要,因为交易在用户明确设置的较晚日期之后将不可重放。
  • 在许多情况下,例如在 ICO 期间,很多人希望他们的交易要么尽快(在几个小时内)被包括在内,要么根本不包括在内。目前,交易会排队,并且可能会在几天内没有执行,这会给用户(最终为失败的购买支付 gas)和网络(处理大型交易队列)带来成本。
  • 节点实现没有普遍认可的指标来决定保留、丢弃或传播哪些交易。在交易上设置 TTL 将使从系统中删除过时交易变得更容易。

规范

定义

TransactionType 2。请参阅 EIP-2718

TransactionSubtype 为 1、2、3 或 4。

ChainId 如果此值为 0,或者它包含在链 ID 等于此值的链上的区块中,则该交易有效。

ValidUntil 如果此值是 0,或者它包含在一个 timestamp 小于或等于此值的区块中,则该交易有效。

YParity secp256k1 签名的 y 值的奇偶性(0 表示偶数,1 表示奇数)。

ChildTransaction 一个嵌套的交易,由 [to, value, data] 组成。

SenderPayload 根据 TransactionSubtype 定义如下:

  1. [1, ChildTransaction[], nonce, ChainId, ValidUntil, gasLimit, gasPrice]
  2. [2, ChildTransaction[], nonce, ChainId, ValidUntil, gasLimit, gasPrice]
  3. [3, ChildTransaction[], nonce, ChainId, ValidUntil, gasLimit]
  4. [4, ChildTransaction[], nonce, ChainId, ValidUntil]

SenderSignature secp256k1(keccak256(rlp([TransactionType, SenderPayload])))[YParity, r, s]

GasPayerPayload 基于 TransactionSubtype 定义如下:

  1. []
  2. []
  3. [gasPrice]
  4. [gasLimit, gasPrice]

GasPayerSignature 对于 TransactionSubType 1[],对于其他 TransactionSubType,为 secp256k1(keccak256(rlp([SenderPayload, SenderSignature, GasPayerPayload])))[YParity, r, s]

新的交易类型

FORK_BLOCK_NUMBER 开始,TransactionType2EIP-2718 交易将将其 Payload 解释为以下内容的 RLP 编码元组:

[...SenderPayload, ...SenderSignature, ...GasPayerPayload, ...GasPayerSignature]

从该 SenderSignature 恢复的地址是…

  1. …交易的第一个调用帧期间由 CALLER 操作码(0x33,又名 msg.sender)返回的
  2. …由 ORIGIN 操作码(0x32,又名 tx.origin)返回的
  3. …使用其 nonce
  4. …如果任何值附加到交易,则扣除其 ETH 余额
  5. …如果 GasPayerSignature 不存在,则扣除其 ETH 余额以支付 gas

如果存在 GasPayerSignature,则从中恢复的地址是…

  1. …扣除其 ETH 余额以支付 gas

此类型交易的基本 gas 成本将是 TRANSACTION_TYPE_2_BASE_GAS_PRICE + TRANSACTION_TYPE_2_CHILD_GAS_PRICE * n,而不是与类型 0 交易和旧交易相关的成本。

新的交易回执

FORK_BLOCK_NUMBER 开始,TransactionType2EIP-2718 交易回执将将其 Payload 解释为 rlp([status, cumulativeGasUsed, logsBloom, logs][]),其中数组的每个项目都对应于交易类型 2 Payload 中匹配偏移量的子交易。

理由

一个整体的 EIP

本 EIP 可以分为多个 EIP,每个子类型一个,元类型一个。或者,每个子类型都可以是唯一的 TransactionType。我们选择使用带有子类型的单个 EIP 的原因是,这 4 个事务都具有很多共同点,并且每个单独的 EIP 几乎与上一个相同。我们认为在这种情况下,拆分为多个 EIP 不值得重复 EIP 内容。

ChainID 未与 v 一起编码

虽然我们可以通过将签名的 y 奇偶校验位与 EIP-155 中的 Chain ID 捆绑在一起来节省常见情况下的一个字节,但这会增加签名工具的复杂性,作者认为考虑到交易的整体大小,这不值得。

ChainID 的可选性

有时拥有可以在多个链上可以重放的交易是有用的。一个例子是当你为交易构造一个虚荣签名并让 from 成为该签名恢复到的任何地址时。通过让其他人成为 gas 支付者(设置 gas 限制和 gas 价格),可以拥有部署合约的交易,这些合约存在于每个链上的相同地址。虽然可以使用旧交易通过 CREATE2 来完成此操作,但我们有机会简化该过程,并通过使 ChainID 成为可选的来启用确定性交易的潜在其他未来用途。

ValidUntil 的可选性

用户可以将 ValidUntil 设置为一个非常大的数字,从而有效地使其永不过期。通过使 ValidUntil 成为可选的,我们可以通过允许此类交易简单地为此字段设置一个 0(RLP 中为 1 个字节)值来节省一些传输量。

SENDER 设置 gasLimitgasPrice

当交易可能会根据这些值的设置方式以不同的方式执行时,此类型的交易非常有用。通过让 SENDER 同时设置它们,我们可以确保 SENDER 完全控制交易细节。

SENDER 设置 gasLimitGAS_PAYER 设置 gasPrice

当交易可能会根据允许的 gas 量(例如,循环次数)以不同的方式执行,但 SENDER 希望让 GAS_PAYER 能够为交易定价以最大化纳入机会时,此类型的交易非常有用。

GAS_PAYER 设置 gasLimitgasPrice

这种类型的交易允许 SENDER 定义他们想要做什么,并将所有关于 gas 的担忧留给 GAS_PAYER。这对于发送者不关心使用了多少 gas 或支付的价格,并且要么信任 GAS_PAYER 是非恶意的,要么不关心 SENDERP 的 nonce 会增加的交易非常有用。当您在 SENDERGAS_PAYER 之间存在协议外信任,并且您想要出于安全或复杂性的原因将关注点(做什么与如何包含)分开时,这种情况非常有用。

Nonce

内部交易需要 nonce 来保护自己免受重放攻击。由于内部交易具有 nonce,我们也获得了外部交易的重放保护,因此对于安全而言,让多个参与者提供 nonce 并非至关重要。

我们可以让 GAS_PAYER 提供第二个 nonce,但这会增加 payload 大小,并且如果他们想要插入一个具有更高 gas 价格的新(不同的内部)交易,则需要 GAS_PAYER 进行替换费用(对 gossip 来说很吵)。如果 SENDER nonce 的排序与 GAS_PAYER nonce 的排序不同,并且如果 SENDER nonce 不是 SENDER 的最低有效 nonce,则还会产生死锁的可能性,那么 GAS_PAYER 还无法签名和提交。最后,如果交易有两个 nonce,则客户端复杂性会略有增加,因为您必须保护自己免受死锁的影响,并做更多的工作来确定有效性。

ValidUntil

对于尘埃帐户清理用例,

  • 此更改对共识引擎的侵入性要小得多。
    • 无需维护“最高已知 nonce”的共识字段或限制来自发送者的区块中的交易数量。
    • 仅触及共识引擎的交易验证部分
    • 使用 nonce 的其他模式可能会产生意外的副作用,
      • 例如无法在某些地址创建合约。
      • 更难与离线签名器集成,因为更复杂的 nonce 方案需要状态访问才能确定。
      • 更复杂的方案(如 highest-nonce)要困难得多,因为 highest-known-nonce 将是一个共识结构,该结构在交易执行期间会递增并可能恢复,从而需要一个额外的日记字段。

ValidUntil 作为时间戳而不是区块号

  • unix 时间通常在大多数设置中都可用,即使在一台离线计算机上也是如此。这意味着即使在区块链信息不可用的设置中,签名交易的参与者也可以生成具有所需属性的交易。
  • 时间和区块号之间的相关性不是固定的;即使 13 秒的区块时间是“理想的”,但这会因网络哈希率和难度炸弹的进展而异。
  • 对于测试网和私有网络,区块号作为时间戳更加不可靠。
  • unix 时间对用户更友好,用户可以更容易地确定交易的合理结束日期,而不是合适的有效区块数。

向后兼容性

没有已知问题。

测试用例

实现

安全注意事项

版权

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

Citation

Please cite this document as:

Micah Zoltu (@MicahZoltu), "EIP-2711: 赞助、过期和批量交易。 [DRAFT]," Ethereum Improvement Proposals, no. 2711, June 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2711.