您的位置:首页 > 编程语言

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

2018-01-20 12:15 405 查看
源码文件名:chainparams.cpp

100 class

CMainParams: public
CChainParams{
101 public:
102 
CMainParams(){
103 // The message start string is designed tobe unlikely to occur in normal data.
104 // The characters are rarely used upperASCII, not valid as UTF-8, and produce
105 // a large 4-byte int at anyalignment.
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 theoutput of the genesis coinbase cannot
117 // be spent as it did not originally existin 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), coinbase04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
122 // CTxOut(nValue=50.00000000,scriptPubKey=0x5F1DF16B2B704C8A578D0B)
123 // vMerkleTree: 4a5e1e
124 const char* pszTimestamp ="TheTimes 03/Jan/2009 Chancellor on brink of second bailout forbanks";
125 
CTransactiontxNew;
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
unsignedchar*)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 usableaddress objects.
157 for (unsigned
int i = 0; i<
ARRAYLEN(pnSeed);i++)
158  {
159 // It'll only connect to one or two seednodes because once it connects,
160 // it'll get a pile of addresses withnewer timestamps.
161 // Seed nodes are given a random 'lastseen 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 
CAddressaddr(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
NetworkNetworkID()const {return

CChainParams::MAIN;}
174 
175 virtual const vector&

FixedSeeds()const{
176 return vFixedSeeds;
177  }
178 protected:
179 
CBlockgenesis;
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 unsignedchar*)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"));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息