主页 > 苹果手机imtoken怎么下载 > 以太坊虚拟机EVM的几个概念介绍(从零开始学区块链139)

以太坊虚拟机EVM的几个概念介绍(从零开始学区块链139)

苹果手机imtoken怎么下载 2023-03-10 05:36:47

这是一篇科普文章。 简单介绍了以太坊EVM中的几个概念。 近期ETH的价值不断攀升,可见业界对智能合约公链的认可。

以太坊虚拟机 (EVM) 是以太坊中智能合约的运行时环境。 它不仅是沙盒化的,而且实际上是完全隔离的,这意味着在 EVM 内运行的代码无法接触网络、文件系统或其他进程。 即使是智能合约,与其他智能合约的联系也很有限。

帐户

以太坊中有两种类型的账户,它们共享相同的地址空间。 外部账户,由公私密钥对(人)控制。 合约账户,此类账户由账户中存储的代码控制。

外部账户的地址由公钥确定,而合约账户的地址是在创建合约时确定的(这个地址是根据合约创建者的地址和该地址发送的交易数量计算的,以及地址发送的交易数量也称为“nonce”)

合约账户存储代码,外部账户不存储代码,除此之外,两类账户对于 EVM 是相同的。

每个账户都有一个键值对形式的持久化存储。 key和value的长度都是256bit,名字是storage。

以太坊经典和以太坊_以太坊的两种账户_sitehqz.com 以太坊和以太坊贸易的关系

此外,每个账户都有一个以太币余额(以“Wei”为单位),可以通过向其发送以太币交易来更改。

贸易

交易是一条消息,从一个账户发送到另一个账户(可以是同一个账户或零账户,见下文)。 交易可以包含二进制数据(有效载荷)和以太币。 如果目标帐户包含代码,则执行该代码,并且有效负载是输入数据。

如果目标账户是零账户(账户地址为0)以太坊的两种账户,交易将创建一个新合约。 如上所述,这个合约地址不是零地址,而是根据合约创建者的地址和这个地址发送的交易数量(称为nonce)计算得出的。 合约创建交易的有效负载作为 EVM 字节码执行。 执行的输出作为合约代码永久存储。 这意味着,为了创建合约,您不需要向合约发送真实的合约代码,而是发送返回真实代码的代码。

气体

以太坊上的每笔交易都会收取一定数量的天然气。 gas 的目的是在支付执行费用的同时限制执行交易所需的工作量。 当EVM执行一笔交易时,gas会按照一定的规则逐渐消耗。

gas price(gas price, in Ether)由交易创建者设定,发送账户需要预付交易费=gas price * gas amount。 如果执行后还有gas剩余,gas会返还给发送账户。

以太坊的两种账户_sitehqz.com 以太坊和以太坊贸易的关系_以太坊经典和以太坊

无论在哪里执行,一旦gas耗尽(比如下降到负值),都会触发out-of-gas异常。 当前调用框架所做的所有状态修改都将回滚。

存储器、主存储器和堆栈

每个帐户都有一个称为存储的持久内存区域。 它的格式是key-value,key和value的长度都是256位。 在合约中,无法遍历账户的存储。 与其他两者相比,存储读取操作的开销相对较大,而修改存储的开销更大。 合约只能读写自己的存储。

第二个内存区域称为主内存。 每次合约执行消息调用时,都会有一个新的、清理过的主内存。 主存可以按字节粒度寻址,但读写粒度为32字节(256位)。 操作主内存的开销随着它的增长而增长(平方尺度)。

EVM 不是基于寄存器的,而是基于堆栈的虚拟机。 因此所有的计算都在一个称为堆栈的区域中进行。 堆栈最多有1024个元素,每个元素256位。 通过允许将顶部 16 个元素之一复制到堆栈顶部,或将堆栈的顶部元素与以下 16 个元素之一交换,对堆栈的访问仅限于其顶部。 所有其他操作只能取栈顶的两个(或一个,或多个,取决于具体操作)元素并将结果压入栈顶。 当然,你可以把栈上的元素放入存储器或主存中。 但是不可能只访问栈上指定深度的元素。 在此之前,必须从堆栈中删除指定深度以上的所有元素。

指令系统

EVM 的指令集有意保持在最小尺寸,以尽可能避免可能导致共识问题的不正确实现。 所有指令都对 256 位的基本数据类型进行操作。 具有常用的算术、位、逻辑和比较运算。 也可以进行有条件和无条件的跳转。 此外,合约可以访问当前区块的相关属性,例如它的编号和时间戳。

以太坊的两种账户_sitehqz.com 以太坊和以太坊贸易的关系_以太坊经典和以太坊

留言电话

合约可以通过消息调用调用其他合约或发送以太币给非合约账户。 消息调用与交易非常相似,它们都有源、目的地、数据有效负载、以太币、gas 和返回数据。 实际上,每笔交易都可以看作是一次顶层的消息调用,进而产生更多的消息调用。

一份合约可以决定剩余gas的分配。 例如内部消息调用使用了多少gas,或者预留了多少gas。 如果在内部消息调用期间发生 out-of-gas 异常(或其他异常),将通知合约并将错误代码压入堆栈。 这种情况只是内部消息调用的gas耗尽。 在 solidity 中,这种情况下的调用合约默认会触发人为异常。 此异常将打印出调用堆栈。

如前所述,被调用合约(以及调用合约)将拥有新的主内存并可以访问调用有效负载。 呼叫有效载荷存储在称为呼叫数据的单独区域中。 调用执行后以太坊的两种账户,返回的数据会存放在调用者预先分配的一块内存中。

调用层数限制为1024,所以对于更复杂的操作,我们应该使用循环而不是递归。

代码调用和库

有一种特殊类型的消息调用称为调用代码。 它与消息调用几乎完全相同,只是从目标地址加载的代码将在调用合约的上下文中运行。

以太坊经典和以太坊_sitehqz.com 以太坊和以太坊贸易的关系_以太坊的两种账户

这意味着合约可以在运行时从另一个地址动态加载代码。 存储、当前地址和余额都指向调用合约,只有代码是从被调用地址中获取的。

这允许 Solidity 实现“库”。 可重用的库代码可以应用于合约的存储,可以用来实现复杂的数据结构。

日志

在块级别,可以使用特殊的可索引数据结构来存储数据。 此功能称为日志记录,Solidity 使用它来实现事件。 合约创建后,无法访问日志数据,但可以从区块链外部高效访问数据。 因为部分日志数据存储在布隆过滤器中,我们可以高效安全地搜索日志,所以那些没有下载整个区块链的网络节点(轻客户端)也可以找到这些日志。

创建

合约甚至可以通过特殊命令创建其他合约(而不是简单地调用零地址)。 创建合约的调用与普通消息调用的区别在于,payload 数据执行的结果被视为代码,调用者/创建者在堆栈上获得新合约的地址。

自我毁灭

sitehqz.com 以太坊和以太坊贸易的关系_以太坊的两种账户_以太坊经典和以太坊

只有当某个地址的合约自毁时,合约代码才会从区块链中移除。 合约地址上剩余的以太币被发送到指定的目的地,然后它的存储和代码被移除。

请注意,即使合约的代码不包含自毁指令,仍然可以通过调用代码执行此操作。

关于这篇文章

作为区块链2.0的代表,以太坊的智能合约机制和EVM是重大创新,也是近期价格暴涨的主要原因; 您也可以分享这篇文章让更多人了解这些知识,您的支持和鼓励是我最大的动力,长按二维码关注

以太坊的两种账户_以太坊经典和以太坊_sitehqz.com 以太坊和以太坊贸易的关系

长按关注探索未来

相关阅读