0%

EVM_security

调研区块链虚拟机安全

EVM的不同实现

其他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上执行

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静态分析、动态分析和相关论文的仓库

学习资料

MOVE VM

以太坊客户端

什么是客户端多样性:https://ethereum.org/en/developers/docs/nodes-and-clients/client-diversity/

客户端多样性:https://clientdiversity.org/

  • 执行客户端
  • 共识客户端

根据以太坊主网的统计数据显示,geth是使用最广泛的执行客户端

image-20231012160435832

  • 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

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 run

      1
      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

测试用例

数据集

总结

  • 可能的研究方向
    • 虚拟机:目前学术论文的研究对象主要是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的链上

其他资料

Videos

The Ethereum Virtual Machine

at https://youtu.be/uke_ZWAXHSc?si=nRH5NRB59oXJrkPJ

EVM的架构

image-20240729152030420

EVM和VM的区别

image-20240729151959465

The Ethereum Virtual Machine Instruction Set

Not interesting