Ethereum EVM简介

article/2025/10/30 23:34:26

1. 引言

首先需了解以下基本概念:

  • 1)区块链
  • 2)世界状态
  • 3)账号
  • 4)交易
  • 5)消息
  • 6)去中心化账本
  • 7)原子性和顺序性

1.1 何为以太坊区块链?

以太坊可看成是基于交易的状态机,交易代表了2个状态间的valid arc:
在这里插入图片描述
将多笔交易整理打包为区块,区块为package of data:
在这里插入图片描述
从状态的角度来看,可将以太坊看成是状态链(chain of states):
在这里插入图片描述
从实现的角度来看,还可将以太坊看成是“BLOCKCHAIN”(chain of blocks):
在这里插入图片描述
从账本的角度来看,还可将以太坊看成是“stack of transactions”:
在这里插入图片描述

1.2 何为世界状态?

世界状态(World state)为address与account state之间的mapping:
在这里插入图片描述
可从多个角度来看待world state:

  • mapping角度
  • table表格角度
  • object对象角度

在这里插入图片描述

1.3 何为账号?

账号(Account)为world state的object对象表示:
在这里插入图片描述

账号状态中可包含EVM code和Account storage:
在这里插入图片描述
以太坊中主要有2种账号状态:

  • Externally owned account(EOA):由某个私钥控制。不允许包含EVM code。
  • Contract account(CA,合约账号):包含了EVM code。由EVM code控制。

在这里插入图片描述
在这里插入图片描述
账号地址以160-bit code来表示:
在这里插入图片描述

1.4 何为交易?

交易为经密码学签名的单个指令:
在这里插入图片描述
交易由external actor来提交:
在这里插入图片描述
有两种实用的交易类型:

  • contract creation交易
  • message call交易

在这里插入图片描述

交易中包含的字段有:

  • nonce
  • gasPrice
  • gasLimit
  • to:若为contract creation交易,该值为0;否则为160 bit address。
  • value:为tranasferred wei(ether)
  • v, r, s:交易签名
  • init or data:contract creation 或 message call

1.4.1 contract creation交易

contract creation交易示意为:
在这里插入图片描述

1.4.2 message call交易

message call交易示意为:
在这里插入图片描述

1.5 何为message?

message的来源主要有:

  • 由交易触发的关联消息
  • 由EVM code触发的消息

在这里插入图片描述
消息之间的发送和接收方可分为以下四种场景:

  • 1)由EOA通过交易发送消息给EOA
  • 2)由EOA通过交易发送消息给CA
  • 3)由CA通过EVM code发送消息给EOA
  • 4)由CA通过EVM code发送消息给CA

在这里插入图片描述

1.6 何为去中心化账本?

区块链不仅为a globally shared, transactional database:
在这里插入图片描述
区块链还是a globally shared, 去中心化, transactional database:
由去中心化节点构成以太坊P2P网络:
在这里插入图片描述
external actors通过以太坊节点来访问以太坊世界:
在这里插入图片描述
不过,实际以太坊客户端是通过Web3 API来访问以太坊网络:
在这里插入图片描述

1.7 何为原子性和顺序性?

交易的原子性是指:

  • 交易为原子式操作,无法分解或中断。
  • 交易要么完全执行成功,要么完全失败。(All(complete done)or Nothing(zero effect))

在这里插入图片描述

交易的顺序性是指:

  • 交易是无法重叠的
  • 交易必须按顺序执行

在这里插入图片描述
不过,交易的顺序不是按交易发起时间来确定的,交易的顺序是无法保证的,由矿工来决定区块内的交易顺序:
在这里插入图片描述
在这里插入图片描述
同时,区块间的顺序则由共识算法(如PoW)来决定:
在这里插入图片描述

2. 虚拟机

以太坊虚拟机为stack-based, big-endian VM with a word size of 256-bits,并用于运行智能合约。智能合约与普通账号类似,只是当收到某交易时,智能合约会运行EVM bytecode,处理相应的计算以及后续交易。
EVM中的opcode有:
在这里插入图片描述
Contract execution starts at the beginning of the bytecode.
Each opcode is encoded as one byte, except for the PUSH opcodes, which take a immediate value.
All opcodes pop their operands from the top of the stack and push their result.

交易的payload可为0或一定字节数的data,用于定义与合约交互的类型即其它额外信息:

  • 1)合约创建交易:
    交易的data payload为所创建合约自身的bytecode,会运行合约的构造函数、设置合约初始状态、并返回最终的合约bytecode。即,一旦合约部署完毕,构造函数将不展示在合约中。
  • 2)合约交互交易:
    通常合约会暴露一个public API——为支持用户与合约交互的一组方法。
    为与合约交互,用户将提交交易,交易内可包含任意wei数量(包括0),以及某格式与ABI匹配的data payload,定义了交互类型以及其他额外参数。
    合约通常由4种方式来处理data:
    • 1)Call Data:通常为:4字节的method identifier + 序列化的参数。相关指令有:CALLDATALOAD/CALLDATASIZE/CALLDATACOPY。
    • 2)Stack:EVM会维护a stack of uint256s来保存本地变量、函数调用参数以及返回地址。区分返回地址与其它变量是复杂的。相关指令有:PUSH1/DUP1/SWAP1/POP等。
    • 3)Memory:为uint8数组,用于保存合约执行过程中的临时数据。memory中的数据无法跨交易保存。相关指令有:MLOAD/MOSTROE/MSTORE8。
    • 4)Storage:为持久关联map,以uint256为key,uint256为value。所有的合约元素以及mappings都存储在storage中。Storage中的元素可通过web3.eth.getStorageAt(address, key)接口来访问获得。相关指令有:SLOAD/SSTORE。

2.1 以太坊虚拟机EVM(Ethereum Virtual Machine)

go-ethereum提供了evm命令行工具对汇编代码进行编译和反汇编,以及执行调试汇编代码:
在这里插入图片描述
可使用evm工具直接执行调试汇编代码:
在这里插入图片描述

在这里插入图片描述

对于message call交易,以太坊虚拟机输入有:

  • 相应合约账号的code
  • 相应合约账号的storage
  • message call交易中的input data

相应的EVM输出会更新到合约账号的stoarge中。
在这里插入图片描述
EVM为以太坊合约的运行时环境:
在这里插入图片描述
EVM采用简单的栈架构,其中:

  • EVM code为Virtual ROM:不变的
  • machine state中包含:PC(Program counter)、Gas(Gas available)、Stack、Memory。这些均是可变的。
  • 合约账号Storage为World state:是持久保存的。

在这里插入图片描述
EVM code可由各种高级语言经相应的编译器编译而来,如:

  • Solidity合约源码:对应Solidity编译器
  • Viper合约源码:对应Viper编译器
  • LLL合约源码:对应LLL编译器
    在这里插入图片描述

EVM code有2种表示方式:

  • 汇编表示
  • bytecode表示:EVM本地执行的EVM code为bytecode表示。

在这里插入图片描述
EVM的执行模式为:
在这里插入图片描述

EVM的machine space中没有寄存器,主要有以下3种资源:

  • Stack:为stack memory,最多可容纳 256 bits x 1024个元素。
  • Memory:为volatile memory,为byte addressing linear memory。
  • (Account)storage:为persistent memory,为256 bits -> 256 bits key-value store。

在这里插入图片描述

2.1.1 EVM的stack

stack中最多可存储1024个元素,每个元素为256bits。
所有操作都是基于stack进行的,访问stack的指令有:

  • PUSH
  • POP
  • COPY
  • SWAP等等

在这里插入图片描述

2.1.2 EVM中的memory

memory为线性的,可按字节寻址。访问memory的指令有:

  • MSTORE:256-bit store
  • MSTORE8:8-bit store
  • MLOAD:256-bit load

memory中所有的位置都是以0为初始值,定义明确的。
在这里插入图片描述

2.1.3 EVM中的(account)storage

storage为key-value store,将256-bit words映射到256-bit words。
访问storage的指令有:

  • SSTORE:256-bit store
  • SLOAD:256-bit load

storage中所有的位置都是以0为初始值,定义明确的。

2.2 Message call

EVM可向其它账号发送消息,message call的深度限制为不超过1024层。
在这里插入图片描述
message call由CALL指令触发,参数和返回值均通过memory来传输:
在这里插入图片描述

2.3 异常情况

EVM执行EVM code时存在多种异常情况,如:

  • 1)无效的jump目标
  • 2)out-of-gas
  • 3)无效的指令
  • 4)stack underflow等

在这里插入图片描述

2.4 Gas and fee

以太坊中所有的程序计算都需要付费(以gas来表示):
在这里插入图片描述
如EVM中的操作需要消耗gas、message call需要更多的gas、操作storage需要更多的gas。
在这里插入图片描述

2.5 EVM的输入和输出

外部数据通过message call输入到EVM中,EVM可输出log,同时也可返回值给Caller EVM。
在这里插入图片描述
input data的指令有:

  • CALLDATALOAD:指向Stack
  • CALLDATACOPY:指向Memory

在这里插入图片描述

2.6 字节顺序

EVM中的字节采用big endian顺序(network byte order)。
memory、input data、以及BYTE指令等都采用big endian顺序,而SIGNEXTEND指令则有所不同。

2.6.1 memory的字节顺序

在这里插入图片描述
MSTORE8指令是指将LSB字节存入到相应的位置:
在这里插入图片描述

2.6.2 input data的字节顺序

在这里插入图片描述

2.6.3 BYTE和SIGNEXTEND指令的字节顺序

在这里插入图片描述

2.6.4 PUSH指令的字节顺序

PUSH系列指令:PUSH1/PUSH4/PUSH32均采用right-aligned,big endian顺序。
在这里插入图片描述

2.7 EVM指令集

EVM指令集通常是256-bit operation。

合约创建和destruct的指令有:

  • CREATE
  • DELEGTECALL
  • CREATE2

Hash指令有:

  • SHA3

Shift指令有:

  • MUL:如MUL m (2^n) == m << n,左移表示乘法指令
  • DIV:表示logical right shift
  • SDIV:表示arithmetic right shift
    在这里插入图片描述
    其中DIV/SDIV等除法指令,无zero divisional exception。

在EVM内部,存在多个copy指令:

  • CALLDATALOAD:将Input data复制到Stack
  • CALLDATACOPY:将Input data复制到Memory
  • CODECOPY:将EVM code复制到Memory
  • EXTCODECOPY:将另一合约的EVM code复制到本合约运行时的Memory中

在这里插入图片描述

2.8 Solidity ABI(Application Binary Interface)

在这里插入图片描述

参考资料

[1] Ethereum EVM illustrated,可参看github https://github.com/takenobu-hs/ethereum-evm-illustrated
[2] Ethereum Virtual Machine Opcodes
[3] Learning Ethereum Virtual Machine Opcodes With EVM Puzzles


http://chatgpt.dhexx.cn/article/h8sOZtfe.shtml

相关文章

误差向量幅度(EVM)

转自&#xff1a;http://blog.sina.com.cn/s/blog_6c46cb860100otm3.html 误差向量幅度&#xff08;EVM&#xff09;&#xff1a;误差向量&#xff08;包括幅度和相位的矢量&#xff09;是在一个给定时刻理想无误差基准信号与实际发射信号的向量差。Error Vector Magnitude E…

WiFi基础知识

术语和定义 1. 发射功率RF Power 在给定频段范围内发射机通过天线对空间辐射的能量。 2. 矢量误差(EVM) EVM是发射信号理想状态下的IQ分量与实际发送信号的IQ分量之间的矢量差&#xff0c;如图1 所示&#xff0c;其数值等于误差矢量幅度与最大符号幅度之比&#xff08;取百…

三分钟读懂什么是EVM

虚拟机指的是&#xff0c;通过软件模拟的、具备完整硬件系统功能并运行在隔离环境下的完整计算机系统&#xff0c;比如虚拟化物理机VMware、Java虚拟机等。实际上在PC上常见的各种手机模拟器、主机模拟器&#xff0c;也都是一种虚拟机。这样的虚拟机往往需要固件运行&#xff0…

射频指标之EVM

说到EVM首先先介绍下EVM是什么&#xff0c;其是指目标功率与实际功率的一个矢量差&#xff0c;用下图可以比较详细的表示&#xff1a; 下面就以几个问题来讨论EVM的问题&#xff1a; 1.问题背景&#xff1a; TC芯片输出的EVM正常&#xff0c;单独测试PA输出的EVM也正常&#…

.lib 静态链接库 的破解方法(局限)(1)

因为之前程序调用了一个试用版的.lib库 , 而这个库有时间限制 , 导致程序在试用期过后不能使用 . 然后编译之后要破解一下编译出来的程序 , 很难受 闲来无事,突然想破解一下.lib , 毕竟是个代码库 , 看看是不是破解完了在编译 , 能正常使用 结果当然是能正常用了 不然就没这…

InfluxDB源码编译、安装、配置及主从同步实现

先扯点蛋 公司有个项目要求使用InfluxDB时序数据库储存点东西。第一次听说还有这种数据库&#xff0c;哈哈哈&#xff0c;孤陋寡闻了&#xff0c;先从各位大佬的博客看起&#xff0c;慢慢学习&#xff0c;逐渐了解了之后在服务器上进行安装。直接使用官方包进行安装很简单&…

一种破解静态链接库(.lib)的简单方法

一种破解静态链接库(.lib)的简单方法 作者&#xff1a;游蓝海 博客&#xff1a;http://blog.csdn.net/you_lan_hai 最近&#xff0c;在研究某代码时&#xff0c;遇到这样一个问题&#xff1a;整个解决方案中&#xff0c;有一个工程没有cpp源码&#xff0c;只有头文件跟一个静…

Linux下静态库生成和使用

一.静态库概念 1.库是预编译的目标文件(object files)的集合&#xff0c;它们可以被链接进程序。静态库以后缀为”.a”的特殊的存档&#xff08;archive file&#xff09;存储。 2.标准系统库可在目录/usr/lib与/lib中找到。比如&#xff0c;在类Unix系统中C语言的数序库一般…

libuvc介绍及简单使用

libuvc是一个用于USB视频设备的跨平台库&#xff0c;构建在libusb之上&#xff0c;编译libuvc时需要依赖libusb。libuvc的License为BSD&#xff0c;最新发布版本为0.0.6&#xff0c;源码地址: https://github.com/libuvc/libuvc libuvc支持在非windows系统上直接编译&#xff0…

linux下封装函数库——动态库.so和静态库.a(代码实现及链接方式)

在linux环境下的链接库分为静态链接库&#xff08;.a库&#xff09;和动态链接库&#xff08;.so库&#xff09;&#xff0c;其作用是把C程序编译好做成一种可执行链接文件&#xff0c;主程序文件调用这些程序的函数接口是可以使用a库或so库&#xff0c;在主程序中只需要includ…

Hyperledger fabric应用的多机部署(自动化一键部署)

前面关于fabric部署的介绍都是基于单机环境下的&#xff0c;实际生产环境中一般会根据应用场景将节点分开部署在多台物理机上&#xff0c;面临的难题主要是不同主机间的节点如何通过网络进行通信。文章最后会分享一键完成多机增加组织的自动化部署脚本。 前言 这里仍然以balan…

Linux系统编程makefile制作动态库和静态库

目录 制作动态库 制作静态库 首先准备简单的add.c&#xff0c;sub.c,main.c,head.h.具体代码如下 #head.h文件 int Add(int a, int b); int Sub(int a, int b);#add.c文件 #include <stdio.h> int Add(int a, int b) {return a b; }#sub.c文件 #include <stdio.h&…

Linux动态库的下载与配置(以libevent库为例)

** Linux动态库的下载与配置 ** 本章以下载、安装、配置libevent库为例(安装libevent的前提是已经成功安装openssl库) 一、libevent的下载 https://libevent.org/ //官网下载源码包如果学习下载1.0版本为好&#xff0c;使用可以下载2.0版本 1.如果Linux已经进行桥接联网&am…

Linux下编译安装libusb动态库(.so) - libus1-0 vs libusb-0.1

最近在调试代码的过程中&#xff0c;发现libusb库中的一些方法没办法debug到&#xff0c;所以试着下载了一版源码&#xff0c;编译安装到指定的目录。这样&#xff0c;在工程的pro文件中&#xff0c;直接指定库和头文件的目录就可以引用自己编译的libusb库了。 在网上查了相关的…

linux编译生成动态库、静态库,以及使用

一、介绍 在实际开发过程中&#xff0c;当代码的文件较多&#xff0c;可以将一部分代码编译成动态库或者静态库然后再加载到程序中使用 编译过程 1、预编译 2、编译 3、汇编 4、链接 静态库和动态库的差异 1、链接静态库简单理解就是复制目标代码嵌入可执行文件中 2、动态库是…

Linux·libusb源码编译

libusb系列--Linux下libusb源码编译​​ ​ ​源码下载及解压​​ ​​下载源码​​ ​​解压下载的源码压缩包​​ ​​打开终端​​ ​​准备编译环境​​ ​​安装make dh-autoreconf​​ ​​安装 libudev-dev​​ sudo ​./autogen.sh​ ​​​​sudo ./configure --prefi…

ESP32如何用makefile直接编译生成.a静态库

目录 编译痛点前提环境编译准备makefile代码编译痛点 开发过esp系列的攻城狮们都知道,esp32的sdk包含了编译器、组件代码和例程代码,编译都是基于cmake的,都是整体一起编译,CMakeList.txt,component.mk,project.mk等等一系列和编译相关的文件,如果你想要自己编译一个自…

Linux 环境下的静态库生成与使用

目录 一&#xff0c;简介 二&#xff0c;如何生成静态链接库 1.准备测试程序 三&#xff0c;如何使用静态链接库 1.生成静态链接库 2.使用静态链接库 一&#xff0c;简介 这里我们只讲 Linux 环境下的静态库与动态库的生成与使用&#xff0c; Windows直接用VS直接就能生成…

Linux 下libusb编译与生成动态链接库

一、前言 上一篇文章提到了怎样使用Ubuntu 安装libusb&#xff0c;忘了如何将如何编译。 二、libusb使用GCC 编译 正常来讲&#xff0c;使用 gccc xxx.c -o xxx -I/usr/include -lusb-1.0 就可以了&#xff0c;如下图&#xff1a; 但是&#xff0c;当使用Ubuntu 12.04 使用…

关于libusb开源库的使用

关于libusb开源库的使用 文章目录 关于libusb开源库的使用1. 概述1.1 介绍1.2 用法 2. API接口2.1 分类2.2 初始化/反初始化2.3 获取设备2.4 打开/关闭设备2.5 根据ID打开设备2.6 描述符相关函数2.6.1 获得设备描述符2.6.2 获得/释放配置描述符 2.7 detach/attach驱动2.7.1 两种…