Mercury 规范 – Seismic 的 REVM
Mercury 是由 Seismic 构建的 EVM 规范。本仓库概述了与标准 EVM/REVM 实现之间的差异。它将承载我们对 EVM 的修改,以及新引入的功能。本文档作为针对 REVM 的差异报告,并假定读者熟悉 REVM 以及更广泛的 EVM。
这项工作站在巨人的肩膀上,如果没有 REVM 的世界级代码库,将不可能实现。
概述
我们引入了以下特性:
- 指令集: 用于访问私有存储的 CLOAD 和 CSTORE。
- 标记存储: 标记存储 引入了一种新机制,其中每个槽位表示为一个元组
(value, is_private),并遵循严格的访问规则。 - 预编译: 预编译 扩展了 EVM 的功能。
- 语义测试: 语义测试 帮助我们捕获回归问题并验证新特性。
语义测试
已添加一套新的语义测试,以确保对编译器的更改不会引入回归。当前限制包括:
- 不支持嵌套依赖。
- 缺少 gas 计量。
- 对库和事件发射的支持不完整。
- 缺乏余额检查及边缘情况处理(例如,调用不存在的函数)。
标记存储
Mercury 引入了标记存储,其中每个存储槽现在表示为一个元组:
(value, is_private)
为支持私有存储,Mercury 提供了新的指令:
| opcode | name | gas | stack input | stack output | description |
|---|---|---|---|---|---|
| 0xB0 | CLOAD | 2_200 | key | value | load word from storage |
| 0xB1 | CSTORE | 22_100 | key/value | save word to storage |
访问规则: 这些指令的语义,以及 SLOAD/SSTORE 针对机密存储的语义如下:
| (0, public) | (x, public) | (0, private) | (x, private) | |
|---|---|---|---|---|
| SLOAD | 0 | x | HALT | HALT |
| CLOAD | 0 | x | 0 | x |
| SSTORE(y) | (y, public) | (y, public) | HALT | HALT |
| CSTORE(y) | (y, private) | HALT | (y, private) | (y, private) |
这些选择背后的推理是:
- 禁止 SLOAD 读取私有槽位是强制执行隐私的主要方式
- 防止 SSTORE 和 CSTORE 写入不匹配的机密性槽位,是保护手动编写 evmasm 的开发者以及 seismic-solidity 编译器错误的护栏
- 鉴于公共槽位和私有槽位共享同一地址空间(以及 trie),必须允许 CSTORE 写入未初始化的槽位,因为这是将槽位从 public->private 切换的唯一方式
- 作为副作用,这意味着可以通过先 SSTORE 0,然后 CSTORE (y, private) 将公共槽位转换为私有槽位
- 然而,一旦槽位变为私有,就没有办法将其翻转为公共
Gas Costs:
机密存储操作(包括加载和存储)产生固定的 gas 成本(SLOAD/SSTORE 可能产生的最大成本)。这是为了防止 gas 成本侧信道泄露信息。
预编译
Mercury 为增强 REVM 的功能添加了多个新的预编译。这些预编译位于固定地址:
| 预编译 | 地址(十六进制) | 地址(十进制) |
|---|---|---|
| RNG | 0x64 | 100 |
| ECDH | 0x65 | 101 |
| AES-GCM 加密 | 0x66 | 102 |
| AES-GCM 解密 | 0x67 | 103 |
| HDKF | 0x68 | 104 |
| SECP256K1 签名 | 0x69 | 105 |
增强的 RNG 逻辑
RNG 预编译与交易环境中的两个额外参数协同工作(TX_ENV):
- tx_hash: 提供域分离。
- RNG_mode: 为模拟调用引入额外熵。
状态管理:
由于 RNG 是有状态的,预执行钩子在每笔交易开始时重置其状态,以确保一致性和提升安全性。
请注意,该预编译的内部逻辑深受 Oasis Sapphire 工作 的启发。
上游
上游仓库位于此处。此 fork 已通过 commit 398ef74 与其保持同步。您可以通过查看本仓库的 main 分支来确认这一点
您可以在这个 pull request 中查看我们相对于上游的所有更改。此 PR 的唯一目的是展示我们的 diff;它永远不会被合并到本仓库的 main 分支
结构
Seismic 对 reth 栈的 fork 都具有相同的分支结构:
main或master:此分支仅包含来自上游仓库的 commit。然而,它很少与上游保持最新。此分支的最新 commit 反映了 Seismic 最近将上游 commit 合并到 seismic 分支的时间seismic:这些仓库的默认分支和生产分支。它包含使我们的网络运行所必需的所有 Seismic 特定代码
结论
我们正在开发更多功能,因此可以预期这份差异文档会随时间增长。在此阶段,这仍然是实验性软件,请谨慎使用!
请随时联系我们——我们也非常乐意接纳新的贡献者加入此仓库。