一个生僻但够呛的参数
添加自定义网络时那栏 Chain ID,平时没人多看一眼,但它管的事情不小:EIP-155 把链号编进交易签名的 v 值里,让一条链上签好的交易拿到另一条链去重放会直接失效。链号取值本身有没有边界?主网协议没有硬性规定,EIP-2294 于是以 Informational 性质在 2019 年 9 月写下建议边界,状态至今 Stagnant。别小看「建议」二字:它列的约束全部来自真实生态组件——钱包前端用 JavaScript 表示数字、客户端用 64 位整数做算术、签名编码要能序列化——任何一环掉链子,轻则签名对不上,重则不同实现算出分歧。

两段区间与 2^31 的由来
标准给出两段。第一段是安全区间:1 到 2 的 31 次方减 1,也就是 2147483647。上限卡在 JavaScript:JS 的数字类型对超过 2 的 53 次方减 1 的整数就不保证精确,而链号还要参与各类运算,留到 31 位以内才能保证各类前端、JSON 序列化、数据库字段全链路不丢精度。第二段是最大区间:上限取 floor(MAX_UINT64 / 2) - 36,算出来是 9223372036854775771。这个奇怪的减 36 来自 EIP-155 的公式——签名过程中算术上出现的最大值是 chainId * 2 + 36,一旦顶破 uint64 上限就会回绕。客户端如果不检测溢出,不同实现会算出不同的 v 值,这就成了共识级事故的材料。0 和负数则被直接排除。
翻车的两种现场
第一种发生在钱包界面:链号超过 JS 安全整数,钱包显示的链号和 RPC 返回的真实值差了几个尾数,用户没察觉,签名请求里的 chainId 字段和实际连的链对不上,要么交易被节点拒收,要么在另一条同号链上被接受——后者正是重放保护想挡住的事。第二种发生在极客自建的实验链:创世配置里随手写一个百位大数,客户端一算 v 值就溢出报错,或者各实现解析分歧。两类事故的根因相同:链号是全局协调的公共编号,不是随便起的域名。
用户侧的核对顺序
普通用户不需要记 9.2×10^18 这个数,需要的是添加网络时的三步纪律。第一步,优先用链的官方文档或可信链标识列表给出的链号,不要手敲记忆中的数字;第二步,把配置页上的链号与公开渠道可查的 eth_chainId 结果对一遍,两边一致才保存;第三步,留意钱包在添加网络弹窗里显示的链号与你输入的完全一致——个别旧版钱包会把大数显示成科学计数法,那就是精度已经在丢的信号。同一次核对里顺手检查 chainId 与 networkId 是否都填对,两者语义不同,填错都会造成连不上或连错网。
为什么边界至今没有强制化
把上限写进共识层意味着给所有新建链设门槛,而链号分配本来就是自愿协调的公共池,强行执法的收益低、兼容代价高,EIP-2294 因此停在建议层面,靠钱包和节点实现各自做防御。这个折中反过来提醒用户:公共池里没有警察,链号冲突、仿冒链抄一个相近编号,都是靠钱包厂商的黑名单和使用者自己的核对来兜底。把上面的三步当成添加网络动作的一部分,比记住任何具体数字都有效。
关于「大链号链」再多说一句
有人会把这条建议误读成链号越大越安全。恰恰相反:编号的价值在于全局可辨识,一个 60 多位的链号在钱包显示、RPC 参数、签名算术任何一环都可能被截断或四舍五入,而相近的编号又给仿冒留了缝。生态里被反复验证的选择方式是中等长度、有出处可查的数字——提案把安全区间定在 2^31-1 以内,也是在用工程语言说同一句话:能被所有工具原样搬运的编号,才是好编号。给新项目建议链号时优先在安全区间里找空闲值,普通用户则只需守住前面那三步核对,不必参与编号分配的讨论。 “添加网络”弹窗到底加了什么:链标识、节点地址与浏览器的三个字段 EIP-155如何阻止跨链重放?
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。