Skip to content

Latest commit

 

History

History
83 lines (43 loc) · 12.4 KB

File metadata and controls

83 lines (43 loc) · 12.4 KB

公链激励

对于公链来说区块链系统是一个典型的经济系统,参与区块链网络的节点通过贡献算力来获得奖励,与此同时也增强了整个区块链系统的安全性和稳定性。可以把每一个节点都当做理性经济人来看待,节点有自利的一面,其个人行为会按自利的规则行为行动;如果能有一种制度安排,使行为人追求个人利益的行为,正好与区块链要实现集体价值最大化的目标相吻合,这一机制的设置就是“激励相容”的。

对于联盟链或者私有链来说,由于共识机制和服务范围的不同所以节点间并不需要激励机制,其更多的是作为企业信息系统的组成部分,需要企业投入人力物力维持系统运转,通过运行在链上的具体业务来创造价值。

公链共识与激励相容

通过对之前比特币和以太坊挖矿过程的介绍可以看到算力的提高对于区块链系统的安全性和稳定是很有益处的,但是每个节点作为一个理性人都有自私的一面。作为参与区块链系统的一个节点或者矿工是倾向于利用一些有利于自己的规则来提高自己在区块链系统中所获得收益的。

如果缺乏有效的手段,节点在挖矿的过程中就会采取一系列的策略来提高自己的收益,在提高收益的同时可能会破坏其它节点的利益以及整个区块链系统的安全性和稳定性。这些破坏区块链安全性和稳定性的的策略并非是节点恶意所为,而是节点在发现“激励相容”机制不合理之后的理性反应。所以在设计激励机制时要慎之又慎。

矿池

在公链全网算力提升到了一定程度后,单台机器挖到块的概率变得非常的低,这对于计算能力弱的矿工来说非常的不友好,获得的收益变的非常不稳定,为了避免这种现象就出现了矿池。矿池集合了大量的矿工使得每个矿工获得挖矿的平均收益从而避免了挖矿收益的不稳定性。

矿池目前有两种组织形式,集中托管式矿池和分布式矿池两种。

  • 集中托管式矿池,矿工可以把挖矿的机器托管给矿池,由矿池统一操作维护,只需要支付一些电费管理费即可,这样就避免了私自广播。
  • 分布式矿池,矿工将机器自行管理,通过矿池协议从网络连接矿池即可,这样就会出现私自广播的可能。

矿池组织大量的矿工挖矿面临很重要的一个问题就是,如何把高难度计算哈希的任务拆解成相对简单的任务发送给单个矿工完成。回顾之前挖矿难度的计算,可以简单的认为前面0的多少表明了挖矿的难易。

0越多,挖矿难度越高,为了降低挖矿难度我们就要增加挖矿哈希0的数量,举个例子:

假设挖矿目标值0x000abc,只要满足这个值就可以打包区块获得挖矿收益;降低挖矿难度为 0x001abc,发送给矿工,矿工只要计算区块头满足这个相对低一点的难度就可以得到一个分片(shared),但是单个矿工挖到这个简单难度的块是无法发布到整个网络中的,但是矿池可以把这个分片记录下来,作为以后给这个矿工奖励的凭证。

0x001abc是0x000abc的子集,只要子集足够多总有一个会满足目标值。 当有一个矿工挖出一个满足目标值之后就可以获得挖矿收益,而挖矿就可以根据矿工分片多少来获得收益,所以就有了一个矿工获得挖矿收益的公式矿工收益 = 区块奖励 / 提交分片的数量

目前矿池对每个分片收益的结算方式主要有:按比例分配(Proportional),根据过去的N个分片来支付收益(Pay-Per-Last-N-Shares,PPLNS),立刻为每个分片支付收益(Pay-Per-Share,PPS)三种。

1)按比例分配(Proportional)模式

按比例分配模式是矿池分配奖励最简单的办法,在采用按比例分配方式的矿池中,矿池每一次挖矿成功后都会将奖励按照矿工在这个过程中提交的分片数量所占比例分配给矿工。因为只有在矿池成功挖到区块后才能收到奖励,所以矿工的收益也会具有一定的不稳定性。

2)PPS模式

PPS模式为立即为每一个分片支付报酬。该支出来源于矿池现有的比特币资金。因此可以立即提现,而不用等待区块生成完毕或者确认。这样可以避免矿池运营者幕后操纵。矿池相当于一个中间商,承受了由矿工转移过来的风险,对于矿工来说却可以获得稳定的收益。

在PPS模式下,矿池的管理者首先会根据所有矿工的总算力在整个区块链网络中的占比估算出每天可能挖到块的数量,然后再根据矿工总算力估算每天可以收到可以收到分片的数量,最后就可以计算出每个分片所对应的奖励。一旦计算完成后这个奖励在一定时间内就不会变化,当矿工提交一个分片时就可以立刻获得分片收益。

举个例子:假设你的算力是100M,而整个矿池的算力是10000M,那么你就占据了矿池算力的1%。然后,假设矿池根据当前的难度和全球总算力,估算出矿池一天大约能够挖到4个区块,假定数量为100个。那么,矿池会为你每天支付全矿池1%,也就是1个币的报酬。这样,即使矿池今天只挖到1个区块,你也是获得1个币(矿池亏本)。如果矿池超额发挥,挖到了10个区块,你还是只有1个比特币的收益(矿池大赚)。

实际上在PPS模式下矿池所面临的风险就是将整个矿池视为一个矿工进行个体挖矿时所面临的风险,因此PPS模式下矿池往往会收取较高的手续费来规避其风险。

3)PPLNS模式

在PPLNS模式下矿池会选择一个时间段,在这个时间段内无论挖到多少区块,奖励都会分配给那些提交了分片的矿工,在PPLNS模式下,运气成分就会非常重要。如果矿池在一段时间内能够发现很多区块,那么大家的收益会非常的多。如果矿池一天下来都没有发现区块,那么大家当天也就没有任何收益。

同时,由于PPLNS下,具有一定的滞后惯性,你的挖矿收益会有一定的延迟。比如说,你加入到一个新的PPLNS矿池,这个时候你会发现前面几个小时的收益比较低。那是因为别人在这个矿池里已经贡献了很多个分片了,你是新来的,你的贡献还很少,所以分红时你的收益都是比较低的。随着时间的推移,该结算的也结算了,大家又开始进行了新一轮的运算时,你就回到和别人一样的水平了。同样道理,若你离开了PPLNS矿池不再挖矿,你贡献的分片还在,在此后的一段时间里,你依然会得到分片收益,直到你的分片被结算完毕。

挖矿风险

对于矿工来说更加关心的是分片结算的机制,以便根据自己的情况选择适宜的矿池获得最大的收益,而对于矿池来说除了设计合理的机制保证可以吸引大量矿工加入外,就需要防止恶意的矿工对矿池或者其它矿工利益的破坏。

1)私自广播

对于矿工来说有这样一种场景,当自己挖到的分片是不符合难度要求的就提交给矿池,当符合全网难度要求的时候就不发给矿池分享收益,转而私自广播到网络中独吞收益。这样既可以分享诚实矿工挖矿的收益还可以额外的独享自己的挖矿收益。如果出现这种情况,并且被大量的矿工知晓那么矿池就无法组建起来,每一个诚实矿工都不愿无偿分享自己的挖矿收益。

以比特币挖矿为例,每一个有效的区块除了包含正常用户发来的有效交易外还包含一笔铸币交易(coinbase),铸币交易的output字段指明了获得挖矿奖励矿工的地址,矿池可以把铸币交易的output字段设置为矿池的地址,然后随机生成一些coinbase data的填充后生成区块头的默克尔树,最后发由矿工去尝试目标值。通过这样的方式,即使矿工找到满足条件的哈希值,铸币交易的地址也是矿池的地址,私自广播区块没有任何收益。如果调整了铸币交易的地址,就又回到了独立挖矿的场景,这样就可以避免矿工私自广播区块的情况。

2)私自挖矿

私自挖矿的情况不仅矿工可能发起,矿池为了自己的利益也有可能发起。自私挖矿也是扣块攻击的一种,具体的方式是在某一段时间的挖到新的区块后暂时不向区块链网络广播出去,即“扣块”,等到合适的时机在广播全部的区块。这种行为的目的并不是要破坏区块链网络本身,而是为了获得更多的利润。

由于区块链网络的去中心化的特点,当一个新的区块产生后在区块链网络中进行传播是有一定的延时性的,每一个节点或者矿工接每次接收新区块的时间都是不一样的,距离挖出新区块的节点越近就会越早的收到新区块。因此当两个新区块在差不多相同的时间被挖出进行广播时就会产生分叉,一部分节点接收到了第一个新区块,另一部分节点接收到了第二个新区块。这个时候每个接收到新区块的矿工都会在自己的分叉上进行挖矿,直到其中一条分叉上有一个新区块被挖到从而成为主链为止。

当矿工或者矿池发现这个漏洞以后就会通过一定的方式来保证自己的那部分分叉成为主链来扩大自己的挖矿收益,在自己成为主链的同时还会消耗诚实矿工的算力在挖掘废弃区块上,这样还会提高自己在区块链网络中有效算力的比例来获得超额收益。

这种私自挖矿的行为本质上是发起者与其它矿工的算力比拼,私自挖矿的矿工期望通过对新挖到区块的暂时隐藏来获得高于自己算力的平均收益。

3)挖空块

当一个区块只包含区块头而区块体为空时称为空区块,矿池或者矿工生成空区块的行为称为挖空块。当矿池或者矿工生成空块时,只能获得铸币交易的奖励,因为区块中没有打包交易所以无法获得交易费奖励。每个节点作为一个理性人,放弃获得交易费用打包空块必然有其合理的原因。

在PoW挖矿机制下,每次生成一个新区块前首先需要获得系统发布的目标难度,并且当高度为H的区块被挖到广播到区块链网络之后,所有矿池才会在当前高度为H的基础之上开始挖高度为H+1的下一个区块。构建一个新区块需要包含区块头和区块体,区块头中有包含高度为H区块的哈希和Nonce值,根据前文我们知道一个区块在网络中的广播过程是分为两个部分的,广播区块头和广播区块体,并且区块头由于体积小只有80字节,一般是会更快的被矿工接收到的。矿工接收到区块头后并不能立刻开始挖H+1个块,因为需要交易H个区块里包含的交易是否有效,同时自己挖H+1区块的时候也需要剔除H个区块中所包含的交易,为了做到这两点就需要等待区块体传输完成,但是在这个时间里矿池巨大的算力是停摆的,而挖矿的竞争十分激烈,大型矿池不是争分夺秒,是争毫秒夺微秒,停摆会带来很大的损失。

在这种情况下矿池最合理的做法是是利用区块传输的这段时间,继续寻找到下一个块。方法是只要发现了新的区块发布,矿工可以在没有拿到块N完整数据时,只进行最简单的验证,先拿到区块N的哈希值,直接跟在后面继续HASH。继续挖矿的过程中为了避免两个区块打包了相同的交易在后续挖H+1区块时就不包含区块体,直接打包空块。

如果区块体1M在6秒传输完成,每个比特币区块的出块时间约为10分钟,那么在比特币网络中出现空块的概率就在1%左右,空块对比特币网络来说也没有带来积极的意义,只是矿池为了自己利益的一种理性选择。

事实上,解决空块问题是有办法的,空块的核心是挖空块时,不敢打包交易,以防止这些交易在上一个区块中出现过。那就构造一些不可能出现在上一个区块上的交易就可以了。比如自己找一些零散的UTXO来整合,比如和交易所合作,交易所使用IP到IP提供一些交易,这些交易不被广播,只可能出现在挖空块的矿池里,这样空块就不会“空”了。