Peercoin genesis block creation

Hello there,

I’m experimenting around with the creation of my own genesis block / own chain of peercoin. Unfortunately the only tutorial for this is for PeerShares, which is not maintained anymore.

From what I’ve read on forums and combined with the peershares tutorial, this is what I did, which unfortunately does not succeeed:

main.cpp commented out line 3222:

//hashGenesisBlock = uint256("00008d0d88095d31f6dbdbcf80f6e51f71adf2be15740301f5e05cc0f3b2d2c0");

main.cpp changed pszTimestamp on line 3271:

const char* pszTimestamp = "NYT 9-4-18 Facebooks Other Critics: Its Viral Stars";

Compiling goes OK, I get this since the hashMerkleRoot is the old one from peercoin chain

/peercoin/src$ ./peercoind
peercoind: main.cpp:3310: bool InitBlockIndex(): Assertion `block.hashMerkleRoot == uint256(“0x3c2d8f85fab4d17aac558cc648a1a58acff0de6deb890c29985690052c5993c2”)’ failed.
Aborted (core dumped)

And the content of my debug.log:

2018-04-09 11:57:45 Opened LevelDB successfully
2018-04-09 11:57:45 Peercoin Network: genesis=0x0000000032fe677166d5 nBitsLimit=0x1d00ffff nBitsInitial=0x1c00ffff nStakeMinAge=2592000 nCoinbaseMaturity=500 nModifierInterval=21600
2018-04-09 11:57:45 LoadBlockIndexDB(): last block file = 0
2018-04-09 11:57:45 LoadBlockIndexDB(): synchronized checkpoint not read
2018-04-09 11:57:45 LoadBlockIndexDB(): synchronized checkpoint 0000000032fe677166d54963b62a4677d8957e87c508eaa4fd7eb1c880cd27e3
2018-04-09 11:57:45 LoadBlockIndexDB(): transaction index disabled
2018-04-09 11:57:45 Initializing databases…
2018-04-09 11:57:45 ba2c38d635163680e895cf4edf86153ccd73fab8fbcd73b00f3b4daefe21f3a4
2018-04-09 11:57:45 0000000032fe677166d54963b62a4677d8957e87c508eaa4fd7eb1c880cd27e3
2018-04-09 11:57:45 e947fc6a60eadcf5b9a891fd23633f44e42e5d70d2fd5390e7f0a016f45e60dc

from debug.log i get the hashMerkleRoot which should be the last value (last line) and add it to line 3310 in main.cpp:

assert(block.hashMerkleRoot == uint256("0x72617357890cf4285cbfd9eaeebf6f25db7057b2b678cd8f5bfaa3080193e74f"));

Now I recompile again, get the genesisBlockHash from the debug file: in this case it should be (?): 2018-04-09 12:31:09 0000000032fe677166d54963b62a4677d8957e87c508eaa4fd7eb1c880cd27e3 and add it to main.cpp line 3222:

hashGenesisBlock = uint256("0000000032fe677166d54963b62a4677d8957e87c508eaa4fd7eb1c880cd27e3");

After last compile, this is my error:

bibz@bibz-u:~/peercoin/src$ ./peercoind
peercoind: main.cpp:3312: bool InitBlockIndex(): Assertion `hash == hashGenesisBlock’ failed.
Aborted (core dumped)

and debug.log:

2018-04-09 12:31:09 Peercoin version v0.6.2ppc-dirty (2018-03-10 20:21:14 +0300)
2018-04-09 12:31:09 Using OpenSSL version OpenSSL 1.0.2g 1 Mar 2016
2018-04-09 12:31:09 Default data directory /home/bibz/.peercoin
2018-04-09 12:31:09 Using data directory /home/bibz/.peercoin
2018-04-09 12:31:09 Using at most 125 connections (1024 file descriptors available)
2018-04-09 12:31:09 Using 12 threads for script verification
2018-04-09 12:31:09 init message: Verifying wallet…
2018-04-09 12:31:09 dbenv.open LogDir=/home/bibz/.peercoin/database ErrorFile=/home/bibz/.peercoin/db.log
2018-04-09 12:31:09 Bound to [::]:9901
2018-04-09 12:31:09 Bound to 0.0.0.0:9901
2018-04-09 12:31:09 init message: Loading block index…
2018-04-09 12:31:09 Opening LevelDB in /home/bibz/.peercoin/blocks/index
2018-04-09 12:31:09 Opened LevelDB successfully
2018-04-09 12:31:09 Opening LevelDB in /home/bibz/.peercoin/chainstate
2018-04-09 12:31:09 Opened LevelDB successfully
2018-04-09 12:31:09 Peercoin Network: genesis=0x0000000032fe677166d5 nBitsLimit=0x1d00ffff nBitsInitial=0x1c00ffff nStakeMinAge=2592000 nCoinbaseMaturity=500 nModifierInterval=21600
2018-04-09 12:31:09 LoadBlockIndexDB(): last block file = 0
2018-04-09 12:31:09 LoadBlockIndexDB(): synchronized checkpoint not read
2018-04-09 12:31:09 LoadBlockIndexDB(): synchronized checkpoint 0000000032fe677166d54963b62a4677d8957e87c508eaa4fd7eb1c880cd27e3
2018-04-09 12:31:09 LoadBlockIndexDB(): transaction index enabled
2018-04-09 12:31:09 Initializing databases…
2018-04-09 12:31:09 dc4cee563966e3aae37f8cab2cbc716204f81d21ca5298bbc718a2089e76f095
2018-04-09 12:31:09 0000000032fe677166d54963b62a4677d8957e87c508eaa4fd7eb1c880cd27e3
2018-04-09 12:31:09 72617357890cf4285cbfd9eaeebf6f25db7057b2b678cd8f5bfaa3080193e74f
2018-04-09 12:31:09 CBlock(hash=dc4cee563966e3aae37f8cab2cbc716204f81d21ca5298bbc718a2089e76f095, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=72617357890cf4285cbfd9eaeebf6f25db7057b2b678cd8f5bfaa3080193e74f, nTime=1523275630, nBits=1d00ffff, nNonce=2179302059, vtx=1, vchBlockSig=)
2018-04-09 12:31:09 Coinbase(hash=72617357890cf4285cbfd9eaeebf6f25db7057b2b678cd8f5bfaa3080193e74f, nTime=1523275630, ver=1, vin.size=1, vout.size=1, nLockTime=0)
CTxIn(COutPoint(0000000000000000000000000000000000000000000000000000000000000000, 4294967295), coinbase 04ffff001d020f27334e595420392d342d31382046616365626f6f6b73204f7468657220437269746963733a2049747320566972616c205374617273)
CTxOut(empty)
vMerkleTree: 72617357890cf4285cbfd9eaeebf6f25db7057b2b678cd8f5bfaa3080193e74f

What am I doing wrong? Did I pick up the wrong genesisHash? And what is the difference between

printf(“%s\n”, hash.ToString().c_str());

and

printf(“%s\n”, hashGenesisBlock.ToString().c_str());

The latter should be the hash of the genesis block which I need in line 3222, right?

Thanks in advance for the help. I’d be glad to setup a small tutorial / guide after I figure out what the problem is.

You are are the right track but probably missing some stuff, like the nonce.

Most of what you need is in Bitcoin/Altcoin tutorials like this:
http://dillingers.com/blog/2015/04/18/how-to-make-an-altcoin/

I tought the nounce can be whatever you want?
I tried setting nNonce to “0”, but that did not help.

Try to read up or study how proof-of-work uses real data plus the random nonce integer to generate the block hash.

Basically, doing proof-of-work means you are trying a whole bunch of different nonce values quickly to find the matching one for the hash.

That includes the genesis hash. You can set it to zero to start, but the code iterates thru tons until it finds the matching nonce value. Once you found it, your coind will fail, but the debug log will show the nNonce value matching your new genesis block. Set and recompile, try to get to the next level :wink:

1 Like

So I basically have to add in a piece of code that illiterates through the nonces, till I find the right one for my hash… Actually “mining” it is needed.

Well, Thanks for not spoon-feeding me and pointing in the right direction.

Now I have the right nNonce by using this snippet:

`
if (block.GetHash() != hashGenesisBlock || !CheckProofOfWork(block.GetHash(), block.nBits, false)) {

            printf("\n");
            printf("FATAL ERROR: The genesis block is invalid.\n");
            printf("If you're working on an Altcoin, we suggest you to use the following parameters as new genesis:\n");

            // This will figure out a valid hash and Nonce if you're
            // creating a different genesis block:

            uint256 hashTarget = CBigNum().SetCompact(block.nBits).getuint256();
            uint256 thash;

            while (!CheckProofOfWork(block.GetHash(), block.nBits, false)) {

                if ((block.nNonce & 0xFFF) == 0)
                    printf("nonce %08X: hash = %s (target = %s)\n", block.nNonce, thash.ToString().c_str(), hashTarget.ToString().c_str());

                ++block.nNonce;

                if (block.nNonce == 0) {
                    printf("NONCE WRAPPED, incrementing time\n");
                    ++block.nTime;
                }
            }

            printf("  - block.nTime = %u \n", block.nTime);
            printf("  - block.nNonce = %u \n", block.nNonce);
            printf("  - block.GetHash = %s\n", block.GetHash().ToString().c_str());

            std::exit( 1 );

        }`

I haved filled in the nNonce and after runnning peercoind I get this:

2018-04-10 07:38:46 Peercoin version v0.6.2ppc-dirty (2018-03-10 20:21:14 +0300)
2018-04-10 07:38:46 Using OpenSSL version OpenSSL 1.0.2g 1 Mar 2016
2018-04-10 07:38:46 Default data directory /home/bibz/.peercoin
2018-04-10 07:38:46 Using data directory /home/bibz/.peercoin
2018-04-10 07:38:46 Using at most 125 connections (1024 file descriptors available)
2018-04-10 07:38:46 Using 12 threads for script verification
2018-04-10 07:38:46 init message: Verifying wallet…
2018-04-10 07:38:46 dbenv.open LogDir=/home/bibz/.peercoin/database ErrorFile=/home/bibz/.peercoin/db.log
2018-04-10 07:38:46 Bound to [::]:9901
2018-04-10 07:38:46 Bound to 0.0.0.0:9901
2018-04-10 07:38:46 init message: Loading block index…
2018-04-10 07:38:46 Opening LevelDB in /home/bibz/.peercoin/blocks/index
2018-04-10 07:38:46 Opened LevelDB successfully
2018-04-10 07:38:46 Opening LevelDB in /home/bibz/.peercoin/chainstate
2018-04-10 07:38:46 Opened LevelDB successfully
2018-04-10 07:38:46 Peercoin Network: genesis=0x0000000032fe677166d5 nBitsLimit=0x1d00ffff nBitsInitial=0x1c00ffff nStakeMinAge=2592000 nCoinbaseMaturity=500 nModifierInterval=21600
2018-04-10 07:38:46 LoadBlockIndexDB(): last block file = 0
2018-04-10 07:38:46 LoadBlockIndexDB(): synchronized checkpoint not read
2018-04-10 07:38:46 LoadBlockIndexDB(): synchronized checkpoint 0000000032fe677166d54963b62a4677d8957e87c508eaa4fd7eb1c880cd27e3
2018-04-10 07:38:46 LoadBlockIndexDB(): transaction index enabled
2018-04-10 07:38:46 Initializing databases…
2018-04-10 07:38:46
2018-04-10 07:38:46 FATAL ERROR: The genesis block is invalid.
2018-04-10 07:38:46 If you’re working on an Altcoin, we suggest you to use the following parameters as new genesis:
2018-04-10 07:38:46 - block.nTime = 1523275630
2018-04-10 07:38:46 - block.nNonce = 1567838384
2018-04-10 07:38:46 - block.GetHash = 00000000ab7dc0bf2094562d6e703cad48b53657ea2441fec5d58a8483265b50

What is block.GetHash? From my understanding it should be the hash of the genesis block, right?

assert(block.GetHash() == hashGenesisBlock);

And this is the error that I get from peercoind (not debug.log):

bibz@bibz-u:~/peercoin/src$ ./peercoind
peercoind: /usr/include/boost/thread/pthread/condition_variable_fwd.hpp:81: boost::condition_variable::~condition_variable(): Assertion `!ret’ failed.
Aborted (core dumped)

That should mean the genesis block is OK, but there is some problem with boost?

After you mined a genesis block, you have to go back in your code and fill in all the variables for genesis block hash, merkle root , nNonce. Recompile and run again.

The assertion fails the first run naturally, because you can’t assert a value you haven’t established yet. Once you have the values, you can plug em in and run without failing the assertion.

Look for where hashGenesisBlock is defined and update. You could have had it as 0x0 when mining the genesis block, but after you set it to the block hash you mined.

Thats exactly what I did?!

block.GetHash() will return the block hash of what is in the block variable at the time. hashGenesisBlock should be the hardcoded value of the genesis block. The assert() compares that they are the same, or else throws an error.

When i was trying this some months back, i added a whole lot of printf() statements to debug what was going on, and make sure things were either what i expected, or else just see what was going on.

Any code or errors you don’t understand i recommend using grep a lot.

grep -R GetHash *

Eventually, you will have the correct values for the genesis block hardcoded, and the coind will start up and run without error. Block 0 will need to get written to the disk (leveldb). You connect 2 nodes running and start mining proof-of-work blocks (CPU mining is easiest to start).

1 Like

Ok that makes sense, thanks for the explanation.

Did you start CPU mining with peercoin-qt or only peercoind? How did you initiate the CPU mining?

So now I should have everything ready since the ‘bruteforcing’ of the nonce was successfull. Now I should only need CPU mining for the first block?

One more last question: The hash of the genesis block doesn’t need to be mined? Is it only the result of the pszTimestamp + timestamp ?

peercoin-qt and peercoind share the exact same consensus and CPU mining code.

“bruteforcing” the nonce is another definition of proof-of-work mining. You “mined” the genesis block when you ran the peercoin code to iterate thru the nonce values and found a hash which was below the “target” value.

Look into the “setgenerate” rpc command or the -gen command line parameter to do CPU mining.

I tried it again and again, but I get stuck on this assert every single time… Here my last output after ‘brute-forcing’ the nNonce:

nonce 80620000: hash = 3d27a9bc24c16af30c4a659d0f5aecacc46a2222838890aca1c41984eeb9b14f
nonce 80630000: hash = 423bb5f192716e014d429b61ec508f54fa898a22688a6a577fd0b02577d8d13e
nonce 80640000: hash = bf6e495db3095a21b532b876f19a3d46052bf3bf4a1cf2dc680abf13f3eb8508
nonce 80650000: hash = dc969ad917051718e5a417e8c9f8e650bfabdf26014ec0dacae97a6b5eefc928
nonce 80660000: hash = 4e31784691fee0111c5df9fec3bb0a06010cd3bb57c6dbbb27646c0a9f39fba2
nonce 80670000: hash = f59955023e1bebbedc4b4828ba6c6482892e130bbc2505fa19427fd632566fc3
nonce 80680000: hash = 54e23220b0b8069622ddfc7549c10e2a4a702b8558fcea6f77eb1c97288a5901
nonce 80690000: hash = d84bf8a054e217c5bf0410a627a565cf45fd9bb6ce354e3cb9f8342b7c9e655b
nonce 80700000: hash = ba7b0b15d8eb1427ede2fd592706c112014a52b82493953fad39e33f23656a39
nonce 80710000: hash = 3f5b0e71414c5ffdf918c7e3ba6672e23caf6c4c3aa164ee789bedb62b91f307
nonce 80720000: hash = 694123b50877bc881eadda8ae4ea904bd1ad49710b97db38df3827402f9bd709
My beautiful block hash 00000000c4308c85660cc70f763a0dd770eafd8a502e5da3c731318e5704c137
hashGenesisBlock (hardcoded) 0000000032fe677166d54963b62a4677d8957e87c508eaa4fd7eb1c880cd27e3
block merkle root e947fc6a60eadcf5b9a891fd23633f44e42e5d70d2fd5390e7f0a016f45e60dc
CBlock(hash=00000000c4308c85660cc70f763a0dd770eafd8a502e5da3c731318e5704c137, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=e947fc6a60eadcf5b9a891fd23633f44e42e5d70d2fd5390e7f0a016f45e60dc, nTime=1523275632, nBits=1d00ffff, nNonce=80723068, vtx=1, vchBlockSig=)
Coinbase(hash=e947fc6a60eadcf5b9a891fd23633f44e42e5d70d2fd5390e7f0a016f45e60dc, nTime=1345083810, ver=1, vin.size=1, vout.size=1, nLockTime=0)
CTxIn(COutPoint(0000000000000000000000000000000000000000000000000000000000000000, 4294967295), coinbase 04ffff001d020f27334e595420392d342d31382046616365626f6f6b73204f7468657220437269746963733a2049747320566972616c205374617273)
CTxOut(empty)
vMerkleTree: e947fc6a60eadcf5b9a891fd23633f44e42e5d70d2fd5390e7f0a016f45e60dc
peercoind: main.cpp:3343: bool InitBlockIndex(): Assertion `hash == hashGenesisBlock’ failed.

I tought by brute-forcing the nNonce, I’m already ‘mining’ the block… Or do I need to also mine it with the bruteforced values? I tried running peercoind with the setgenerate command but its not possible to run it since the assert stops the program from running

Yes you mined the block, and you have all the values you need in that debug log there.

But you have code comparing hash == hashGenesisBlock . Clearly one side doesn’t match the other. So make it match.

Seems like apparently one of those steps of mine was wrong… Now it works! Genesis seems to have been created, I’ll give it a shot at connecting the nodes with each other now. Thanks a lot for your kind help @nohea. And I’m sorry for all those questions, hope I didn’t come off as someone that needs spoon-feeding :disappointed:

This is now my last status from debug.log, I already set “setgenerate true” on my host, now I guess I need only to wait?:

2018-04-16 21:19:31 send version message: version 70001, blocks=0, us=xxxxxxxx:9901, them=xxxxxxxxxxxxx:27450, peer=xxxxxxxxxxxxxxxxx:27450
2018-04-16 21:19:31 Added time data, samples 2, offset +0 (+0 minutes)
2018-04-16 21:19:31 receive version message: /Satoshi:0.8.6/Peercoin:0.6.2v0.6.2ppcdirty/: version 70001, blocks=0, us=xxxxxxxxxx:9901, them=0.0.0.0:0, peer=xxxxxxxxxxx:27450
2018-04-16 21:19:31 getblocks -1 to 0000000000000000000000000000000000000000000000000000000000000000 limit 500
2018-04-16 21:19:31 Added 1 addresses from xxxxxxxxxx: 0 tried, 2 new
2018-04-16 21:19:45 socket closed
2018-04-16 21:19:45 disconnecting node xxxxxxxxxxxxxxx:27450
2018-04-16 21:19:45 trying connection xxxxxxxxxxxxxxx:9901 lastseen=2.0hrs
2018-04-16 21:19:50 accepted connection xxxxxxxxxxxxxxx:27422
2018-04-16 21:19:50 send version message: version 70001, blocks=0, us=xxxxxxxxxxxxxxx:9901, them=xxxxxxxxxxxxxxx:27422, peer=xxxxxxxxxxxxxxx:27422
2018-04-16 21:19:50 receive version message: /Satoshi:0.8.6/Peercoin:0.6.2v0.6.2ppcdirty/: version 70001, blocks=0, us=xxxxxxxxxx:9901, them=0.0.0.0:0, peer=xxxxxxxxxxxxxxx:27422
2018-04-16 21:19:50 getblocks -1 to 0000000000000000000000000000000000000000000000000000000000000000 limit 500
2018-04-16 21:19:50 connection timeout

Will you also be securing the chain with check pointing in the beginning? That was instrumental in stopping forks from happening when there was not enough stake and historical transactions.

Yes I will surely do that before I release it to the public (if I do, then there willl be a pre-mine anyways).

I hope its ok if I use this same thread again. I am stuck on block height 1. I let the CPU miner run for 2 days, but no new blocks were generated (setgenerate true).

This is some output from debug.log:

2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 CPUMiner started for proof-of-work
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)
2018-04-29 17:28:33 Running PeercoinMiner with 1 transactions in block (191 bytes)

just a wild guess, maybe the coins have to mature and than PoS block mining kicks in?

Well there are no coins there. The only block in the chain is the genesis block. :confused:

It’s possible you broke some code during modification. I’d recommend you run your coin with some print debugging, and compare that to running the official peercoind doing CPU mining on testnet. You may find something out. Monitor/compare debug.log

~/.yourcoin/yourcoind -gen -debug -printcreation
tail -f ~/.yourcoin/debug.log

vs.

~/.peercoin/peercoind -testnet -gen -debug -printcreation
tail -f ~/.peercoin/testnet/debug.log

I bet the peercoin testnet you will mine some.