<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                PoS,即Proof of Stake,譯為權益證明。 無論PoW或PoS,均可以理解為“誰有資格寫區塊鏈”的問題。 PoW通過算力證明自己有資格寫區塊鏈,而PoS則是通過擁有的幣齡來證明自己有資格寫區塊鏈。 ### **PoW的優勢和弊端** PoW,優勢為可靠,使用廣泛,是經歷了充分的實踐檢驗的公有鏈共識算法。 但其缺點也較為明顯: * 1、消耗了太多額外算力,即大量能源。 * 2、資本大量投資礦機,導致算力中心化,有51%攻擊的安全隱患。 ### **PoS的提出和點點幣** 第一個基于PoS的虛擬幣是點點幣。 鑒于PoW的缺陷,2012年Sunny King提出了PoS,并基于PoW和PoS的混合機制發布了點點幣PPCoin。 前期采用PoW挖礦開采和分配貨幣,以保證公平。后期采用PoS機制,保障網絡安全,即擁有51%貨幣難度更大,從而防止51%攻擊。 PoS核心概念為幣齡,即持有貨幣的時間。例如有10個幣、持有90天,即擁有900幣天的幣齡。 另外使用幣,即意味著幣齡的銷毀。 在PoS中有一種特殊的交易稱為利息幣,即持有人可以消耗幣齡獲得利息,同時獲得為網絡產生區塊、以及PoS造幣的優先權。 ### **點點幣的PoS實現原理** 點點幣的PoS證明計算公式為: proofhash < 幣齡x目標值 展開如下: hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget x bnCoinDayWeight * 其中proofhash,對應一組數據的哈希值,即hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime)。 * 幣齡即bnCoinDayWeight,即幣天,即持有的幣數乘以持有幣的天數,此處天數最大值為90天。 * 目標值,即bnTarget,用于衡量PoS挖礦難度。目標值與難度成反比,目標值越大、難度越小;反之亦然。 由公式可見,持有的幣天越大,挖到區塊的機會越大。 peercoin-0.6.1ppc中PoS證明計算代碼如下: ```c++ 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 violation return error("CheckStakeKernelHash() : nTime violation"); unsigned int nTimeBlockFrom = blockFrom.GetBlockTime(); if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement return error("CheckStakeKernelHash() : min age violation"); //目標值使用nBits CBigNum 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 low int64 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 hash CDataStream 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; } //代碼位置src/kernel.cpp ``` ### **點點幣的PoS挖礦難度** 點點幣使用目標值來衡量挖礦難度,目標值與難度成反比,目標值越大、難度越小;反之亦然。 當前區塊的目標值與前一個區塊目標值、前兩個區塊的時間間隔有關。 計算公式如下: 當前區塊目標值 = 前一個區塊目標值 x (1007x10x60 + 2x前兩個區塊時間間隔) / (1009x10x60) 由公式可見,兩個區塊目標間隔時間即為10分鐘。 如果前兩個區塊時間間隔大于10分鐘,目標值會提高,即當前區塊難度會降低。 反之,如果前兩個區塊時間間隔小于10分鐘,目標值會降低,即當前區塊難度會提高。 peercoin-0.6.1ppc中目標值計算代碼如下: ```c++ unsigned int static GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) { if (pindexLast == NULL) return bnProofOfWorkLimit.GetCompact(); // genesis block const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); if (pindexPrev->pprev == NULL) return bnInitialHashTarget.GetCompact(); // first block const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake); if (pindexPrevPrev->pprev == NULL) return bnInitialHashTarget.GetCompact(); // second block int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); // ppcoin: target change every block // ppcoin: retarget with exponential moving toward target spacing CBigNum 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(); } //代碼位置src/kernel.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證明計算代碼如下: ```c++ 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 violation return error("CheckStakeKernelHash() : nTime violation"); //目標值使用nBits CBigNum 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; else ss << 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; } ``` ### **附錄** * [點點幣github](https://github.com/peercoin) * [黑幣github](https://github.com/CoinBlack/blackcoin) * [點點幣白皮書(中文版)](https://github.com/fengchunjian/ConsensusAlgorithm/blob/master/pos/%E7%82%B9%E7%82%B9%E5%B8%81%E7%99%BD%E7%9A%AE%E4%B9%A6%EF%BC%88%E4%B8%AD%E6%96%87%E7%89%88%EF%BC%89.pdf) * [黑幣PoS協議2.0版白皮書](https://github.com/fengchunjian/ConsensusAlgorithm/blob/master/pos/%E9%BB%91%E5%B8%81PoS%E5%8D%8F%E8%AE%AE2.0%E7%89%88%E7%99%BD%E7%9A%AE%E4%B9%A6.pdf) ### **后記** PoS有種種優點,但也有所缺陷。 即因為PoS并不消耗更多的算力,因此如果出現分叉,理性節點會在所有鏈上同時PoS挖礦。 以至于每次分叉都會形成新的山寨幣,即PoS無法很好的應對分叉
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看