播客链目前已经到了测试阶段了。


很多熟悉我文章的读者都知道,播客链采用的是DPos的共识机制。那播客链是如何将Pow修改成DPos的呢?除了修改成DPos之外,播客链还修改了很多地方,例如:在交易中增加了扩展字段、取消了基础合约的Gas消耗、增加了合约的等级、定时基础链与合约产生交互,从而获取合约中所设置的一些信息……嗯,真改得蛮多的。


下面这张PPT是播客链对于以太坊修改的整个情况。

刺猬文│从启动方式来看播客链的运行机制—共识机制_第1张图片


修改了这么多的内容,如何将它们联合起来,让播客链正常运行呢?


从今天开始,我和大家聊聊播客链增加的这些内容都是如何实现的。


首先是如何改造以太坊Pow的问题。


大家都知道以太坊采用了两种共识机制,在正式链上采用的是Pow的共识机制,在测试链上采用的是Poa的共识机制。那如何将以太坊公网的Pow机制改成DPos机制呢?


DPos机制其实就是一种出块节点轮询的模式。


例如有100个节点,其中有23个节点作为出块节点,那么我们只要能够精确地计算出某一个时刻,应该是由哪一个出块节点来进行出块,就可以了。


这要怎么做呢?


我们需要知道一些信息,例如出块速度是多少?这里的速度一定是确定的,而不像以太坊那样出块时间不确定。为了让我们得到某一个时刻应该由哪一个出块节点来进行出块,我们需要定义一些术语:


1.出块周期:就是从确定一批出块节点开始,到这一批出块节点结束的一个周期时间。假设我们设置每2天为一个出块周期,这就意味着,我们每2天就有机会修改出块节点的成员信息。


2.出块时间:说明我们每一次出块的时间间隔是多久。这里和Pow有点区别:对于以太坊来说,一个出块时间大致是在12秒左右浮动。这就意味着我们无法确切地知道某一刻是否应该出块。这在Dpos中是不允许的,因为Dpos机制中每一个出块节点之间的关系不再是竞争关系,而是协作关系,这也就意味着每一刻,、每一个节点都能计算出当前时间应该由哪一个节点来进行出块打包。


3.出块节点数量:对于Pow来说每一个节点都可以进行出块,但对于DPos来说,只能是特定的节点来进行出块。


有了以上三个术语信息,我们就可以计算出任意一个时刻应该出块的节点信息了。

我们来举个例子,说明如何计算出某一时刻该有哪个出块节点来进行出块的。


假设:

出块周期(EpochInterval) = 1天 = 86400秒

出块时间 (ProducerInterval)= 5秒

出块节点 (producerSize)= 23个

当前时间 = 21006055


根据当前时间计算当前出块节点的实现如以下代码:


刺猬文│从启动方式来看播客链的运行机制—共识机制_第2张图片


根据这段代码我们可以计算出:

Offset= 21006053 % 86400 = 10855

Offset= 10855 / 5 = 2171

Offset= 2171 % 23 = 9

计算这三个Offset的代码分别是:


刺猬文│从启动方式来看播客链的运行机制—共识机制_第3张图片


这样可以得到当前时间出块节点,应该是出块节点数组中第9个位置的节点。


所有节点都通过上面的公式来计算,出来的结果一定是相同的,这样所有的节点就达成了共识。


假设其中有一个节点的公式被人为做了修改,他所计算出来的结果和别人的不相同,他所打包的区块,将不会被其它节点所承认,这就意味着它打包失败了。


这个过程是怎么做的呢?


在播客链中,节点打好包以后,会在包头中写入打包这个区块的账号信息,以及这个区块的打包时间。这样一来,当这个区块发送给其它节点后,其它节点就可以根据这两个信息来检测这个区块是否是由当时改打包节点来进行打包的。


刺猬文│从启动方式来看播客链的运行机制—共识机制_第4张图片


这个过程就是播客链的DPos运行机制。


其实这个机制比较简单,麻烦的会是下一个:如何确定打包者节点的方式。


网上的很多做法都是定义一个特殊的交易,然后在每一个周期开始的时候,节点读取本节点的候选人的Hash树信息,根据规则来生成打包者。但是这种方式我们觉得灵活性非常差,要对这种生成打包者的规则进行修改的时候,那就意味着必须要更新链才能做到。


这种方式还无法做到手动限制。


所以播客链采用的是:基础链和合约进行交互的方式,将这种规则放到合约之中,这样可以大大增加生成打包者的灵活性。


下一期我将简单介绍一下播客链是如何做到这一点的。