以太币:昨天和比特兄重点讲了以太坊的状态转换函数。今天让我们再看看代码的执行和挖矿。
比特币:行。你们确认创建了一个更有意思的家伙。
以太币:以太坊合约的代码是用低级的,基于堆栈的字节代码语言写成。叫做以太坊虚拟机代码或者EVM代码。代码是由代表操作的一系列字节组成。一般来说,代码的操作是一个连续执行操作的无限循环。每一次操作程序计数器(从零开始)增加一步,直到代码执行完毕或者返回一个错误,操作可以防访问三种数据存储空间。
比特币:具体是哪三种了?
以太币:第一种堆栈,一种后进先出的数据储存,价值可以入栈出栈。第二种是内存,无限扩展的字节列队。第三种是合约的长期储存,也是密钥/价值的存储,存储价值会长期保存。它不像堆栈和内存是计算结束以后重设。代码也能进入价值,发送者,即将进来的数据信息和区块头数据。代码也能返回一个字节列队的数据作为输出。
比特币:这些设计都很合理。
以太币:比特兄你或许想不到EVM正式执行模型非常的简单。当EVM运行的时候,它所有的运算状态可以被定义为元组(block_state,transaction, message, code, memory, stack, pc, gas)。Block-state是包含所有账户的余额和存储的全局状态。在每一轮的执行开始时,当前指令被找到通过调出第pc个字节的代码,每个指令对于怎么影响元祖有它们自己的定义。
比特币:确实很简单。比如ADD将两个元素出栈并将他们的和入栈,减少一个能量增加一个pc。SSTORE将顶部的两个元素出栈,然后将第二个对象按照第一个对象的指引放入合约存储。尽管有许多方式通过即使编程去优化执行,但以太坊的基础实施能用几百行代码完成。
以太币:是的,比特兄的例子解释的更清楚了。接着我们来说一说挖矿吧。
比特币:好的,这也是非常关键的步骤。
以太币:先说底层的区块链吧,其实和比特兄你的区块链有很多相似的地方,但还是有一点点不同。最大的不同就在于架构,比特兄你的只是包含交易信息。而以太坊的既有交易信息,也有最近的状态,区块序号和难度值。以太坊的区块确认算法有8个步骤。
比特币:嗯,你的区块丰富了这么多信息。我看看是怎么共识挖矿的。
以太币:第一步检查区块引用的上一个区块是否存在。第二步看区块的时间戳是不是大于上一个区块,时间要小于15分钟。第三步检查区块序列,难易度,交易根,叔根和能量限制(不同的以太坊底层特有的概念)是否有效。第四步看区块上面的工作正式是否有效。第五步将S[0]成为上一个区块的STATE-ROOT。第六步让TX成为区块的交易列表,一共有n笔交易,对于属于属于0……n-1的i,进行状态转换S[i+1]= APPLY(S[i],TX[i]),如果任何一个应用发生错误,或者程序执行到此处所花费的能量超过了能量限制,返回错误。第七步让S_FINAL为S[n],但是增加要支付给矿工的奖励。第八步是看默克尔树根里面,由区块头提供的最终状态树根是否等于STATE_ROOT。如果是,区块有效。如果不是,区块无效。
比特币:过程很详细,非常清晰。但是比我们的就要复杂一些了。
以太币:第一眼看这些操作感觉好像非常没效率,因为每个区块都需要储存整个状态。事实上效率可以和比特兄你的区块链相提并论。原因是状态存储在树结构中,每增加一个区块只用修改树上很小的一部分。因此,一般来说,两个相邻区块树的主体大部分都是一样的。数据储存一次,可以利用指针(子树哈希)引用2次。一种被称为Patricia tree的树就被用于完成这个功能,它还包含了对默克尔树概念的修改,这个概念允许节点插入和删除,不仅仅是改变。另外,因为所有的状态信息是最后一个区块的一部分,储存整个区块链的历史是不必要的。这个方法如果比特兄你也像应用的话,经计算可以节约5-20x的空间。
比特币:好建议,但要去问问本聪兄才行。
以太币:我经常被问到合约的代码是在哪里执行?这里有个简单的答案,执行合约代码的过程是状态转换功能的一部分定义。也是区块有效算法的一部分。如果一个交易被增加到区块B,代码的执行就被交易孵化,交易会被所有的节点执行,现在和未来,可以下载和正式区块B。
比特币:好吧,整个原理已经清楚了,现在就看能应用在哪些领域了。
以太币:明天开始我们详细说说应用。
比特币:没问题。
参考阅读
https://ethfans.org/posts/ethereum-whitepaper
https://github.com/ethereum/wiki/wiki/White-Paper
领取专属 10元无门槛券
私享最新 技术干货