建站服务器
位置,即利害关系证明,译为权益证明。
无论啪或位置,均可以理解为"谁有资格写区块链"的问题。
啪通过算力证明自己有资格写区块链,而刷卡机则是通过拥有的币龄来证明自己有资格写区块链。
?
啪的优势和弊端
?
动力,优势为可靠,使用广泛,是经历了充分的实践检验的公有链共识算法。
但其缺点也较为明显:
1、消耗了太多额外算力,即大量能源。
2、资本大量投资矿机,导致算力中心化,有51%***的安全隐患。
?
刷卡机的提出和点点币
?
第一个基于刷卡机的虚拟币是点点币。
鉴于啪的缺陷,2012年阳光国王提出了位置,并基于啪和刷卡机的混合机制发布了点点币PPCoin。
前期采用啪挖矿开采和分配货币,以保证公平。后期采用刷卡机机制,保障网络安全,即拥有51%%u8D27币难度更大,从而防止51%***。
?
刷卡机核心概念为币龄,即持有货币的时间。例如有10个币、持有90天,即拥有900币天的币龄。
另外使用币,即意味着币龄的销毁。
在刷卡机中有一种特殊的交易称为利息币,即持有人可以消耗币龄获得利息,同时获得为网络产生区块、以及刷卡机造币的优先权。
?
点点币的刷卡机实现原理
?
点点币的刷卡机证明计算公式为:
proofhash币龄x目标值
?
展开如下:
哈希(nStakeModifier tx prev。阻止。发送前一时间。偏移tx prev。发送前一时间。vout。n时间)bn目标x bnCoinDayWeight
?
其中证明哈什,对应一组数据的哈希值,即哈希(nStakeModifier tx prev。阻止。发送前一时间。偏移tx prev。发送前一时间。vout。n nTime)。
币龄即bnCoinDayWeight,即币天,即持有的币数乘以持有币的天数,此处天数最大值为90天。
目标值,即bnTarget,用于衡量刷卡机挖矿难度。目标值与难度成反比,目标值越大、难度越小;反之亦然。
?
由公式可见,持有的币天越大,挖到区块的机会越大。
?
peercoin-0.6.1ppc中刷卡机证明计算代码如下:
?
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) //事务时间戳冲突
返回错误(CheckStakeKernelHash() : nTime违例);
无符号int nTimeBlockFrom=blockFrom .获取阻塞时间();
if(nTimeBlockFrom nStakeMinAge nTimeTx)//最小年龄要求
返回错误(CheckStakeKernelHash():最小年龄冲突);
//目标值使用nBits
CBigNum bnTargetPerCoinDay
bnTargetPerCoinDay .集合压缩(nBits);
int 64 nValueIn=tx prev。vout[prev out。n].n值
//v0.3协议内核哈希权重在30天最小年龄时从0开始
//此更改增加了参与哈希的活动硬币,有助于
//当证明利害关系的难度较低时保护网络
int 64 nti时间权重=min((int 64)nti metx-tx prev)。ntime,(int 64)STAKE _ MAX _ AGE)-(isprotocolv 03(nti metx)?nStakeMinAge:0);
//计算币龄,STAKE_MAX_AGE为90天
CBigNum bnCoinDayWeight=CBigNum(nValueIn)* n time weight/COIN/(24 * 60 * 60);
//计算哈希
CDataStream ss(SER_GETHASH,0);
//权重修正因子
uint 64 nStakeModifier=0;
int nStakeModifierHeight=0;
int 64 nStakeModifierTime=0;
if(isprotocolv 03(nTimeTx))//v 0.3协议
{
如果(!GetKernelStakeModifier(阻止从.GetHash(),nTimeTx,nStakeModifier,nStakeModifierHeight,nStakeModifierTime,fPrintProofOfStake))
返回错误的
ss语句修饰符
}
else //v0.2协议
{
ss nBits
}
//计算proofhash
//即计算哈希(nStakeModifier tx prev。阻止。发送前一时间。偏移tx prev。发送前一时间。vout。n分钟)
来自nTxPrevOffset tx prev的ss ntimeblock。时间预防。n nTimeTx
hashproofskate=Hash(ss。begin(),ss。end());
if (fPrintProofOfStake)
{
if (IsProtocolV03(nTimeTx))
printf(CheckStakeKernelHash():对高度=%d时间戳=%s的块使用高度=%d时间戳=%s的修饰符0x 6优先级64x \ \ \ \ n,
nStakeModifier,nStakeModifierHeight,
DateTimeStrFormat(nStakeModifierTime).c_str(),
mapBlockIndex[blockFrom .GetHash()]-nHeight,
DateTimeStrFormat(blockFrom .GetBlockTime()).c _ str());
printf(CheckStakeKernelHash():check protocol=% s modifier=0x 6 pri 64 x nTimeBlockFrom=prev offset=meTxPrev=evout=meTx=
hProof=%s\\\\n,
IsProtocolV05(nTimeTx)?0.5 : (IsProtocolV03(nTimeTx)?0.3 : 0.2),
IsProtocolV03(nTimeTx)?nstak修饰符:(uint 64)nBits,
nTimeBlockFrom,nTxPrevOffset,txPrev.nTime,prevout.n,nTimeTx,
hashProofOfStake .ToString().c _ str());
}
//现在检查利害关系证明哈希是否符合目标协议
//判断是否满足proofhash币龄x目标值
if(CBigNum(hashproofskate)bnCoinDayWeight * bnTargetPerCoinDay)
返回错误的
如果(fDebug!fPrintProofOfStake)
{
if (IsProtocolV03(nTimeTx))
printf(CheckStakeKernelHash():对高度=%d时间戳=%s的块使用高度=%d时间戳=%s的修饰符0x 6优先级64x \ \ \ \ n,
nStakeModifier,nStakeModifierHeight,
DateTimeStrFormat(nStakeModifierTime).c_str(),
mapBlockIndex[blockFrom .GetHash()]-nHeight,
DateTimeStrFormat(blockFrom .GetBlockTime()).c _ str());
printf(CheckStakeKernelHash():pass protocol=% s modifier=0x 6 pri 64 x nTimeBlockFrom=prev offset=meTxPrev=evout=meTx=
hProof=%s\\\\n,
IsProtocolV03(nTimeTx)?0.3 : 0.2,
IsProtocolV03(nTimeTx)?nstak修饰符:(uint 64)nBits,
nTimeBlockFrom,nTxPrevOffset,txPrev.nTime,prevout.n,nTimeTx,
hashProofOfStake .ToString().c _ str());
}
返回真实的
}
//代码位置src/kernel.cpp
?
点点币的刷卡机挖矿难度
?
点点币使用目标值来衡量挖矿难度,目标值与难度成反比,目标值越大、难度越小;反之亦然。
当前区块的目标值与前一个区块目标值、前两个区块的时间间隔有关。
?
计算公式如下:
当前区块目标值=前一个区块目标值x (1007x10x60 2x前两个区块时间间隔)/(1009x10x60)
?
由公式可见,两个区块目标间隔时间即为10分钟。
如果前两个区块时间间隔大于10分钟,目标值会提高,即当前区块难度会降低。
反之,如果前两个区块时间间隔小于10分钟,目标值会降低,即当前区块难度会提高。
?
peercoin-0.6.1ppc中目标值计算代码如下:
?
无符号int static GetNextTargetRequired(const CBlockIndex * pindexLast,bool fProofOfStake)
{
if (pindexLast==NULL)
返回bnProofOfWorkLimit .get compact();//起源块
const CBlockIndex * pindexPrev=GetLastBlockIndex(pindexLast,fProofOfStake);
if (pindexPrev-pprev==NULL)
返回bnInitialHashTarget .get compact();//第一个块
const CBlockIndex * pindexPrev=GetLastBlockIndex(pindexPrev-PP rev,fProofOfStake);
if (pindexPrevPrev-pprev==NULL)
返回bnInitialHashTarget .get compact();//第二块
int 64 nActualSpacing=pindexPrev-get block time()-pindexPrev-get block time();
//ppcoin:目标每块都改变
//ppcoin:以指数形式向目标间距移动的重定目标
CBigNum bnNew
bn新.set compact(pindexPrev-nBits);
//STAKE _ TARGET _ spaceing为10分钟,即10 * 60
//两个区块目标间隔时间即为10分钟
int 64 nTargetSpacing=fProofOfStake?STAKE _ TARGET _ SPACING:min(nTargetSpacingWorkMax,(int 64)STAKE _ TARGET _ SPACING *(1 pin dex last-n height-pin dex prev-n height));
//nTargetTimespan为一周,即7 * 24 * 60 * 60
//nInterval为1008,即区块间隔为10分钟时,1周产生1008个区块
int 64 nInterval=nTargetTimespan/nTargetSpacing;
//计算当前区块目标值
bn new *=((nInterval-1)* n targetspacing nActualSpacing nActualSpacing);
bn new/=((nin interval 1)* nTargetSpacing);
if(bnNew bnproofworklimit)
bnNew=bnProofOfWorkLimit
返回bn新.get compact();
}
//代码位置src/kernel.cpp
?
位置2.0的提出和黑币
?
为了进一步巩固刷卡机的安全,2014年rat4(帕维尔瓦辛)提出了位置2.0,并发布了黑币。
黑币前5000个块,为纯啪阶段;第5001个块到第10000个块为啪与刷卡机并存阶段,从第10001个块及以后为纯刷卡机阶段。
黑币首创快速挖矿低股息发行模式,发行阶段采用啪方式,通过算法改进在短时间内无法制造出专用的国家政治保卫局。参见国家政治保卫局和AISC矿机,解决分配不公平的问题。
?
PoS2.0相比刷卡机的改进:
?
1、将币龄从等式中拿掉。新系统采用如下公式计算权益证明:
proofhash币数x目标值
?
点点币中,部分节点平时保持离线,只在积累了可观的币龄以后才连线获取利息,然后再次离线。
位置2.0中拿掉币龄,使得积攒币龄的方法不再有效,所有节点必须更多的保持在线,以进行权益累积。
越多的节点在线进行权益累积,系统遭遇51%***的可能性就越低。
?
2、为了防范预先计算***,权益修正因子每次均改变。
3、改变时间戳规则,以及哈希算法改用SHA256。
?
黑币的刷卡机实现原理
?
黑币的刷卡机证明计算公式为:
proofhash币数x目标值
?
展开如下:
哈希(nStakeModifier tx prev。阻止。发送前一时间。发送前一时间。vout。哈希发送前一个。vout。n时间)bn目标* NW重量
?
其中证明哈什,对应一组数据的哈希值,即哈希(nStakeModifier tx prev。阻止。发送前一时间。发送前一时间。vout。哈希发送前一个。vout。n nTime)。
币数即重量级,目标值即bnTarget。
?
黑色硬币-1.2.4中刷卡机证明计算代码如下:
?
静态bool checkstakekernelhashv 2(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) //事务时间戳冲突
返回错误(CheckStakeKernelHash() : nTime违例);
//目标值使用nBits
CBigNum bnTarget
bnTarget .集合压缩(nBits);
//计算币数x目标值
int 64 _ t nValueIn=tx prev。vout[prev out。n].n值
CBigNum bn权重=CBigNum(nValueIn);
bnTarget *=bnWeight
targetprooffstake=bn目标。get uint 256();
//权重修正因子
uint 64 _ t nStakeModifier=pindexPrev-nStakeModifier;
uint 256 bnstakemodifierv 2=pindexPrev-bnstakemodifierv 2;
int nStakeModifierHeight=pindexPrev-n height;
int 64 _ t nStakeModifierTime=pindexPrev-nTime;
//计算哈希值
//即计算哈希(nStakeModifier tx prev。阻止。发送前一时间。发送前一时间。vout。哈希发送前一个。vout。n分钟)
CDataStream ss(SER_GETHASH,0);
if (IsProtocolV3(nTimeTx))
ss bnStakeModifierV2
其他
ss nStakeModifier nTimeBlockFrom;
ss tx prev。时间预防。哈希预输出。n nTimeTx
hashproofskate=Hash(ss。begin(),ss。end());
if (fPrintProofOfStake)
{
LogPrintf(CheckStakeKernelHash():在高度=%d时间戳=%s处对时间戳=%s的块使用修饰符0x6x \ \ \ \ n,
nStakeModifier,nStakeModifierHeight,
DateTimeStrFormat(nStakeModifierTime),
DateTimeStrFormat(nTimeBlockFrom));
LogPrintf(CheckStakeKernelHash():check modifier=0x6x nTimeBlockFrom=meTxPrev=evout=meTx=
hProof=%s\\\\n,
nStakeModifier,
nTimeBlockFrom,txPrev.nTime,prevout.n,nTimeTx,
hashProofOfStake .ToString());
}
//现在检查利害关系证明哈希是否符合目标协议
//判断是否满足proofhash币数x目标值
if(CBigNum(hashprofsket)bn目标)
返回错误的
如果(fDebug!fPrintProofOfStake)
{
LogPrintf(CheckStakeKernelHash():在高度=%d时间戳=%s处对时间戳=%s的块使用修饰符0x6x \ \ \ \ n,
nStakeModifier,nStakeModifierHeight,
DateTimeStrFormat(nStakeModifierTime),
DateTimeStrFormat(nTimeBlockFrom));
LogPrintf(CheckStakeKernelHash():pass modifier=0x6x nTimeBlockFrom=meTxPrev=evout=meTx=
hProof=%s\\\\n,
nStakeModifier,
nTimeBlockFrom,txPrev.nTime,prevout.n,nTimeTx,
hashProofOfStake .ToString());
}
返回真实的
}
?
后记
?
刷卡机有种种优点,但也有所缺陷。
即因为刷卡机并不消耗更多的算力,因此如果出现分叉,理性节点会在所有链上同时刷卡机挖矿。
以至于每次分叉都会形成新的山寨币,即刷卡机无法很好的应对分叉。
更多关于云服务器,域名注册,虚拟主机的问题,请访问西部数码代理商官网:www.chenqinet.cn