当一个节点成功地构造出一个新的候选区块(计算出了正确的Nonce随机数)后,节点会将这个候选区块在P2P网络中传播,每一个节点转发这个区块到其节点之前,会进行一系列的验证,没有通过验证的区块会被节点拒绝收录和传播。每个节点都将按照以下检查项对新区块进行验证:
src/validation.cpp中的区块验证代码如下:
bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot) { if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW)) return false; // 验证Merkle根 if (fCheckMerkleRoot) { bool mutated; uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated); if (block.hashMerkleRoot != hashMerkleRoot2) return state.DoS(100, false, REJECT_INVALID, "bad-txnmrklroot", true, "hashMerkleRoot mismatch"); // 检查Merkle树的延展性 (CVE-2012-2459): 侦测即使在区块Merkle根没有被改变的情况下,如发现有重复的交易则依然拒绝该区块 if (mutated) return state.DoS(100, false, REJECT_INVALID, "bad-txns-duplicate", true, "duplicate transaction"); } // Size 限制 if (block.vtx.empty() || block.vtx.size() * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT || ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed"); // 第一笔交易必须是coinbase交易,且其他位置不能是coinbase交易 if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) return state.DoS(100, false, REJECT_INVALID, "bad-cb-missing", false, "first tx is not coinbase"); for (unsigned int i = 1; i < block.vtx.size(); i++) if (block.vtx[i]->IsCoinBase()) return state.DoS(100, false, REJECT_INVALID, "bad-cb-multiple", false, "more than one coinbase"); // 检查交易 for (const auto& tx : block.vtx) if (!CheckTransaction(*tx, state, true)) return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), state.GetDebugMessage())); }
当区块通过验证后,节点把这个新区块转发给邻近节点,并把这个区块收录到本地存储中,区块的链接就算完成了。如果这个节点是一个挖矿节点,节点将基于这个新区块的头部哈希值重新构造新的区块,并基于新区块的数据信息开始新一轮的挖矿。
如果一个区块被拒绝,那么发起这个区块的矿工不但得不到任何奖励,还会损失挖矿所付出的电费以及硬件成本。比特币价格的逐步上涨将吸引更多的矿工加入,这会导致挖矿的难度和挖矿的成本增加,大大增加了矿工的“作恶”成本,所以矿工会严格按照系统的规定进行操作。比特币价格越坚挺,系统将越健壮,恶意节点也将越少。