区块链知识系列 - 系统学习EVM(一)

news2024/11/25 12:42:38

EVM有一个基于栈的架构,在一个栈中保存了所有内存数值。EVM的数据处理单位被定义为256位的“字”(这主要是为了方便处理哈希运算和椭圆曲线运算操作

这里所说的内存数值是指那些EVM字节码运行所需要的输入、输出参数数据和智能合约程序运行中所需要的局部变量等数据,而不是指下文中所提到的“内存”数据;下文中的“内存”是一个与栈共同存在的、独立的临时存储空间。

以太坊EVM的架构和执行上下文
在这里插入图片描述

虚拟机引擎

目前市面上比较主流的是BTC脚本引擎和以太坊虚拟机(Ethereum Virtual Machine, EVM)。

  • BTC事务由一套脚本引擎(Script)处理,Script是一种类Forth的、基于栈式模型的、无状态的、非图灵完备的语言。
  • EVM基于Account模型将智能合约代码以对外完全隔离的方式内部运行,实现了图灵完备的智能合约体系。
    • EVM类似于Java虚拟机(JVM),编译后基于字节码运行,开发时则可以使用高级语言实现,编译器会自动转化为字节码。
    • EVM。以太坊虚拟机是以太坊中智能合约的运行环境,并且是一个沙盒,与外界隔离。
    • 智能合约代码在EVM内部运行时,是不能进行网络操作、文件I/O或执行其他进程的。智能合约之间也只能进行有限的调用,这样保证了合约运行的独立性,并尽可能提高了运行时的安全性。

图灵完备

图灵完备的计算环境——以太坊虚拟机(EVM)。这就意味着在EVM上可以做所有的能想得到计算,包括无限循环。EVM指令包括一个JUMP的跳转指令,可让程序跳回前面的程序代码,也可以像条件判断语句那样做条件跳转,当满足一定条件时将程序跳转到另一个地方执行。另外,一个合约可以调用其他合约,这提供了潜在的递归调用的功能。

以太坊虚拟机

EVM模块主要分为三大模块:编译合约模块、Ledger模块和EVM执行模块。

  • 编译合约模块
    • 主要是对底层Solc编译器进行一层封装,提供RPC接口给外部服务,对用Solidity编写的智能合约进行编译。编译后将会返回二进制码和相应的合约ABI, ABI可以理解为合约的手册
  • Ledger模块
    • Ledger模块主要是对区块链Account系统进行修改和更新,Account一共分为两种,分别是普通Account(EOA)和智能合约Account,调用方如果知道合约Account地址则可以调用该合约,Account的每一次修改都会被持久化到区块链中。
  • EVM执行模块
    • EVM执行模块作为核心模块,主要功能是对事务中的智能合约代码进行解析和执行,一般分为创建合约和调用合约两部分。
    • 支持普通的字节码执行和JIT模式的指令执行

指令集

EVM指令由很多标准机器码指令组成,包含:

  • 算术和位运算逻辑操作
  • 执行上下文查询
  • 栈、内存和存储访问
  • 处理流程操作
  • 日志、跳转和其他操作

EVM模块执行流程

EVM执行事务的流程如图所示
epub_38493592_21

(1) EVM接收到Transaction信息,然后判断Transaction类型是部署合约还是执行合约。如果是部署合约,执行指令集,来存储合约地址和编译后的代码;如果是执行合约或是调用合约,则使用EVM来执行输入指令集。

(2) 执行上一条指令集之后,判断EVM是否停机,如果停机则判断是否正常停机,正常停机则更新合约状态到区块链,否则回滚合约状态。如果不停机则回到上一步(1)进行判断。

(3) 执行完的合约会返回一个执行结果,EVM会将结果存储在Receipt回执中,调用者可以通过Transaction的哈希来查询结果。

EVM代码的正式执行模型

每轮执行时,通过调出代码的第pc(程序计数器)个字节,每个指令如何影响元组都有定义。例如,ADD将两个元素出栈并将它们的和入栈,将Gas减1并将pc加1; stack将顶部的两个元素出栈,并将第2个元素插入由第1个元素定义的合约存储位置,同样减少最多200的Gas值,并将pc加1。虽然有许多方法通过即时编译去优化以太坊,但以太坊的基础性的实施可以用几百行代码实现。

EVM是基于栈的虚拟机

以太坊合约的代码是使用低级的基于堆栈的字节码的语言写成的,被称为“以太坊虚拟机代码”或者“EVM代码”。代码由一系列字节构成,每一个字节代表一种操作。一般而言,代码执行是无限循环,程序计数器每增加一(初始值为零)就执行一次操作,直到代码执行完毕或者遇到错误、STOP或者RETURN指令。

EVM不是基于寄存器的,而是基于栈的虚拟机。因此所有的计算都在一个称为栈的区域内执行。栈最大有1024个元素,每个元素有256位。对栈的访问只限于其顶端,允许复制最顶端的16个元素中的一个到栈顶,或者是交换栈顶元素和下面16个元素中的一个。所有其他操作都只能取最顶的一个或几个元素,并把结果压在栈顶。当然可以把栈里的元素放到存储或者主存中。但是无法只访问栈里指定深度的那个元素,在那之前必须把指定深度之上的所有元素都从栈中移除才行。

EVM的指令集被刻意保持在最小规模,以尽可能避免可能导致共识问题的错误。所有的指令都是针对256位这个基本的数据单位进行的操作,具备常用的算术、位、逻辑和比较操作,也可以进行条件和无条件跳转。

执行指令部分的Gas

虚拟机(EVM)执行指令部分的Gas计算是最为复杂的。虚拟机(EVM)事务执行期间的所有操作,包括数据库读写、消息发送以及虚拟机采取的每个计算步骤都要消耗一定量的燃料,并且在不同参数和缓存影响的情况下都会对应有不同的燃料标价。图2-15是取自以太坊官方黄皮书中的非指令部分的燃料标价示例图。

黄皮书链接:https://ethereum.github.io/yellowpaper/paper.pdf

高级语言

以太坊的高级语言最后会编译成在EVM中执行的EVM字节码(bytecode),部署在以太坊区块链上。以太坊提供3种编程语言:Solidity、Serpent和LLL。


往期精彩回顾:
区块链知识系列
密码学系列
零知识证明系列
共识系列
调研系列
BTC系列
以太坊系列
EOS系列
Filecoin系列
联盟链系列
Fabric系列
智能合约系列
Token系列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/168104.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

拉伯证券|锂离子动力电池有哪些优缺点?锂离子电池的优缺点详解

锂离子动力电池是20世纪开发成功的新型高能电池。这种电池的负极是石墨等资料,正极用磷酸铁锂、钴酸锂、钛酸锂等。70年代进入实用化。因其具有能量高、电池电压高、工作温度规模宽、贮存寿命长等优点,已广泛应用于军事和民用小型电器中。 锂离子动力电池…

jvm垃圾回收笔记

JVM基础知识笔记 1. 垃圾回收相关算法 标记清除-标记整理-复制 这三个看上面的文章 1.1 分代收集算法 将不同生命周期的对象采用不同的收集方式,以便提高回收效率,一般是将Java堆分为新生代和老年代,这样可以根据各个年代的特点使用不同的…

拉伯证券|A股涨势趋缓,个股分化,北向资金继续“买买买”

今天上午,A股商场涨势趋缓,主要指数涨跌互现。 个股方面也现较大分解,接连涨停股和接连大幅跌落股同时呈现。 值得注意的是,作为近期最为坚定买入A股的力量之一,北向资金今天上午继续“买买买”,上午半个交…

Wider Face+YOLOV7人脸检测

1 Wider Face标注格式转成YOLO格式1.1 Wider Face标注介绍The format of txt ground truth. File name Number of bounding box x1, y1, w, h, blur, expression, illumination, invalid, occlusion, pose0--Parade/0_Parade_marchingband_1_849.jpg 1 449 330 122 149 0 0 0 0…

Java开发 - Spring Test知多少?

前言 在前文中,我们也使用了测试代码来进行简单的单元测试,但是我们会发现,里面有大量的重复代码,实际给我们的体验并不是太好,所以这篇,我们来学习Spring Test,Spring Test不仅仅限于在Mybati…

AUTOSAR RTE 总结

1. Interface和在Interface下面包含哪些data element在SWC创立之前就定义好了,存储在一个arxml文件里面, 它相当于一个库文件,在新建AUTOSAR project的第一步就应该被导入进来 2. port在SWC创建的阶段被create,因为Interface没有…

某博数据挖掘:使用Scrapy构建自定义数据采集提取洞察信息

想要深入了解某博上最新的动态和信息吗?那么学习如何使用Scrapy构建一个某博数据采集将是不二之选。Scrapy是一个强大的框架,能够快速地爬取网站上的数据。 新版API构建的某博数据采集拥有最丰富的字段信息,能够更好地深入挖掘某博上的数据。提供了多种采集模式,包括用户、…

邮件定时发送java实现

本文总结如何通过java实现邮件接口的定时发送任务。1、邮箱服务器地址和端口以139邮箱为例,获取服务器地址和端口。139邮箱的路径:设置-常见设置-邮箱协议设置2、客户端配置工具:springboot2.4.3使用maven,使用java11pom.xml引入m…

华为机试题:HJ14 字符串排序(python)

文章目录知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。2、print() :打印输出。3、int() :将一个字符串或数字转换为整型(强转)。4、range() :输出指定范围…

《Linux Shell脚本攻略》学习笔记-第十二章

12.1 简介 我们可以通过关闭无用的服务、调整内核参数或是添加新的硬件来改善系统性能。 12.2 识别服务 Linux系统可以同时运行数百个任务,其中可能也会有那么一两个你不需要的守护进程。 有三种可以用于启动守护进程和服务的工具,Linux发行版支持其中任…

LeetCode题解 贪心(一):455 分发饼干;376 摆动序列;53 最大子序和

随想录 && LeetCode 贪心算法 贪心之于算法,内核是一个最优解是由多个局部最优解组合而成的 比如,如何在一个月之内最有效的减肥,子问题就是每周如何减肥,再拆分就是每一天如何减肥 如果能找到令每一天都有效减肥的策…

vue实现购物车思想

vue实现购物车思想一、问题:二、解决步骤一、问题: 实现购物车功能,具体如下 在该界面显示所有物品的列表,点击开菜显示购物车 在该界面只显示订单的列表 如何实现购物车数据的同步呢? 二、解决步骤 具体思路如…

day21-反射枚举

day21_反射&枚举 课程目标 1. 【理解】类加载器 2. 【理解】什么是反射 3. 【掌握】获取Class对象的三种方式 4. 【掌握】反射获取构造方法并创建对象 5. 【掌握】反射获取成员变量并使用 6. 【掌握】反射获取成员方法并使用 7. 【掌握】反射综合案例 8. 【理解】枚举类加…

在Ubuntu上安装 Hadoop 3详细过程(验证+填坑总结)

在Ubuntu上安装 Hadoop 3 前提条件: Python 推荐3.8JDK 推荐1.8 解压安装 sudo tar -zxvf hadoop-3.3.0.tar.gz -C /usr/local cd /usr/local sudo mv hadoop-3.3.0 hadoop sudo chown -R hadoop ./hadoop 配置环境变量 vim ~/.bashrc # hadoop export…

5、数组的创建和操作

目录 一、创建空数组、行向量、列向量 二、访问数组 三、 子数组的赋值(Assign) 四、其他创建数组的方式 1. 通过冒号创建一维数组 2.通过logspace函数创建一维数组 3.通过linspace函数创建一维数组 在MATLAB中一般使用方括号“[ ]”、逗号“,”、…

Python FastAPI 框架入门(一)【用于后端API快捷开发】

FastAPI 框架,高性能,易于学习,高效编码,生产可用 官方中文文档:FastAPI 框架中文文档 官方介绍: FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Py…

【GD32F427开发板试用】-05-GD32F427移植Coremark

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:申小林 如何在GD32F427开发板上移植CoreMARK? 1 下载CoreMARK源码 CoreMark开源的代码可以在Gitbub上自己做下载。 下载地址:ht…

CSS设置元素字体、降级使用字体、引入外部字体

设置元素字体 通过font-family属性,可以设置元素里面的字体样式。 font-family 可以把设置多个字体名称。 降级使用字体 几乎所有浏览器都有支持几种通用字体。比如: monospace,serif和sans-serif,当字体不可用,浏览器可以 “…

通过Docker启动Solace,并在Spring Boot通过JMS整合Solace

1 简介 Solace是一个强大的实时性的事件驱动消息队列。本文将介绍如何在Spring中使用,虽然代码使用的是Spring Boot,但并没有使用相关starter,跟Spring的整合一样,可通用。JMS是通过的消息处理框架,可以深入学习一下&…

02.指针的进阶1.练习题

1.辨析 //数组指针是一种指针,指向数组的指针 //数组指针是指向数组地址的指针 //回调函数是调用函数指针指向函数 EG1:杨氏矩阵 有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中…