比特币源码阅读(0.16)(四)

chainparams.cpp::CreateGenesisBlock

可以使用工具生成创世块的参数

  1. https://github.com/lhartikk/GenesisH0
  2. https://github.com/nasa8x/node-genesis-block
  3. https://github.com/nasa8x/genesis-block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
//用一条当天新闻表示之前没有偷挖过矿
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";

//创世块中,这个值没有什么具体用途,只要是个唯一的值就可以了,不一定需要是私钥。
const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;

return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}


static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
//被广播到网络上和打包进区块的基本的交易结构,一个交易可以有多个的输入和输出
//区块中的第一笔交易是笔特殊交易,称为创币交易或者coinbase交易。
CMutableTransaction txNew;
txNew.nVersion = 1;
//1个输入
txNew.vin.resize(1);
//1个输出
txNew.vout.resize(1);
//与常规交易不同,创币交易没有输入,不消耗UTXO。它只包含一个被称作coinbase的输入,仅仅用来创建新的比特币。
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
//创币交易有一个输出,支付到这个矿工的比特币地址。
txNew.vout[0].nValue = genesisReward;
txNew.vout[0].scriptPubKey = genesisOutputScript;

CBlock genesis;
//创世块生成的UNIX时间
genesis.nTime = nTime;
//挖矿的过程,就是寻找数字,来使得区块的HASH值小于nBits所指定的难度目标
genesis.nBits = nBits;
//挖矿的目标是找到一个使区块头哈希值小于难度目标的 nonce。挖矿节点通常需要尝试数十亿甚至数万亿个不同的nonce取值,直到找到一个满足条件的nonce值。.
genesis.nNonce = nNonce;
genesis.nVersion = nVersion;
genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
genesis.hashPrevBlock.SetNull();

//在比特币网络中,Merkle树被用来归纳一个区块中的所有交易,同时生成整个交易集合的数字指纹,
//且提供了一种校验区块是否存在某交易的高效途径。生成一棵完整的Merkle树需要递归地对哈希节点对进行哈希,
//并将新生成的哈希节点插入到Merkle树中,直到只剩一个哈希节点,该节点就是Merkle树的根。
//在比特币的Merkle树中两次使用到了SHA256 算法,因此其加密哈希算法也被称为double-SHA256。
genesis.hashMerkleRoot = BlockMerkleRoot(genesis);

return genesis;
}