如果问一块显卡它最恨什么,那么答案一定是以太坊。
以太坊,矿工为之疯狂,显卡为之颤抖,游戏玩家为之骂娘。
然而,除了购买矿机、连接矿池、卖币套现之外,是否有人关注过以太坊的奖励机制呢?
且听我慢慢道来。
临时分叉
区块链由于是一种去中心化的技术,全世界所有的矿工同时工作,各自独立的挖掘满足要求的区块。由于是各自独立的工作,就有可能出现两个独立的矿工先后发现了两个不同的满足要求的区块,就像下面这种情况,被称为临时分叉。
注:箭头指向某区块代表它保存了前一个区块的Hash
两位矿工都发现了高度2的区块,那么该采用谁的呢?
于是撕逼开始,区块链是个势利眼,只承认最长的链,黄色和绿色的区块谁先有后继区块,变成最长的链,谁就会被承认,失败的就会被抛弃。为了成为最长的链,两个矿工都拼命的把自己挖到的区块通过广播的方式告诉更多的节点,并希望他们能把自己的区块传播得更广,从而使更多的矿工在自己挖出的区块下挖掘下一个区块,最终让自己的区块变成最长链的一部分。
然而,胜利者只有一个,胜利者写历史,失败者将被抛弃,其中的交易会重新被打包到之后的区块中。下面这张图就是绿色区块获得了胜利,黄色区块成为孤儿区块,被抛弃。
这种事其实每时每刻都在上演,并不罕见。区块如果被废弃了,其中包含的挖矿奖励怎么办呢?对比特币来说,赢者通吃,失败者一无所有,竹篮打水一场空。挖出黄区块的矿工心都要碎了,他在哭泣?。
叔块(Uncle Block)
以太坊创造了一个新的名词叔块(Uncle Block)。对高度3的区块来说,绿色区块是他的父区块。黄色区块虽然失败了,但好歹也是高度1的区块的子区块,绿区块的兄弟区块。于是,高度3的区块就尊称这个黄区块为叔叔,叔块就是这么得名的。
注意:虚线部分仅仅用来陈述关系,不表示有实际连接。
不能成为主链一部分的孤儿区块,如果有幸被后来的区块通过uncles字段收留进区块链就变成了叔块。如果一个孤儿区块没有被任何区块收留,这个孤儿区块还是会被丢弃,不会进入区块链,也就是说孤儿区块被收留后才会变成叔块。
以太坊的设计比比特币人性的多,叔块也是可以获得奖励的,矿工们再也不用担心白忙乎了。而且以后的区块谁要是把叔块收留了,收留了叔块的区块还有额外的奖励,收留叔块也被称为包含叔块。
下图就是高度3的区块包含了一个叔块,不过叔块也就仅仅是被包含而已,叔块中的交易会重新回归交易池,等待重新打包。一个区块最多只能包含2个叔块。
以太坊为什么要这么设计呢?因为以太坊的区块时间是20秒左右,相对于比特币,更容易出现临时分叉和孤儿区块。而且较短的区块时间,也使得区块在整个网络中更难以充分传播,尤其是对那些网速慢的矿工,这是一种极大的不公平。为了平衡各方利益,才设计了这样一个叔块机制。叔块在全部挖掘出来的区块中占的比例叫叔块率,目前叔块率在9.7%左右。
数据来源:The ethereum blockchain explorer
驱动着程序运行的汽油(Gas)
以太坊是一个运行智能合约的去中心化平台,提供了一个以太坊虚拟机(Ethereum Virtual Machine),简称EVM,开发者可以在其上开发各种应用。你可以把这个EVM想像成你的电脑,它能够运行一些以太坊定义的指令。与比特币的脚本引擎不同,以太坊的EVM功能非常强大,号称“图灵完备”。先不管什么是“图灵完备”,你只要知道“图灵完备”的虚拟机可以实现循环语句,有了循环就一定会有小坏蛋或者不合格的程序员弄出死循环,电脑死循环了大不了死机,重启就好,不过以太坊是去中心化的,EVM要是死循环了,可没法重启。
有没有办法能解决这个问题呢?
很遗憾,这个问题很多年前就有人研究过了,叫图灵停机问题(The Halting Problem),已经证明不存在一种能够检测程序是否会死循环的方法。
既然不能检测,还有没有别的方法阻止死循环呢?
在加油站加油的空闲,以太坊的开发者们陷入了沉思,自言自语道:为什么汽车不会一直暴走停不下来?“因为会没油!”加油的师傅边拔出加油枪边说。
这个故事只是我自己脑补的,增加点儿趣味性。
如果让EVM上的程序的每条指令都要消耗一点儿“资源”,“资源”用光了,无论程序执行完没有,都会被强行终止,这样无论是不是死循环都没关系了。
这个执行程序时要消耗的资源就被称为汽油(Gas),每一条指令都要消耗不同数量的汽油。
举几个例子:
- ADD:加法操作 3Gas
- MUL:乘法操作 5Gas
- SUB:减法操作 3Gas
- DIV:除法操作 5Gas
- HASH:计算哈希值 30Gas
越复杂的运算,需要消耗的Gas越多,只要给程序加上一个消耗Gas的上限,就可以防止程序出现死循环而不能停止的情况了。同时,以太坊还给每个区块包含的程序消耗的总Gas设定了上限,以免区块中包含的程序过多,影响一些性能比较弱的节点。每个区块能消耗的Gas上限也是可以调整的,由矿工们进行投票决定,目前是6725538Gas,也就是下图中的GAS LIMIT部分。
汽油在现实生活中不是免费的,在以太坊中也不是,要用以太币购买Gas。每个程序都会给出他们愿意用多少以太币购买1单位的Gas,这被称为汽油价格(Gas Price)。
每个程序需要为Gas支付的以太币可以用如下公式计算:
Gas花费 = 消耗的Gas数量 x Gas的价格
你愿意支付的Gas价格越高,你的交易就会越快被矿工打包,这和比特币的交易费很类似。
以太坊的区块奖励
前面介绍了叔块和Gas,下面进入核心部分,以太坊的奖励机制。前面已经说过了,以太坊的区块有两种,普通区块和叔块,我们需要分情况来讨论每种区块的奖励。
普通区块奖励:
- 固定奖励5ETH,每个普通区块都有
- 区块内包含的所有程序的Gas花费的总和
- 如果普通区块包含了叔块,每包含一个叔块可以得到固定奖励5ETH的1/32,也就是0.15625ETH。
叔块奖励:
叔块的奖励计算有些复杂,公式为:
叔块奖励 = ( 叔块高度 + 8 - 包含叔块的区块的高度 ) * 普通区块奖励 / 8
实践一下
首先感谢一下
是他让我知道了一个很好的以太坊区块浏览器Ethereum Blocks Information,这个浏览器可以很详细的查看每个区块的奖励。
我们来看一个刚挖出来的区块4222300,由于我们是在主链上看到它的,所以它是普通区块。
它的奖励包含三部分:
固定奖励:5ETH
Gas总花费(也有人称之为交易费):0.281837168043699381ETH
将两个叔块包含进来的奖励:5 * ( 1 / 32 ) * 2 = 0.3125ETH
这里有一点要注意,官方文档中的原文是“an extra reward for including uncles as part of the block”,我在2015年刚接触以太坊时不少网上的文章直接说成了“包含叔块奖励”,使我误以为是得到与挖掘出这些叔块得到的奖励等同数额的奖励,也就是上图中的Uncles Reward:8.75ETH,这是错误的,“包含叔块奖励”指的是将叔块包含进区块链这个行为的奖励,希望大家能够避免踩进这个坑。
我们再来看一个叔块0x1c2cbba0403f1079dcdb70e5971a87ce0fbc03d4572be30e2d17e4e4a0f136d5,是不是看着挺别扭,叔块不方便用高度来表示,因为同一个高度上已经有了个主链区块,就是这么惨。其实叔块也是有高度的,叔块的父区块的高度+1就是叔块的高度。
直接代入公式:
( 4222271 + 8 - 4222272 ) * 5 / 8 = 4.375ETH
题外话
奖励机制就说到这里,细心的读者有没有发现前面挖了个坑:
- “每个区块能消耗的Gas上限也是可以调整的,由矿工们进行投票决定”,这个投票调整的过程是怎样的呢?
为了不让这篇文章太长,给大家的阅读造成不便,先卖个关子,以后我会慢慢把这些坑都填上的。以太坊真的是一个很好的平台,也在快速发展着,希望大家能够关注它、了解它、驾驭它,而不是炒作它并最终毁掉了它。