加载中…
正文 字体大小:

比特币源代码阅读笔记-创世块的产生

(2014-05-11 05:50:50)
标签:

比特币

源代码

开发

分类: 比特币
如果你有兴趣和我一起探讨比特币源代码,
可以加QQ群157491340   157491340157491340157491340
版本 0.9.99
源码文件名:chainparams.cpp

100 class CMainParams : public CChainParams {
101 public:
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:
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"));

0

阅读 评论 收藏 转载 喜欢 打印举报
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有