第七章以太坊工作原理:虚拟机、账户、状态函数及应用

去中心化应用协议-以太坊诞生

以太坊的目的是创建一种去中心化应用的协议,提供一套对大量的去中心化应用程序非常有用的新方案,特别强调快速开发,对小的和少数人使用的应用也非常安全(小而使用人少的应用容易被 51%攻破),以及不同的应用程序之间能够有效的互动。以太坊通过建立在本质上是抽象的基础层来完成这一工作:一个区块链其内置了图灵完备的编程语言,允许任何人编写智能合约和去中心化的应用程序,在这些应用程序中,他们可以创建任意的属于他们自己的规则、交易格式和状态转换函数。名字币的一个简单版本在以太坊可以用两行代码来编写完成,而其他协议如货币和信用系统则可以用不到 20 行的代码来构建。智能合约-包含价值而且只有满足某些条件才能打开的加密箱子-也能在我们的平台上构建,并且因为图灵完备性、价值知晓(value-awareness)、区块链知晓(blockchain-awareness)和多状态所增加的力量,远比特币脚本所能提供的功能强大得多。

以太坊虚拟机

以太坊是一个可编程的区块链,不仅仅是给用户一些预定义操作(如比特币只交易),以太坊允许用户创建属于他们自己的复杂的操作。以太坊作为一个平台为不同的区块链技术应用提供服务。
 
狭义来说,以太坊是一系列协议,其核心就是一个以太坊虚拟机,能执行遵守协议的任何复杂的代码。以太坊虚拟机是图灵完备的,开发者可以在虚拟机上使用像 javascript,python 这样的友好的编程语言来创建应用。
 
和任何的区块链一样,以太坊包含了一个点对点的网络协议。这以太坊区块链是被链接着这个网络的各个节点维护和更新的。网络中的各个节点的虚拟机都执行相同的指令来共同维护区块数据库, 因为这个原因,以太坊有时候被人称为“世界计算机”。
 
以太坊全网的大规模并行计算不是只为了提计算效率,而是为了保证全网的数据一致性。实际上, 这使得在以太网上的 运算要比传统的电脑慢的多,成本也昂贵得多。全网中的每一台虚拟机的运行都是为确保全网数据库的一致性。去中心化的一致性给全网极端的容错能力;抗审查能力和永不宕机能力等!

以太坊账户类型分类

以太坊的基本单元是账号。每一个账户都有一个 20 个字节长度的地址 。以太坊区块链跟踪每一个账号的状态,区块链上所有状态的转移都是账户之间的令牌(令牌即以太币)和信息的转移。
以太坊有 2 种账户类型:
外部账号,简称 EOA,是由私钥来控制的。
合约帐户,由合约代码来控制,且只能由一个 EOA 账号来操作
 
对于大多数用户来说,最基本的区别在于,用户掌握着 EOA 账号,因为用户掌握着控制 EOA 账号的私钥。而合约账号由内部程序代码来控制的,当然掌控私钥的 EOA 账户可以通过编写特定的程序代码来掌控合约账户。流行的术语“智能合约”就是合约账号中的代码,当一个交易被发送到该账户时,合约中的代码就会被执行。用户可以通过把代码部署到区块链中来创建一个新合约,也即创建了一个新的合约账户。
 
合约账户只有在 EOA 账户发出一个指令的时候才会去执行一个操作。所以一个合约账户是不可能自己去执行一个操作的,如生产一个随机数或执行一个 API 调用等,它只有在 EOA 账户作出确认的情况下才会去做这些事情。这是因为以太坊要求节点能够对计算的结果无论对错都达成一致,这就对操作有了一个必定会执行的要求。
 
在以太坊中,全网的状态是由被“账户”的对象组成的,账户之间可以直接的进行价值和信息的转移,一个以太坊的账户包含下面 4 个字段:
  • 随机数, 一个计数器,用以确保每个交易都只会被处理一次
  • 账户当前的以太币额度
  • 账户的合约代码, 如果有的话
  • 这个账户的 存储 (默认空) 
“以太币” 是以太坊主要的内部加密燃料,并且被用来支付交易的费用。一般情况下,有 2 种类型的账户: 外部拥有的账户,被私钥控制的,和合约账户, 被合约代码控制的。外部拥有的账户没有代码,用户可以通过一个外部账户来创建和签名一个交易来送一个消息;合约账户中,每次当这个合约收到一个消息的时候,它的代码就会被激活,允许它读取这个消息,并且写入到内部存储中,然后按照一定顺序发送其他的消息或创建合约等。
 

以太坊系统数据包的发送和传输

名词“交易”在以太坊中是指签名的数据包,这个数据包中存储了从外部账户发送的消息,交易包含以下内容:
  • 消息的接收者
  • 一个可以识别发送者的签名
  • 发送方给接收方的以太币的数量
  • 一个可选的数据字段
  • 一个 STARTGAS 值, 表示执行这个交易允许消耗的最大计算步骤
  • 一个 GASPRICE 值, 表示发送方的每个计算步骤的费用
 
前面三个是每一个加密货币都有的标准字段。默认情况下第四个数据字段没有任何功能,但是合约可以访问这里的数据;举个例子,如果一个合约是在一个区块链上提供域名注册服务的,那么它就会想把这数据字段中的数据解析成 2 个字段,第一个字段是域名,第二个字段是域名对应的 IP 地址。这个合约会从数据字段中读取这些值,然后适当把它们保存下来。
 
这个 STARTGAS 和 GASPRICE 字段 是以太坊的预防拒绝式攻击用的,非常重要。为了防止在代码中出现意外或敌对的无限循环或其他计算浪费,每个交易都需要设置一个限制,以限制它的计算总步骤是一个明确的值。这计算的基本单位是“汽油(gas)”; 通常,一个计算成本是一个 1 滴汽 油,但是一些操作需要消耗更多的汽油,因为它们的计算成本更高。在交易数据中每一个字节需要消耗 5 滴汽油。这样做的目的是为了让攻击者为他们所消耗的每一种资源,包括计算,带宽和存储支付费用;所以消耗网络资源越多,则交易成本就越大。

消息 

合约有能力向其他合约发生“消息”。消息是虚拟的对象,它从来不会被序列化,而且只存在于以太坊的执行环境中。一个消息包含以下内容:
  • 消息的发送者 (隐式)
  • 消息的接收者
  • 与消息一起传送的以太币的数量
  • 一个可选的数据字段
  • 一个 STARTGAS 值 
从本质上说,一个消息就像一个交易, 只是它是由一个合约产生的而不是一个外部用户。一个正在执行代码的合约,当执行到 CALL 代码时,会产生并执行一个消息。就像一个交易,一个消息会导致接收方的账户运行它的代码。因此,合约之间是可以互相发生作用的。

以太坊状态转移函数

以太坊状态函数图解
以太坊的状态转移函数 APPLY(S,TX) -> S' 可以被定义成下面的:
  1. 检查这个交易是不是合法的 ,签名是不是合法的, 这随机数是不是匹配这个发送者的账户, 如果答案是否定的,那返回错误。
  2. 用 STARTGAS * GASPRICE 计算交易的费用,并且从签名中确定这个发送者的地址。 从发送者的余额中减去费用,并且增加发送者的随机值。如果余额不够,则返回错误。
  3. 初始化 GAS = STARTGAS, 并根据这交易中的字节数拿走一定量的汽油。
  4. 把交易的值从发送的账户转移到接收者的账户。如果接收者的账户还不存在,就创建一个。如果这个接收者的账户是一个合约,那么就运行合约的代码直到完成,或者报汽油消耗光的异常。
  5. 如果值转移失败了,因为发送者没有足够多的余额,或代码执行消耗光了汽油,恢复除了支付的费用外的所有的状态,并且把这个费用添加到矿工的账户上。
  6. 另外,把所有剩下的汽油退还给发送者,然后把用于支付费用的汽油发送给矿工。举例,假设合约的代码是这样的:

     if !self.storage[calldataload(0)]:
    self.storage[calldataload(0)] = calldataload(32)

 
注意,真实的合约代码是用底层的 EVM 代码编写的;这个列子是用一个叫 Serpent 的高级语言写的。假设这个合约的存储开始是空的,并且发送了一个交易,其中包含 10 个以太币,2000 个汽油,汽油价格是 0.001 比特币,和 64 字节的数据,其中 0-31 字节代表数字 2,32-63 字节代表字符串 CHARLIE。在这个案例中,这状态转移函数的处理如下:
  1. 检查者交易是否有效并且格式完好。
  2. 检查者交易的发送者是否至少有 2000 * 0.001 = 2 以太币。如果有,则从发送者的账户中减去 2 以太币。
  3. 初始化 汽油(gas)= 2000;假设这个交易是 170 个字节长度并且每个字节的费用是 5,那么减去 850,汽油还剩 1150。
  4. 从发送者的账户减去 10 个以太币,并且添加到合约的账户中。
  5. 运行合约的代码. 在这里例子中:检查合约的存储的第 2 个索引是否已经被使用,注意到它没有,然后就把这数据存储的第二个索引的值设置为 CHARLIE. 假设这个操作消耗了 187 个汽油,那么剩下的汽油总量是 1150 – 187 = 963
  6. 把 963 * 0.001 = 0.963 以太币加到发送者的账户,然后反正结果状态。
如果交易的接收端没有合约,那么这总的交易费用就简单的等于汽油的价格乘以这个交易的字节长度,与交易一起发送的数据字段的数据将无关重要。
 
注意,在恢复这个方面,消息和交易的处理方式是相同的: 如果一个消息执行消耗光了汽油,那么这消息的执行和其他被触发的执行都会被恢复,但是父类的执行不会恢复。

智能合约代码执行

以太坊的合约代码是用底层的基于堆栈的字节码语言来编写的,被称为 “以太坊虚拟机代码” or “EVM 代码”。这代码有一系列的字节组成,其中每一个字节都标识一个操作。在一般情况下,代码的执行是一个无限循环,直到代码运行结束或遇到错误,或检测到 STOP 或 RETURN 指令。这些操作有三种类型的空间可用于存储数据:
  • 堆栈, 一种后进先出的容器
  • 内存, 一种无线扩展的字节数组
  • 合约的持久化 存储, 一种键值对的方式. 不像堆栈和内存,计算结束后将会被重置, 存储将长期保存。
代码还可以访问值(以太币),发送者,传入的消息的数据,以及区块的头信息,并且也可以返回一组字节数组当做输出。

区块链和挖矿

以太坊矿工挖矿图解
这以太坊的区块链和比特币的区块链有很多相似的地方,也有很多不同的地方。这个以太坊和比特币在区块链体系中最重要的不同点是 :以太坊的区块同时包含了交易列表和最近区块的状态。除此之外,2 个其他的值,区块的编号和难度值也存在在区块中。以太坊中最基本的区块验证算法如下:
  1. 检查上一个区块是否存在和其有效性。
  2. 检测这区块的时间戳,是不是比上一个区块的大,并且小于 15 分钟
  3. 检查这区块编号,难度值,交易根(transaction root) , 叔根(uncle root)和汽油限制是否有效
  4. 检查这区块的工作证明是否有效
  5. 把 S[0] 设置成上一个区块的末端的状态
  6. 让 TX 成为这区块的交易列表,如果有 n 个交易。则做 for 循环 For i in 0...n-1, 设置S[i+1] = APPLY(S[i],TX[i]). 如果任何一个应用发生错误,或这区块中汽油的总的消耗达到了 GASLIMIT, 则返回一个错误.
  7. 让 S_FINAL 等于 S[n], 但是把支付给矿工的奖励添加到这区块里。
  8. 检查这个状态 S_FINAL 的默克尔树树根是不是和区块头信息中所提供的状态根是一样的。如果是,则区块有效,不然则无效。
乍看上去,这种方法似乎效率很低,因为它需要将整个状态存储在每个块中,但在现实中,效率应该与比特币相当。原因在于,状态存储在树结构中,并且每个块后,只需要修改树的一小部分。此外,由于所有的状态信息都是最后一个区块的一部分,所以不需要存储整个区块链的历史——这一策略,如果它可以应用于比特币,那么它的磁盘空间将节省 5-20 倍。
以太坊网络中交易会被验证这网络的节点收集起来。这些“矿工”在以太坊网络中收集、传播、验证和执行交易,然后整理归档这些交易,打包成一个区块,与别的矿工竞争将区块添加到区块链 中,添加成功的矿工将收到奖励。通过这样的措施,鼓励人们为区块链全网提供更多的硬件和电力支持。

区块链系统以太坊金融应用

以太坊框架本身并没有什么特别的功能。就好像程序语言一样,它做什么,都是由企业或开发者自己来决定的。如,复杂的金融合约的自动化。比特币可以让用户不通过第三方机构,如银行,政府等就可以直接兑换货币。但是以太坊的介入可能会产生更加深远的影响,因为任何复杂的金融操作都是可以自动被执行的,并且可以写成代码在以太坊上运行。当然除了金融外,任何情况下,只要对信用、安全、和持久有极高的要求,比如资产注册登记,投票,管理和物联网等都有可能受到以太坊平台的影响。
 
一般来说,在以太坊上有三种类型的应用。
第一种是金融应用,这包括 子货币,金融衍生品,套期保值合约,和一些雇佣合同等。
第二类是半金融应用,这里有钱的存在但也有很重的非金钱的方面;
最后,还有在线投票和去中心化治理这样的完全的非金融应用。

扩展资料:
1、百度百科以太坊智能合约开发实战
2、以太坊是什么?

免责声明:本文由信比特作者原创文章,不构成投资建议,请谨慎对待。

版权声明:信比特作者保留原创权利。文章为作者独立观点,转载请注明出处

原文链接:http://www.bitpoa.com/BlockchainCollege/48.html

生成海报
收藏

相关推荐

2021年2月份将迎来以太坊的牛市春天!(图文)

前言:从行情表现上看,以太坊似乎仍然是比特币的“跟屁虫”;然而在梳理其基本面和消息面后,我们认为,以太坊将很有可能在2月实现大爆发,走出不一样的趋势。下面,我们将一一介绍以太坊在2月即将迎来的重大利好,以及为什么越来越多机构和大户开始看好以太坊。 ...

Reddit宣布与以太坊基金会合作的思考

前言:中国已经开始在国际上布局社交网络,但是最近发生在Reddit社区的walltreetbets匿名组织公开抵制华尔街空投机构,以及取得了完美的胜利,把Reddit再次推向了公众的视野,同时,Reddit极力拥抱区块链,在uniswap上的议论热潮也推向了顶峰。 ...

关于以太坊智能合约ERC20代币精度

前言:在撰写本文时(Solidity v0.4.24),Solidity 不支持定点或浮点数。这意味着浮点表示必须用 Solidity 中的整数类型进行表示。如果没有正确实施,这可能会导致错误/漏洞。 ...

举例说明以太坊扩容方案optimistic rollup运作方式

前言:optimistic rollup是以太坊 layer 2 扩展方案中的佼佼者,既能把可扩展性的蛋糕做大,也能让你吃到 —— 至少是吃到一部分吧。大家之所以对optimistic rollup如此兴奋,是因为它及它的表亲—— ZK-Rollup,克服了侧链、 plasma、状态通道等方案都没有解决的 layer 2 难题。 ...

关于以太坊智能合约升级,编译器版本兼容性问题的介绍

前言:相信很多智能合约初级开发者,在使用以太坊生态平台进行区块链项目开发的过程中,当遇到以太坊智能合约升级了,那么对于原有的编辑过得代码,在新的编译器版本中,并不能完美兼容,经常报错,那么下面信比特技术人员,分析具体原因,对于以太坊升级后,智能合约兼容性问题进行拆解。 ...

以太坊技术开发课程02:深入学习以太坊区块叔伯块及挖矿奖励分配(图文)

前言:以太坊生态优于比特币系统,同时为了区块链项目的应用落地,在出块时间做了很大的调整,这样子提高了TPS吞吐量,同时,也给矿工挖矿带来了一些负荷,因为出块时间的缩短(比特币系统为10分钟左右出块),势必会让矿工同时挖到相同的区块,如果不对这种逻辑进行优化,对于矿工来说是不公平的,所以,以太坊叔块就产生了,下面,让我们来详细的讲解关于以太坊叔块的概念和怎么样解决矿工奖励的问题,进行分析讨论。 ...

0 条评论

微信扫一扫

微信扫一扫

微信扫一扫,分享到朋友圈

第七章以太坊工作原理:虚拟机、账户、状态函数及应用