比特币源代码阅读笔记-创世块的产生_易安定_新浪博客

如果你有兴趣和我一起探讨比特币源代码,
可以加QQ群157491340

 157491340157491340157491340

版本 0.9.99
源码文件名:chainparams.cpp

 

 

 

100 class CMainParams

: public CChainParams

{

 

 

101 public:

 

 

102  CMainParams()

{

 

 

103  // The message start string is designed to

be unlikely to occur in normal data.

 

 

104  // The characters are rarely used upper

ASCII, not valid as UTF-8, and produce

 

 

105  // a large 4-byte int at any

alignment.

 

 

106  pchMessageStart[0] = 0xf9;

 

 

107  pchMessageStart[1] = 0xbe;

 

 

108  pchMessageStart[2] = 0xb4;

 

 

109  pchMessageStart[3] = 0xd9;

 

 

110  vAlertPubKey = ParseHex(“04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284″);

 

 

111  nDefaultPort = 8333;

 

 

112  nRPCPort = 8332;

 

 

113  bnProofOfWorkLimit = ~uint256(0)

>> 32; //这个位置,是设置最小难度的限制,uint256是一个封装类,经常用来存储hash值之类的大数据.

256位,64字节. 将它右移32位, 实际上就是前面4字节是0的一个64位值.16进制是

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

 

 

114  nSubsidyHalvingInterval =

210000;

 

 

115 

 

 

116  // Build the genesis block. Note that the

output of the genesis coinbase cannot

 

 

117  // be spent as it did not originally exist

in the database.

 

 

118  //

 

 

119  // CBlock(hash=000000000019d6, ver=1,

hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e,

nTime=1231006505, nBits=1d00ffff, nNonce=2083236893,

vtx=1)

 

 

120  // CTransaction(hash=4a5e1e, ver=1,

vin.size=1, vout.size=1, nLockTime=0)

 

 

121  // CTxIn(COutPoint(000000, -1), coinbase

04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)

 

 

122  // CTxOut(nValue=50.00000000,

scriptPubKey=0x5F1DF16B2B704C8A578D0B)

 

 

123  // vMerkleTree: 4a5e1e

 

 

124  const char* pszTimestamp =

“The

Times 03/Jan/2009 Chancellor on brink of second bailout for

banks”;

 

 

125  CTransaction

txNew;

 

 

126  txNew.vin.resize(1);

 

 

127  txNew.vout.resize(1);

 

 

128  txNew.vin[0].scriptSig

= CScript()

<< 486604799 << CScriptNum(4)

<< vector((const unsigned char*)pszTimestamp, (const unsigned

char*)pszTimestamp +

strlen(pszTimestamp));

 

 

129  txNew.vout[0].nValue

= 50 * COIN;

 

 

130  txNew.vout[0].scriptPubKey

= CScript()

<< ParseHex(“04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f”)

<< OP_CHECKSIG;

 

//这段代码创建一个交易, pszTimestamp 是coinbase 的文字,

作者用2009年1月3日在报纸上的一个标题写在这里,为的是证明这个创世块的产生迟于2009年1月3日,以表明在这之前,作者没有预挖比特币.很聪明的做法.

 

 

131  genesis.vtx.push_back(txNew);

 

 

132  genesis.hashPrevBlock = 0;

 

 

133  genesis.hashMerkleRoot =

genesis.BuildMerkleTree();

 

 

134  genesis.nVersion = 1;

 

 

135  genesis.nTime =

1231006505;//这个时间,就是unix时间,从1970年1月1日到2009年1月3日之间的秒数.unix系统常常用这种整数表达时间.

 

 

136  genesis.nBits = 0x1d00ffff;

//这个是难度

 

 

137  genesis.nNonce =

2083236893;//这个不是随机数字,挖矿的过程,就是寻找这个数字,来使得区块的HASH值小于genesis.nBits

所指定的难度.

genesis.nNonce是参与hash运算的源数据的一部份.所以,修改这个值,整个hash值就会发生改变.

 

 

138 

 

 

139  hashGenesisBlock =

genesis.GetHash();//计算区块的hash值

 

 

140  assert(hashGenesisBlock == uint256(“0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f”));//这段代码是检验hash值是不是正确.

 

 

141  assert(genesis.hashMerkleRoot ==

uint256(“0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b”));

 

 

142 

 

 

143  vSeeds.push_back(CDNSSeedData(“bitcoin.sipa.be”,

“seed.bitcoin.sipa.be”));

 

 

144  vSeeds.push_back(CDNSSeedData(“bluematt.me”, “dnsseed.bluematt.me”));

 

 

145  vSeeds.push_back(CDNSSeedData(“dashjr.org”, “dnsseed.bitcoin.dashjr.org”));

 

 

146  vSeeds.push_back(CDNSSeedData(“bitcoinstats.com”,

“seed.bitcoinstats.com”));

 

 

147  vSeeds.push_back(CDNSSeedData(“bitnodes.io”, “seed.bitnodes.io”));

 

 

148  vSeeds.push_back(CDNSSeedData(“xf2.org”, “bitseed.xf2.org”));

 

 

149 

 

 

150  base58Prefixes[PUBKEY_ADDRESS] =

list_of(0);

 

 

151  base58Prefixes[SCRIPT_ADDRESS] =

list_of(5);

 

 

152  base58Prefixes[SECRET_KEY] =

list_of(128);

 

 

153  base58Prefixes[EXT_PUBLIC_KEY] =

list_of(0x04)(0x88)(0xB2)(0x1E);

 

 

154  base58Prefixes[EXT_SECRET_KEY] =

list_of(0x04)(0x88)(0xAD)(0xE4);

 

 

155 

 

 

156  // Convert the pnSeeds array into usable

address objects.

 

 

157  for (unsigned int i = 0; i

< ARRAYLEN(pnSeed);

i++)

 

 

158  {

 

 

159  // It’ll only connect to one or two seed

nodes because once it connects,

 

 

160  // it’ll get a pile of addresses with

newer timestamps.

 

 

161  // Seed nodes are given a random ‘last

seen time’ of between one and two

 

 

162  // weeks ago.

 

 

163  const int64_t nOneWeek =

7*24*60*60;

 

 

164  struct in_addr ip;

 

 

165  memcpy(&ip,

&pnSeed[i],

sizeof(ip));

 

 

166  CAddress

addr(CService(ip,

GetDefaultPort()));

 

 

167  addr.nTime

= GetTime() –

GetRand(nOneWeek)

– nOneWeek;

 

 

168  vFixedSeeds.push_back(addr);

 

 

169  }

 

 

170  }

 

 

171 

 

 

172  virtual const CBlock&

GenesisBlock()

const {

return genesis; }

 

 

173  virtual Network

NetworkID()

const {

return CChainParams::MAIN;

}

 

 

174 

 

 

175  virtual const vector& FixedSeeds()

const

{

 

 

176  return vFixedSeeds;

 

 

177  }

 

 

178 protected:

 

 

179  CBlock

genesis;

 

 

180  vector vFixedSeeds;

 

 

181 };

 

 

 

 

因为我要创建新的货币,所以,尝试创建自己的创世区

 

 

 

代码如下:

 

 

 

const char*

pszTimestamp = “2014/5/11 Write by Andy,Email:yianding@gmail.com”;

//我的创世区块 CTransaction txNew; txNew.vin.resize(1);

txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() <<

486604799 << CBigNum(4) << vector((const unsigned

char*)pszTimestamp, (const unsigned char*)pszTimestamp +

strlen(pszTimestamp)); txNew.vout[0].nValue = 50 * COIN;

txNew.vout[0].scriptPubKey = CScript() <<

ParseHex(“04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f”)

<< OP_CHECKSIG; genesis.vtx.push_back(txNew);

genesis.hashPrevBlock = 0; genesis.hashMerkleRoot =

genesis.BuildMerkleTree(); genesis.nVersion = 1; genesis.nTime =

1399744437; genesis.nBits = 0x1e00ffff; //我将难度设置的比较低.便于我快速的找出nNonce

,当然,最后发布的时候,我会重新生成难度比较高的区块。 genesis.nNonce = 130387;

//符合要求的nNonce值。这个值,我通过下面的代码来寻找。 //这段代码寻找我的nNonce值 unsigned int i;

CBigNum bnTarget; for(i=0;i<0x7fffffff;i++){ //基本上是穷举法 ,让i不断增加

genesis.nNonce = i; //将i赋值给nNonce hashGenesisBlock =

genesis.GetHash();//生成 hash值 bnTarget.SetCompact(genesis.nBits);

//将nBits参数转换成256位的最大hash值。挖矿就是要寻找比这个 hash值更小的值。 if

(hashGenesisBlock < bnTarget.getuint256()){

//判断hash值是否小于最大hash值,如果小于,那就说明我找到了合适的nNonce值。挖矿成功。我这里找到的值就是130387,当然,我不会每次都重新挖我的创世区块,实际运行的时候,我会把130387直接写入nNonce。

printf(“\nI=%i \n”,i);

cout<<“\nnNonce=”<<genesis.nNonce<<”

hash=”<<hashGenesisBlock.GetHex(); break;

//寻找到了这个值,自然就退出循环。实际上,符合条件的nNonce不会只有一个。但是,我们只要找到这个符合条件的值就可以了。 }

}

 

//——寻找nNonce值代码结束

//printf(“hashGenesisBlock: %x\n”,hashGenesisBlock); //

printf(“genesis.hashMerkleRoot: %x\n”,genesis.hashMerkleRoot);

//assert(hashGenesisBlock ==

uint256(“0x1a5299d469c5d424a999c82a05bb36b631cccb899b44cb16c46d5b03b50e696″));

// assert(genesis.hashMerkleRoot ==

uint256(“0xa3bdc0d6741b0d1c3bcbca154f3deb84132fbfde9dfaa2f880e40ff3e3c38712″));

 

 

来源URL:http://blog.sina.com.cn/s/blog_5922b3960101s3ap.html