以太坊虚拟机EVM的工作原理是怎样的

以太坊虚拟机EVM的工作原理是怎样的

如果你打算尝试在以太坊区块链上开发智能合约,或者已经在该领域工作了一段时间,可能会遇到EVM一词,EMV是太坊虚拟机的缩写。 虚拟机本质上是在执行代码和执行的机器之间创建一个抽象级别。需要这一层抽象来提高软件的可移植性,以及确保应用程序彼此分离,并与运行它们的主机分离。

创建智能合约

智能合约通常用一种名为Solidity的编程语言编写,这种语言类似于 JavaScript 和 C++。 其他编写智能合约的语言包括 Vyper 和 Bamboo。 在 Solidity 发布之前,使用了其他语言,如 Serpent(已弃用)和 Mutan(已弃用)。

在这里插入图片描述

像 Solidity 这样的智能合约语言不能由 EVM 直接执行。 相反,它们需要被编译为低级别的指令(称为操作码)。

操作码

在底层,EVM 使用一组指令(称为操作码)来执行特定任务。 在撰写本文时,有 140 个唯一操作码。 这些操作码一起使 EVM 成为图灵完备的环境。 这意味着在有足够资源的情况下,EVM 能够(几乎)计算任何东西。 因为操作码是 1 个字节,所以最多只能有 256 (16²) 个操作码。 简单起见,我们可以将所有操作码分为以下几类:

  • 堆栈操作操作码(POP、PUSH、DUP、SWAP)
  • 算术/比较/按位操作码(ADD、SUB、GT、LT、AND、OR)
  • 环境操作码(CALLER、CALLVALUE、NUMBER)
  • 内存操作操作码(MLOAD、MSTORE、MSTORE8、MSIZE)
  • 存储操作操作码(SLOAD、SSTORE)
  • 程序计数器相关操作码(JUMP、JUMPI、PC、JUMPDEST)
  • 停止操作码(STOP、RETURN、REVERT、INVALID、SELFDESTRUCT)

在这里插入图片描述

字节码

为了有效地存储操作码,它们被编码为字节码。 每个操作码都分配有一个字节(例如;STOP 是 0x00)。 我们来看看下面的字节码:0x6001600101

在这里插入图片描述

在执行过程中,字节码被分成它的字节(1 个字节等于 2 个十六进制字符)。 0x60–0x7f (PUSH1-PUSH32) 范围内的字节处理方式不同,因为它们包含推送数据(需要附加到操作码,而不是被视为单独的操作码)。

第一条指令是 0x60,它转换为 PUSH1。 因此,我们知道推送数据是 1 个字节长,我们将下一个字节添加到堆栈中。 堆栈现在包含 1 个项,我们可以移动到下一条指令。 由于我们知道 0x01 是 PUSH 指令的一部分,因此我们需要执行的下一条指令是另一个 0x60 (PUSH1) 以及相同的数据。 堆栈现在包含 2 个相同的项。 最后一条指令是 0x01,翻译为 ADD。 该指令将从堆栈中取出 2 个项,并将这些项目的总和压入堆栈。 堆栈现在包含一项:0x02

合约状态

虽然许多流行的顶级编程语言允许用户直接将参数传递给函数(function(argument1,argument2)),但低级编程语言通常使用堆栈将值传递给函数。 EVM 使用 256 位寄存器堆栈,可以一次访问或操作最近的 16 项。总共,堆栈只能容纳 1024 个项。

由于这些限制,复杂的操作码改为使用合约内存来检索或传递数据。然而,记忆不是持久的。合约执行完成后,内存内容不会被保存。可以将堆栈类比为函数参数,将内存类比为声明变量。

为了无限期地存储数据并使其可用于未来的合约执行,可以使用存储。合约存储本质上充当公共数据库,可以从外部读取值,而无需向合约发送交易(不收费!)。但是,与写入内存相比,写入存储非常昂贵(高达 6000 倍成本)。

于合约交互的成本(gas fee)

由于所有合约的执行都是由运行以太坊节点的个人运行的,攻击者可以尝试创建包含大量计算成本高的操作的合约来减慢网络速度。 为了防止此类攻击的发生,每个操作码都有自己的基本 gas 成本。 此外,一些复杂的操作码也会收取动态 gas 成本。 例如,操作码 KECCAK256(以前称为 SHA3)的基本成本为 30 gas,每个字的动态成本为 6 gas(字是 256 位项目)。 计算成本高的指令比简单、直接的指令收取更高的 gas 费用。 最重要的是,每笔交易都以 21000 gas 开始。

在这里插入图片描述

当执行减少状态大小的指令时,gas 也可以退还。 将存储值从非零设置为零会退还 15000 gas,而完全删除合约(使用 SELFDESTRUCT 操作码)会退还 24000 gas。 退款仅在合同执行完成后才会发生,因此合同无法自行支付。 此外,退款不能超过当前合同调用所用 gas 的一半。

如果有兴趣阅读更多有关gas的信息,请随时查看这篇出色的文章:“什么是gas?”

https://support.mycrypto.com/general-knowledge/ethereum-blockchain/what-is-gas/

部署智能合约

部署智能合约时,会创建一个常规交易,没有地址。 此外,添加了一些字节码作为输入数据。 此字节码充当构造函数,需要在将运行时字节码复制到合约代码之前将初始变量写入存储。 在部署期间,创建字节码只会运行一次,而运行时字节码将在每次合约调用时运行。

在这里插入图片描述

我们可以把上面的字节码分为三个部分

构造器

60806040526001600055348015601457600080fd5b5060358060226000396000f3fe

在这里插入图片描述

运行时

6080604052600080fdfe

在这里插入图片描述

元数据

a165627a7a723058204e048d6cab20eb0d9f95671510277b55a61a582250e04db7f6587a1bebc134d20029

在这个字节码的末尾,附加了一个由 Solidity 创建的元数据文件的 Swarm 散列。 Swarm 是一个分布式存储平台和内容分发服务,或者更简单地说:一个去中心化的文件存储。 尽管 Swarm 哈希也将包含在运行时字节码中,但它永远不会被 EVM 解释为操作码,因为它的位置永远无法到达。 目前,Solidity 使用以下格式:

0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20 [32 bytes swarm hash] 0x00 0x29

因此,在这种情况下,我们可以提取以下 Swarm 哈希:

4e048d6cab20eb0d9f95671510277b55a61a582250e04db7f6587a1bebc134d2

元数据文件包含有关合约的各种信息,例如编译器版本或合约的功能。 不幸的是,这是一个实验性功能,没有多少合约公开将其元数据上传到 Swarm 网络。

反编译字节码

有几个项目已经创建了工具来尝试使字节码更具可读性。 例如你可以使用 eveem.org 或 ethervm.io 在主网上反编译合约。 不过,由于编译器进行了优化,原始合约源的某些部分(例如函数名称或事件名称)总是丢失。 尽管如此,大多数函数名称仍然可以通过将函数签名与包含流行函数和事件名称的大型数据集进行比较来强制执行(参见 4byte.directory)。

合约调用通常需要“ABI”(应用程序二进制接口),它是记录所有功能和事件的数据,包括它们所需的输入和输出。 在合约上调用函数时,函数签名是通过对函数名称(包括其输入)进行哈希处理(使用 keccak256)并截断除前 4 个字节之外的所有内容来确定的。

在这里插入图片描述

如上图所示,我们的函数 HelloWorld() 解析为签名哈希 0x7fffb7bd。 如果我们想调用这个函数,我们的交易数据需要以 0x7fffb7bd 开头。 需要传递给函数的参数(在这种情况下没有)可以在交易输入数据中的签名哈希之后添加到称为单词的 32 字节片段中。

如果一个参数包含超过 32 个字节(256 位)的数据,如数组或字符串,则该参数将拆分为多个字,这些字会在包含所有其他参数后添加到输入数据中。 此外,所有单词的总大小作为另一个单词包含在所有数组单词之前。 在包含参数的位置,将添加数组单词(包括大小单词)的起始位置。

总结

以太坊为开发人员提供了一个去中心化的生态系统,可以使用 Solidity 和 EVM 构建出色的产品。 尽管通过智能合约与 EVM 交互可能比在传统服务器上运行程序要昂贵得多,但在许多用例中,去中心化更受大家的关注。

如果阅读本文使您有兴趣了解有关开发智能合约的更多信息,请通过查看“智能合约简介”来深入了解 Solidity 的工作原理。 谢谢阅读!

引用

  • https://ethereum.github.io/yellowpaper/paper.pdf
  • https://docs.soliditylang.org/en/latest/
  • https://blog.zeppelin.solutions/deconstructing-a-solidity-contract-part-i-introduction-832efd2d7737
  • https://blog.qtum.org/diving-into-the-ethereum-vm-6e8d5d2f3c30

本篇翻译自下面这篇文章

https://medium.com/mycrypto/the-ethereum-virtual-machine-how-does-it-work-9abac2b7c9e

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在现有省、市港口信息化系统进行有效整合基础上,借鉴新 一代的感知-传输-应用技术体系,实现对码头、船舶、货物、重 大危险源、危险货物装卸过程、航管航运等管理要素的全面感知、 有效传输和按需定制服务,为行政管理人员和相关单位及人员提 供高效的管理辅助,并为公众提供便捷、实时的水运信息服务。 建立信息整合、交换和共享机制,建立健全信息化管理支撑 体系,以及相关标准规范和安全保障体系;按照“绿色循环低碳” 交通的要求,搭建高效、弹性、高可扩展性的基于虚拟技术的信 息基础设施,支撑信息平台低成本运行,实现电子政务建设和服务模式的转变。 实现以感知港口、感知船舶、感知货物为手段,以港航智能 分析、科学决策、高效服务为目的和核心理念,构建“智慧港口”的发展体系。 结合“智慧港口”相关业务工作特点及信息化现状的实际情况,本项目具体建设目标为: 一张图(即GIS 地理信息服务平台) 在建设岸线、港口、港区、码头、泊位等港口主要基础资源图层上,建设GIS 地理信息服务平台,在此基础上依次接入和叠加规划建设、经营、安全、航管等相关业务应用专题数据,并叠 加动态数据,如 AIS/GPS/移动平台数据,逐步建成航运管理处 "一张图"。系统支持扩展框架,方便未来更多应用资源的逐步整合。 现场执法监管系统 基于港口(航管)执法基地建设规划,依托统一的执法区域 管理和数字化监控平台,通过加强对辖区内的监控,结合移动平 台,形成完整的多维路径和信息追踪,真正做到问题能发现、事态能控制、突发问题能解决。 运行监测和辅助决策系统 对区域港口与航运业务日常所需填报及监测的数据经过科 学归纳及分析,采用统一平台,消除重复的填报数据,进行企业 输入和自动录入,并进行系统智能判断,避免填入错误的数据, 输入的数据经过智能组合,自动生成各业务部门所需的数据报 表,包括字段、格式,都可以根据需要进行定制,同时满足扩展 性需要,当有新的业务监测数据表需要产生时,系统将分析新的 需求,将所需字段融合进入日常监测和决策辅助平台的统一平台中,并生成新的所需业务数据监测及决策表。 综合指挥调度系统 建设以港航应急指挥中心为枢纽,以各级管理部门和经营港 口企业为节点,快速调度、信息共享的通信网络,满足应急处置中所需要的信息采集、指挥调度和过程监控等通信保障任务。 设计思路 根据项目的建设目标和“智慧港口”信息化平台的总体框架、 设计思路、建设内容及保障措施,围绕业务协同、信息共享,充 分考虑各航运(港政)管理处内部管理的需求,平台采用“全面 整合、重点补充、突出共享、逐步完善”策略,加强重点区域或 运输通道交通基础设施、运载装备、运行环境的监测监控,完善 运行协调、应急处置通信手段,促进跨区域、跨部门信息共享和业务协同。 以“统筹协调、综合监管”为目标,以提供综合、动态、实 时、准确、实用的安全畅通和应急数据共享为核心,围绕“保畅通、抓安全、促应急"等实际需求来建设智慧港口信息化平台。 系统充分整合和利用航运管理处现有相关信息资源,以地理 信息技术、网络视频技术、互联网技术、移动通信技术、云计算 技术为支撑,结合航运管理处专网与行业数据交换平台,构建航 运管理处与各部门之间智慧、畅通、安全、高效、绿色低碳的智 慧港口信息化平台。 系统充分考虑航运管理处安全法规及安全职责今后的变化 与发展趋势,应用目前主流的、成熟的应用技术,内联外引,优势互补,使系统建设具备良好的开放性、扩展性、可维护性。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值