本文是对区块链的一种恶搞。
当然,说是说恶搞,恶搞的是实现手法,而不是目的。
目录
- 为什么是区块链
-
恶搞块
- 记账
· 分区选举 - 提成
- 挖矿
- 阶段性小结
- 惩罚
- 第二矿脉
- 遗忘重铸
- 记账
为什么是区块链
区块链是为了解决无中心、无信任网络上的信息共享而发展出的一套方案,而且是众多可选方案的一种。
与无中心、无信任的信息共享网络相比,区块链的主要特征是引入了延时确认,即并不是所有数据修改请求都会被实时地提交确认,而是会延时进行。延时的时间段内的所有请求都会被存起来,而确认的时候打包成一个区块,加到已经被确认的所有区块中,构成一根全网唯一的链条。
所以,区块链就是一种无中心、无信任网络上的信息延时确认共享方案。
当然,由于CAP原理,你要在一个节点可能掉线可能变节的网络上做到有效的共识与可用,基本都会是延时确认提交的,所以这里怎么细分并不是特别重要。
它的主要核心有这么几个部分:
- 安全的散列函数;
- 全网时间戳方案;
- 非对称加密算法;
- 点对点信息传输方案;
- 共识机制;
- 分布式信息存储。
前四条是底层基础,后两条是核心,而延时提交体现在共识机制中,也是分布式信息存储的一种形式。不同区块链实现与不同的无中心网络实现可以选择不同的函数与方案。
传统的共识方案是PBFT,即为了解决一个可能出现掉线或者变节的网络上的拜占庭将军问题[1]而提出的确定性算法——实用型拜占庭容错方案。
而后,有一个数学家Back,为了解决垃圾邮件的问题而提出了PoW算法(事实上是一个框架体系),即工作力证明(Proof of Work)[2]。
如果说PBFT是通过一套协议最终使少数服从多数成为可行的选择进而解决数据正确性的纷争,那么PoW的思想是压根不去解决这个问题,而是选出一个满足工作力证明条件的节点大家都来听他的。
举例来说,PBFT是101个人里谁的提案能获得绝大多数人的支持(三分之二)则谁的提案是最终提案,那么PoW就是所有提案者一起赛跑谁先跑到终点就听谁的。
很简单粗暴,但也很有效。
简单来说,工作力证明及其衍生品,主要做两件事:
- 争夺记账权;
- 证明区块中数据的正确性。
第二点是因为生成的工作力证明是与生成时区块内的所有数据相关的,从而验证该证明的同时,也就校验了区块内的数据,只要数据有变动,那么该工作力证明就变得无效。
让我们想一下,假如有人要篡改数据,那么他需要编造一条新数据后,重新通过工作力证明,因为没有这个证明全网的节点不会认可;而要通过工作力证明,他就需要消耗计算力,而且还要比别人先完成工作力证明,完成以后还要全网的节点都认同(区块链不管是哪套实现方案,都采用最长链确认原则),所以这个代价就很大了——有这么多的算力你去干什么不好。
后期的PoS、DPoS等共识机制,都是对PoW方案的优化与调整,试图解决PoW浪费计算力的问题,数据修改请求的确认过慢的问题,等等,这里就不一一介绍了。
当我们用基于PoW之类的共识机制而成的区块链方案来做为电子掌簿的底层实现时,每次生成新的区块就是完成记账,每次获得生成新区块的权力就是获得记账权,但争夺记账权需要消耗大量更多算力来做工作力证明,从而为了鼓励更多的人参与其中,你做出了工作力证明就给你一定的奖励——这就是这一类电子货币中的“挖矿”。
下面,让我们来恶搞一种新型的区块链:恶搞块。
恶搞块
恶搞块中,我们把用户分解为三类:
- 用户;
- 掌簿;
- 旷工。
一个节点可以同时是这三个角色,也可以只作为一个角色存在。
所以这样的一个系统是一个角色体系,而不是全同体系。
下面先从记账开始玩起。
记账
PoW的问题就是浪费计算力,从而不“环保”,这个已经是业内共识。
基于PoW,有人提出了PoS,这个就环保了很多。其中最有趣的一个PoS方案,是素数币PrimeCoin,它的共识机制不是工作力证明,而是看谁先找到下一个素数。
由此可见,这个浪费的计算力其实可以用来做很多事,比如给科研社区做区块链应用的话,共识机制可以是格点计算,比如SETI@Home这种寻找外星人信号的,或者寻找蛋白质折叠形式的,寻找某种病毒对应的抗素的,寻找地外行星或者暗物质分布的,等等等等。
格点计算的一个好处,就是完成工作量可以明确地度量,所以可以用来代替工作力证明。但它也有一个明确的坏处,那就是在解的模空间中,解所代表的点的位置分布是不均匀的,所以你无法知道下一次出区块是什么时候,也不知道你挖的这个搜索空间里到底有没有区块。
让我们换一个思路——不浪费计算力的一个方法,是把算力化为有用的东西,比如上面说的格点计算;但还有一个方法,那就是真的不用花那么老多的算力。
比如PrimeCoin的提出者提出的另一种基于PoS的共识机制NXT,它就不需要大家花什么算力,你完全可以预先知道下一次你能掌握记账权是什么时候,不用瞎算。
我的方案很简单:猜拳。
具体来说是这样的:
- 系统中要有一个非对称公私钥对的生成器;
- 每个用户都根据当前收到的所有待提交请求(其实是这些请求构成的Markle树[3]的根节点值,一个哈希值)与一些必要的元数据(比如上一个区块的哈希,以及时间戳)一起,加上一个随机值,一起构造一个哈希,记为投票H,这个行为记为“出拳”;
- 节点们每过一段时间T,就对所有节点提交的投票H做一次拼接,然后取哈希,记为平均哈希X;
3.1 如果一个节点给出了多于一次出拳的数据,则以时间戳更大的为准; - 利用X,我们将每个节点i的出拳结果H_i与X的差Abs(H_i-X)做一个降序排列(万一两个节点的该结果相同,则H_i较大的那个排序靠前),最小的那个为本轮记账的主掌簿,第二小的那个为次掌簿;
- 主掌簿将它所记录的所有数据记为有效数据,利用公私钥生成器生成一个私钥与一个公钥,用私钥对数据加密后销毁私钥,然后将加密好的数据与公钥一起作为新的准区块,生成所需的元数据,做哈希,交给次掌簿;
- 次掌簿核先用哈希校验数据,然后用公钥阅读数据并校对,校对无误后,将准区块中除了主掌簿生成的哈希外的所有数据,连同自己这次生成的公钥一起,作为新的区块,做哈希,全网广播。
6.1 如果次掌簿校验发现数据有问题,则通知所有参与猜拳的节点本次猜拳无效,重来一次;
6.2 如果全网广播新区块后,有节点发现自己的记录有部分比新广播的区块中记录的继续要新,则自动移到本身的新候选区块中,并将这些记录做广播;
6.3 如果全网广播后,有节点发现自己的记录与新区块中的记录冲突,则以新区块中的记录为准;
6.4 如果两个节点同时认为自己是获得记账权的(这种情况在多分区模式下可能出现),则以更长的链为准;如果链一样长,则以更多记录的为准;如果记录一样多,则以最晚发生冲突的区块为准;如果连这个都一样,那就待定吧。。。下一轮采用少数服从多数。
PoW的方式是寻找一个哈希,它小于某个特定值,从而提高算力可以寻找更多的哈希,提高自身找到满足条件的哈希的概率。但在猜拳方案中,你并不需要也不可能为了某个特定的目标而消耗算力,因为你也不知道这个目标是什么,只有当全网都提交猜拳结果后,你才知道目标值是什么,但此时因为你已出拳,结果已经无法更改。
因此,对于参与到掌簿猜拳环节的节点来说,耗费计算力去算哈希是无意义的,因为你根本不知道你要的哈希应该满足什么条件——只要我们选择的散列函数在值域上的分布足够均匀,那么高算力节点相对低算力节点而言根本没有任何优势。
而主掌簿和次掌簿的设置,主掌簿确认哪些数据有效,并和次掌簿一起做加密——除非这两个节点串通好,否则主掌簿或次掌簿都无法对数据进行修改。而规则4则保证了这样的节点的产生是随机的,高算力节点组无法垄断主次掌簿。
从概率上说,如果网络中有N个人,而一个人控制了k的节点,那么他同时掌握主次节点的概率为k(k-1)/N/(N-1)
。假定网络中有10000个节点,而一个人控制了100个节点,那么它同时掌握主次掌簿的概率不到万分之一。
事实上,规则4还可以拓展,设置一个全网参数来控制次掌簿的数量——当然,代价就是校验次数增加,从而记账时间延长。
这套规则的特点,就是彻底摆脱算力绑定,对记账权的争夺更加随机——这也是它相对NXT的优势,NXT中下次记账到底谁来记其实在上一个区块生成的时候基本上就确定了,没有什么随机性,除非在你之前的节点都掉线,否则你如果不是第一顺位那就根本没有机会。而在猜拳方案中,每个节点都有机会,人人平等,更加符合中本聪所提倡的“人人平等”的理念——而且因为摆脱了算力捆绑,所以其实比比特币所以来的PoW共识机制的区块链更符合中本聪的理念。
同样的,如果我们将猜拳共识方案下的区块链作为电子账簿,那么其上的恶搞币自然可以给与主次掌簿们记账时的收益,这个收益规则下面再说。
其次,节点可以根据数据变更请求的发生频次来调整局部猜拳的频率,比如每100次交易就进行一次猜拳,或者虽然100次交易没到但时间已经到了1分钟也进行一次猜拳。猜拳请求发出后,需要询问所有相邻节点是否同意猜拳,而邻节点判断自身记录中的上述两个条件是否满足,以及不满足的偏差量有多大,是否在5%的可接受范围内,在的话就同意猜拳,并以此类推。当全网节点都一致意见(比如基于PBFT)后就开始进行猜拳(都PBFT了为什么还要猜拳???)。关于猜拳的一些更加有趣的问题,在后面的章节中展开。
此外,由于现在记账与挖矿分离,所以单独调节记账的频率不会影响挖矿出币的速率,因此高频请求就与发币速率脱离,这点有利于高频交易的发生。
现在共识和记账权靠猜拳来决定,这已经是一个恶搞的地方了。
但由于数据量可能会过大,所以我们在猜拳基础上,还可以引入分区选举掌簿的方法。
分区选举
猜拳共识的一个问题,就是后期校验的时候会有问题,因为目标哈希X需要所有猜拳的人的结果都拼在一起才行,所以如果人多比如几百万的话,那么一次猜拳的数据量就会非常大。
而如果不做全量数据保存的话,那就无法确认目标哈希X是多少,从而也就无法判断一笔传播而来的记录到底是不是合法记录。
一个解决方案,是使用分区制。
通过随机连接后重组的方式,可以在全网建立起若干独立的分区,这些分区可以较小,在其中进行全量猜拳数据的核对,然后分区主次掌簿确定了本分区的区块后,主掌簿们一起作为一个集体,进而第二次分区,选出第二级的主次掌簿,一直到最顶层,被最终确定下来,然后从最顶层分区的主掌簿开始全网广播,被全网接受。
全网接受的时候,根据广播中的逐层猜拳数据进行掌簿权限确认,此时就可以使用自己所在层的分区中的数据进行确认。等几轮过后(一般三轮就足够了),这些数据就可以清除,而只保留猜拳目标哈希X。
下面我们来看一下挖矿与提成。
提成
比特币等虚拟币的另一个问题,就是矿工的收益。
比特币的初衷当然是好的,人人平等地争夺记账权,然后获得记账权的就可以获得相应的收益(一个是区块中所有交易的记账提成,一个是获得记账权的挖矿收益)。
但这里有两个问题:
- 挖矿的方式会导致马太效应;
- 挖出来的新币并不贴合全网的流通性需求。
第一点很好理解:我挖到了币,那么我自然可以购买更多的设备,提高算力,从而我就有计划挖到更多的币;而如果你没有挖到币,那么算力的提升就有限,甚至无法提升算力,那么你就在挖矿行为上竞争不过我。
NXT这种不依赖算力的方案当然可以解决这个问题,PoS等方案也在调节挖矿难度——但PoS1.0与矿工的币龄有关,PoS2.0与矿工的余额有关,PoS虽然在调节挖矿难度,但和算力增长相比,要么无关,要么正相关,从而都加剧了马太效应。
使用猜拳当然可以做到算力与出币概率无关,所以是一个候选方案。
第二个问题则在于,无论是比特币还是别的虚拟币,出币速率都是时间的固定函数。比特币是每10分钟出一次币,原本是50个比特币,此后每过一段时间减半,最终流通货币总量有限。
但,你看,出币速度和市场需求是脱节的——也就是说,市场如果要的流通性为X,市场上所有可流通货币总量Y,那么Y单纯地只是时间t的函数,而和X完全无关。
举例来说,我们用比特币来购物,一开始用来购买披萨和可乐,10个比特币对一个披萨,一个比特币能买一罐可乐,全网100个人,每人每天买一个披萨两罐可乐。那么,一天的交易所需要的比特币,也就不过是120个比特币。而今天一开始有100个比特币,后来每10分钟出产10个比特币,到第二天的时候,全网已经有244个比特币,已经流通性过剩。但第二天还是这100个人,还是每人一个披萨两罐可乐,需要的比特币依然只有120个,可第二天一早全网流通的比特币是244个,到了晚上的时候已经是388个了。流通性需求没有增长,但可流通货币总量却无视需求,达到了需求的三倍。
这就是供求关系脱节的体现。
我们当然可以说,这样比特币就贬值了,应该30个比特币买一个披萨,3个比特币买一罐可乐——那这就是通货膨胀了啊。
而如果某一天,突然一大波便利店都加入了这个网络,你不单能买披萨和可乐,还能买肯德基麦当劳雪碧美年达,每个人每天要用的比特币从12个变成了72个,使用比特币的人也从100个增长为1000个,那么一天对比特币的总需求就从本来的120变成了现在的7200。但此时比特币总数还是244个,到了晚上才变成388个,显然严重无法满足需求,此时就是流通性不足——我们也可以认为此时物价应该下降,比如应该0.5个比特币买一个披萨,0.05个比特币买一罐可乐——这可不就是通货紧缩么?
这里不考虑交易所里发生的投机炒作带来的币值变化。
因此,比特币的产出速率与市场流通性脱节,导致一段时间内货币的供需关系可能严重失衡——比如现在抛开投机操作不说,比特币市场的实际货币需求到底多大?和现在市场中的比特币总值是什么关系?这个有经济学家或者圈内人士统计过么?就个人看来,两者基本已经完全脱节了。
而,就算比特币最后总币数稳定在一个最高值[4]了(比特币以及所有它的衍生品,都打了一个旗号,就是总量有限),就没问题了么?
市场对货币的需求并不是恒定的,所以总值固定的货币不是好货币。比如现在全球货币需求是一千万亿(我随口说的),此时比特币的发行量达到最高值,总币数不再发生变化。明年科技进步经济发展,全球货币总需求涨到了一万亿亿,比特币怎么应对?那就只能通货紧缩啦。
可比特币又有最小币值单位:聪(一亿分之一枚比特币)。所以这个紧缩也是有限的,当需求比总币量大太多的时候,比特币就彻底无法应对这个局面了。
好在,这一天估计是永远不会到来的。
同样的,币值恒定以后,如果货币总需求量下降,那么通胀一样会发生,因此币值是否恒定与通胀或者通缩是否发生,并没有必然联系。
导致通胀的不是货币总量增长,而是货币总量脱离货币需求量的增长——这点在挖矿没挖到尽头以前,一样可以在任何一个虚拟币上发生。
所以,一个好的挖矿机制(这里不算掌簿们在记账过程中获得的提成),应该是可以随着市场对货币的总需求而变更的。
因此,我们可以通过考察全网交易量来做一个简单的判断:
假定全网单位时间T(不同于掌簿的记账周期)内的总流通货币数为N1(如果采用UTXO账目[5],那么这个数值倒是很好估算,把每个新区块或者每组新区快中所有TXO的总和加起来就行,这个单节点自己就能做),扣除交易环节点数小于M的循环交易的货币数N2,为真正的有效流通货币量N。
这里循环交易,就比如A把x1个恶搞币交给B,然后B把x2个恶搞币交给C,C又把x3个恶搞币交给A,这样的交易构成一个环A-B-C-A,参与节点数为3,而M设为4,则这组交易中的x1、x2和x3都要被扣除。
实际情况当然比这个复杂,我们可以计算两个有交易节点之间的总交易额,即把区块内所有从A到B的交易额加在一起,然后构成一个有向图,找到图中所有周长小于M的环。这里要注意如果两个这种环共用一些边,则边上的流量不得重复计算。所以可以是有向图上找小环,然后给小环的边上色,接着计算所有上色边的流量总值[6]。
只所以要扣掉这些小环上的流通量,是为了避免两个节点之间反复来往交易造成的刷量行为——虽然无论M设得多大,这种行为理论上都是无法避免的,但节点越多,交易次数也就越多,那么要被扣除的记账提成也就越多,如果有人舍得花这笔钱,那也不错。
然后把这个量N乘上一个系数Q,就可以认为是周期T内的总货币流通量。
然后计算当前有效货币量。
使用UTXO账目,我们在获得单笔货币流量的同时,也能得到账户在进行交易前的总储蓄量(这里只计算资金的流出方,流入方不考虑)。因此,我们在计算得到系统总流通量的同时,也能获得系统总储蓄量——这里,同一个账户的储蓄量可能被多次计算,因为它可能发出多次交易,这是允许的。
想象一下,一个账号里有余额100,然后不停地收到10然后用掉10,时间周期T内这样的操作有100次,那么总流入为1000,总流出也为1000,如果储蓄只算一次,那么流通的部分就远超储蓄的部分,但这并不符合试试。
所以,单个节点的总储蓄量可以看做是储蓄量与交易次数的乘积——或者更简单地说,是每次交易后储蓄量的累积。
我们将总储蓄量记为C,所以现在我们有了总流通量NQ和总储蓄量C,如果NQ与C的比值NQ/C大于某一个阈值H,那么我们就可以认为市场流通性需求比货币供应更大,所以需要发放更多货币;而如果NQ/C小于阈值,则我们认为市场流通性需求比货币供应要小,那么此时我们就不需要发放任何货币,甚至如果必要的话还需要销毁部分货币。
取I=(NQ)/(CH)-1
为通胀率,如果该值大于0,则掌簿节点(主掌簿与次掌簿)在每次交易中,自动从获得Bcn'I/(n+1)
枚货币作为提成,其中c是交易货币量,n为参与交易的掌簿节点加权总合,n'是获得提成节点的权重值,主掌簿为2,次掌簿为1,最后系数B为一个介于0到1之间的比例系数,用来控制提成比例,与挖矿产出做平衡。而如果I不大于0,那么掌簿节点就不抽成。
实际使用的时候,可以将最近多次通胀率求一个加权平均,比如最近十次交易的通胀率根据5:5:5:4:4:3:3:2:2:1的权重做平均。
而且,采用参与交易节点的累计总储蓄量,还可以有效避免比特币中那种发生意外而无法登录自己账号从而将货币锁死的死穴节点对全网造成的影响——他们压根不在货币流通网内,所以他有再多的货币也没用,对市场不造成任何影响。
同样的,加入有人打算大量囤积货币,也会受到牵制,因为囤积货币越多,C就越大,从而I就越小,最终导致整个市场处于货币超发的状态,不再有提成发生。
这里潜在的一个问题,就是一个人或者几个人,掌控了多于M个节点,且有大量的货币在手,于是每个节点都将自身所有的货币传递给下一人,在这个环中全量跑,那么此时I就被活生生地拉高了,而货币也就可以被源源不断地提成了出来。当然,这个问题其实还行,因为只要节点够多,全量货币足够大,那么这种操作带来的影响是有限的,而提成出来的货币在猜拳机制下是被随机分散在网络中,并不会聚集在上述环中。而这种造币机制本身可以通过调整网络的提成参数B来控制。
在具体实现方面,我们可以取统计周期T是记账周期t的一个整数倍,而只有掌簿需要进行相关计算,主掌簿的必须和所有次掌簿的结果相匹配,否则次掌簿可以否决主掌簿的记账权,大家再次猜拳。
于是,一种基于市场整体通胀率的货币,就这么诞生了。
当然,光光这样的话,系统还是不完善——节点可能完全因为无法获得更多收益而没有交易的兴趣,从而使得供货方无意进场,从而导致根本没有交易发生,从而加剧通缩,于是掌簿更加没有收益,这样系统就陷入了死水状态。
因此,需要有一种奖励措施,刺激市场进行消费。
挖矿
要刺激消费,除了增加商品从而提高消费的欲望之外,另一种就是给人发货币,让人有“咱有了钱可以买两套煎饼果子吃一套摔一套”的脑残快感。
而,消费方面,能最有效提升消费欲望的,其实既不是最没钱的人,也不是最有钱的人。
最没钱的节点,你给了他一笔钱,消费能力也有限;而最富有的人,钱多一点少一点也不过是一个数字游戏,无法激发欲望。
所以,最适合给与资金激励的,应该是处于中游的人。下面我们就来设法找到这样的“中产阶级”。
在上一个环节,我们知道我们可以获得了市场总流通量N与总储蓄量C,我们当然也可以获得一个周期内的参与交易总结点数R、总交易次数X以及市场上当下的总货币量K,从而每个节点都可以计算出一平均余额:L=C/X。
同时,我们也可以知道一个节点i当前的余额c_i与历史总挖矿所得b_i,于是就可以得到一个系数:
其中deltaT是从有节点挖到钱到现在的时间间隔,以秒为单位;passT是上次该节点挖到钱的时间到上次有节点挖到钱的时间间隔,以小时为单位取整,最大不超过某个系数MAXPASS,比如20;param是一个比例系数,可以全网调节。
上面这个是挖矿的难度系数,而每个旷工节点都将上次挖到钱的交易记录的哈希,接上上次记账的账簿哈希,再接上一个当前时间,最后接上一个随机数,整体取一个哈希,记为h_i = hash(LastMineHash + LastBalanceHash + CurrentTime + Nonce)。
因此,如果h_i小于p_i,则挖矿成功。
我们假定全网货币均匀分布,每个节点的算力差不多持平(由于难度系数p_i的存在,现在高算力节点的优势也不明显)且都是矿工,平均每时每刻在线的节点数为D,c_i与L的比值与b_i与K/R的比值近似相等为q,约等于D/Total,Total为总节点数,那么难度系数基本就是
因此,存在一个时间T_C,这个时间到了后,必然有节点能挖到矿——因为难度系数p_i是在不断增大的,而且显然会在某个时刻达到1,从而怎么着都能挖到矿。而预估如果挖矿是连续的,则在每一轮中,时间为T时有节点挖到矿的概率为(其中\Delta T是一次挖矿计算的耗时):
其中上面第一个就是必然会有节点挖到矿的时间点,下面是有节点挖到矿的概率(近似值,准确值要用二阶多重对数的指数函数来表示)。这个概率近似为1时的T_P为:
可见,因为D一般很大,\Delta T一般很小,所以现在的系统,如果大家连续挖矿的话,那么出矿的速度将会非常快,远远快于等待矿自己出现的时间T_C。
这样的设置是不合理的,因为这样有变成了大家比拼算力的游戏,因此我们不得不略微做一些调整:
现在挖矿成功的条件修改为:
这里m是一个大于1的实数,用来调节出矿速率。
可以看到,当m很大的时候,虽然p_i依然是随着t而增长的,但是在T_C时刻到来之前,整个出矿概率依然非常小,因为此时的出矿概率随时间的曲线会变成一个躺L形。
更准确地说,我们可以近似计算出现在的出矿概率随时间的关系为:
而此时平均能挖出矿的时间为:
我们可以取D为一百万,\Delta T为0.001秒,总结点数为一千万,param值为0.00001,那么现在必然能出矿的特征时间T_C差不多就是一个半小时,此时\Lambda约为5.5 * 10^12。如果我们取m为15,那么差不多每十七分三十秒就可以有一个不停挖矿的人挖出矿,是必能出矿时间的差不多五分之一。m为36时,这个比值差不多就是一半了,即不用心挖矿的情况下,一个半小时必然有人能挖到矿,而用心挖矿的情况下,也需要等四十五分钟才会有人挖到矿。
由于现在挖矿与记账分离,所以这个时间周期设得长一点也不会影响到整个记账系统的运行。
事实上,我们现在可以根据全网节点数Total和在线节点数D来调节参数param,使T_C维持在一个我们想要的时间长度上,同时又根据在线节点数D来调节m,是的平均挖矿时常T_P也保持在一个理想的时长水平上,从而做到调节全网矿源货币的产出速率。
这种挖矿方式的特点,就是对算力有一定的要求,但要求又不是太高——这个p_i是随着时间自然增长的(因为deltaT是一个随着时间线性增长的函数),所以只要你不是上一轮挖到矿的人(passT此时为0),那么只要你等的时间足够长,p_i自然会超过任意h_i。但和NXT那种彻底无关算力的挖矿又不同,这里随机数Nonce的引入又使得你加紧运算是有利可图的,因为这样你可以更快地遍历整个搜索空间,从而就有可能更快地挖到矿,抢在别人之前。
挖矿难度除了是随时间自然增长的,它同时也看每个节点的余额与历史挖矿所得。余额越往两极靠的,挖矿难度越高,同时历史挖矿所得越多的节点,挖矿难度也越高。上一次挖到矿的时间也是一个因素,所以算力越高,平均而言passT就越小,所以也就越不利。
整体而言,这个难度系数对于具有高算力的节点是不亲和的,对于积极参与挖矿的节点也没那么亲和。而且,即便你不去挖矿,也依然有一定的概率可以拿到矿产出产。
那么,出产多少合适呢?
这个就要使用上一个环节计算出的I了:N_M = Between[Abs(I) * c; min, max_sign(I)]
。
这里I是上一节算出的通胀系数,min是最小产出量,max_1是流通性不足时的最大产出量,max_-1是流通性过剩时的最大产出量,这三个参数都可以为0。
所以,现在全网最慢每T_C时长增加create枚货币,最快则是T_P时长增加create枚货币。而这些货币流入市场后,如果不被使用,则会造成C的增大而N不变,从而I变小,系统进入通缩状态;如果都被使用,则C不变而N增大,则I增大
而增加的货币量会在一段时间的流通后,影响到系统的通胀率I,最终让系统趋于稳定。
在最糟糕的情况中,系统中没有多少活跃节点,从而货币流通需求保持不变,而总货币数以N_M/T_C的速率在缓慢增长。这样的系统基本就是一个失败的系统了。
我们知道通过提成获得新货币的速率为N_B=BCI/T_B
,其中T_B为记账周期,B是记账提成系数,所以现在系统整体的货币增长速率就是N_T = BCI/T_B + N_M/T_M
,其中T_M是一个介于T_C与T_P之间的数字,看系统整体的挖矿情况而定。而理想状态下,为了能保持系统中货币流通性需求与总货币量的关系很定,我们希望这个货币增幅为CI/T
,这里T是前面提到的用于评估系统总货币流通量与累计总储蓄量的特征时间,即一个系统参数,因此我们现在就可以通过控制参数B和max_1与max_-1实现对系统整理货币增幅的控制。
当然,由于当系统处于I小于0的情况下,我们没法扣除货币,而挖矿还在继续,所以I小于0的情况是非常危险的,很容易导致系统整体的货币超发。
阶段性小结
现在小结一下,这套系统采用了下面这三个很特别的设计:
- 使用完全无关算力的猜拳模式来作为记账共识方案;
- 根据货币流通量与储蓄量来决定提成与采矿收益;
- 采取对高算力节点很不亲和、让低算力节点可以完全靠运气来获取矿藏的挖矿规则。
这些设计已经和现在流行的各种虚拟币完全背道而驰了。
但这还没有完。
惩罚
在前面的设计中,提成与采矿在I小于0的情况下,是不小于零的。提成可以为0,采矿甚至可以大于零。
因此,当I小于0的时候,可能出现持续投放更多货币到市场,但市场还是流通性不足的情况,虽然投放更多货币的原意是要刺激消费。
但要刺激消费并不只有投放货币一种——如果让人觉得,自己不把这钱花掉,钱自己就没了,那自己就亏了,那这样也可以变成一种刺激。
所以,下面我们就来看一种带有惩罚性质的设计。
我们可以将提成中I小于0时不提成这条规则取消,即,如果系统流通性不足,I小于0,那么此时如果有交易发生,主掌簿和次掌簿在完成记账的同时,还要额外花自己的钱,交给整个系统,作为交易的记账费——而原本是从系统获得交易等比例的提成作为奖励。
这边是说,在流通性不足的环境中,别人交易而你不交易的话,你还有可能会被罚款。
但这样的做法显然会导致越来越多的节点设法不再担任掌簿,从而会导致交易本身的完成度收到破坏。
所以,提成中的惩罚不能加诸掌簿身上。
还记得我们选举出掌簿的方法么?就是通过生成哈希,将所有哈希拼接在一起再生成哈希,到这个哈希的差的绝对值做降序,选择前几位。那么,我们还是使用这个排序,但这次在掌簿之后再选出若干位节点,这些节点是要接受惩罚的人。而掌簿则依然可以获得提成奖励,只不过现在的提成是一个最小值,而所有提成与流通性不足的惩罚加在一起,由那几位被选出来的节点平均分摊,接受惩罚。
更详细来说,可以在主次掌簿之后顺序选择后10个节点,将惩罚金额与主次掌簿的提成累计后分为5份,在10个节点中依次进行甄别,如果节点余额的十分之一大于比惩罚金额少,则跳过这个结果,直到招满5个节点,或者10个节点都筛完为止,接着对选出来的节点进行惩罚性扣款。
之所以不对所有非掌簿节点进行惩罚,因为这样节点太多交易太多,对区块的复旦过大。
惩罚完掌簿,下面还可以惩罚旷工,根据I的值进行扣款,那就是谁挖到矿谁倒霉。但和记账必须实现不同,挖矿实在不行可以不挖,所以靠挖矿来惩罚不大靠谱。我们可以在I小于0时,将B设为1。
第二矿脉
PoW共识有浪费计算力的名声,那么我们可以将这个系统进行一个改造,改造成一个分布式计算平台。
所有在这个平台上发布的任务,都与原本的挖矿独立进行,但需要有明确的判定规则,判定节点的计算结果是否成立。
比如说,我们可以把搜索外星人的要求放到这个平台上,把寻找蛋白质折叠形式的需求也放到平台上,等等。
不过这类矿脉的特点是,解在模空间中的分布中未必是均匀的,所以没人知道下一次找到解是什么时候,所以出矿速度是不稳定的,找到一个解以后说不定还能在周围找到别的解,没法作为一个优质的矿脉。
遗忘重铸
对于作为账簿的区块链,其历史记录并不总是必须的。
让我们计算一下,假如网络上总共有N个节点,每个节点每过单位时间t进行一笔交易,每次交易的数据包就算只给一个哈希,也要32字节,那么经过时间T后数据增长量就是NT/(32768t)
单位是MB。假如说,全网有一百万个节点,t为1秒,那么一年的数据增量就是918TB。
中本聪设计的账簿中,完整的账簿采用了下述三层结果:
- 区块头与元信息;
- Markle树验证数据,其叶节点为UTXO账目的哈希;
- 最底层是UTXO账目。
而他提出的SPV(Simplified Payment Verification,简化支付验证)账簿方案则是一种强有力的简化,此时SPV节点只需要保存前两类甚至只需要第一类数据即可。
SPV账册的特点,是对于大多数情况,大部分节点并不需要保存完整的UTXO账目记录,只需要使用转账(也即支付)的哈希(也就是一条UTXO账目的哈希)来定位区块,然后使用Markle树来做验证,从而判断一条转账数据是否真实存在。
换言之,每一条交易都可以被唯一定位,只需要提供上一个区块(因为交易发生时只可能被记录到候选区块,此时该区块的哈希未定,但因为区块链是全网唯一的[7],所以上一个区块的哈希是确定且唯一的)的哈希,和当前交易记录的哈希即可。
而因为账目内容可以被Markle树的叶节点校验,所以即便没有数据内容,只要提供哈希一样可以检验一个节点是否存在已经是否为真。
因此,使用SPV账簿方案的时候,对于老的历史数据可以只保留Markle树而不用让所有节点都记录对应的UTXO账目。甚至于,如果我们可以通过别的手段重生Markle树根节点,那么甚至不需要保留Markle树而只需要保留其根节点即可[8]。
只有当我们需要查看完整数据的时候,才需要向全网请求一个区块的哈希或者一条交易的哈希所对应的完整数据。
但,这个还不是遗忘,而是一种精简。
遗忘方案是指,当一个区块已经足够古老的时候,将其中最重要的信息提取出来,然后把其余的数据完全删除。只要全网的所有掌簿们都认同遗忘,那么遗忘就可以发生。
比如说,对于已经过了100代的数据,我们进行遗忘操作,保留改区块的长度,以及其中所有账号的当下余额(比特币中就是每个地址而非账号,因为一个账号可以有若干个地址)。
在UTXO中,原本挖矿所得的输入方为CoinBase(以太坊等中是CoinStake等),然后输入的值为挖矿所得,输出为一条UTXO,收款人是挖矿者。
而在遗忘重铸步骤中,需要考虑节点的总挖矿收入A与当前余额B之间的关系,如果A>B,则重铸账簿的输入源是CoinBase和CoinForge两个,CoinBase的输入金额为A,而CoinForge的输入金额为B-A,输出为一条UTXO,金额为B;如果A<=B,则重铸账簿的输入源只有CoinBase,输入金额为A,而输出有两条,一条是到CoinForge,金额为A-B,另一条为UTXO,金额为B。
接下来,下一步是要搜索全部联调中输入方是被遗忘区块的UTXO账目,然后新建一批特殊的区块,这些区块的输入是上述新根区块,而输出是这些被找到的区块的所有者,最关键的是,这个区块的哈希是上述UTXO账目的输入哈希——从而这个哈希不是根据区块内容算出来的,而是被强制要求的,所以这条账目会有一个特殊的标记位。
因此,现在整个账目系统的数据结构将发生改变:
- 自身哈希;
- 标记是否是遗忘重铸区块;
- 输入源哈希与输入金额;
- 输出目标列表,每一项都包含一个输出目标哈希与输出金额,最后一条是UTXO;
- 交易时间戳;
- 重铸哈希。
这里,重铸哈希是将之前五项拼接后形成的哈希,用于完整性校验,即:
L1=Hash(L2+L3+L4+L5)
L6=Hash(L1+L2+L3+L4+L5)
这样,所有查账都会在经历一系列UTXO账目的回溯后,找到上述遗忘重铸区块,然后追溯到遗忘重铸的根区块上,而被遗忘的区块都不再被使用。
对于足够古老的数据,在不出重大意外的情况下,我们并不需要使用其中的所有信息,而只需要知道进行支付能力验证以及货币归属权验证即可。在UTXO中,货币归属权由输出账户决定,而支付能力是基于UTXO的完整交易链的总UTXO输出决定,因此我们只需要将这两类信息保存下来即可。
遗忘之后的一个必然的问题,就是如果要追溯已被遗忘的区块中的交易,此时将无法追溯。对于这类交易,只能判定为追溯失败。
由于重铸是非常有危险的行为——重铸根节点可以通过哈希进行校验,但它之后的一层连接重铸根节点与正常交易区块的区块是不满足哈希校验规则的——它提供的哈希不等于此后数据(不包括重铸哈希)的哈希,而正常节点是满足这条要求的。虽然可以适应重铸哈希进行校验,但毕竟还是有一定的风向。
所以重铸行为必须慎重——只有当各分区的所有掌簿的90%都同意遗忘重铸,才能遗忘重铸。
总结
到此,一个非常逗逼恶搞的区块链虚拟货币就好了,让我们总结一下它的特点:
- 节点可分选择功能:掌簿与旷工;
- 使用无关算力的猜拳共识方案;
- 使用分区分层猜拳;
- 根据全网货币的流通量与累计储蓄量进行交易提成计算,交易提成从系统获取而不从交易双方获取;
- 使用几乎不依赖算力的、对高算力节点不亲和的、低算力节点有更高几率成功的挖矿机制;
- 当全网流通性不足时会采取惩罚性措施来刺激交易;
- 可以作为分布式计算系统;
- 支持遗忘重铸以缩短区块链。
其中,最恶搞的就是猜拳共识、高算力不亲和挖矿与流通性不足惩罚这三项,基本上是和试图靠算力来囤积货币的人对着干的设计思路。
事实上,提成收益率和挖矿产出率都试图与全网系统中的货币流通性需求挂钩,当流通性不足时会尝试刺激交易,目标依然是让货币产出率与货币的流通性需求关联,避免两者脱钩而导致的无意义通胀或者通缩。
其中,有一堆参数是需要调整的,部分是程序性的,部分则可以调整,调整策略基本也是由各层各区的掌簿进行分层投票(甚至也可以根据所在层级进行不同权重的投票,采用PoS机制)来决定如何修改。
总之,一句话:怎么难过怎么来,目的就是让人不乱花钱乱投机。
所以,就此看来,基本上没人会想用它的吧。。。
通过本协议,您可以分享并修改本文内容,只要你遵守以下授权条款规定:姓名标示 、非商业性、相同方式分享。
具体内容请查阅上述协议声明。
本文禁止一切纸媒,即印刷于纸张之上的一切组织,包括但不限于转载、摘编的任何应用和衍生。网络平台如需转载必须与本人联系确认。
如果喜欢简书,想要下载简书App的话,轻戳这里~~
私人推荐订阅专题:《有意思的文章》、《严肃码匠圈》
-
拜占庭将军问题是上个世纪七十年代被提出的,和拜占庭帝国没任何关系。提出者为了让问题便于理解而借用了拜占庭帝国的将军要攻打地方又担心存在有变节的将军搞信息篡改这么一个例子,从而得名。在它之前有一个比较类似的问题,是中国将军问题,可惜没有流传开。还有一个很类似的是两军问题,主要考虑的是信息传递的安全有效,后来得到了三次握手算法,即TCP的基础算法。 ↩
-
有趣的是,一个差不多思路的主意前两年国内也有人提出了,而他应该完全不知道区块链与工作力证明。PoW使用高昂的算力来保证要发垃圾邮件,你的付出可能比垃圾邮件带来的汇报要多;而他的想法是:每次你给我发邮件你都要付费,所谓的邮资。这就是饱醉豚搞(然后搞失败了)的投一封邮件花一元的电子邮箱。 ↩
-
这货搞P2P、分布式以及数据校验的人应该非常熟悉了,一种早就非常成熟的基于哈希的二叉或者多叉树,每个节点都是子节点并联的哈希,而叶节点是内容。在比特币中,叶节点是UTXO账目的哈希。 ↩
-
目前比特币系统的最高币数约为2100万枚。考虑到现在最小单位为聪,而一亿聪等于一比特币,所以按照最小货币单位计,就是总共两千一百万亿个最小单位。 ↩
-
UTXO即未支付交易输出,也就是自己给自己转账的记录。UTXO账目用来记录单枚比特币(或者说是单次挖矿挖出的比特币)的完整交易记录链,且要求输入严格等于输出,所以就有了UTXO。用Git做类比的话,完成的交易TXO就是每次Git中提交的增量变化数据,而UTXO就是额外要求再给一个改变后的snapshot。使用UTXO对于做账目追踪是有好处的(虽然基于账户而不是货币的账簿一样可以做到这点,你别只记录一个总数嘛),更重要的是,如果我们要给一枚比特币配置一个过期时间,那么基于货币而非账户的UTXO就很合适了——所以个人认为中本聪以前应该做过积分商城……因为UTXO是我们这边早就在用的积分商城的思路………… ↩
-
所以,很显然,UTXO对应的就是只有一个节点的环。 ↩
-
实际上这个说法过于绝对,区块链允许一段时间内两条链同时存在。网络在确认哪个区块可以入链的时候,除了工作力证明,还有一种可能是因为偶然或者网络问题,两个区块同时都满足工作力证明,并被广播,或者网络原本分裂的后来融合在了一起,从而同时有两条甚至多条链,那么此时网络的规则是选择最长的区块链。但也存在一种可能,此时两条或者多条链的长度相等,那么此时这几条区块链将同时有效并存,然后在下一次有区块入链的时候看此时哪条链被确认的次数更多(单链的新块即便入块了,也需要6次确认才会最终生效,6次以内依然存在被别的区块替换的可能)。 ↩
-
区块链中的节点可以分为两类:全数据节点与轻数据节点。全数据节点将保存所有三层信息,每一笔UTXO都会被保存下来,以及完整的Markle树索引。而轻数据节点就是SPV节点,只需要保存区块链的头部数据,里面只有Markle树的根节点。当有需要检索完整的从比特币被挖掘出来到被消费的完整历史,则需要全数据节点提供完整联调,轻数据节点则只能进行存在性验证。从这点来说,所有的全数据节点构成了一个核心社区,轻数据节点是依附于核心社区的使用者。 ↩