NULS设计文档解读——共识模块

摘要:NULS,让区块链更简单!

为什么要有共识模块

在传统的中心化系统中,所有用户都使用中心服务器提供的服务,信任中心服务器提供的数据,其他分支服务器,也是在信任中心服务器的前提下,备份相关数据。正常情况下,在中心化系统中,服务器之间,是不存在信任问题的。

但在去中心化的环境中,所有提供服务的节点,拥有同等的权力,他们可以自行选择提供或者停止服务,也可以自行决定存储什么数据。这样在去中心化的环境中,建立一个系统,就存在信任问题,到底哪个节点的数据是真的?其他节点又应该以哪个节点的数据为准?

为了能够解决去中心化环境中节点之间的信任问题,保证去中心化系统能够像中心化系统一样,保持数据的正确性和一致性,就需要有一套明确的规则和算法。这样一套明确的规则和算法,就是我们所说的区块链共识机制。

保证去中心化环境中,数据的正确性和一致性,是实现其他所有功能的基础,所以共识机制是区块链系统中的核心。

在NULS2.0中,NULS采用的是自主研发的POC(Proof of Credit)信用共识机制。POC信用共识机制,兼具POS和DPOS特性,能让所有人自由参与主网共识,获得共识奖励,也能让所有节点公平的参与出块,做到高效低能耗。NULS2.0提供单独的共识模块,来实现POC共识机制,保证整个NULS网络安全稳定地运行。

POC信用共识机制介绍

NULS主网采用的是自主研发的POC信用共识机制,要想理解POC共识模块的功能和实现方式,就必须先了解POC信用共识机制的设计理念和业务规则。下面,我们先介绍POC信用共识机制。

POC在共识算法中,引入了信用评价体系,当矿工锁定一定数量的NULS,创建好节点,在节点信用达标的情况下,节点即可参与主网共识,赚取共识收益。POC采用轮流出块机制,每轮重新统计出块节点,计算出块顺序,当节点退出共识时,锁定的NULS将会解锁。

共识进入与退出机制

任何人都可以随时加入到NULS的共识之中,只要满足条件,遵守规则,即可持续获得NULS共识奖励。POC的加入分为硬性指标和软性指标。硬性指标指的是信用分值必须达到一定标准线,以排除掉一部分曾经作恶的节点。软性指标指的是,必须锁定一定数量的NULS作为保证金,以杜绝节点的泛滥。同时,为了让整个系统更加公平,系统给可以锁定的保证金设置了一个范围:20,000NULS~200,000NULS。保证金的多少会和最终的奖励挂钩。

黄牌惩罚

在共识出块期间,由于节点硬件配置、网络环境等原因,造成的掉线、死机等无法出块,但不属于违规的情况,会对整个系统造成一定影响,所以系统有一个轻度的警告机制,会一定程度上影响节点信用的评定。

红牌惩罚

对于一些双花、尝试分叉系统、不遵守系统规则的恶意人为破坏情况,NULS坚决抵制,所有节点都可以检测到这类情况的发生。一旦有恶意节点确实试图挑战NULS网络,那么对应创建节点的保证金将会被锁定60天,节点将被强制停止出块,且创建地址将永远无法再创建节点。

信用评级

在NULS网络中,信用值是节点在系统中的诚信系数,所有节点的信用值会在区间[-1,1]内,通过信用评级算法公式自动计算。

信用评估公式:

信用基数=能力系数+责任系数

能力系数:根据历史出块数量计算

责任系数:根据违规情况和出块正确性计算

共识奖励

为了整个NULS网络的平衡与公平,共识奖励根据所有共识节点所提交的保证金与共识节点信用值综合计算。

共识奖励计算公式:

fee:本块手续费

rnc:本轮共识节点数

bti:出块间隔时间(秒)

spy:一年总时间(秒)

cmc:共识委托Token数

cr:信用基数

四种角色

在矿工创建节点,参与NULS主网共识挖矿时,节点中会涉及到四种不同的角色,本质上,这些角色都是地址。因为NULS主网是去中心化的匿名环境,所以我们通过地址来区别不同的角色,承担不同的职责。

代理人:即共识节点的创建地址。NULS持有人发起一笔创建共识节点的交易,记录到链中,告诉所有人我要做共识节点。节点创建的基本条件是需要锁定20,000—200,000个NULS,且没有红牌惩罚记录。打包人:代理人在创建共识节点时,指定的打包地址,可以是自己的其他地址,也可以是懂技术的朋友。这样设计是为了,让打包人可以在不持有任何NULS的情况下,只要提供服务器,就可以参与共识。这样设计的好处是,即使服务器遭到攻击,矿工也不会有巨大损失,损失的只是被攻击后的收益。需要注意的是,打包人是真正出块的地址,每次打包区块后,都需要对区块签名,因此打包地址一定不能设置密码。奖励人:代理人在创建共识节点时,指定的共识奖励受益人,节点参与共识获得的NULS奖励将全部发放到该地址中。委托人:将自己持有的NULS委托给节点的NULS持有人。委托人可以根据节点的信用值情况,把自己的NULS委托给信用值高的节点,保证自己可以获得更高的NULS共识奖励。委托人单次委托不能低于2000NULS,可以随时加入或退出。

其中,打包人地址与其他角色的地址不能相同,代理人地址和打包人地址要没有红牌惩罚记录。

通用共识机制

NULS是一个提供定制化服务的区块链底层基础设施,在其主网上不运行任何应用业务,所有应用业务均由平行链运行。通过NULS的链工厂产品,基于模块仓库,能快速地部署区块链,且可灵活定制各种运行参数,包括是否支持基础Token、加密算法、共识机制、存储机制等。

NULS定义了通用共识模块,以提供接口兼容不同的共识机制。NULS社区会陆续开发POW、DPOS、POS、PBFT、POOL验证池等共识机制,以供用户自由选择。

POC共识模块功能

POC共识模块功能体现了该模块的作用,也是开发该模块需要达到的目标。读者阅读本文档的目标是理解POC共识模块具有哪些功能,以及这些功能的实现流程。

根据POC共识机制的设计理念和业务规则,POC共识模块主要有节点管理、轮次管理和打包出块三个功能。下面对这三个功能做详细介绍。

节点管理

POC信用共识机制引入了POS的特性,矿工需要通过抵押最低2万、最高20万的NULS,作为保证金,才能创建节点。节点管理主要是指矿工创建节点、委托人发起委托、委托人撤销委托、矿工停止节点等功能,本质上这些功能都是基于交易实现的。下面对这些功能做详细介绍:

创建节点:矿工发起一笔创建节点的交易,共识模块会判断矿工用于创建节点的代理人地址中,保证金是否在20000-200000NULS的限制之内,判断矿工设置的代理人地址和打包人地址是否受到过系统的红牌惩罚,没有红牌惩罚记录,才能成功创建节点。节点创建成功,矿工的保证金将被锁定。委托人发起委托:NULS持有人通过钱包选择自己信任的节点,发起委托交易。共识模块会判断委托人的委托金额是否不低于2000NULS,被委托的节点的NULS委托量是否超过了委托上限50万NULS。如果满足要求,委托交易才能发起成功。委托发起成功,委托人的NULS将会被锁定。委托人撤销委托:当委托人想要撤销委托时,可以通过钱包发起退出委托交易。共识模块负责发起退出委托交易,委托人撤销委托只能逐一进行撤销,例如,委托人在同一节点上进行了3笔委托,想要撤销所有委托,只能分3次完成。NULS的委托都是即进即出的,没有时间限制。撤销成功,委托人的NULS将会被解锁。矿工停止节点:当矿工想要停止节点的时候,矿工可以发起一笔停止节点交易。共识模块发起停止节点交易后,节点中所有委托人的NULS将自动解锁,矿工的保证金将在72小时之后,自动解锁。

轮次管理

维护共识节点集合:

POC共识机制采用轮流出块的方式,让所有符合出块标准的节点,参与主网共识,获取奖励。所以共识模块内部,会维护一个共识节点集合,这个集合里维护的节点信息,会根据节点管理里提到的四种交易,进行及时的更新;

下面是集合里维护的节点信息格式:

名称 描述 agentAddress 代理人地址   packingAddress 打包人地址   rewardAddress 奖励人地址   deposit 保证金   time 创建时间   blockHeight 所在区块高度   delHeight 节点注销高度   status 共识状态0:待共识,1:共识中   creditVal 信用值   txHash 创建节点的交易哈希  

POC共识机制中规定,当节点委托没有达到20万NULS时,节点虽然创建成功,但是还不能参与出块。当节点的委托量达到参与共识的要求时,节点的共识状态,将从待共识切换到共识中。

维护轮次信息集合:

因为采用轮流出块的机制,而每轮中参与出块的节点可能会不一样,每轮的开始时间和结束时间等轮次信息,都是实时计算出来的,所以需要有一个轮次信息集合,用来单独维护与轮次相关的信息。

下面是轮次信息集合存储的轮次信息格式:

名称 描述 totalWeight 当前轮次总权重。每个节点的权重占总权重的比例,是计算节点收益的依据   index 轮次下标   startTime 轮次开始时间   endTime 轮次结束时间   memberCount 本轮次出块节点数   memberList 本轮次出块节点信息   preRound 上一轮信息。在下一轮要利用上一轮信息判断是否应该给节点红黄牌。   myMember 当前节点出块信息  

在当前的出块轮次中,共识模块会让所有本轮可以出块的节点随机排队,然后进行打包出块。

打包出块

打包出块是POC共识模块负责的主要功能。符合出块条件的节点,会根据轮次信息,轮流对内存池的交易进行验证打包,然后组装成新区块,广播到全网。打包出块功能的主要流程如下:

启动出块线程:根据轮次信息,判断是否该自己出块,如果是,启动出块线程;打包出块:开始出块后,共识模块会向交易管理模块发起区块交易打包指令,交易管理模块会根据指令,进行区块交易打包操作;接着,共识模块会根据信用值、轮次总权重等信息,计算自己的coinbase,根据上一轮信息,判断其他节点是否有红黄牌;最后,共识模块会计算区块头、梅克尔哈希等内容,完成区块签名后,和打包好的交易一起组装成区块,区块组装完毕,共识模块会将区块发送给区块管理模块。验证区块:在打包出块流程结束之后,共识模块的操作就完成了,但是后续区块管理模块会发起验证区块的操作,共识模块会提供对应的接口,帮助区块管理模块完成验证操作。

其他

网络通讯协议

用于广播打包的新区块

Length Fields Type Remark 4 chainId int 链ID ?? smallBlock String SmallBlock对象序列化的十六进制字符串

模块配置

{
{
“name”: “packingInterval”,
“remark”: “打包间隔时间”,
“changable”: “true”,
“default”: “10秒”
}, {
“name”: “redPublishLockTime”,
“remark”: “获得红牌保证金锁定时间”,
“changable”: “true”,
“default”: “3个月”
}, {
“name”: “stopAgentLockTime”,
“remark”: “注销节点保证金锁定时间”,
“changable”: “true”,
“default”: “3天”
}, {
“name”: “commissionRateMin”,
“remark”: “佣金比例的最小值”,
“changable”: “true”,
“default”: “10”
}, {
“name”: “commissionRateMax”,
“remark”: “佣金比例的最大值”,
“changable”: “true”,
“default”: “80”
}, {
“name”: “depositMin”,
“remark”: “创建节点的保证金最小值”,
“changable”: “true”,
“default”: “20000”
}, {
“name”: “depositMax”,
“remark”: “创建节点的保证金最大值”,
“changable”: “true”,
“default”: “200000”
}, {
“name”: “commissionMin”,
“remark”: “出块节点最小委托金额”,
“changable”: “true”,
“default”: “200000”
}, {
“name”: “commissionMax”,
“remark”: “出块节点最大委托金额”,
“changable”: “true”,
“default”: “500000”
}, {
“name”: “entrusterDepositMin”,
“remark”: “委托最小金额”,
“changable”: “true”,
“default”: “2000”
}, {
“name”: “blockMaxSize”,
“remark”: “区块最大值”,
“changable”: “true”,
“default”: “4900000”
}, {
“name”: “maxAgentCountOfAddress”,
“remark”: “一个账户最多可创建的节点数”,
“changable”: “true”,
“default”: “1”
}, {
“name”: “mainChainCommissionRatio”,
“remark”: “跨链交易手续费主网收取比例”,
“changable”: “true”,
“default”: “60”
}, {
“name”: “seedNodes”,
“remark”: “种子节点列表”,
“changable”: “true”,
“default”: “NULSd6Hge7xHDnvsSpnzbR2gWHd31zJ1How11,NULSd6Hgc5VNP4rF4wxdiXEQKpBKUE4w5RS22”
}, {
“name”: “password”,
“remark”: “出块账户尼玛”,
“changable”: “true”,
“default”: “nuls123456”
}, {
“name”: “agentChainId”,
“remark”: “本链创建共识节点锁定的资产链ID”,
“changable”: “true”,
“default”: “1(本链链ID)”
}, {
“name”: “agentAssetId”,
“remark”: “本链创建共识节点锁定的资产ID”,
“changable”: “true”,
“default”: “1(本链主资产ID)”
}, {
“name”: “awardAssetId”,
“remark”: “挖矿资产ID”,
“changable”: “true”,
“default”: “1(本链主资产ID)”
}, {
“name”: “feeUnit”,
“remark”: “共识交易手续费单价”,
“changable”: “true”,
“default”: “100000”
}, {
“name”: “totalInflationAmount”,
“remark”: “总通胀量”,
“changable”: “true”,
“default”: “11000000000000000”
}, {
“name”: “inflationAmount”,
“remark”: “初始通胀金额”,
“changable”: “true”,
“default”: “41095890410959”
}, {
“name”: “initTime”,
“remark”: “通胀开始计算时间”,
“changable”: “true”,
“default”: “1594483200”
}, {
“name”: “deflationRatio”,
“remark”: “通缩比例”,
“changable”: “true”,
“default”: “99.6”
}, {
“name”: “deflationTimeInterval”,
“remark”: “通缩间隔时间”,
“changable”: “true”,
“default”: “2592000”
}
}

共识模块启动时需要依赖的模块