(本文使用的是比特币v0.1.0版本 点击下载源码)
本文主要描述创世块是如何产生的,接着之前的文章《比特币源码解读之初始化》中初始化加载模块进行描述,本文主要描述创世块时间戳、创币奖励、区块信息的初始化,以及区块的存储以及区块索引的生成。
流程图如下所示:
加载区块索引
if (!LoadBlockIndex())strErrors += "Error loading blkindex.dat\n";bool LoadBlockIndex(bool fAllowNew){//// Load block index//CTxDB txdb("cr");if (!txdb.LoadBlockIndex())return false;txdb.Close();....}
判断区块索引是否为空
// Init with genesis block//if (mapBlockIndex.empty()){if (!fAllowNew)return false;...}
初始化时间戳和交易
(1)时间戳为”The Times 03/Jan/2009 Chancellor on brink of second bailout for banks” ,这句话正是泰晤士报当天的头版文章标题“2009年1月3日,财政大臣正站在第二轮救助银行业的边缘”。时间戳是作为存在性证明(Proof of existence)的关键参数。
(2)创世币的奖励为50BTC,输入为空,输出公钥为
// Genesis blockchar* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";CTransaction txNew;txNew.vin.resize(1);txNew.vout.resize(1);txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp));txNew.vout[0].nValue = 50 * COIN;txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG;
初始化区块
CBlock block;block.vtx.push_back(txNew);block.hashPrevBlock = 0; 前一区块为0block.hashMerkleRoot = block.BuildMerkleTree(); 计算交易的Merkle值block.nVersion = 1; 版本号为1block.nTime = 1231006505; 北京时间为2009/1/4 2:15:5block.nBits = 0x1d00ffff; 记录本区块难度block.nNonce = 2083236893; 随机数
其中nNonce 的值设定使得该块的hash是以一串0开头的。对于块数据的一点点改变(比如nonce)都会引起block hash的巨大变化。由于逆向预测hash值相对应的一组bit值(hash原文)是不可行的,在尝试足够多的nonce值且计算每个nonce值相对应的block hash之后可以找到一个满足有指定数量 0 bits (0比特位) 的hash值。
HASH校验
校验交易的Merkle值和区块Hash
assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));assert(block.GetHash() == hashGenesisBlock);
区块写入磁盘中
文件名为blk0001.dat,后续区块名字递增,如blk0002.dat …
unsigned int nFile;unsigned int nBlockPos;if (!block.WriteToDisk(!fClient, nFile, nBlockPos))return error("LoadBlockIndex() : writing genesis block to disk failed");bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet){// Open history file to appendCAutoFile fileout = AppendBlockFile(nFileRet);if (!fileout)return error("CBlock::WriteToDisk() : AppendBlockFile failed");if (!fWriteTransactions)fileout.nType |= SER_BLOCKHEADERONLY;// Write index headerunsigned int nSize = fileout.GetSerializeSize(*this);fileout << FLATDATA(pchMessageStart) << nSize;// Write blocknBlockPosRet = ftell(fileout);if (nBlockPosRet == -1)return error("CBlock::WriteToDisk() : ftell failed");fileout << *this;return true;}
增加区块索引
if (!block.AddToBlockIndex(nFile, nBlockPos))return error("LoadBlockIndex() : genesis block not accepted");
其功能包含重复性区块检查、最好分支处理、新最好分支处理等等,在后续比特币源码解读之挖矿一文中介绍
上一篇: 比特币源码解读之私钥、公钥和地址
版权声明:B链网原创,严禁修改。转载请注明作者和原文链接
http://www.360bchain.com/article/76.html