Good guide!
A couple of updates for Bitcoin release 0.17.1 which I wanted to use.
Also if you want to build a Windows GUI wallet, you will have to git clone and add --branch v.0.17.1 (it accepts a tag) so you get the /depends directory and all the stuff inside needed for cross-compile dependencies. That way you can cross-compile for Win 64 on Ubuntu and get a slick Bitcoin Core wallet. If you know how to get gitian up and running, you can make a setup .exe. If you have Mac libs, you can cross-compile for a Mac wallet, too.
So first swap out the RPC port step and instead change it here in src/chainparamsbase.cpp:
std::unique_ptr CreateBaseChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
return MakeUnique("", 10332); // I set my port to 10332, Bitcoin's is 8332, I left the rest alone
else if (chain == CBaseChainParams::TESTNET)
return MakeUnique("testnet3", 18332);
else if (chain == CBaseChainParams::REGTEST)
return MakeUnique("regtest", 18443);
else
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}
In chainparams.cpp, set the P2P port under the pchMessageStart lines:
nDefaultPort = 10333; // Bitcoin's is 8333, I set mine to a thousand above Litecoin's P2P port (9333)
Not long after that, when you create a genesis block with genesisgen or GenesisH0's Python tool, this line should look familiar:
genesis = CreateGenesisBlock(1553416095, 2546245826, 0x1d00ffff, 1, 50 * COIN);
That was mine, but now do the same thing for testnet, otherwise the daemon will fail with the assert on the genesis hash for it. So in chainparams.cpp set your genesis block again. Look for the Testnet (v3) comment and the process is the same for main-net
For bech32_hrp, I left mine as "bc" but you can change that. Litecoin's is "ltc". Note that with miners, I found they failed to mine to older style addresses, so you will probably have to bitcoin-cli getnewaddress, then bitcoin-cli getaddressinfo "addr" and find the bech32 address in there, and set that as your --coinbase-addr parameter with cpuminer, then it works.
with chainTxData in chainparams.cpp, set nTime to the UNIX timestamp of your genesis block and the nTxCount and dTxRate both to 0.
An important step to take if you publish your source on github is to mine say 100 blocks and have them confirmed, and adjust your nPowTargetTimespan as a minimum to try and prevent instamining. People will find it and instamine it immediately, if it looks like a new alt-coin to them, leaving you with the likely situation that they out-gun you with a higher hashrate, and trying to catch up means you could get blocks, but they will all probably get orphaned. And then leave your blockchain in a mess and your coin stalling.
I set mine to:
consensus.nPowTargetTimespan = 3 * 60 * 60; // three hours
consensus.nPowTargetSpacing = 2 * 60; // two minutes
to begin with. It probably still isn't good enough in comparison to implementing DGW v3 or MIDAS or something of your own invention, in particular you might like to have difficulty readjustments done less than every 3 hours as above. This works out for me just in a test environment, and I usually get my block every two minutes although sometimes a few will pop through every minute then it will slow down again and not find a few blocks for longer than the target of 2 minutes that I wanted.
You can also premine coins for yourself if you want to with the GetBlockSubsidy function in validation.cpp.
Please note I haven't tested this at all, but for example:
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
{
int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
// Force block reward to zero when right shift is undefined.
if (halvings >= 64)
return 0;
// Premine in first ten blocks, the simple approach
// Start with 5000 coins per block after genesis, but otherwise leave default subsidy unchanged
CAmount nSubsidy = 50 * COIN;
// First 10 blocks after genesis, up the subsidy to 5000 coins
if (nHeight > 0 && nHeight <= 10) {
nSubsidy = 5000 * COIN;
// You may wish to leave out the halvings below and just
return nSubsidy;
// especially if you just premine in block #1 and leave it at that, but check
// to make sure it doesn't get all screwed up...
}
// otherwise leave nSubsidy in its default state
// Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years. (Not true for my adjustments, pay attention here)
nSubsidy >>= halvings;
return nSubsidy;
}
I left the coin supply and subsidy halving for the moment because it doesn't matter, it's not an alt-coin but a learn-by-doing exercise, trying to retrofit in the bare minimum of difficulty adjustments, experimenting with scripts in transactions (enabling some, trying new ones, going a bit crazy there but the programmable money part is a lot of fun for me), and looking at how more privacy of transactions could be implemented. I expect I'm a couple of years away from that, but I hope to get there some day, otherwise it's worth trying to clone ZCash or another coin.
I think I've covered the bare basic bits as a follow-on to this guide if you want Bitcoin 0.17.1, you might run into make issues after changing everything from Bitcoin to NewCoin and so on. So for example if the build process fails in doc/man (a situation I ran into before) saying it has no rule to make newcoind.1. Stop., then just rename bitcoind.1 to newcoind.1 (and same for 3 other files there) then run make again and it will continue where it left off.
For a Windows QT wallet, cross-compiling on Ubuntu 18.04 LTS:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils python3 libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libboost-all-dev libboost-program-options-dev
sudo apt-get install libminiupnpc-dev libzmq3-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode-dev unzip
// Get into your src directory, e.g.
cd ~/bitcoin-0.17.1
// For a 64-bit Windows wallet
sudo apt install g++-mingw-w64-x86-64
// Set mode to POSIX when it asks after running
sudo update-alternatives --config x86_64-w64-mingw32-g++
// Get ready and change into depends directory
PATH=$(echo "$PATH" | sed -e 's/:\/mnt.*//g')
cd depends
// This will take a while
make HOST=x86_64-w64-mingw32
// Up one level to your top level src dir (not in /src, up from there to configure and make)
cd ..
// I use the latest Berkeley DB, so if like me you don't need "compatible" wallets,
// always configure with the latest Berkeley DB and pass in --with-incompatible-bdb
// This will also take a while...
./autogen.sh
CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure --with-incompatible-bdb --prefix=/
make
If all goes well, the 64-bit Windos GUI wallet e.g. newcoin-qt.exe will be in the folder src/qt when compiled. The other tools newcoin-cli.exe, newcoin-tx.exe and the daemon newcoind.exe will be in the src folder.
So I think that's all for now for a quick and dirty Bitcoin 0.17.1 based on last year's Christmas Day release.