EIP-7709 深度解析:从 EIP-2935 系统合约存储读取 BLOCKHASH 并重构其 Gas 计费

发布时间:2026/9/16 7:11:17
EIP-7709 深度解析:从 EIP-2935 系统合约存储读取 BLOCKHASH 并重构其 Gas 计费 EIP-7709 深度解析从 EIP-2935 系统合约存储读取 BLOCKHASH 并重构其 Gas 计费【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs导读EIP-7709Read BLOCKHASH from Storage and Update Cost是面向以太坊执行层Core的协议提案其核心目标是将BLOCKHASH (0x40)操作码从依赖客户端历史区块数据的特殊案例重构为基于 EIP-2935 系统合约存储的状态支撑访问并同步引入与SLOAD对齐的冷/热存储 Gas 计费。阅读本文后你将掌握 EIP-7709 的完整规格参数、窗口计算、槽位映射、resolve_blockhash伪代码的逐行语义、三种客户端解析路径、激活前提以及它与 EIP-2929 冷热访问计费、EIP-2930 访问列表之间的联动关系。一、背景与动机BLOCKHASH 的协议特殊案例困境在现行 EVM 中BLOCKHASH (0x40)操作码负责返回最近 256 个祖先区块中某一区块号的哈希。它存在一个结构性问题它假定客户端本地拥有最近的区块历史。这使得它成为协议中的一个特殊案例——它依赖历史链数据却没有像其他读取那样被建模为状态支撑的读取state-backed read。这种特殊性带来的代价是多方面的对于无状态客户端stateless client历史区块哈希无法打包进 witness无法通过状态证明来验证对于witness 构建客户端不得不在 witness 构造逻辑中为BLOCKHASH单独开一条通过父区块头链证明的旁路而不是复用现成的状态访问机制在计价上BLOCKHASH使用固定的极低费用现行 EVM 中为固定 20 gas 的基础成本与它实际触发的资源消耗状态存储访问完全不匹配。EIP-2935已 Final解决了第一个问题它在每个区块处理开始时将最近HISTORY_SERVE_WINDOW8191个区块哈希写入一个系统合约的环形缓冲区ring buffer存储。EIP-7709 则在此基础上更进一步让窗口内的BLOCKHASH查询直接建模为对系统合约存储的访问同时保持BLOCKHASH返回值的既有语义不变。二、核心规格从存储解析 BLOCKHASH2.1 参数表EIP-7709 定义了以下协议参数参数值FORK_TIMESTAMPTBD待定HISTORY_STORAGE_ADDRESS0x0000F90827F1C53a10cb7A02335B175320002935BLOCKHASH_SERVE_WINDOW256HISTORY_SERVE_WINDOW8191其中HISTORY_STORAGE_ADDRESS与HISTORY_SERVE_WINDOW均继承自 EIP-2935BLOCKHASH_SERVE_WINDOW保持既有BLOCKHASH服务窗口不变256 个祖先区块。注意这两个窗口大小不同且作用不同BLOCKHASH_SERVE_WINDOW决定BLOCKHASH操作码的返回值窗口HISTORY_SERVE_WINDOW决定环形缓冲区的槽位模数。2.2 触发边界fork_blockEIP-7709 从fork_block开始生效其定义是fork_block.timestamp FORK_TIMESTAMP 且 fork_block.parent.timestamp FORK_TIMESTAMP即时间戳跨过FORK_TIMESTAMP的第一个区块。从该区块起BLOCKHASH指令按新的存储解析逻辑执行。2.3 resolve_blockhash 伪代码逐行解析EIP-7709 用如下 Python 伪代码定义新的解析逻辑def resolve_blockhash(block: Block, state: State, arg: uint64): # note that outside the BLOCKHASH_SERVE_WINDOW we continue to return 0 # despite the 2935 history contract being able to serve more hashes if arg block.number or (arg BLOCKHASH_SERVE_WINDOW) block.number: return 0 # performs an sload on arg % HISTORY_SERVE_WINDOW including gas charges, # warming effects as well as state-access recording # # note that the BLOCKHASH_SERVE_WINDOW and the 2935 ring buffer window # HISTORY_SERVE_WINDOW for slot calculation are different return state.load_slot(HISTORY_STORAGE_ADDRESS, arg % HISTORY_SERVE_WINDOW)逐行解读窗口外返回 0若arg block.number查询当前或未来区块或arg 256 block.number查询超出最近 256 个祖先直接返回0与现行语义一致。值得强调的是即便 EIP-2935 合约存储了多达 8191 个哈希BLOCKHASH操作码依然只在 256 窗口内提供服务——这是为了保持向后兼容不扩展上述豁免范围。槽位映射窗口内的查询执行一次state.load_slot(HISTORY_STORAGE_ADDRESS, arg % HISTORY_SERVE_WINDOW)即对系统合约地址上arg % 8191号槽位做一次存储读取。这里的关键设计是返回值窗口256与环形缓冲区模数8191不同——由于 EIP-2935 在set操作中写入block.number - 1 % HISTORY_SERVE_WINDOW槽位查询区块号arg的哈希恰好落在arg % 8191槽位。完整副作用load_slot的注释明确要求包含 Gas 计费、槽位预热warming以及状态访问记录state-access recording三类副作用详见下一节。2.4 三种客户端解析路径对于窗口内的arg客户端执行客户端可以任选以下方式之一解析直接SLOAD直接从状态中读取HISTORY_STORAGE_ADDRESS的对应槽位系统调用 EIP-2935 合约的get机制以非SYSTEM_ADDRESS调用者身份调用历史合约因为get仅在调用者不是SYSTEM_ADDRESS时触发内存/既有设计如全节点客户端按现行设计维护所需历史时直接从内存服务。无论选择哪种解析方式只要arg处于正确的BLOCKHASH窗口内客户端必须应用当前激活分叉所定义的SLOAD操作的全部语义与副作用。三、强制语义完整落地 SLOAD 的三大副作用EIP-7709 明确列出了窗口内查询必须应用的SLOAD副作用SLOAD的 Gas 成本冷或热针对槽位arg % HISTORY_SERVE_WINDOW。按 EIP-2929已 Final的定价首次访问冷为COLD_SLOAD_COST 2100gas交易内已访问过热为WARM_STORAGE_READ_COST 100gas。SLOAD的预热后效读取后该槽位被加入交易级accessed_storage_keys集合后续同交易内访问按热价计费。状态访问记录按当前激活分叉要求为对应的SLOAD记录状态访问这是 witness 构建与无状态执行的基础。底层机制来自 EIP-2929已 Final它维护交易级集合accessed_addresses与accessed_storage_keysSLOAD (0x54)首次访问冷槽位收 2100 gas已访问热槽位收 100 gas。EIP-7709 正是把这一整套机制复用到BLOCKHASH上使BLOCKHASH的计价与其实际访问的资源系统合约存储严格对齐。3.1 系统合约执行的 Gas 不适用一个容易被忽略的细节即便客户端选择通过系统调用来解析BLOCKHASH系统代码执行的 Gas 也不会被收取——只应用上述SLOAD的效果。这一点在 EIP-2935 的系统中同样成立区块处理开始时的系统更新调用process_block_hash_history或SYSTEM_ADDRESS调用不会预热历史合约账户及其存储槽位第一次调用需按 EIP-2929 规则支付预热费用。EIP-7709 延续了这一思路保持 Gas 低廉且对选择其他解析方式的客户端实现简单。3.2 预热的现实意义访问列表EIP-2930由于冷SLOAD成本高达 2100 gas窗口内BLOCKHASH的成本将由固定 20 gas跃升为基础成本 2100冷/ 100热。这与 EIP-2930已 Final的访问列表机制天然互补交易可在accessList中预先声明HISTORY_STORAGE_ADDRESS及其目标槽位每个存储键预付费ACCESS_LIST_STORAGE_KEY_COST 1900gas将其提前载入accessed_addresses/accessed_storage_keys集合从而使实际执行中的SLOAD仅按 100 gas 热价计费——这是对依赖固定 Gas 成本合约的迁移缓冲手段。四、激活机制与前提条件EIP-7709 的激活以 EIP-2935 已激活为前提并规定了两种可接受的时序提前量足够EIP-7709 的激活须在 EIP-2935 激活之后至少BLOCKHASH_SERVE_WINDOW256 个区块以上或创世激活在测试网/开发网中EIP-7709 可与 EIP-2935 一同在创世genesis激活。这一前提的根源在于 EIP-2935 的环形缓冲区需要时间灌满它需要HISTORY_SERVE_WINDOW8191个区块才能完全填满缓冲区且合约只包含分叉区块的父哈希、不含更早历史。若 EIP-7709 在 EIP-2935 激活后不足 256 个区块即生效系统合约尚未保存所需的完整窗口历史将导致破坏性变更详见第六节。五、Rationale 解读为什么这样设计EIP-7709 的 Rationale 明确阐述了四个设计取舍计价与资源匹配更新后的 Gas 成本与所访问的资源等价——即读取一次存储。将BLOCKHASH纳入既有的冷/热状态访问定价体系而不是为近期区块哈希新增一条独立的 Gas 规则。替代方案对比客户端虽然也可以通过一串父区块头链证明近期区块哈希但那会让BLOCKHASH继续作为 witness 构建中的特殊案例无法复用 EIP-2935 提供的状态访问机制。不引入新特殊规则无论始终按热SLOAD收费还是自定义BLOCKHASH价格都能降低兼容性风险但都会引入一条新的特殊案例 Gas 规则故被否决。系统合约执行费用不适用EIP-2935 系统合约执行的收费与访问均不被应用以保持 Gas 低廉并让选择直接 SLOAD 或内存解析的客户端实现保持简单。此外需要明确边界BLOCKHASH操作码只服务有限的BLOCKHASH_SERVE_WINDOW256窗口以保持向后兼容、不扩展上述豁免。更深层的历史访问需直接调用 EIP-2935 系统合约其get操作支持[block.number - 8191, block.number - 1]范围此时将按正常合约执行收费并记录访问——这正是 EIP-2935 为 Rollup 等场景提供的长历史窗口查询能力。六、向后兼容性与破坏性影响EIP-7709 明确了两点兼容性结论返回值语义不变BLOCKHASH在窗口内的返回值、窗口外返回0的语义均与现行行为一致不改变任何应用读取到的哈希值。Gas 成本显著上升窗口内查询从固定低费用变为基础成本 冷/热 SLOAD 成本可能破坏依赖旧 Gas 成本的用例例如对子调用设置固定 Gas 上限的合约。这与 EIP-2929 涨价时的合约破坏风险同类开发者可通过 EIP-2930 访问列表预先预热存储槽位来缓解。分叉间距不足的破坏若 EIP-2935 与 EIP-7709 分叉之间不足BLOCKHASH_SERVE_WINDOW256个区块且 EIP-2935 未在创世激活如测试网/开发网场景则 EIP-2935 系统合约尚未保存所需历史将引入破坏性变更。七、测试用例清单EIP-7709 给出了可执行的行为验证标准若BLOCKHASH的参数超出最近BLOCKHASH_SERVE_WINDOW个祖先或大于等于当前区块号返回0且不应用额外的存储访问副作用若查询窗口内祖先且对应存储槽位为冷操作码收取基础BLOCKHASH成本 冷SLOAD成本2100 gas若同一交易内多次BLOCKHASH查询映射到同一存储槽位后续查询按热SLOAD成本100 gas计费每次BLOCKHASH操作的基础成本仍应被收取叠加每次查询的SLOAD成本若直接调用 EIP-2935 合约而非经由BLOCKHASH则按当前分叉的正常合约执行规则收取 Gas、记录状态访问并应用其他效果若 EIP-7709 在 EIP-2935 之后正确激活间隔 BLOCKHASH_SERVE_WINDOWBLOCKHASH解析结果应保持一致。八、安全考量EIP-7709 明确表示除 EIP-2935 中已包含的安全考量外暂无新增安全考量。需要留意的是 EIP-2935 提到的分支投毒branch poisoning风险——系统合约热更新路径可能被攻击者以微量 ETH 投毒以拖慢状态根更新但该 EIP 已评估攻击成本会显著上升难以造成有意义的减速。九、生态位置与相关 EIP 脉络EIP-7709 处于以太坊将历史区块哈希纳入状态的演进主线上其技术栈关联如下EIP-2935Final必选前置在区块处理开始时以SYSTEM_ADDRESS调用历史合约的set()输入为block.parent.hashGas 上限30_000_000、价值0将block.number - 1 % 8191槽位写入父哈希该 EIP 明确对BLOCKHASH解析机制无影响——EIP-7709 正是补上这一环。EIP-2929Final提供COLD_SLOAD_COST 2100、WARM_STORAGE_READ_COST 100及交易级访问集合是 EIP-7709 计费语义的底层来源。EIP-2930Final访问列表机制为合约迁移提供预热缓冲。EIP-4788定义了系统调用system call的约定执行至完成、不计入区块 Gas 上限、不遵循 EIP-1559 燃烧语义EIP-2935 的合约调用遵循同一约定EIP-161 则保证历史合约账户免于空账户清理。在生态层面EIP-8081元 EIP追踪分叉范围已将 EIP-7709 列为 Proposed for Inclusion提议纳入而 EIP-7709 自身的状态仍为DraftFORK_TIMESTAMP为 TBD属于推进中的协议变更提案。读者若需验证实现细节可对照 EIP-2935 中给出的历史合约 EVM 汇编get/set双路径、0x1fff即 8191 模数及其合成部署交易参数理解HISTORY_STORAGE_ADDRESS的由来——该地址由部署交易发送者0x3462413Af4609098e1E27A490f554f260213D685部署的首个合约地址rlp([sender, 0])计算得出密码学绑定于部署交易的 initcode。结语EIP-7709 的提案思路可以概括为一句让BLOCKHASH不再是特例而是一次普通的存储读取。通过复用 EIP-2935 的系统合约存储与 EIP-2929 的冷热访问定价它把历史区块哈希访问纳入统一的状态访问计价与 witness 记录框架为无状态执行铺路同时保持返回值语义完全向后兼容。对于合约开发者理解其基础成本 冷/热 SLOAD的新计价模型以及访问列表预热的缓解手段是分叉升级前做好 Gas 预算评估的关键。本文基于仓库 EIPS/eip-7709.md 编写版权声明遵循 CC0Copyright and related rights waived via CC0。【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询