解密EVM实现机制

本文介绍了EVM的工作原理,包括stack、memory和storage的实现,智能合约调用的gas消耗,以及EVM的关键指令。通过分析,揭示了智能合约开发中可能遇到的安全问题和理解难点,如stack的动态数组实现、memory的数据不持久化和storage的数据持久化。此外,还探讨了EVM的命令集分类,强调了理解这些底层机制对于编写安全智能合约的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下都是来自我的新作《解密EVM机制及合约安全漏洞》里的内容

电子版PDF下载https://download.youkuaiyun.com/download/softgmx/10800947

 

研究环境:

OS

ubuntu 16.04

VM及合约语言

EVM/ solidity

合约调试器

https://remix.ethereum.org

Ethererum源码

go语言版本的

 

EVM机制原理

智能合约容易产生漏洞的主要原因:

  • 开发人员对EVM的运行机制不了解
  1. stack、memory和storage是怎样存储数据的
  2. 合约间调用是怎样实现的,传参和返回值又是怎样在合约间传递的
  3. 用链上数据做随机数种子时,应注意伪随机的问题(链上数据是可见的,合约里定义的私有变量实际是公开可见的,且一些字段是可以被矿工操纵的)
  4. solidity封装好的区块访问方法实际上是读取区块链的哪部分数据
  5. 区块链中交易费用出价高者可以插队优先交易
  6. gas的消耗实现机制
  • 开发人员对solidity编译器的一些内部处理不了解
  1. send、transfer和call底层转账方法的实现原理和区别
  2. fallback机制的实现原理
  3. storage变量的存储和索引原理
  • 开发人员对solidity语言不熟悉
  1. 构造函数
  2. 鉴权方法
  3. 日志记录
  4. 算数溢出

 

这样我们分析问题可以抽象出的三个层次来研究,如下图:

 

                                                  图一 智能合约的层次

 

以太坊的智能合约机(EVM)构成及工作原理:

每次我们call一个合约方法时,在call的函数实现里,首先会创建一个contract 类对象,并填充对应的字段值(code,CallerAddress,Input,gas,value,selfAddress),然后把这个contract对象传入EVM的解释器Interpeter进行逐条指令的解释执行,但在开始解释之前,会生成一个新的stack和一个memory对象以用于后面程序的运行,并把结果写入合约地址对应的StateDB。

 

                                                          图二 EVM的工作原理

下面列出了EVM的几个关键类的定义:

 

                                                                    图三 对应的类图

 

 

                     

                                 图四 EVM执行智能合约中function的过程

 

EVM三大核心部件:

  1. stack
  2. memory
  3. storage

 

Stack的实现:

    type Stack struct {

            data []*big.Int

    }

  1. 最小单元32字节(最小对齐单位)
  2. 初始容量1024个元素
  3. 以动态数组方式实现,理论上可扩容(但实际上一个方法只有1024个元素可用)
  4. 主要指令push、pop、swap 、dup
  5. 数据不持久化
  6. 合约间调用,方法之间不共用栈(一个方法分配一个栈)
  7. 同一合约的方法调用不产生call, 直是简单的 jump

    

Memory的实现:

        type Memory struct {

                store       []byte

                lastGasCost uint64

         }

  • 最小单位有一个字节
  • 以动态字节数组方式实现,可以扩容
  • 类似x86架构里的堆,数据不具有持久性,合约执行完成,数据消失
  • 主要指令mload、mstore

Storage的实现:

  • 通过StateDB把数据存储在区块链上
  • 主要指令sload、sstore
  • 数据被持久化(写在链上了,并在所有矿机上同步)
  • 容量是2的256次幂,storage[slot]=value,   key和value都是32位对齐的

slot=[ 0x0000000000000000000000000000000000000000000000000000000000000000,……

,0xffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff]

命令集分类:

  • 算术、逻辑运算(addsubmuldivmodlt ,gt notxororand)
  • 栈操作、内存操作、存储操作(pushpopmloadmstoresloadsstore)
  • 区块链操作(addressbalancegascallercallvalueoriginblockhashtimestampdifficultygaslimitcoinbaselog
  • 执行流操作(jumpjumpicallcallcodedelegatecall staticcall

 

命令集具体说明:

Instruction

 

 

Explanation

stop

-

F

stop execution, identical to return(0,0)

add(x, y)

 

F

x + y

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值