2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

フォークコインを作るときに、ジェネシスブロックのハッシュ値をマイニングする

2
Last updated at Posted at 2018-08-28

以前の記事が自分の勘違いで一切マイニングをしないコードになっていたため、きちんとマイニングするように修正しました。

genesisのpszTimestampやnTime、を書き換えると、起動時にこんな感じのエラーが出る。

coind: chainparams.cpp:152: CMainParams::CMainParams(): Assertion `consensus.hashGenesisBlock == uint256S("00000…0000")' failed

原因はsrc/chainparams.cppのここ

genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1e0ffff0, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x0000…f"));
assert(genesis.hashMerkleRoot == uint256S("0x12345…f"));

もちろんジェネシスブロックのハッシュが変わってるのでassertで落ちてる。
ファイルの頭あたりにあるCreateGenesisBlockの中で力技でマイニングさせるようにする。

差分はこんな感じ。

ヘッダーにarith_uint256.hを追加
  #include "chainparams.h"
  #include "consensus/merkle.h"
+ #include "arith_uint256.h"
 
  #include "tinyformat.h"
  #include "util.h"
マイニングするコードを追加
static CBlock CreateGenesisBlock(const CScript& pszTimestamp, const CScript& genesisOutputScript, …enesisReward)
{
    CMutableTransaction txNew;
    txNew.nVersion = 1;
    txNew.vin.resize(1);
    txNew.vout.resize(1);
    txNew.vin[0].scriptSig = …………
    txNew.vout[0].nValue = genesisReward;
    txNew.vout[0].scriptPubKey = genesisOutputScript;

    CBlock genesis;
    genesis.nTime    = nTime;
    genesis.nBits    = nBits;
    genesis.nNonce   = nNonce;
    genesis.nVersion = nVersion;

    genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
    genesis.hashPrevBlock.SetNull();
    genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
+
+    arith_uint256 hashTarget = arith_uint256().SetCompact(genesis.nBits);
+    std::cout << hashTarget.ToString() << '\n';
+    while (UintToArith256(genesis.GetHash()) > hashTarget) ++genesis.nNonce;
+
     return genesis;
 }

で、これでマイニングが成功すると、動作が帰ってくる。
そのときにnNonceを表示するため、genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1e0ffff0, 1, 50 * COIN);の下に以下のコードを挿入する。

std::cout << "genesis.nTime = " << genesis.nTime << '\n';
std::cout << "genesis.nBits = " << genesis.nBits << '\n';
std::cout << "genesis.nNonce = " << genesis.nNonce << '\n';
std::cout << "genesis.GetHash = " << genesis.GetHash().ToString() << '\n';

これで、coind起動時にマイニングが起動、ジェネシスブロックをマイニングしてそのnNonceを吐き出すようになる。その値をassertに突っ込めば良い。

ちなみに、今回のnBitsである0x1e0ffff0はモナコインから流用した。難易度的にはものすごく簡単なため数秒でマイニングに成功する。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?