EIP-155 提议使用链 ID 来防止不同链之间的重放攻击。当处理签名时,在智能合约中拥有相同的可能性将是一个巨大的好处,特别是对于使用 EIP-712 的 Layer 2 签名方案。
规范
在 0x46 处添加一个新的操作码 CHAINID,它使用 0 个堆栈参数。 它将当前的链 ID 推送到堆栈上。 链 ID 是一个 256 位的值。 该操作的执行成本为 G_base。
当前链 ID 的值从链 ID 配置中获得,该配置应与客户端将从传入交易中接受的 EIP-155 唯一标识符匹配。 请注意,根据 EIP-155,并非 必须 让交易具有 EIP-155 唯一标识符,但在这种情况下,此操作码仍将返回配置的链 ID,而不是默认值。
理由
EIP-712 提出的当前方法是在编译时指定链 ID。 使用这种方法会在硬分叉后导致问题,以及可能导致资金损失或签名消息重放攻击的人为错误。
通过添加提议的操作码,可以访问当前的链 ID 并基于该链 ID 验证签名。
目前,对于特定网络如何设置链 ID,没有规范,这依赖于客户端实现者和链社区手动做出的选择。 在一个有争议的问题上发生“有争议的分裂”期间,可能会出现这样一种情况:使用特定链 ID 值的社区将决定分裂成两条这样的链。 当发生这种情况时,将链 ID 保持在两条链上的相同值是不安全的,因为链 ID 用于协议内交易的重放保护(根据 EIP-155),以及用于 L2 和“元交易”用例(根据 EIP-712,由本提案启用)。 在当前流程下,在这种情况下有两种可能的解决方案:1) 一条链决定修改其链 ID 值(而另一条链保持不变),或 2) 两条链都决定修改其链 ID 值。
为了缓解这种情况,提议的 CHAINID 操作码的用户必须确保他们的应用程序可以处理在使用应用程序期间对链 ID 值的潜在更新,以防发生这种情况,如果需要继续使用应用程序。 记录链 ID 更改发生的时间戳的 Trustless Oracle 可以作为应用程序合约系统内的应用程序级功能实现,也可以作为全局标准合约引用。 如果不为此方案提供缓解措施,可能会导致先前签署的链下消息突然失去合法性,这在结算期和这些类型消息的其他长期验证事件中可能会成为问题。 并非此操作码的所有应用都需要缓解措施来处理此方案,但开发人员应根据具体情况提供理由。
一个不适合利用全局 oracle 的例子是 Plasma L2 范例。 在 Plasma 范例中,运营商或运营商组将来自 L2 网络的区块提交到基础链(在本例中为以太坊),总结了该链上发生的交易。 这些区块的提交可能与主链上的重大事件并不完全一致,例如导致链 ID 更新的分裂,如果链 ID 用于签名消息,这可能会导致协议中出现重大不安全。 如果不允许运营商控制链 ID 的更新,他们将无法将其更新与区块提交完美同步,并且某些过去的交易可能会被拒绝,因为它们与更新不一致。 这是试图在有争议的分裂期间过多地指定链 ID 行为的意外后果的一个例子,也是为什么拥有一个简单的操作码进行访问是最优的,而不是更复杂的预编译或合约。
这个提议的操作码将是实现此功能的最简单方法,并允许开发人员灵活地实现他们自己的全局或本地链 ID 更改处理(如果需要)。