关于执行模型、共识、EVM 基础与可验证 AI 的技术长文。每一篇洞察,都让 Web3 世界变得更清晰。
编辑推荐执行客户端把 EVM 当作一块可替换的执行器,中间隔着一层状态访问接口。go-ethereum 的内置解释器、evmone 与 revm 定位各不相同,多实现一致性靠规范测试向量保障,解释器的优化空间则集中在分派、gas 计量与内存管理上。
阅读全文 →
执行客户端把 EVM 当作一块可替换的执行器,中间隔着一层状态访问接口。go-ethereum 的内置解释器、evmone 与 revm 定位各不相同,多实现一致性靠规范测试向量保障,解释器的优化空间则集中在分派、gas 计量与内存管理上。

状态变量按声明顺序落在 32 字节的槽里:小类型共享槽,映射与动态数组靠哈希派生位置,继承顺序还会整体平移槽号。这些定位规则决定了升级代理为什么必须绕开编译器会分配的槽。

四个调用指令在字节码里只差几个编号,语义却决定代码跑在谁的上下文、写谁的存储、msg.sender 与 address(this) 变成什么。逐个对照 CALL、CALLCODE、DELEGATECALL 与 STATICCALL,可以看清代理为何依赖 DELEGATECALL、STATICCALL 因何引入。

从裸 calldata 出发拆解 ABI:4 字节 selector 由规范签名截断而来,静态类型直接占满一个字,动态类型靠偏移量与长度二级寻址;事件把 indexed 参数写进 topics,换来可检索性。ABI 不自描述,解码与升级因此都受约束。

以太坊黄皮书把区块级状态转移写成嵌套调用,求值顺序因此属于规范的一部分。逐笔串行的语义来源、读写集冲突为何无法预先判定、确定性与验证简单性换来了什么,以及这个设计原点正在被怎样的方案正面回应,是接下来的主线。

区块头里的 stateRoot 只有 32 字节,却绑定了全网账户、余额与合约存储。下面拆开 Merkle Patricia Trie 的节点结构与账户下挂存储 trie 的设计,说明 Merkle 证明如何支撑链下校验,以及状态膨胀的成本落到谁身上。

Gas 是 EVM 的资源计量单位,价格则由费用市场决定;把两者混为一谈,会误判扩容与执行中止的边界。下面拆解固有成本与动态成本的构成,说明 out-of-gas 与 REVERT 各退什么,EIP-1559 的 base fee 与 tip 各归谁。

同一份 32 字节数据放在 memory、storage 还是 transient storage,gas 成本能差两个数量级,生命周期也完全不同。下面沿归属、寿命与计价三条线拆开三类存储,说明重入锁、临时数组与状态变量各自该放在哪里。

EVM 是一台没有寄存器的栈机:256 位字长、1024 项栈深、一个只能跳到 JUMPDEST 的程序计数器。取指、解码、执行这一轮循环解释了栈下溢与溢出为何烧光 gas,也解释了栈机相对寄存器机买到了什么、付出了什么代价。

把以太坊当成一本记录转账的账本,会漏掉它最关键的部分:账户存储里可任意读写的变量。依据黄皮书的状态转移函数 Υ(σ, T),以太坊是一个分布式状态机,EVM 是这套状态转移的执行规范。全网逐位重放又给执行语义带来了一组硬约束。