比特幣原始碼閱讀筆記-創世塊的產生_區塊鏈
來源:互聯網
上載者:User
源碼檔案名稱: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 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 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 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 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"));