链号不是刻在石头上的
签名里带链ID是防跨链重放的标准做法——EIP-712 弹窗里那行”链”就是它,两条链共用链号会出什么事此前单独讲过,见一枚签名多条链通用:ERC-7964 把链标识从域名里拿掉之后。但有个反方向的问题很少有人想:链号自己会变。硬分叉就可能改链ID,今天的主网标识正是 2017 年那次升级钉下来的。对链上交易,改号影响不大;对链下签好待用的消息——状态通道收据、Layer2 意向单——却是灭顶之灾:签名里钉死的是旧链号,分叉后合约按新链号一验,一夜之间全部作废。2019 年 4 月,同一位作者提交了配套提案回答这件事:EIP-1959 问”这个链号在本链历史上出现过吗”,EIP-1965 再追问一步”它在那个区块高度时有效吗”。两份提案如今都停在 Stagnant。

从”最新值”到”历史集”
要理解这两份提案,先要看清它们想修正的对象。EIP-1344 让合约能读当前链ID,状态 Final,是 CHAINID 操作码的正规来源。问题在于”当前值”是个会动的靶子:合约若写死”签名链号必须等于当前链号”,分叉改号那一刻,此前所有合法签名集体失效——用户签的时候没做错任何事,规则却变了。提案作者把这称为”反向的重放问题”,并算过状态通道场景的账:链上资产错了可以追责,链下状态一夜不可访问,损失可能灾难性。EIP-1959 的解法干净:加一个操作码(提案定为 0x46),传入一个数,返回它是否出现在本链自创世以来的链号历史里,成本与读最近区块哈希相当。链号只在硬分叉时变化,历史集合极小,查询并不贵。
1965 补的角
EIP-1959 有个它自己承认的软肋:争议分叉若由少数派发起且多数派不跟着改链号,多数派继续用旧号签的新消息,可以在少数派链上被重放——因为那个号在两边历史上都”有效”。EIP-1965 把问题升维:设计一个预编译,收链号加区块高度两个参数,回答”这个号在那一刻有效吗”。这样每条消息都能带签署高度,合约按高度精确判定。它明确写了两种分叉剧本的结论:多数派无视的少数派链,其用户若同时用两条链,应得到保护而无须等多数派改号;完全被无视的链则不假设它能成气候。成本上限是读块哈希加一条极廉价的指令。
双双搁浅之后
两份提案都没走完:状态 Stagnant,操作码与预编译都未上主网。原因是多方面的——链号变更本身极罕见,为一个二十年一遇的事件加共识规则收益单薄;EIP-1344 描述的软件层缓存方案”够用”;而 1959 与 1965 之间、以及与既有防重放体系之间的取舍始终没有共识。对普通用户,这条提案线的现实含义落在核对动作上。第一,遇到”分叉后我的旧签名/旧凭证还能用吗”这类问题,别默认协议有历史查询能力——链上合约验不验旧链号,完全取决于合约作者的自觉。第二,钱包在发起签名时永远填最新链号,这本身是有意的设计:保住”当前值”这条防重放底线,代价就是跨分叉兼容性交给具体协议自己处理。第三,参与状态通道、链下订单簿这类依赖旧签名长期有效的产品时,把它对”链号变更”的预案列入尽调问题——就像核对授权边界那样,见连接钱包、签署消息、授权转账是三件事:各自动了你什么。
一个小清单
用三条问题收束:这份签名里有没有链号?它验的是当前链号还是历史集合?如果出现分叉,我签过的东西站在哪一边?三问有两问答不上来,说明该协议的分叉兼容性是隐式假设而非显式设计,金额较大的链下承诺值得先小额试路径。
本文为技术说明,不构成投资建议;链下签名在分叉场景下的有效性取决于具体协议实现,请先核实条款。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。