以太坊合约里一笔调用能拿走父调用多少燃料,并不是”全给”或者”随便要”,而是受一条固定比例规则约束:最多只能带走”全部减去六十四分之一”,写成分数形式是 N − floor(N/64)。这条规则随 2016 年的 Tangerine Whistle 升级生效,用一种看起来不显眼的方式,同时处理了拒绝服务攻击和调用栈深度限制两件大事。本文讲清它的算式、来历和今天仍然起作用的地方。
算式与效果
假设父上下文有 64,000 gas,子调用最多拿走 64,000 − floor(64,000/64) = 63,000,剩下的 1,000 gas 必然留在父调用手里。含义很直接:无论合约怎么嵌套调用,每一层调用栈都保证留有一段”回家路费”——父上下文一定会恢复执行并观察到子调用的失败或成功,不会出现”整条栈一口气烧光、没有任何一方有燃料记录结果”的断崖。

来历:2016 年的拒绝服务攻击
这条机制属于 EIP-150 对调用类操作码的改动之一。2016 年夏季,网络被一系列”读状态”类交易拖慢:读存储树的操作定价过低,一条交易就能迫使节点读大量磁盘数据。治理思路分两半:给这些操作码重新定价(把单块需读取的数据量压到目标量级),以及改造 gas 转发规则。官方文本同时引入”EIP 90 式”转发:既然调用要交更贵的过路费、金额还不可预测,就顺手把”最多转发 gas 减去 1/64”写进规则,并借此把原来靠 1024 层调用栈深度做的硬限制,换成随 gas 分布自然形成的软限制——实际最大栈深降到约 340 层(此前约 1024),调用栈深度攻击作为一个攻击类别被消解。
为什么是 1/64
留白太小,等于没留;留白太大,深层合法调用会拿不够燃料。1/64 是一个折中常数,并且配合新定价后,每一层的绝对留白会随总 gas 下降而收窄,形成”指数衰减”的燃料预算——嵌套到深处,每层可用的 gas 已经小得不足以做坏事,软限制因此闭合。
今天的存在感
从伦敦硬分叉的访问列表计价(EIP-2929/EIP-2930)到后来的各项 gas 提案,这条 63/64 规则都没有被动过,仍是现行调用语义的一部分。审计合约时它体现在两个细节:一是最深处调用可能”差一口气”的 OOG(out of gas)错误,根因常在嵌套深度而不是总额;二是任何”把剩余 gas 全转走”的写法(gasleft() 直接透传)实际拿到的永远是 63/64,高级组合协议要按这个上限设计预算。
一笔直觉算术
把 63/64 规则连续套十层看看量感:第 1 层给第 2 层最多约 98.4% 的燃料,十层嵌套后传到底部的只剩初始 gas 的约百分之八十五;套三十层剩约六成二;套六十层剩约四成。衰减是指数式的,但底数非常接近 1——单纯”深”并不可怕,可怕的是每一层还要按自己的最低成本扣 gas。所以现实里触发深层 OOG 的从来不是嵌套本身,而是”浅层把预算花在别处、深层只剩零头”的组合。排障时这条算术能帮你快速判断:错误出现在第几层、那层拿到的预算够不够它做本层必须做的事。
与其他 gas 机制的关系
这条规则常与另外两个数字混进同一个话题,值得分开:六十四分之一管”调用之间怎么分”;每区块 gas 上限管”一笔交易总共能烧多少”;EIP-150 的另一半——各操作码的重定价——管”每件事单价多少”。三者相乘才是你在浏览器上看到的最终行为:单价决定这层花多少,63/64 决定下层能拿多少,区块上限决定谁最终被挤出。把它们混成一个”gas 机制”,是社区讨论里最常见的概念塌缩。
快速问答
问:给子调用传超过上限的 gas 会报错吗? 答:不会,会被静默截断到上限,多余的留在调用方。
问:留住的 1/64 会退款吗? 答:不会,没花完的部分最终不退还给外部发送者,只影响调用树内部的预算。
问:普通用户需要关心它吗? 答:排查”交易失败但 gas 全烧”类问题时,它是背景知识;日常使用无需操作。
风险提示:本文仅为技术与机制科普,不构成任何投资建议,也不构成对任何软件、交易对或收益的承诺;涉及资产操作前请以当期官方文档为准,并自行承担操作风险。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。