IntroductionI am the author of the Kryptofranc ... you will hear about them very soon.
https://kryptofranc.comI have spent the time to adapt the latest Bitcoin Core development to my own fully functional blockchain and on the way of doing it, I have found that a LOT of things in the previous guides posted on the net were lacking of update or were totally obsolete.
Therefore, I have decided to update these guides to my own sauce, and I hope it will save time for the newbies, and update the legendary programmers to the latest roadblocks the Bitcoin core team have left for us recently.
1) Choice of Bitcoin Core 0.18 (mostly still works with 0.20)
This is the most updated and dynamic development out there. Almost all the good ideas from other coins are ending up in the Bitcoin core source one day or another, and usually with a better implementation.
Take Sigwit, pruning, HD address, privacy, lightning network; Bitcoin Core does it all.
However, the Bitcoin core team seems to try to make it impossible to create an alt coin from their core, by removing the solo mining first, then the RPC mining, and by adding plethora of tests for “security” but that are blocking new coins to mine when they are at the genesis state.
This guide will sort out all these problems.
2) Do not expect it to be easy.
Many people around are offering alt coin based on templates. First, be careful as a Trojan can be hidden very easily and you might lose all your work if you deal with the wrong people. Then most of the time they are using outdated versions of Bitcoin core, Litecoin that is based on outdated Bitcoin core, Dash that is based on outdated Bitcoin core etc… basically, they are using a version with solo-mining or RPC mining enabled, avoiding the real problems. If you are doing that, you are going to get an obsolete coin that will never be trusted, and it is just a matter of time until investors realize that, and sell.
3) Do not blame me for errors
If you find an error, tell me and I will fix it. Let us collaborate. I am writing this guide quickly, it is a complex subject so, be kind and complete the missing points if you find some.
4) Give credit to this page with a link if you copy this post to your blog.
Setting Upa) You will need two Unix instances to create a functional coin that will also mine.
Server 1: Mining wallet and development server.
Server 2: Second node and receiving wallet.
I suggest purchasing a dedicated server at Hetzner. Their auctions have the best value for the price (I am not related to them, you can use any ISP) :
https://www.hetzner.com/sbFor 21 Eur you can get a 9000 Benchmark server. Don’t take an Atom that will take forever to compile. Get 2 instances for about 42 Eur.
b) Get an account at Github, and fork the latest Bitcoin core version (0.18 here).
c) Install the latest Ubuntu on both servers. Install Mate to have a graphic interface that is fast. Do that on both servers.
sudo apt install ubuntu-mate-desktop
and XRDP
sudo apt install xrdp
sudo systemctl enable xrdp
Now you can login with Remote Desktop from your local windows.
Install Clion to edit your C++ code with ease. You get 1 month free, enough for your development. This development tool is worth every penny, specially for its search that will save you a lot of time.
https://www.jetbrains.com/clion/download/#section=windows
d) On server 1 install Yiimp by using this script:
https://github.com/xavatar/yiimp_install_scrypt_ubuntu18.04 or use my backup on my repository, it is working and clean
https://github.com/NicolasChoukroun/yiimp_install_scrypt_ubuntu18.04Also be cautious, some people are offering to install Yiimp for you but they also install a backdoor and get a fee from every mining, I got this problem and I had to do everything myself to get rid of it. So beware the “services”. Do it yourself!
Now you are ready to modify Bitcoin Core to your flavor, do it on server 1. Server 2 will compile the result and run a second node when you have finished.
Yiimp will be used to mine the coin, do your premine and also as a block explorer.
Bitcoin Core modifications.a) Directory structure.
Use this structure.
Yourcoin/Yourcoincore/
In /Yourcoin/ put everything that needs to be out of the Bitcoin Core source code, your scripts, assets, pictures, translation scripts etc…
In /Yourcoin/Yourcoincore/ dump the Bitcoin source code that you have forked
Save that result to your own GitHub so that when you make a mess, you can clone and start again.
You can also use this script to automatically compile your coin and the dependencies. Note that this script solves some compilation issues for windows that many seems to be unaware of.
https://github.com/NicolasChoukroun/BitcoinMakerUsage is included in the script just run ./maker.sh and see.
At this point, you need to compile Bitcoin:
https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.mdOr
./maker.sh unix install
./maker.sh unix all
Don’t go further until Bitcoin is launching on your machine.
b) Creation of the certificates (optional)
You can keep the Bitcoin certificates, but it is better to have your own for the strength of your blockchain.
openssl ecparam -genkey -name secp256k1 -text -noout -outform DER | xxd -p -c 1000 | sed 's/41534e31204f49443a20736563703235366b310a30740201010420/PrivKey: /' | sed 's/a00706052b8104000aa144034200/\'$'\nPubKey: /'
Replace the result in chainparams.cpp here:
const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
And change your passphrase here with what you want:
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
Remember to keep it short, I think that the length is limited to 150 characters, so do not write a book or you will get an error.
c) Creation of the genesis.
In order to have your own blockchain, you need to have your own genesis. This step is explained in many tutorials; it should not be a problem.
I have made my own function based on what I have found in another altcoin, you can get the code here:
https://github.com/NicolasChoukroun/altcoin-genesisYou need to copy the code as explained in the readme and you will get the nTime, nNone, nBits, Hash and Merkle Root (inverted).
You can now replace these in chainparams.cpp, in 3 places, in “main”, “testnet” and “regnet”.
genesis = CreateGenesisBlock(nTime, nNonce, 0x1d00ffff, 1, 50 * COIN);
Also change the asserts with the Hash and Merkle Root you got from the genesis. Do it 3 times for main, testnet and regnet.
assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
Compile and run the wallet, see if you get an assert error. If you have, you made a typo.
d) Change all Bitcoin core mentions with your altcoin name.
This is tricky as Bitcoin is all over the place. I cannot help too much; I personally use PHP to do it. You need to scan all the files with conditions to avoid replacing code. Show your scripting skills here.
e) Change the graphics
/src/qt/res/ there are icons and graphics, replace them with the one from yourcoin.
f) Customize chainparams.cpp
This file has things to change to personalize your coin, so I will make a list to get this done quickly. Read the comments in the following code.
// change all the pchMessageStart with something else, so that your messages are unique.
pchMessageStart[0] = 0xf9;
pchMessageStart[1] = 0xbe;
pchMessageStart[2] = 0xb4;
pchMessageStart[3] = 0xd9;
// change the default port, choose one port that is not used by another popular prog like ftp, or emails. Choose a different port for main,testnet and regnet.
nDefaultPort = 8333;
// change this to this value so that the consensus will accept your low difficulty mining at starting.
consensus.nMinimumChainWork = uint256S("0000000000000000000000000000000000000000000000000000000100010001");
// start all the PIB from height 1, so change these to 1
consensus.BIP34Height = 1;
consensus.BIP65Height = 1;
consensus.BIP65Height = 1;
// change the hash of BIPs to your genesis hash (see the genesis section) ??? is your genesis hash
// do it for main, testnet and regnet.
consensus.BIP16Exception = uint256S("0x???");
consensus.BIP34Hash = uint256S("0x???");
// fix the checkpoint data with your genesis hash, do it for main,testnet and regnet
checkpointData = {{{0, uint256S("0x???")},}};
// empty ChainTxData like this
chainTxData = ChainTxData{};
// you can change how often the wallet will retarget the difficulty.
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
// you can change the target for coin generation; bitcoin is 10 minutes, litecoin 2.5 minutes. Short means quicker transactions, but also more risk of orphan and failed transactions due to network issues.
// Also the faster, the more inflation, take this in account when you calculate your max coin generation, and rates.
consensus.nPowTargetSpacing = 10*60;
// blockchain size: your blockchain is very small; change this parameter to 1 so that it will not ask too much space at starting.
m_assumed_blockchain_size = 1; // was 240
// comments all the vSeeds, and change that to your server 1 and server 2 address since they will run the wallet and need to be peer to each other to get your coin to be functional.
vSeeds.emplace_back("seed.bitcoin.sipa.be");
vSeeds.emplace_back("dnsseed.bluematt.me");
// change the prefixes to your coin. If your coin is named Yourcoin for example you want that prefix to be Y
// prefixes are not that obvious, check https://en.bitcoin.it/wiki/List_of_address_prefixes
// to understand how prefixes are calculated
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);
// change this to something of your own
bech32_hrp = "bc"; // change to yc for yourcoin for example?
That’s it for chainparams.cpp. Remember to do these changes for all the networks, main, testnet and regnet
g) Customize validation.cpp
Mostly validation deals with subsidy and validity checks. Subsidy defines how many coins are created when the proof of work submitted by a miner is accepted. This is the reward formula. This is where you will do your premine.
There are some traps not to fall into here. nSubsidy is a CAmount (int64_t), it is not a float. So be sure that with your calculation, you will not have a divide by zero!
Here is an example that is functioning. Note the +1 to avoid having 0 divides. I also add a debug to console so that the subsidy can be witnessed from the console.
In that code, you can see that we premine 120000 coins to 6 wallets. The method is as follow.
At height 10, 50, 70, 90, 110 and 130 we will mine 20000 coins. The blocks in between are here to allow the time to get the mined coins to maturity, then send the coins from server1 wallet to server2 wallet, then mine more to allow the transaction to be confirmed. Once this done you can encrypt the server2 wallet, backup it, remove the .yourcoin directory and restart the wallet with a fresh new address
This way you can premine and save in different wallet to distribute to your team, friends, investors.
Once the premine is done, the script will delivers 63/halfing coins every coin mined.
Note that this algorithm is not waiting 2 years to adjust like Bitcoin, it adjust every coin mined. You might change it to your liking.
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams) {
CAmount nSubsidy;
if (nHeight == 10 || nHeight == 50 || nHeight == 70 || nHeight == 90 || nHeight == 110 || nHeight == 130) {
nSubsidy = 20000*COIN; // premine 6x20000 coins
} else {
if (nHeight <= 150) {
nSubsidy = 10 * COIN ; // small mining to carry out the transactions
} else {
float year= (nHeight / 210240)+1; // avoid to get a negative nSubsidy
float halfing = year/ 1.618033988750;
nSubsidy = (63 / halfing)*COIN;
}
}
printf("GetBlockSubsidy: height: %i - nSubsidy: %ld \n",nHeight, nSubsidy);
return nSubsidy;
}
Validation.cpp is not finished yet. We have a problem with SEGWIT. It cannot work at height 1. So in the beginning, we need to disable some checks, that will have to be re-enabled when the blockchain has at least 2000 blocks mined. You have to experiment here; the goal of this tutorial is not to deal with the blockchain maintenance.
bool IsWitnessEnabled needs to return true in all cases. So just add return true; at the beginning of the function.
IsNullDummyEnabled has the same problem, do the same to that function.
Find this “return state.DoS(100, false, REJECT_INVALID, "bad-cb-height", false, "block height mismatch in coinbase");” and comment it.
End of the validation.cpp customization.
h) Other code modifications.
There are more modifications, spread everywhere that needs to be fixed in order to get the coin to work correctly.
validation.h :
- you need to change the DEFAULT_MAX_TIP_AGE to something very large (60*60*24*365 for example). This is temporary. This is the interval when the blockchain is not mining. At starting you might have a genesis made long time ago, and not have mined for a while, so that this has to be changed or your Coin will not work.
- DEFAULT_CHECKPOINTS_ENABLED = true; needs to be changed to false, or your coin will try to verify that you are on the Bitcoin blockchain, which you are not.
\rpc\mining.cpp :
Another SEGWIT test that needs to be removed:
throw JSONRPCError(RPC_INVALID_PARAMETER, "getblocktemplate must be called with the segwit rule set (call with {\"rules\": [\"segwit\"]})");
Comment this line.
net_processing.cpp :
- STALE_CHECK_INTERVAL need to be changed to a large value to avoid having a STALE error, this is again temporary, once the blockchain is mined by many people, it can be back to the original values. (3600*24*365 for example)
- STALE_RELAY_AGE_LIMIT same for this static variable.
\qt\bitcoingui.cpp
Get rid of the loading form set this variable to 0.
qint64 secs = blockDate.secsTo(currentDate);
becomes qint64 secs=0;
Now you should have a functional Coin. But you need to mine.
------------------------------------------------------------------------------------------------------------------------------------------
Mining with stratum and Yiimpa) Modification of stratum.
In order to mine your coin, you need to use Yiimp that you have installed previously.
But the latest version won’t work with a “virgin” coin at block zero so here is how to fix that.
First, you need to setup your coin by following this tutorial:
https://www.boostrend.com/2018/03/how-to-setup-new-coin-wallet-on-pool.htmlThe most important things are: - Run your coin wallets by using the code given in the coin settings of Yiimp, but don’t forget to change the path since the installation script install stratum in /var/stratum. blocknotify=/var/stratum/blocknotify pool.kryptofranc.net:3333 1455 %s
for example is what is working for me.
- Run your coin by using the following command line:
yourcoin-qt –deprecatedrpc=accounts -printtoconsole- Type getnewaddress in the console on server1: enter this address everywhere an address is asked in the coin definition of Yiimp backend.
- Compile and run your coin on server2
- Type getnewaddress in the console of server2 to get an address to send to from the mining wallet.
- Download ccminer (version 230 is working for me) for windows and edit a config file to match your coin definition, for example:
ccminer.exe -a bitcoin -o stratum+tcp://pool.yourcoin.com:3333 -u xxxyourserver2addressxxx -p c=KYFreplace xxxyourserver2addressxxx with the address you got from your server2.
- Run stratum on server1 (/var/stratum/run.sh sha)
If ccminer cannot mine, then you can use my fixed version here:
https://github.com/NicolasChoukroun/stratumUse it at your own risk, it is working for me, but who knows?
What needs to be fixed in Stratum is in coind.cpp function coind_can_mine, there are several tests of (!coind->height) which are not working for us since we are at block 0. This needs to be changed to
If (!coind->height)
// change to
if (coind->height<0)
My version also adds a lot of real-time comments to help debug stratum.
The coin must be set to auto ready, enabled, and difficulty must be >0
Mission accomplished! Now you have a fully working coin, which can mine though stratum.------------------------------------------------------------------------------------------------------------------------------------------
DISCLAIMERThis tutorial may contain technical or typographical errors.
I do not guarantee its accuracy, completeness, or suitability.
IN NO EVENT SHALL I BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES RELATING TO THIS TUTORIAL, FOR ANY USE OF THIS TUTORIAL.
I take no responsibility and makes no warranty whatsoever from the use of this tutorial linked to or from this tutorial.
IT IS DELIVERED ** AS IS **.
ANYONE USING THIS TUTORIAL IS DOING IT AT HIS/HER OWN RISKS.