9

温故知新:EVM 101

 2 years ago
source link: https://learnblockchain.cn/article/3227
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
温故知新:EVM 101

温故知新:EVM 101

通俗易懂的 EVM 入门文章,理解以太坊与 EVM 的关系,深入了解 EVM 的架构

来源 | medium.com/@somubhargava97
作者 | Somu Bhargava

abd43aa8e060fad60d06eb143ab6af8c.jpg
图片来源:executium ,unsplash

EVM 对于以太坊状态机就好比处理器对于计算机般至关重要。它主要是用于执行智能合约的逻辑和进行相应的状态转换。在我们深入 EVM 时,现在先简单看看以太坊吧。

以太坊简介

以太坊是开源、去中心化的区块链,具有智能合约的额外功能。它意味着,在网络上发生的交易种类大致是 ETH 转账 (或) 智能合约部署 (或) 智能合约调用——所有这些都会改变以太坊区块链的状态。一堆这些交易按照特定顺序组合成一个区块,执行该区块里交易合起来所需的 gas 应小于或等于区块 gas 上限 (译者注:EIP-1559 后 gas 上限是 30 m) 。

一笔交易大概如下:

Transaction -
    nonce - 由交易发件人发送的交易号
    gas price - 这笔交易的 gas 价格 (单位为 wei)
    gas limit - 这笔交易可以使用的最高 gas 量
    to - 这笔交易的受款人
    value - 转给受款人的 wei 数值
    data - 信息调用的输入数据
    v, r, s - 可恢复的发件人 Secp256K1 签名

以太坊的世界状态就是地址和其对应的账户状态之间的映射。账户状态大概如下:

Account -
    nonce - 到现在从该相应账户发送的交易数量的值
    balance - 这个账户持有的 wei 数量
    storageRoot - 256 位键值对之间的映射
    codeHash- 属于这个账户的的 EVM 代码的不可变哈希值。当有人与这个账户进行交易时,此代码将被执行。

矿工通过汇集一些交易来形成一个区块,并获取打包该区块的工作量证明。这个区块随后会在网络被广播到其他参与以太坊区块链的节点。现在,其他接收到此区块的节点必须验证其有效性,因为矿工可能是恶意的,可能会出现传输错误,中间人攻击 (man-in-the-middle attack)。每个节点 (大致) 从以下方面验证区块:

  • 它们按照以太坊协议验证区块特性 (如区块高度、父块哈希值、时间戳、gas 上限、使用的 gas 量等)
  • 然后这个区块里的交易会被逐一执行。执行每笔交易都会消耗一些 gas 并改变区块链的状态。因此,在区块执行的最后,我们会得到一个结果状态,它由状态树根来表示,这个根是唯一的。如果矿工和验证节点对协议和交易都达成共识,那么状态根应该是唯一的。矿工添加在区块头获得的状态根,随后其他节点根据区块头提到的状态根对其进行验证。

以太坊虚拟机 (Ethereum Virtual Machine, EVM) 负责执行交易和更新区块链状态。让我们在下文了解更多 EVM 的细节。

以太坊虚拟机 (EVM)

智能合约可以被编译成 EVM 字节码。作为类比,把 Solidity 代码 (编写智能合约的通用语言) 想象成 C++代码。把 EVM 字节码看作是机器代码,它是可以被处理器理解和执行的。因此,EVM 可以被认为是以太坊的一个处理器。EVM 字节代码是操作码和数据序列,可以被 EVM 处理,形成状态转换。

因此,EVM 在执行交易中的作用:

  • 使一个账户转账 WEI (1 ETH = 10¹⁸ WEI) 到另一个账户变得可能
  • 如果交易的受款人账户有一些字节码与 EVM 相关,EVM 必须执行相应的字节码 (可能使用从 transaction.data 栏位获取的输入数据)。

现在,任何账户都可以有与 EVM 相关的字节码吗?答案是否定的。以太坊有两种类型的账户——外部所有账户 (EOA) 和合约账户 (CA)。EOA 是具有私人密钥关联的账户,由像个人、组织等的外部实体操作。另一方面,合约账户是通过部署智能合约创建的。它们没有相关私钥,并由外部实体对其进行的代码调用 (通过区块链上的交易) 控制。

基本上,每个节点上都会启动一个 EVM 实例来执行每笔交易。但是,只有当交易的受款方 (或目标) 是一个合约账户时,EVM 实例才会执行字节码。

现在,让我们来看看 EVM 的架构。

54808eb1ca5b1616ab6878461aac0818.png
图表来自 https://ethereum.org/en/developers/docs/evm/

启动的每个 EVM 实例都是为运行一个特定的字节码 (由于交易的目标是一个合约账户)。因此,字节码就像是 EVM 实例的 ROM,是不能修改的。类似于[图灵机](notion://www.notion.so/Turing Machine),EVM 由一个程序计数器 (Program Counter)、堆栈 (Stack)、内存 (Memory) 和外部存储器。这个外部存储器对所有交易进行永久存储,但其余组件的存储是易失的,并会对 EVM 的每个实例进行重新实例化。

让我们来逐个了解这些组件——

  • 程序计数器 (PC) 只是一个指向字节码中下一个操作码的指针,由 EVM 执行。它是一个非负整数,范围是 [0, number_of_bytes(bytecode)-1]
  • EVM 里的堆栈可以有最多 1024 个条目,每个条目都是 256 位 (32 字节) 的无符号整数。
  • EVM 里的内存是可以无限扩充的 (尽管你必须为内存扩充本身支付额外的费用) 且每个条目都有一个 8 位 (1字节) 的无符号整数。
  • 这里的外部存储就是所有账户存储的集合。( EVM 的字节码可以写到目标账户或外部账户的存储空间 )

与计算机处理器如何根据每个指令集理解特定的操作码类似,EVM 也需要理解操作码。每个 EVM 操作码都是一个字节,因此根据理论,最多可以有 256 个操作码,但这里就不列出全部 256 个操作码了。EVM 操作码主要可分为以下几类——

  • 控制像 PC、堆栈、内存和存储状态的操作码
  • 算数运算和按位运算
  • 环境信息——关于区块、当前交易或某特定账户的属性的信息
  • 日志操作——添加日志记录
  • 系统操作——创建新的合约账户、对另一个账户进行信息调用、销毁已创建的合约账户等

很快会出下一篇更详细的关于操作码的文章。敬请关注!

ECN的翻译工作旨在为中国以太坊社区传递优质资讯和学习资源,文章版权归原作者所有,转载须注明原文出处以及ethereum.cn,若需长期转载,请联系[email protected]进行授权。

本文首发于:https://news.ethereum.cn/Technology/introduction-to-evm-part-1

  • 发表于 2小时前
  • 阅读 ( 33 )
  • 学分 ( 0 )
  • 分类:以太坊

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK