共识机制-权益证明 PoS

什么是权益证明

权益证明( Proof of Stake,PoS )最早在2013年被提出,并在 Peercoin 系统中实现,类似于现实生活中的股东机制,拥有股份越多的人越容易获取记账权。

点点币的PoS实现原理

点点币PPCoin 前期采用PoW挖矿开采和分配货币,以保证公平。后期采用PoS机制,保障网络安全,即拥有51%货币难度更大,从而防止51%攻击。

PoS核心概念为币龄,即持有货币的时间。例如有10个币、持有90天,即拥有900币天的币龄。另外使用币,即意味着币龄的销毁。

在PoS中有一种特殊的交易称为利息币,即持有人可以消耗币龄获得利息,同时获得为网络产生区块、以及PoS造币的优先权。

点点币的PoS证明计算公式为:

proofhash < 币龄x目标值

其中proofhash,对应一组数据的哈希值,即hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime)。

币龄即bnCoinDayWeight,即币天,即持有的币数乘以持有币的天数,此处天数最大值为90天。

目标值,即bnTarget,用于衡量PoS挖矿难度。目标值与难度成反比,目标值越大、难度越小;反之亦然。

由公式可见,持有的币天越大,挖到区块的机会越大。

peercoin-0.6.1ppc中PoS证明计算代码如下:

bool CheckStakeKernelHash(unsigned int nBits, const CBlockHeader& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, bool fPrintProofOfStake)
{if (nTimeTx < txPrev.nTime)  // Transaction timestamp violationreturn error("CheckStakeKernelHash() : nTime violation");unsigned int nTimeBlockFrom = blockFrom.GetBlockTime();if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirementreturn error("CheckStakeKernelHash() : min age violation");//目标值使用nBitsCBigNum bnTargetPerCoinDay;bnTargetPerCoinDay.SetCompact(nBits);int64 nValueIn = txPrev.vout[prevout.n].nValue;// v0.3 protocol kernel hash weight starts from 0 at the 30-day min age// this change increases active coins participating the hash and helps// to secure the network when proof-of-stake difficulty is lowint64 nTimeWeight = min((int64)nTimeTx - txPrev.nTime, (int64)STAKE_MAX_AGE) - (IsProtocolV03(nTimeTx)? nStakeMinAge : 0);//计算币龄,STAKE_MAX_AGE为90天CBigNum bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60);// Calculate hashCDataStream ss(SER_GETHASH, 0);//权重修正因子uint64 nStakeModifier = 0;int nStakeModifierHeight = 0;int64 nStakeModifierTime = 0;if (IsProtocolV03(nTimeTx))  // v0.3 protocol{if (!GetKernelStakeModifier(blockFrom.GetHash(), nTimeTx, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake))return false;ss << nStakeModifier;}else // v0.2 protocol{ss << nBits;}//计算proofhash//即计算hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime)ss << nTimeBlockFrom << nTxPrevOffset << txPrev.nTime << prevout.n << nTimeTx;hashProofOfStake = Hash(ss.begin(), ss.end());if (fPrintProofOfStake){if (IsProtocolV03(nTimeTx))printf("CheckStakeKernelHash() : using modifier 0x%016" PRI64x" at height=%d timestamp=%s for block from height=%d timestamp=%s\n",nStakeModifier, nStakeModifierHeight,DateTimeStrFormat(nStakeModifierTime).c_str(),mapBlockIndex[blockFrom.GetHash()]->nHeight,DateTimeStrFormat(blockFrom.GetBlockTime()).c_str());printf("CheckStakeKernelHash() : check protocol=%s modifier=0x%016" PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",IsProtocolV05(nTimeTx)? "0.5" : (IsProtocolV03(nTimeTx)? "0.3" : "0.2"),IsProtocolV03(nTimeTx)? nStakeModifier : (uint64) nBits,nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx,hashProofOfStake.ToString().c_str());}// Now check if proof-of-stake hash meets target protocol//判断是否满足proofhash < 币龄x目标值if (CBigNum(hashProofOfStake) > bnCoinDayWeight * bnTargetPerCoinDay)return false;if (fDebug && !fPrintProofOfStake){if (IsProtocolV03(nTimeTx))printf("CheckStakeKernelHash() : using modifier 0x%016" PRI64x" at height=%d timestamp=%s for block from height=%d timestamp=%s\n",nStakeModifier, nStakeModifierHeight, DateTimeStrFormat(nStakeModifierTime).c_str(),mapBlockIndex[blockFrom.GetHash()]->nHeight,DateTimeStrFormat(blockFrom.GetBlockTime()).c_str());printf("CheckStakeKernelHash() : pass protocol=%s modifier=0x%016" PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",IsProtocolV03(nTimeTx)? "0.3" : "0.2",IsProtocolV03(nTimeTx)? nStakeModifier : (uint64) nBits,nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx,hashProofOfStake.ToString().c_str());}return true;
}
//代码位置 https://github.com/peercoin/peercoin/blob/ppc-0.6-rc1/src/kernel.cpp

点点币的PoS挖矿难度

点点币使用目标值来衡量挖矿难度,目标值与难度成反比,目标值越大、难度越小;反之亦然。当前区块的目标值与前一个区块目标值、前两个区块的时间间隔有关。

计算公式如下:
  当前区块目标值 = 前一个区块目标值 x (1007x10x60 + 2x前两个区块时间间隔) / (1009x10x60)

  由公式可见,两个区块目标间隔时间即为10分钟。
  如果前两个区块时间间隔大于10分钟,目标值会提高,即当前区块难度会降低。
  
  反之,如果前两个区块时间间隔小于10分钟,目标值会降低,即当前区块难度会提高。

peercoin-0.6.1ppc中目标值计算代码如下:

unsigned int static GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake)
{if (pindexLast == NULL)return bnProofOfWorkLimit.GetCompact(); // genesis blockconst CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake);if (pindexPrev->pprev == NULL)return bnInitialHashTarget.GetCompact(); // first blockconst CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake);if (pindexPrevPrev->pprev == NULL)return bnInitialHashTarget.GetCompact(); // second blockint64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime();// ppcoin: target change every block// ppcoin: retarget with exponential moving toward target spacingCBigNum bnNew;bnNew.SetCompact(pindexPrev->nBits);//STAKE_TARGET_SPACING为10分钟,即10 * 60//两个区块目标间隔时间即为10分钟int64 nTargetSpacing = fProofOfStake? STAKE_TARGET_SPACING : min(nTargetSpacingWorkMax, (int64) STAKE_TARGET_SPACING * (1 + pindexLast->nHeight - pindexPrev->nHeight));//nTargetTimespan为1周,即7 * 24 * 60 * 60//nInterval为1008,即区块间隔为10分钟时,1周产生1008个区块int64 nInterval = nTargetTimespan / nTargetSpacing;//计算当前区块目标值bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);bnNew /= ((nInterval + 1) * nTargetSpacing);if (bnNew > bnProofOfWorkLimit)bnNew = bnProofOfWorkLimit;return bnNew.GetCompact();
}
//代码位置 https://github.com/peercoin/peercoin/blob/master/src/main.cpp

PoS 2.0的提出和黑币

为了进一步巩固PoS的安全,2014年rat4(Pavel Vasin)提出了PoS 2.0,并发布了黑币。
  黑币前5000个块,为纯PoW阶段;第5001个块到第10000个块为PoW与PoS并存阶段,从第10001个块及以后为纯PoS阶段。
  黑币首创快速挖矿+低股息发行模式,发行阶段采用POW方式,通过算法改进在短时间内无法制造出专用的GPU和AISC矿机,解决分配不公平的问题。

  PoS2.0相比PoS的改进:

  1、将币龄从等式中拿掉。新系统采用如下公式计算权益证明:
  proofhash < 币数x目标值

  点点币中,部分节点平时保持离线,只在积累了可观的币龄以后才连线获取利息,然后再次离线。
  PoS 2.0中拿掉币龄,使得积攒币龄的方法不再有效,所有节点必须更多的保持在线,以进行权益累积。
  越多的节点在线进行权益累积,系统遭遇51%攻击的可能性就越低。

  2、为了防范预先计算攻击,权益修正因子每次均改变。
  3、改变时间戳规则,以及哈希算法改用SHA256。
  

黑币的PoS实现原理

黑币的PoS证明计算公式为:

proofhash < 币数x目标值hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) < bnTarget * nWeight

其中proofhash,对应一组数据的哈希值,即hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime)。
  
币数即nWeight,目标值即bnTarget。

blackcoin-1.2.4中PoS证明计算代码如下:

static bool CheckStakeKernelHashV2(CBlockIndex* pindexPrev, unsigned int nBits, unsigned int nTimeBlockFrom, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake)
{if (nTimeTx < txPrev.nTime)  // Transaction timestamp violationreturn error("CheckStakeKernelHash() : nTime violation");//目标值使用nBitsCBigNum bnTarget;bnTarget.SetCompact(nBits);//计算币数x目标值int64_t nValueIn = txPrev.vout[prevout.n].nValue;CBigNum bnWeight = CBigNum(nValueIn);bnTarget *= bnWeight;targetProofOfStake = bnTarget.getuint256();//权重修正因子uint64_t nStakeModifier = pindexPrev->nStakeModifier;uint256 bnStakeModifierV2 = pindexPrev->bnStakeModifierV2;int nStakeModifierHeight = pindexPrev->nHeight;int64_t nStakeModifierTime = pindexPrev->nTime;//计算哈希值//即计算hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime)CDataStream ss(SER_GETHASH, 0);if (IsProtocolV3(nTimeTx))ss << bnStakeModifierV2;elsess << nStakeModifier << nTimeBlockFrom;ss << txPrev.nTime << prevout.hash << prevout.n << nTimeTx;hashProofOfStake = Hash(ss.begin(), ss.end());if (fPrintProofOfStake){LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",nStakeModifier, nStakeModifierHeight,DateTimeStrFormat(nStakeModifierTime),DateTimeStrFormat(nTimeBlockFrom));LogPrintf("CheckStakeKernelHash() : check modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",nStakeModifier,nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,hashProofOfStake.ToString());}// Now check if proof-of-stake hash meets target protocol//判断是否满足proofhash < 币数x目标值if (CBigNum(hashProofOfStake) > bnTarget)return false;if (fDebug && !fPrintProofOfStake){LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",nStakeModifier, nStakeModifierHeight,DateTimeStrFormat(nStakeModifierTime),DateTimeStrFormat(nTimeBlockFrom));LogPrintf("CheckStakeKernelHash() : pass modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",nStakeModifier,nTimeBlockFrom, txPrev.nTime, prevout.n, nTimeTx,hashProofOfStake.ToString());}return true;
}//源码地址 https://github.com/CoinBlack/blackcoin/blob/master/src/kernel.cpp

PoS 潜在攻击方法

账本分叉问题 ( Nothing at Stake Problem )

在 PoW 机制中,当账本出现分叉时,对 PoW 这种算力敏感的算法,矿工必须选择一个方向进行挖矿。而在 PoS 这种算力不敏感的时候,PoS 矿工往往会两个方向都挖,以争取实现利益最大化。当多数矿工都在两条链上一起挖矿的时候,就会很容易出现双重支付攻击。

冷启动问题 ( Initial Distribution Problem )

PoS 机制中,由于持币量会对挖矿难度产生影响。因此,当一个基于 PoS 体系代币系统启动时,就会面临早期获得代币的持有者,没有动力去花费或者转移代币给第三方。同时,持有越多的币,越容易挖到矿,这样就产生了代币初始流通性问题。

解决方案:早起几个版本,通过 PoW 机制来创建货币,而非 PoS。由于 PoW 本身的性质,矿工在挖矿过程中往往需要资金来升级硬件,所以会让矿工手中的币流通起来。

长距离攻击 ( Long-Range Attack )

PoS 中,产生每个 Block 的速度相对 PoW 快了很多。因此,少数不怀好意的节点会想着把整个区块链共识账本全部重写。这在 PoW 中是经典的 51% 问题,即:当某一个节点控制了 51% 及以上算力,就有能力篡改账本,但达到 51% 算力是件极其困难的事情。而在 PoS 中缺乏对算力的约束,那么就存在潜在可能篡改账本。

解决方案:同步时,限制最大能接受的分叉节点数量。

贿赂攻击(Bribe Attack)

贿赂攻击流程如下:

攻击者购买某个商品或服务
商户开始等待网络确认这笔交易
此时,攻击者开始在网络中首次宣称,对目前相对最长的不包含这次交易的主链进行奖励。
当主链足够长时,攻击者开始放出更大的奖励,奖励那些在包含此次交易的链条中挖矿的矿工。
六次确认达成后,放弃奖励。
货物到手,同时放弃攻击者选中的链条。
因此,只要此次贿赂攻击的成本小于货物或者服务费用,此次攻击就是成功的。相比之下,PoW 机制中贿赂攻击就需要贿赂大多数矿工,因此成本极高,难以实现。

币龄加和攻击 ( Coin Age Accumulation Attack )

在最早的 Peercoin 版本中,挖矿难度不仅与当前账户余额有关,也与每个币的持币时间挂钩。

H(H(Bprev),A,t) ≤ balance(A)mAge(coins)

这就导致,部分节点在等待足够长时间后,就有能力利用 Age 的增加来控制整个网络,产生非常显著的影响。

解决方案:限制 CoinAge 的最大值。

预计算攻击 ( Precomputing Attack)

当 PoS 中的某一节点占有了一定量的算力后,PoS 中占有特定算力的节点,就有能力通过控制 H prev
来使自己所在算力范围有能力去计算

H(H(Bprev),A,t) ≤ balance(A)m

PoS 的优缺点

优点

节能。不用挖矿,不需要大量耗费电力和能源。
更去中心化。首先说,去中心化是相对的。相对于比特币等PoW类型的加密货币,PoS机制的加密货币对计算机硬件基本上没有过高要求,人人可挖矿(获得利息),不用担心算力集中导致中心化的出现(单用户通过购买获得51%的货币量,成本更高),网络更加安全有保障。
避免紧缩。PoW机制的加密货币,因为用户丢失等各种原因,可能导致通货紧缩,但是PoS机制的加密货币按一定的年利率新增货币,可以有效避免紧缩出现,保持基本稳定。比特币之后,很多新币采用PoS机制,很多采用工作量证明机制的老币,也纷纷修改协议,“硬分叉”升级为PoS机制。

缺点

纯PoS机制的加密货币,只能通过IPO的方式发行,这就导致“少数人”(通常是开发者)获得大量成本极低的加密货币,在利益面前,很难保证他们不会大量抛售。
PoS机制的加密货币,信用基础不够牢固。
为解决这个问题,很多采用PoW+PoS的双重机制,通过PoW挖矿发行加密货币,使用PoS维护网络稳定。或者采用DPoS机制,通过社区选举的方式,增强信任。

参考链接:

http://blog.51cto.com/11821908/2060084

https://daimajia.com/2017/09/14/pow-and-pos

https://juejin.im/post/5ac1e9adf265da23906c2dc8

共识机制-权益证明 PoS相关推荐

  1. 区块链共识机制:权益证明POS和委托权益证明DPOS

    详情参见个人博客: http://brainware360.cn/%E5%8C%BA%E5%9D%97%E9%93%BE%E5%85%B1%E8%AF%86%E6%9C%BA%E5%88%B6%E4% ...

  2. 对话V神:权益证明POS新趋势

    对话V神:权益证明POS新趋势 BitMEX研究院 2018-05-02 16:17 发布在 链圈子 1 3628

  3. 区块链共识机制技术二——POS(权益证明)共识机制

    前言 由于区块链是去中心化分散网络,所以必须设计一套维护系统的运作顺序和公平性的机制,即共识机制,用来决定谁取得区块链的记账权并获得系统新币奖励.比特币的POW共识机制是一种多劳多得的模式,其优点是算 ...

  4. Go学习之编码实现区块链 - 【权益证明PoS】

    在上一篇讲到如何快速实现一个简单的区块链,相信朋友们已经对其有了一个基础的认识.接下来,我们在此基础上进行重构,加入当下热议的一项技术,就是权益证明(Proof of Stake)的代码实现.在实现之 ...

  5. 区块链去中心化的生命之源:“DPOS(委托权益证明)共识机制”

    区块链去中心化的生命之源:"DPOS(委托权益证明)共识机制" 原创2018-04-24[水伯]战略忽悠局政委水伯 移动网络时代唯一壁垒就是认知,周二有约给思想洗澡让认知破壁! D ...

  6. pos共识机制_OK区块链60讲 | 第17集:什么是PoS共识机制

    什么是PoS共识机制https://www.zhihu.com/video/1196092110837805056 <OK区块链60讲>是由OKEx&新浪科技联合出品的区块链科普动 ...

  7. 股权证明pos记账权是根据不同节点_POC、POW、POS,谁才是共识之王?

    区块链发展至今已经诞生了许多的共识,其中大部分的共识机制诞生于"Proof of X部落"和"BFT(拜占庭容错)部落",目前区块链世界以"Proof ...

  8. 共识机制:区块链技术的根基

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. Chapter-1:什么是共识机制? 技术定义是:共识机制是一个群体决策的流程,群体中的个体会执行和支持对群体其他个人最 ...

  9. 区块链核心技术:委任权益证明算法DPoS

    委任权益证明Delegated Proof of Stake(简称DPoS)是比特股BitShares采用的区块链公识算法.在加密货币技术中,使用共识算法来保证整个区块链网络的安全可靠,著名的共识算法 ...

最新文章

  1. 【Android 应用开发】Android 组件 位置坐标 属性 ( 组件位置属性 | 父容器坐标系坐标 | 窗口坐标系坐标 | 屏幕坐标系坐标 | 触摸坐标 )
  2. 阿里P7大牛手把手教你!一眼就能看懂的Android自学手册,真香!
  3. weblogic漏洞复现(CVE-2020-2555)
  4. inside-the-linux-kernel-full
  5. iOS页面间跳转的方式
  6. 电脑输入法变成繁体中文如何改回来
  7. 高效能程序员的修炼札记:创建和管理社区
  8. 充电电池的充放电电流-0.2C、1C、2C的含义
  9. matlab限幅器无饱和怎么设置,基于MATLAB 的直流电动机双闭环调速系统的仿真研究...
  10. solicit报文_DHCPv6原理与配置
  11. 《微信小程序-比较数字大小》
  12. 华科教授因学生住宿问题投诉后勤处:被学校处分,取消两年评优资格
  13. java卖票_Java中卖票问题
  14. 黑马程序员Java零基础视频教程(2022最新Java)B站视频学习笔记-Day14-面向对象进阶02
  15. 人工智能 | CIFAR10卷积神经网络实践
  16. java导出pdf文件并下载_java根据模板生成pdf文件并导出
  17. 迅为龙芯2K1000开发板双核64位系统处理器,流畅运行多个系统
  18. crontab使用案例
  19. 机器学习/深度学习-学习笔记:概念补充(上)
  20. 在飞书上定制 BOT 服务,Chatopera 机器人让办公更智能 | Chatopera

热门文章

  1. 大数据时代数据中心的发展思考
  2. 第001期:数据中心知识问答
  3. 成功解决ValueError: min_samples_split must be an integer greater than 1 or a float in (0.0, 1.0]; got th
  4. DL之AE:自编码器AutoEncoder的简介、应用、经典案例之详细攻略
  5. json中的转义字符和数字
  6. Visual Code 快捷创建HTML,CSS和Class
  7. 2019.1.11英语笔记1
  8. 第二次周考题目答案整理
  9. python之web开发“三剑客”
  10. 如何编写一份软件工程实验报告