
EIP-7971 深度解读为以太坊瞬态存储引入交易级硬上限与恒定低 Gas 定价【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs导读EIP-7971Hard Limits for Transient Storage是一项面向以太坊核心共识协议的 Standards Track 提案旨在把TLOAD/TSTORE两个瞬态存储操作码的 Gas 成本从与热存储访问相同的 100 gas 大幅下调至恒定低价5 / 12 gas同时引入一个交易级全局瞬态存储槽数量上限防止攻击者利用廉价写入无限分配内存。读完本文你将掌握该提案的参数体系、交易级计数器的精确语义、参考实现背后的账务机制以及它与 EIP-1153、EIP-8038 等提案之间的演进关系与安全权衡。背景与动机为什么 100 gas 的瞬态存储不够便宜瞬态存储的前世今生瞬态存储由 EIP-1153Transient storage opcodesCancun 升级中已生效状态为 Final引入通过TLOAD0x5c与TSTORE0x5d两个操作码提供行为与持久存储几乎一致、但在每笔交易结束时自动丢弃的存储区域。它的核心优势在于值永远不会被序列化到磁盘或从磁盘反序列化因此天然比持久存储便宜天然支持同一交易内跨调用帧CALL frame的通信无需依赖不可信中间帧透传输入输出用于重入锁时不受 EIP-3529 引入的退款上限为交易 Gas 的 20%限制。然而EIP-1153 给TLOAD/TSTORE的定价是与热存储访问warm storage access相同的 100 gas。EIP-7971 在 Motivation 一节指出了这一现状的三点局限重入保护成本过高每次操作 100 gas导致默认在语言层面普遍启用重入锁仍然太贵合约因而继续暴露在最常见的攻击向量之下合法用途被抑制临时授权temporary approvals、回调元数据callback metadata、交易内跨帧通信等场景同样承受高昂成本定价与资源消耗不匹配瞬态存储本质上不涉及磁盘 I/O、不更新状态根所需资源远少于持久存储却与热存储操作同价。从源码结构看这一同价源于 EIP-1153 的定价模型其规范明确写道 Gas cost forTSTOREis the same as a warmSSTOREof a dirty slot (currently 100 gas)即直接沿用了 EIP-2929 引入的 warm access 成本常数。EIP-7971 正是要打破这一耦合。提案核心恒定低价 交易级硬上限EIP-7971 的方案由两大部分组成把瞬态存储改成恒定低价以及引入交易级全局上限来封顶内存分配。这两者缺一不可——没有上限低价会成为内存耗尽型 DoS 攻击的放大器。参数体系提案在 Specification Parameters 一节引入了 4 个参数常量值说明GAS_TLOAD5TLOAD的 Gas 成本GAS_TSTORE12TSTORE的基础 Gas 成本MAX_TRANSIENT_SLOTS131072单笔交易内允许的瞬态存储槽最大数量GAS_TSTORE_ALLOCATE24额外分配新槽位的成本Gas 成本变更TLOAD操作码0x5c的 Gas 成本从GAS_WARM_ACCESS100降为GAS_TLOAD5TSTORE操作码0x5d的基础Gas 成本从GAS_WARM_ACCESS100降为GAS_TSTORE12。注意第 2 点是基础成本由于写入全新槽位需要内存分配比写入已存在槽位更贵提案还通过GAS_TSTORE_ALLOCATE24对首次分配槽位额外收费详见下文参考实现。交易级瞬态存储上限机制提案在 Transaction-Global Transient Storage Limit 一节定义了全局计数器的精确语义每笔交易开始时将计数器transient_slots_used初始化为 0每当执行TSTORE时若该槽位在**本交易内跨所有合约**尚未被写入过则递增transient_slots_used若transient_slots_used超过MAX_TRANSIENT_SLOTS交易必须异常中止exceptionally halt计数器在交易内的所有消息调用message call之间持续存在计数器在交易结束时重置为 0。实现说明槽位唯一性判定实现必须跨所有合约追踪瞬态存储分配。一个槽位以元组(contract_address, storage_key)判定唯一——这与 EIP-1153 中瞬态存储对拥有它的合约私有DELEGATECALL/CALLCODE时归属调用方、CALL/STATICCALL时归属被调用方的归属规则天然衔接。同一槽位在交易内被多次写入首次写入之后通常不再递增计数器除非该槽位因 revert 被释放。这一语义与 EIP-1153 的 revert 行为紧密相关EIP-1153 规定若一个帧 revert则从进入该帧到返回之间对瞬态存储的所有写入包括内部调用中的写入都会被回滚。因此一个被 revert 释放的槽位可以在后续执行中再次成为新槽位再次触发计数与GAS_TSTORE_ALLOCATE收费——这正是参考实现中unique_slots集合与存储映射需要分开维护的原因。参考实现拆解Python 伪代码逐行讲解EIP-7971 在 Reference Implementation 一节给出的 Python 伪代码完整实现了按槽位是否已分配来差异化定价TSTORE的机制# Pseudo-code for transaction execution with global transient storage limit GAS_TLOAD 5 GAS_TSTORE 12 GAS_TSTORE_ALLOCATE 24 MAX_TRANSIENT_SLOTS 131072 class TransactionContext: def __init__(self): self.transient_storage {} # (address, key) - value self.unique_slots set() # set of (address, key) tuples self.transient_slots_used 0 def tload(self, address: Address, key: Bytes32) - Bytes32: # Charge gas self.charge_gas(GAS_TLOAD) # Return value or zero return self.transient_storage.get((address, key), Bytes32(0)) def tstore(self, address: Address, key: Bytes32, value: Bytes32): # Charge gas self.charge_gas(GAS_TSTORE) # Check if this is a new unique slot slot_id (address, key) if slot_id not in self.unique_slots: self.charge_gas(GAS_TSTORE_ALLOCATE) self.unique_slots.add(slot_id) # Check limit if len(self.unique_slots) MAX_TRANSIENT_SLOTS: raise ExceptionalHalt(Transient storage limit exceeded) # Store value self.transient_storage[slot_id] value实现要点tload只收取GAS_TLOAD读取只需内存访问、无磁盘 I/O读一个从未写过的槽位返回Bytes32(0)零值与 EIP-1153 参考实现中get()对缺失键返回EMPTY_VALUE的行为一致tstore先收基础费再判断是否为新槽位只有(address, key)不在unique_slots中时才额外收取GAS_TSTORE_ALLOCATE24 gas、加入集合并检查上限这解释了为什么TSTORE的实际成本是12 或 1224两档len(self.unique_slots)即transient_slots_used集合长度天然等价于提案规范中的计数器超过MAX_TRANSIENT_SLOTS即抛出ExceptionalHalt对应规范第 2 步的交易异常中止transient_storage与unique_slots分离映射保存真实值集合只负责是否已分配的记账为 revert 释放槽位后的重新计数预留了语义空间。对比 EIP-1153 的 TypeScript 参考实现使用current状态映射 journal变更日志 checkpoints检查点实现 O(1) 写入、O(N) 回滚EIP-7971 的伪代码侧重于交易级账务而非帧级回滚——两者关注点不同EIP-7971 的实现要叠加在 EIP-1153 的瞬态存储执行语义之上。设计动机Rationale深入解析为什么选恒定定价 硬上限提案列举了三条核心理由Rationale Constant Pricing with Hard Limit资源上界更容易推理硬上限让客户端能直接确定总资源消耗的保证值无需根据当前 gas limit 做函数式计算去推断内存消耗上限常见用例不被最坏情况惩罚重入锁这类只占 1-2 个槽位的普通场景不应为 DoS 攻击的最坏资源占用买单支持预保留内存客户端可以在交易开始时安全地一次性预保留瞬态存储可能用到的全部内存。其中第 3 点是实现层面的直接红利在知道MAX_TRANSIENT_SLOTS的前提下节点可预先分配约 8 MB 的内存池避免执行过程中的动态分配开销与碎片化。Gas 数值的选择依据参数依据Gas Cost SelectionGAS_TLOAD 5瞬态存储读取仅需内存访问无磁盘 I/OGAS_TSTORE 12写入需要内存分配且需日志记录journaling以支持 revertGAS_TSTORE_ALLOCATE 24写入全新槽位需要内存分配比写入已有槽位更昂贵关于GAS_TSTORE_ALLOCATE提案特别指出TSTORE当前是固定成本但首次分配槽位与后续写入的成本不同因此考虑通过该参数对首次分配多收费前提是需要引入判断首次分配 vs 后续分配的机制——这正是参考实现中unique_slots集合的职责。基准测试与 EIP-8038 的一致性提案明确声明Benchmarking目前尚无最终定稿的数字需要依赖尚在开发中的瞬态内存操作基准测试收集数据后将确定最终数值并据此判断新槽位分配差异化定价是否值得从缓存加载的**热存储读取warm storage loads**预期与瞬态存储读取有相近的性能特征因此最终参数应与 EIP-8038State-access gas cost update状态访问 Gas 更新目前状态为 Review保持一致。从 EIP-8038 的参数表可见其WARM_ACCESS维持 100 gas 不变、而STORAGE_WRITE被大幅上调——EIP-7971 的恒定低价与 EIP-8038 的状态访问随状态膨胀涨价形成互补瞬态存储作为交易内短暂数据不参与状态树理应走独立的低价轨道。硬上限数值的选择MAX_TRANSIENT_SLOTS 131072Hard Limit Selection的取值逻辑是为典型用户应用提供充足的槽位数量将单笔交易的内存占用约束在约 8 MB131072 槽 × 64 字节/槽从而防止 OOM 型 DoS 攻击。131072 2^17这一2 的幂选择也便于客户端实现位图、分页等高效的内存管理结构可推断提案未明说。被否决的备选方案提案在 Design Alternatives Considered 一节对比了三种替代路线每合约上限Per-Contract Limits增加基于调用栈形态推理资源消耗的复杂度超线性定价Superlinear Pricing增加复杂度且仍然惩罚普通非 DoS用例不设上限No Limit若交易级 gas limit 未来变化或定价调整可能引发基于内存的 DoS 攻击。硬上限的核心优势在于即使协议中其他参数发生变化资源消耗依然可预测地被限定——这是前三种方案都无法提供的强保证。安全考量8 MB 上限如何封顶内存型 DoSEIP-7971 的 Security Considerations 给出了量化对比本提案生效后MAX_TRANSIENT_SLOTS 131072时单笔交易最大内存分配被限定为8 MB131072 × 64 字节当前定价100 gas下一笔 60M gas 的交易可分配最多600,000 个槽位约 38.4 MB结论本提案将最大分配量减少约 79%。这一风险在 EIP-1153 的 Security Considerations 中早有预警其原文计算了30M gas × 1 TSTORE / 100 gas × 32 bytes ≈ 9.15 MB并对比了MSTORE在同一 gas 下仅能分配约 3.75 MB——即 TSTORE 是当时每单位 gas 内存产出最高的分配途径之一。EIP-7971 把这条路径从依赖 gas 总量间接约束改为协议级硬上限直接约束属于对 EIP-1153 安全模型的补强。向后兼容性与实施状态向后兼容提案的 Backwards Compatibility 一节指出除现有操作的成本变低之外没有已知问题。由于只改变 Gas 定价并新增上限检查不改变任何操作码的语义或执行结果已部署合约的行为不受影响——这与 EIP-1153 的兼容性声明不改变任何现有操作码行为一脉相承。需要说明的是与 EIP-1153 一样本提案属于 Core 类别实施需要硬分叉。实施状态与后续工作状态Draft草稿创建于 2025-06-12要求依赖 EIP-1153Test Cases标为 TBD待定尚无正式测试向量Benchmarking标为 TODO– TODO –占位瞬态内存操作基准测试仍在开发中最终 Gas 数值将在数据就绪后定稿。因此文中所有参数值5 / 12 / 24 / 131072均为提案草案阶段的拟议值读者在跟踪实施时应以最终纳入规范的数字为准。按仓库 README 的说明状态为 draft、review 或 last call 的 EIP 属于未完成草稿其规范很可能在后续变更。在仓库中的定位与延伸阅读本仓库Ethereum Improvement Proposal repository以 EIP 文档为主体EIP-7971 与以下文档构成完整的瞬态存储定价演进脉络文档与 EIP-7971 的关系EIPS/eip-1153.md瞬态存储操作码的源头Final 状态定义了TLOAD/TSTORE语义、revert 行为、100 gas 初始定价及其 TypeScript 参考实现EIP-7971 是其定价的后续修订提案EIPS/eip-8038.md状态访问 Gas 更新Review 状态EIP-7971 的最终参数需与之保持一致二者共同勾勒持久状态变贵、瞬态数据变便宜的定价方向EIPS/eip-2929.md引入 cold/warm access 定价模型GAS_WARM_ACCESS 100的原始提案EIP-7971 要解除的正是与GAS_WARM_ACCESS的耦合LICENSEEIP-7971 全文采用 CC0 公有领域授权与仓库所有 EIP 一致若想追踪提案的最新状态可关注其discussions-to指向的 Ethereum Magicians 论坛讨论串add-eip-hard-limit-and-cost-reduction-for-transient-storage-allocation从源码角度验证 EIP-1153 的执行语义可直接研读其参考实现中checkpoint/commit/revert三个方法对瞬态存储日志的管理方式。总体而言EIP-7971 代表了一种值得关注的协议设计范式用协议级硬上限换取大幅降价空间在提升常规用例经济性的同时把资源耗尽风险转化为客户端可预先推理、可预先分配的确定边界。【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考