任意精度是自由,也是裂缝
以太坊规范长期把大多数整数字段定义为”无上限的无符号整数”:交易 JSON 里 gas 字段理论上可以填一长串任意位数的数字。规范留白之处,各家客户端按工程习惯自立上限——有的内部按 64 位处理,有的做溢出环绕。2018 年 8 月 1 日,Alex Beregszaszi 与 Paweł Bylica 提交 EIP-1985,主张由共识层把值域写死:动机很直白,统一边界能降低客户端互相兼容的成本、减少无效的极端测试用例,某些场景还顺带提速。

四道值域的清单
1985 把参数划成四组。第一组,Gas 与区块高度、时间戳(原文分两小节,数值边界相同):单笔交易的 gas 上限、区块 gas 上限、NUMBER、TIMESTAMP 的输出一律限制在 0 到 2**63 - 1,即 9223372036854775807——刚好是能塞进 64 位有符号整数的最大值;受影响的指令包括 GAS、GASLIMIT、NUMBER、TIMESTAMP。第二组,账户地址固定为低 160 位有效、高 96 位必须为零,ADDRESS、ORIGIN、CALLER、COINBASE 乃至 CREATE 与 CREATE2 的输出都受此约束。第三组,各类尺寸——调用数据长度、代码长度、内存尺寸、程序计数器——上限 2**32 - 1,即 4294967295,受 CALLDATASIZE、CODESIZE、EXTCODESIZE、RETURNDATASIZE、MSIZE、PC 六条指令牵制。这些边界约束的是”能压上栈的值”,列出的指令输出永远不许越界。
4803:单独把 gas 上限钉进创世
2022 年 2 月 2 日,同为 1985 作者的 Alex Beregszaszi 提交 EIP-4803,把交易 gas 字段单独拎出来:任何 gas 上限超过 2**63 - 1 的交易自创世起即无效、不可入块。它选 2**63 - 1 而非更大的 2**64 - 1,理由写得很工程——让 gas 能当有符号数处理,越界检查退化成一次”减法后是否小于零”的判断。提案也顺手评估过更低的 2**31 - 1(方便 JavaScript 生态),最终没有采纳。它同时澄清了历史上一个理论漏洞:EIP-1559 之前允许 gasPrice 为 0 的交易,数学上曾让天文数字的 gas 上限通过余额校验,只是区块 gas 上限规则让它实际进不了块。两份提案的状态如今都停在 Stagnant。
已经生效的先例说明这事可行
值域类提案并非永远没戏。EIP-2681 就把账户 nonce 封顶在 2**64 - 1,状态是 Final,且规则自创世追溯生效——理由同样朴素:没有任何现实账户接近该值,而证明系统与客户端都能因此把 nonce 从 256 位大整数放心降格成 64 位处理。提案文本统计到 2020 年 11 月时全网最高 nonce 的账户也只有约 2900 万次。这条先例反衬出 1985 与 4803 停滞的原因:不是方向错,而是优先级排不上——没有现实事故施压,纯预防性共识改动的动力永远不足。相关脉络见 序号也有尽头:EIP-2681 把账户 nonce 封顶在 2 的 64 次方减一。
与钱包屏幕上那个大数字的关系
值域问题离用户并不远。RPC 接口按约定以十六进制字符串返回这些数值,钱包拿到后通常要转成十进制展示。JavaScript 用 64 位浮点数表示数字,超过 2**53 的部分会静默丢精度——而自定义代币的最小单位换算后轻松越过这条线,这正是正规钱包一律用大数类型处理金额、而不是原生 number 的原因。用户端的实际意义有二:金额显示与粘贴地址后的位数 sanity check 值得作为习惯;而”数值溢出导致资产异常”类传言,多数能追溯到工具实现没做对,而非链本身少了一条天花板。转账费用估算的口径可参考 以太坊Gas费怎么估算?。
为什么这类提案难以上车
值域提案有个结构性尴尬:越是提前划界,越没有事件给它们拉票。分叉预算是稀缺资源,社区优先给能降费用、提吞吐或修事故的方向;“防止某天某客户端溢出”的收益在一切正常时恰好是零。1985 与 4803 于是长期停在 Stagnant,靠被其他提案引用而维持存在——写形式化验证、做共识测试的人绕不开它们。另一个现实原因:许多边界已被主流客户端的事实行为兜住,共识化只是把默契写成法条,改进紧迫性进一步下降。理解这层优先级逻辑,比记住每个上限数字更有用:以太坊的”没写进共识”不等于”没人管”,也不等于”可以做”,工具链的既有防线很多时候先于规则起作用。风险提示:本文为共识机制分析,不构成投资建议;字段处理以实现与最新规范为准。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。