全称为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