日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

共识机制-权益证明 PoS

發(fā)布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 共识机制-权益证明 PoS 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

共識機制-權(quán)益證明 PoS

什么是權(quán)益證明

權(quán)益證明( Proof of Stake,PoS )最早在2013年被提出,并在 Peercoin 系統(tǒng)中實現(xiàn),類似于現(xiàn)實生活中的股東機制,擁有股份越多的人越容易獲取記賬權(quán)。

點點幣的PoS實現(xiàn)原理

點點幣PPCoin 前期采用PoW挖礦開采和分配貨幣,以保證公平。后期采用PoS機制,保障網(wǎng)絡安全,即擁有51%貨幣難度更大,從而防止51%攻擊。

PoS核心概念為幣齡,即持有貨幣的時間。例如有10個幣、持有90天,即擁有900幣天的幣齡。另外使用幣,即意味著幣齡的銷毀。

在PoS中有一種特殊的交易稱為利息幣,即持有人可以消耗幣齡獲得利息,同時獲得為網(wǎng)絡產(chǎn)生區(qū)塊、以及PoS造幣的優(yōu)先權(quán)。

點點幣的PoS證明計算公式為:

proofhash < 幣齡x目標值

其中proofhash,對應一組數(shù)據(jù)的哈希值,即hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime)。

幣齡即bnCoinDayWeight,即幣天,即持有的幣數(shù)乘以持有幣的天數(shù),此處天數(shù)最大值為90天。

目標值,即bnTarget,用于衡量PoS挖礦難度。目標值與難度成反比,目標值越大、難度越小;反之亦然。

由公式可見,持有的幣天越大,挖到區(qū)塊的機會越大。

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);//權(quán)重修正因子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挖礦難度

點點幣使用目標值來衡量挖礦難度,目標值與難度成反比,目標值越大、難度越小;反之亦然。當前區(qū)塊的目標值與前一個區(qū)塊目標值、前兩個區(qū)塊的時間間隔有關(guān)。

計算公式如下:
  當前區(qū)塊目標值 = 前一個區(qū)塊目標值 x (1007x10x60 + 2x前兩個區(qū)塊時間間隔) / (1009x10x60)

  由公式可見,兩個區(qū)塊目標間隔時間即為10分鐘。
  如果前兩個區(qū)塊時間間隔大于10分鐘,目標值會提高,即當前區(qū)塊難度會降低。
  
  反之,如果前兩個區(qū)塊時間間隔小于10分鐘,目標值會降低,即當前區(qū)塊難度會提高。

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//兩個區(qū)塊目標間隔時間即為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,即區(qū)塊間隔為10分鐘時,1周產(chǎn)生1008個區(qū)塊int64 nInterval = nTargetTimespan / nTargetSpacing;//計算當前區(qū)塊目標值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,并發(fā)布了黑幣。
  黑幣前5000個塊,為純PoW階段;第5001個塊到第10000個塊為PoW與PoS并存階段,從第10001個塊及以后為純PoS階段。
  黑幣首創(chuàng)快速挖礦+低股息發(fā)行模式,發(fā)行階段采用POW方式,通過算法改進在短時間內(nèi)無法制造出專用的GPU和AISC礦機,解決分配不公平的問題。

  PoS2.0相比PoS的改進:

  1、將幣齡從等式中拿掉。新系統(tǒng)采用如下公式計算權(quán)益證明:
  proofhash < 幣數(shù)x目標值

  點點幣中,部分節(jié)點平時保持離線,只在積累了可觀的幣齡以后才連線獲取利息,然后再次離線。
  PoS 2.0中拿掉幣齡,使得積攢幣齡的方法不再有效,所有節(jié)點必須更多的保持在線,以進行權(quán)益累積。
  越多的節(jié)點在線進行權(quán)益累積,系統(tǒng)遭遇51%攻擊的可能性就越低。

  2、為了防范預先計算攻擊,權(quán)益修正因子每次均改變。
  3、改變時間戳規(guī)則,以及哈希算法改用SHA256。
  

黑幣的PoS實現(xiàn)原理

黑幣的PoS證明計算公式為:

proofhash < 幣數(shù)x目標值hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) < bnTarget * nWeight

其中proofhash,對應一組數(shù)據(jù)的哈希值,即hash(nStakeModifier + txPrev.block.nTime + txPrev.nTime + txPrev.vout.hash + txPrev.vout.n + nTime)。
  
幣數(shù)即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);//計算幣數(shù)x目標值int64_t nValueIn = txPrev.vout[prevout.n].nValue;CBigNum bnWeight = CBigNum(nValueIn);bnTarget *= bnWeight;targetProofOfStake = bnTarget.getuint256();//權(quán)重修正因子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 < 幣數(shù)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 機制中,當賬本出現(xiàn)分叉時,對 PoW 這種算力敏感的算法,礦工必須選擇一個方向進行挖礦。而在 PoS 這種算力不敏感的時候,PoS 礦工往往會兩個方向都挖,以爭取實現(xiàn)利益最大化。當多數(shù)礦工都在兩條鏈上一起挖礦的時候,就會很容易出現(xiàn)雙重支付攻擊。

冷啟動問題 ( Initial Distribution Problem )

PoS 機制中,由于持幣量會對挖礦難度產(chǎn)生影響。因此,當一個基于 PoS 體系代幣系統(tǒng)啟動時,就會面臨早期獲得代幣的持有者,沒有動力去花費或者轉(zhuǎn)移代幣給第三方。同時,持有越多的幣,越容易挖到礦,這樣就產(chǎn)生了代幣初始流通性問題。

解決方案:早起幾個版本,通過 PoW 機制來創(chuàng)建貨幣,而非 PoS。由于 PoW 本身的性質(zhì),礦工在挖礦過程中往往需要資金來升級硬件,所以會讓礦工手中的幣流通起來。

長距離攻擊 ( Long-Range Attack )

PoS 中,產(chǎn)生每個 Block 的速度相對 PoW 快了很多。因此,少數(shù)不懷好意的節(jié)點會想著把整個區(qū)塊鏈共識賬本全部重寫。這在 PoW 中是經(jīng)典的 51% 問題,即:當某一個節(jié)點控制了 51% 及以上算力,就有能力篡改賬本,但達到 51% 算力是件極其困難的事情。而在 PoS 中缺乏對算力的約束,那么就存在潛在可能篡改賬本。

解決方案:同步時,限制最大能接受的分叉節(jié)點數(shù)量。

賄賂攻擊(Bribe Attack)

賄賂攻擊流程如下:

攻擊者購買某個商品或服務
商戶開始等待網(wǎng)絡確認這筆交易
此時,攻擊者開始在網(wǎng)絡中首次宣稱,對目前相對最長的不包含這次交易的主鏈進行獎勵。
當主鏈足夠長時,攻擊者開始放出更大的獎勵,獎勵那些在包含此次交易的鏈條中挖礦的礦工。
六次確認達成后,放棄獎勵。
貨物到手,同時放棄攻擊者選中的鏈條。
因此,只要此次賄賂攻擊的成本小于貨物或者服務費用,此次攻擊就是成功的。相比之下,PoW 機制中賄賂攻擊就需要賄賂大多數(shù)礦工,因此成本極高,難以實現(xiàn)。

幣齡加和攻擊 ( Coin Age Accumulation Attack )

在最早的 Peercoin 版本中,挖礦難度不僅與當前賬戶余額有關(guān),也與每個幣的持幣時間掛鉤。

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

這就導致,部分節(jié)點在等待足夠長時間后,就有能力利用 Age 的增加來控制整個網(wǎng)絡,產(chǎn)生非常顯著的影響。

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

預計算攻擊 ( Precomputing Attack)

當 PoS 中的某一節(jié)點占有了一定量的算力后,PoS 中占有特定算力的節(jié)點,就有能力通過控制 H prev
來使自己所在算力范圍有能力去計算

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

PoS 的優(yōu)缺點

優(yōu)點

節(jié)能。不用挖礦,不需要大量耗費電力和能源。
更去中心化。首先說,去中心化是相對的。相對于比特幣等PoW類型的加密貨幣,PoS機制的加密貨幣對計算機硬件基本上沒有過高要求,人人可挖礦(獲得利息),不用擔心算力集中導致中心化的出現(xiàn)(單用戶通過購買獲得51%的貨幣量,成本更高),網(wǎng)絡更加安全有保障。
避免緊縮。PoW機制的加密貨幣,因為用戶丟失等各種原因,可能導致通貨緊縮,但是PoS機制的加密貨幣按一定的年利率新增貨幣,可以有效避免緊縮出現(xiàn),保持基本穩(wěn)定。比特幣之后,很多新幣采用PoS機制,很多采用工作量證明機制的老幣,也紛紛修改協(xié)議,“硬分叉”升級為PoS機制。

缺點

純PoS機制的加密貨幣,只能通過IPO的方式發(fā)行,這就導致“少數(shù)人”(通常是開發(fā)者)獲得大量成本極低的加密貨幣,在利益面前,很難保證他們不會大量拋售。
PoS機制的加密貨幣,信用基礎不夠牢固。
為解決這個問題,很多采用PoW+PoS的雙重機制,通過PoW挖礦發(fā)行加密貨幣,使用PoS維護網(wǎng)絡穩(wěn)定。或者采用DPoS機制,通過社區(qū)選舉的方式,增強信任。

參考鏈接:

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

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

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

總結(jié)

以上是生活随笔為你收集整理的共识机制-权益证明 PoS的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。