调研区块链虚拟机安全
EVM的不同实现
- EVM官方实现:Ethereum Virtual Machine (EVM) | ethereum.org
- Py-EVM - Python
- evmone - C++
- ethereumjs-vm - JavaScript
- eEVM - C++,微软开发
- revm - Rust
- SputnikVM:- rust
- pyethereum:- py,2023.3已被弃用
- 其他以太坊execution client的EVM, accessed at 2024/0314
其他VM
- NEO VM:采用C#实现,Neo链目前的市值排行66,NEO支持多种常用的编程语言,如C#、Java和Python等编写智能合约
- Solana Virtual Machine:Solana链(市值第7)上的虚拟机,rust实现.
- 智能合约语言可以是Rust, C, and C++,翻译成BPF字节码执行;支持交易并行
- Neon用于solana和EVM对齐
- Cardano:token ADA,目前市值排行8,采用Haskell语言实现,以KEVM,EVM的形式化验证版本为基础
- 其中Milkomeda C1是Cardano对应的EVM侧链
- Tezos:目前的市值排行52,项目采用的语言是OCaml,合约采用的编程语言是Archetype, LIGO, 和SmartPy,翻译为底层语言Michelson后在VM上执行
- 虚拟机的设计未详细介绍,参考资料What Smart Contracts are and How They Work
- github镜像:tezos/tezos-mirror: Github test mirror of the Octez software
WASM
- EOSIO, EOS-VM:第一个DpoS的链,C++实现,目前的市值排行57,采用WebAssembly(WASM)作为底层引擎,通过即时编译技术将智能合约字节码转换为本地机器码;同样支持多种编程语言,包括C++、Rust、Python等编写智能合约
- Near:采用Rust实现,Wasm作为执行引擎,市值排行43
- 国内的迅雷公司的迅雷链:采用Wasm作为VM,目前提供数字藏品
- Tron:市值10声称要支持WASM,但是根据官方白皮书的介绍,目前采用的实现是以太坊的fork
- Hera:Geth采用的Wasm,需要EVMC的支持
- awesome-wasm-tools:Wasm静态分析、动态分析和相关论文的仓库
学习资料
- fuzzinglab
- 开源工具集 FuzzingLabs
- medium Fuzz testing in webassembly vms https://medium.com/wasmer/fuzz-testing-in-webassembly-vms-3a301f982e5a
- 学习教程 https://fuzzinglabs.com/journey-fuzzing-webassembly-wasm-vm/
- 中科大CSS实验室 https://csslab-ustc.github.io/index.html
- 在py虚拟机 wasm虚拟机方面有很多工作
MOVE VM
- github的awesome库:https://github.com/MystenLabs/awesome-move#papers
- MoveVM:Facebook旗下的区块链项目Diem( Libra )采用的虚拟机,rust实现
- Sui:Mysten Labs于2022年3月发起的layer1 PoS公链,目前市值排行91,同样采用Move作为运行时
以太坊客户端
什么是客户端多样性:https://ethereum.org/en/developers/docs/nodes-and-clients/client-diversity/
客户端多样性:https://clientdiversity.org/
- 执行客户端
- 共识客户端
根据以太坊主网的统计数据显示,geth是使用最广泛的执行客户端
- Geth:占比50.0%,采用go语言实现,最常用的客户端
- 支持Mainnet, Sepolia, Goerli
- Nethermind:占比29.3%,采用C#实现
- 支持Mainnet, Sepolia, Goerli, and more
- Erigon:占比11.12%,采用go语言实现,作为Openethereum的后继者
- Mainnet, Sepolia, Goerli, and more
- besu:占比9%,Java实现,Hyperledger 项目的一部分,是一个企业级以太坊客户端
- Mainnet, Sepolia, Goerli, and more
- reth:占比0.5%,Rust实现
- Mainnet, Sepolia, Goerli, and more
Openethereum:采用Rust实现,曾经仅次于geth, August 4, 2021已被弃用
Coregeth:Go实现,Geth的下游发行版
EVM兼容的区块链
所有兼容EVM的区块链可见 EVM公链列表CoinCarp
- Binance Smart Chain:token BNB,市值排行第4,由币安交易所推出
- 客户端bsc基于geth fork开发,EVM类似于geth
- Fantom:token FTM,市值排行63
- 客户端opera采用go实现,利用了EVM的实现go-opera
- Polygon:token MATIC,市值排行13
- 虚拟机是zkEVM,声称与EVM等价 Polygon zkEVM | Scaling for the Ethereum Virtual Machine
- Bor,EVM实现是geth的fork
- Avalanche:token AVAX,市值排行22
Ethereum持久化存储调研
调研以太坊的持久化存储包含的内容,以及哪些操作码会直接影响持久化存储
以太坊操作码语义:https://www.ethervm.io/
https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy-5a5?s=r
学习数据结构博客:https://medium.com/shyft-network/understanding-trie-databases-in-ethereum-9f03d2c3325d
以太坊黄皮书
状态和区块
以太坊的世界状态 state 是地址(160bit)和账户状态(RLP)的映射,映射采用Merkle-Patricia树维护,具体由后端数据库去维护字节数组到字节数组的映射
账户状态$\sigma[a]$包含四个字段:
- nonce:地址发出的交易数量(如果账户有对应的代码,则表示账户创建的合约数量),$\sigma[a]$表示状态$\sigma$中地址$a$的nonce值
- balance:账户地址有多少wei,1 ETH=$10^{18}$ wei
- storgeRoot:账户存储内容的Merkle Patricia树的根节点的256bit哈希值
- codeHash:EVM代码的哈希值,创建后不可更改,即 $KEC(b)=\sigma[a]_c$
区块头
parentHash: 父区块头的Keccak 256 位哈希
ommersHash:已经废弃,目前是常量KEC(RLP(()))
beneciary:160bit的地址,表示获得挖矿奖励的地址
stateRoot:所有交易执行完且区块定稿后状态树根节点的Keccak 256 位哈希
transactionRoot:当前区块中所有交易组成的树的根节点的Keccak 256 位哈希
- standalone EVM仅包含1个交易
receiptsRoot:当前区块中所有交易的收据组成的树的根节点的Keccak 256 位哈希
- standalone EVM中没有相关结构
logsBloom:当前区块中所有交易的收据中可索引的信息(包括产生日志的地址和日志主题)组成的Bloom过滤器
difficulty:当前区块的难度水平,可以根据前一个区块的难度和时间戳计算得到
number:当前区块祖先区块的数量,用于PoW,现在已经被弃用,设置为常数0
gasLimit:当前区块的gas消耗上限
gasUsed:交易开销的gas
timestamp:Unix时间
extraData:小于32 bytes的任意数据
prevRandao:共识层产生的伪随机值,https://github.com/ethereum/consensus-specs
solidity0.8.18已经支持该操作码,发现geth0.13.4版本存在空指针
```
./evm —debug —verbosity 1 —gas 0xffffff —nomemory=false —json —sender 0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f —receiver 0x000000000000000000000000636F6E7472616374 —code 6080604052348015600e575f80fd5b50600436106026575f3560e01c80639ceee80c14602a575b5f80fd5b60306044565b604051603b91906061565b60405180910390f35b5f44905090565b5f819050919050565b605b81604b565b82525050565b5f60208201905060725f8301846054565b9291505056fea264697066735822122097f788bd78037d47c3e87ca3ee039171808cf9ea275785553c6ccd08d982424464736f6c63430008170033 —input 9ceee80c —prestate ./genesis.json run1
2
3
4
5
- 在geth 0.14.0进行验证,发现该版本对push0的支持有问题,已报告 https://github.com/ethereum/go-ethereum/issues/28690
- ```
./evm --debug --verbosity 1 --gas 0xffffff --nomemory=false --json --sender 0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f --receiver 0x000000000000000000000000636F6E7472616374 --code 6080604052348015600e575f80fd5b50600436106026575f3560e01c8063b349cb3214602a575b5f80fd5b60406004803603810190603c919060b2565b6042565b005b8073ffffffffffffffffffffffffffffffffffffffff16ff5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f608682605f565b9050919050565b609481607e565b8114609d575f80fd5b50565b5f8135905060ac81608d565b92915050565b5f6020828403121560c45760c3605b565b5b5f60cf8482850160a0565b9150509291505056fea2646970667358221220802b048b24208868e10a279d062a61966de4d4410bf3b21674deb80178cc524964736f6c63430008170033 --input b349cb320000000000000000000000009957acb0b63afca54257b634bc605ec639f8165c --prestate ./genesis.json run
nonce:由于PoW被替换后废弃,64bit的0
baseFeePerGas:每单位gas对应wei
执行模型
基础
EVM是一个准图灵机,准来源于计算是由gas限制的
基于栈的架构,字长256bit,栈的深度为1024,所有内存和存储初始化为0
和冯诺依曼架构不同,代码存储在虚拟机的ROM,只有特定的指令可以交互。发现异常时EVM会中断执行,告知上层的执行环境进行处理
gas概述
三种不同条件下收取
- 操作的计算
- 执行低级别的函数调用或函数创建
- 内存使用增加
存储费用的目的是激励最小化的存储使用(清除存储内的值的gas不但被免除,还会得到refund
machine state $\mu=(g,pc,m,i,s)$包括可用的gas,程序计数器,内存的内容,内存中已经使用的字,栈的内容
合约实践
- 外部数据获取:调用oracle合约的用户需要自行决定对被调用oracle合约的信任
- 随机数:利用执行交易时尚未知的信息作为随机源,如利用前256个区块的BLOCKHASH、区块的哈希值、区块的时间戳、区块的beneficiary地址
Besu
Not available in evm-tools
build my own
0X55 SSTORE, 0X5D TSTORE
0XF0 CREATE, 0XF5 CREATE2
0XFD REVERT, 0XFF SELFDESTRUCT
EIP paper
- CCS22:Empirical Analysis of EIP-1559: Transaction Fees, Waiting Time, and Consensus Security ,介绍了EIP1559的基本情况和对市场的影响 https://cfcs.pku.edu.cn/news/240640.htm
测试用例
EVMtest 以太坊项目官方对客户端会进行单元测试,
Blockbench 区块链测试用例
数据集
11个fuzzer的综述论文 2000个合约
- https://github.com/SE2023Test/SCFuzzers
- Not available
web3bug
- 源码
- Code4rena审计过的项目,被论文广泛引用 https://github.com/ZhangZhuoSJTU/Web3Bugs/
- Defihacks https://wooded-meter-1d8.notion.site/0e85e02c5ed34df3855ea9f3ca40f53b?v=22e5e2c506ef4caeb40b4f78e23517ee
IC综述论文数据集
字节码和源代码,没有abi
总结
- 可能的研究方向
- 虚拟机:目前学术论文的研究对象主要是EVM的官方实现(geth/aleth/js-evm/openethereum)和EVM兼容的链(FISCO-BCOS-evm),逐渐开始有向其他公有链项目采用的VM进行延伸(Neo)的工作。后续工作可以考虑对其他EVM兼容的区块链上的EVM实现(如SputnikVM)进行差分模糊测试和对其他非EVM的知名公有链的虚拟机(EOS-VM/Solana/Cardano)安全性进行研究
- 客户端:现有的对以太坊客户端的测试主要以Geth为主。但是从以太坊官方的统计数据来看,除了Geth之外,Nethermind、Eriqon、besu同样占有较大的比例,对以上客户端内的EVM实现进行差分模糊测试也是具有一定研究意义的
- 目前探索的方向:学习EVMfuzzer和NeoDiff,扩展到EVM compatible的链上
其他资料
- 6年前其他人总结的EVM相关的资料:pirapira/awesome-ethereum-virtual-machine: Ethereum Virtual Machine Awesome List (github.com)
- https://github.com/kareniel/awesome-evm-security
- WASM对应的VM:appcypher/awesome-wasm-runtimes: A list of webassemby runtimes (github.com)
- Move语言相关资料:MystenLabs/awesome-move: Code and content from the Move community. (github.com)
Videos
The Ethereum Virtual Machine
at https://youtu.be/uke_ZWAXHSc?si=nRH5NRB59oXJrkPJ
EVM的架构
EVM和VM的区别
The Ethereum Virtual Machine Instruction Set
Not interesting