智能合约开发(3)—— 以太坊虚拟机(EVM)基础

以太坊虚拟机(EVM)是以太坊中智能合约的运行环境。它不仅被沙箱封装起来,事实上它被完全隔离,也就是说运行在EVM内部的代码不能接触到网络、文件系统或者其他进程。甚至智能合约与其他智能合约之间也只有有限的接触

(1) 账户
以太坊有两类账户,共用一个地址空间:外部账户(被公钥——私钥对控制),合约账户(被存储在账户中的代码控制)。
外部账户的地址由公钥决定,合约账户的地址在创建合约时确定(这个地址由合约创造者的地址和该地址发出过的交易数量计算得到,地址发出过的交易数量被称作“nonce”)。
合约账户中存储了代码,外部账户没有。
每个账户都有一个key-value形式的持久化存储。其中key和value长度都是256bits,名字都叫做storage。
每个账户都有一个以太币余额(单位为‘Wei’),该账户余额可以通过向他发送带有以太币的交易来改变。

(2)交易
一笔交易就是一条消息,从一个账户发送到另一个账户(可能是相同的账户或者零账户)。交易可以包含二进制数据(payload)和以太币。
如果目标账户包含代码,该代码会执行,payload就是输入数据。
如果目标账户是零账户(账户地址是0),交易将创建一个新合约。正如上文所讲,这个合约地址不是零地址,而是由合约创建者的地址和该地址发出过的交易数量(被称为nonce)计算得到。创建合约交易的payload被当做EVM字节码执行。执行的输出作为合约代码被永久存储。这意味这,为了创建一个合约,你不需要向合约发送真正的合约代码,而是发送能够返回真正代码的代码(注意这句话很重要)。

(3)Gas
以太坊上每笔交易都会被收取一定数量的gas。

(4)存储,主存和栈
每个账户都有一块持久化内存区域被称为存储。形式为key-value。一个合约只能对他自己的存储进行读写。
第二个内存区被称为主存。合约每次执行消息调用时,都有一块新的,被清除过的主存。
EVM不是基于寄存器,而是基于栈的虚拟机。

(5)指令集
EVM的指令集被刻意保持在最小规模,以尽可能避免可能导致共识问题的错误实现。

(6)消息调用
合约可以通过消息调用的方式来调用其他合约或者发送以太币到非合约账户。

(7)代码调用/库
存在一种特殊类型的消息调用,被称为callcode。它跟消息调用几乎完全一样,只是加载自目标地址的代码将在发起调用的合约上下文中运行。
这意味着一个合约刻意在运行时从另外一个地址动态加载代码。存储,当前地址和余额都指向发起调用的合约,只有代码是从被调用地址获取的。Soli可以实现‘库’。

(8)日志
在区块层面,可以用一种特殊的可索引的数据结构来存储数据。这个特性被称为日志,solidity用它来实现事件。合约创建之后就无法访问日志数据,但是这些数据可以从区块链外高校的访问。因为部分日志数据被存储在布隆过滤器(Bloom fliter)中,我们可以高效并且安全的搜索日志,所以那些没有下载整个区块链的网络节点(轻客户端)也可以找到这些日志。

(9)创建
合约甚至可以通过一个特殊的指令来创建其他合约(不是简单的向零地址发起调用)。创建合约的调用跟普通的消息调用的区别在于,负载数据执行的结果被当做代码,调用者/创建者在栈上得到新合约的地址

(10)自毁
只有在某个地址上的合约执行自毁操作时,合约代码才会从区块链上移除。合约地址上剩余的一台币会发送给指定的目标,然后其存储和代码被移除
注意,即使一个合约的代码不包含自毁指定,依然可以通过代码调用(callcode)来执行这个操作。

猜你喜欢

转载自blog.csdn.net/weixin_42595515/article/details/81807142