Alert Source Discuss
🚧 Stagnant Standards Track: Core

EIP-1965: 检查 chainID 在特定区块号是否有效的方法

Authors Ronan Sandford (@wighawag)
Created 2019-04-20
Discussion Link https://ethereum-magicians.org/t/eip-1965-valid-chainid-for-specific-blocknumber-protect-all-forks/3181
Requires EIP-155

摘要

本 EIP 添加了一个预编译合约,用于返回特定的 chainID (EIP-155 唯一标识符) 在特定 blockNumber 处是否有效。ChainID 假定在被新的 chainID 替换之前,都是有效的。

动机

EIP-155 提议使用链 ID 来防止不同链之间的交易重放。当处理链下消息签名时,在智能合约内部拥有相同的可能性将是一个巨大的好处,特别是对于使用 EIP-712 的 Layer 2 签名方案。

EIP-1344 试图通过让智能合约访问 chainID 历史的顶端来解决这个问题。但这并不充分,因为这样的值正在变化。因此,EIP-1344 描述了一种基于合约的解决方案来解决这个问题。最好以一种更简单、更便宜和更安全的方式来解决它,消除 EIP-1344 中存在的潜在误用风险。此外,EIP-1344 无法正确地保护由少数人主导的硬分叉的重放,因为缓存系统无法保证引入新 chainID 的 blockNumber 的准确性。

EIP-1959 解决了 EIP-1344 的问题,但没有试图防止由少数人主导的硬分叉,正如理由中所提到的。我们认为这是一个错误,因为它消除了一些分叉的自由。我们认为所有分叉都应该被给予平等的机会。虽然对于大多数忽略特定分叉的人,我们总会遇到无法解决的问题,但是决定同时使用少数人分叉和多数人链的用户应该受到保护,免受重放攻击,而无需等待多数人链更新其 chainID。

规范

添加一个新的预编译合约,它使用 2 个参数:一个 32 字节的值,表示要测试的 chainID,以及一个 32 字节的值,表示测试 chainID 的 blockNumber。如果 chainID 在特定的 blockNumber 处有效,则返回 0x1,否则返回 0x0。请注意,chainID 被认为在被替换的 blockNumber 之前都是有效的。因此,对于每个超过其替换的 blockNumber,它们都是有效的。

该操作的执行成本不会超过 G_blockhash + G_verylow。这可能会更低,因为 chainID 仅在硬分叉期间引入。

操作的成本可能需要在以后进行调整,因为链的历史记录中的 chainID 数量会增加。

请注意,虽然跟踪旧 chainID 的替代方法是实现一个基于智能合约的缓存解决方案,正如 EIP-1344 提议的那样,但它的总体 gas 成本更高,并且对于由少数人主导的硬分叉存在问题(请参阅下面的“理由”部分)。因此,gas 成本只是该功能的必要成本。

理由

EIP-1959 的理由也适用于这里:

  • 对于过去的 chainID,一个操作码比缓存系统更好。它更便宜、更安全,并且不包含差距。
  • 直接访问最新的 chainID 是危险的,因为它使合约很容易将其用作重放保护机制,同时阻止在改变 chainID 的分叉之后,其他有效的旧消息有效。这可能会对用户造成灾难性的后果。
  • 在分叉之前签署的所有链下消息都应该在分叉的所有方面都有效。

唯一的区别是,当前的提案提出了一种保护由少数人主导的硬分叉的解决方案。

总而言之,存在 2 种可能的分叉情况:

1) 大多数人决定进行硬分叉,但少数人不同意(ETC 就是这样的例子)。该分叉计划在区块 X 进行。如果大多数人不采取任何行动来自动执行为两者分配不同 chainID 的过程,则少数人有足够的时间计划在同一区块 X 发生 chainID 升级。现在,如果他们不这样做,他们的用户将面临他们的消息将在多数人链上可重放的问题(请注意,反过来是不正确的,因为我们假设大多数人决定更改 chainID)。因此,没有理由让他们保持这种状态。

2) 少数人决定创建一个大多数人不同意(或只是忽略)的硬分叉。现在,与上面相同的事情可能会发生,但是由于我们正在谈论少数人,因此大多数人有可能不在乎少数人。在这种情况下,将没有动力让大多数人升级 chainID。这意味着,除非采取额外的预防措施,否则多数人链的消息将可以在少数人链上重放(即使少数人链已更改其 chainID)。

解决方案是添加表示消息签署时间的 blockNumber,并将其用作此处提出的操作码的参数。这样,当少数人使用新的 chainID 进行分叉时,先前的 chainID 从那时起失效。因此,针对多数人链的新消息不能在少数人分叉上重放。

向后兼容性

EIP-712 仍在草案中,但需要进行更新,以将 blockNumber 作为钱包需要验证的值的一部分,以保护其用户。

由于 chainID 和 blockNumber 会有所不同,因此它们不应成为域分隔符(旨在生成一次)的一部分,而应成为消息的另一部分。

虽然对于不关心重放或有其他方法来防止重放的合约,该对可以是可选的,但是如果存在 chainID,则 blockNumber 也必须存在。并且如果存在任何一个,钱包需要确保 chainID 确实是所使用链的最新 chainID,而 blockNumber 是签署时的最新 blockNumber。在分叉过渡期间,钱包可以使用 blockNumber 来了解要使用哪个 chainID。

参考

先前已将其作为 EIP1959 讨论的一部分提出。

版权

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

Citation

Please cite this document as:

Ronan Sandford (@wighawag), "EIP-1965: 检查 chainID 在特定区块号是否有效的方法 [DRAFT]," Ethereum Improvement Proposals, no. 1965, April 2019. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1965.