全稱爲Proof Of Work,又叫工做量證實。POW是最先的共識機制。POW是指工做者經過必定的工做量,提供一個能被大多數驗證者快速驗證的答案,從而獲得獎勵的機制。git
講原理以前,先給你們普及兩個概念:難度值和noncegithub
難度值就是礦工挖礦成功的難度成程度,那這個是怎麼判斷的呢?咱們先學習一個公式:
target值 = 最大目標值 / 難度值
其中最大目標值是固定的,出塊以前,區塊鏈網絡設置了一個target值,target值越低,生成有效hash的集合就越小,生成有效hash就越困難。當前出塊難度值,它決定了大概須要通過多少次哈希運算才能產生一個合法的區塊。出塊以前,區塊鏈網絡設置了一個target值,target值越低,生成有效hash的集合就越小,生成有效hash就越困難。安全
nonce值是什麼呢?它就是一個隨機數,系統區塊工做證實的參數。因爲給定的一組數據只能生成一個hash,礦工如何確保他們生成的hash小於target?它們經過添加一個稱爲nonce的整數(number only used once )來改變輸入的數據,一旦找到一個有效的hash,它就被廣播到網絡中,同時區塊被添加到區塊鏈中,找到這個nonce整數的礦工就能得到獎勵。網絡
上面兩個概念瞭解了以後呢,原理其實就很容易理解了。pow機制的原理其實就是:系統設定好挖礦難度(比特幣2016個塊以後從新計算,以太坊每次生成區塊都從新計算),而後礦工開始工做出塊,礦工每次出塊都是nonce從1開始遞增進行尋找可用的nonce值,直到找到符合規則、可用的hash爲止,最早找到的礦工可得到挖礦獎勵。ide
理論咱們講的差很少了,你們坐穩扶好,接下來直接上代碼進行分析,一口氣讀完溫馨感最佳。函數
static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& max_tries, unsigned int& extra_nonce, uint256& block_hash) { // 區塊hash置空 block_hash.SetNull(); { LOCK(cs_main); CHECK_NONFATAL(std::addressof(::ChainActive()) == std::addressof(chainman.ActiveChain())); IncrementExtraNonce(&block, chainman.ActiveChain().Tip(), extra_nonce); } CChainParams chainparams(Params()); // 獲取可用nonce值 while (max_tries > 0 && block.nNonce < std::numeric_limits<uint32_t>::max() && !CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus()) && !ShutdownRequested()) { ++block.nNonce; --max_tries; } if (max_tries == 0 || ShutdownRequested()) { return false; } if (block.nNonce == std::numeric_limits<uint32_t>::max()) { return true; } std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block); if (!chainman.ProcessNewBlock(chainparams, shared_pblock, true, nullptr)) { throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); } block_hash = block.GetHash(); return true; }
計算nonce值的那一段咱們單獨進行分析學習
while (max_tries > 0 && block.nNonce < std::numeric_limits<uint32_t>::max() && !CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus()) && !ShutdownRequested()) { ++block.nNonce; --max_tries; }
1.首先判斷是否達到最大重試次數MaxTries > 0 ,maxTries默認值DEFAULT_MAX_TRIES爲1000000,達到最大重試次數未得到可用nonce,則該礦工這次挖礦失敗。區塊鏈
if (max_tries == 0 || ShutdownRequested()) { return false; }
2.判斷nNonce < std::numeric_limits<uint32_t>::max(),即控制nonce在一次挖礦做業中的隨機次數不得超過uint32的最大值。若是nNonce值修改的次數已經超過了規定的次數尚未找到工做量證實的一個解,則廢棄這個候選區塊,從新回到前面建立一個新的候選區塊。ui
if (block.nNonce == std::numeric_limits<uint32_t>::max()) { return true; }
3.執行CheckProofOfWork,源碼以下code
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params) { bool fNegative; bool fOverflow; arith_uint256 bnTarget; bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) return false; // Check proof of work matches claimed amount if (UintToArith256(hash) > bnTarget) return false; return true; }
上面函數大概意思就是根據nBits難度值獲取到的target,是在可用區間內的,而且計算得出的hash小於target值,則本次hash爲可用hash值。
4.未挖礦成功則一直循環計算,直到找到可用nonce值或上述一、二、3中某一步驟不符合while循環條件爲止。
待整理
將記帳權公平的分派到全部節點,記帳權是經過看節點的PoW, 誰挖礦最快, 誰就能拿到這個礦
破解系統至少須要51%的節點,成本高,耗時長
節點之間無需信任保證,經過零知識證實快速驗證安全性
顧名思義,工做量證實須要大量的工做計算hash,花費的共識時間長,出塊速度慢。好比比特幣出塊時間10分鐘,每秒鐘支持最大交易數僅爲7筆。
挖礦須要大量的哈希運算,須要電力和各類算力資源,並且找到合適的哈希值實際上並無其餘的做用
因爲礦池的出現,致使如今算力集中在幾家,BTC.COM,Antpool,ViaBTC前三大礦池,已經佔到了全網52.4%的算力水平。
咱們看完文章就應該知道,pow的初衷就是它的破解複雜度,安全性高,pow的破解須要51%的節點纔可能實現。可是算力集中化的出現,致使前幾大礦池擁有的算力超過了51%,可能會出現他們聯合起來惡意出塊的現象,違背了pow的初衷。
比特幣源碼連接:https://github.com/bitcoin/bitcoin