How to create cryptocurrency (POW/POS Peercoin based)
I have been trying for some days to clone the current Peercoin client to create new altcoin. Mostly to learn about the blockchain and to have a bit of fun. Now I’m in the stage when it seem to be running so decided to share the steps with others as there is not much resources on the subject. Also I’m quite sure I will soon forget many of the steps so want to keep it for my records.
I’m not a developer or coder so if you find that some of the part could be done better please let me know in comments. Also please note that my goal was to clone the coin, modify just as little as needed and get the blockchain up and running. Tweeking the coin to fully working alt was not yet my purpose. I will welcome any help to make this guide clear and correct for others.
I will be using Linux Ubuntu 16.04 for this exercise.
Lets get started.
Download the newest source https://github.com/peercoin/peercoin/archive/master.zip
Unpack and install dependencies for the daemon to be able to compile.
sudo apt-get install build-essential libssl-dev libdb4.8-dev libdb4.8++-dev sudo libboost-all-dev libminiupnpc-dev
Rename the peercoin-master folder to your new coin name. Deadcoin it will be in my case.
Using Notepad++ (or any other text editor able to search & replace multiple folders at once) search and replace Peercoin, PPC, peercoin and ppcoin with your desired coin. I’m not sure why there is peercoin and ppcoin, but if you rename both to the same file, later you will get error when compiling so just name it slightly differently. Please note that Notepad++ in Linux has to be run via wine.
/src/net.cpp:1204 – Enter DNS information to allow wallets to connect to peers without needing addnodes
/src/base58.h:276 – Change the pubkey to the corresponding number for the letter you want addresses to start with (https://en.bitcoin.it/wiki/List_of_address_prefixes)
/src/checkpoints.cpp:42 – Delete all the checkpoints except Genesis block.
/src/protocol.h:18/19 – These are the ports your new coin will use.
/src/protocol.cpp:22 – Change the pchMessage values to be unique to your coin (otherwise you will try piggybacking other chains and it will cause problems).
/src/version.cpp:14 – Change to whatever you want your buildname to be.
/src/version.h:35: – This will be the version number for your new coin.
/src/main.h:35-70 – These are overall coin specs and most are written in readable english. If you don’t know what one means, don’t change it. Values are in satoshi format. (I have not been playing with those much yet).
/src/main.cpp:1159 – Year staking rewards setup (I have not been changing mining reward, if anyone could share how to do it properly I’d be happy to include in guide)
/src/qt/res/icons – This is the folder that contains all the icons for your QT wallet
/src/qt/res/images – This is the splash (loading) screen for your new coin and QT wallet.
SETTING UP DNS SEEDS
Go the the DNS settings of the domain you wish to use and add a DNS Record as follows: dnsseed.domain.com, A Record, 14400 TTL
You can add multiple seeds by repeating these steps and simply changing the IP it is pointed to. Point it to the IP of your dedicated node (or checkpoint server’s IP).
The DNSseed is not required in order to run the network. It only help each node to automatically connect to the dnsseed server and receive blockchain information. You don’t need it at the moment.
REMOVING GENESIS BLOCK AND GENERATING NEW ONE
Main.cpp:32710 – Change the value for the constant, pszTimestamp, to something unique, up to 91 characters.
Main.cpp:2261 – Change txNew.nTime, block.nTime value to current epoch time (https://www.unixtimestamp.com/). Do the same for testnet bellow.
Main.cpp:2262 – Make sure that block.nNonce=0, do the same for testnet.
Main.cpp:3293, 3303 – delete #ifdef TESTING and #endif to uncommend the code.
Main.cpp:3221, 3228, 3235 – delete #ifdef TESTING and #endif to uncommend the code.
Main.cpp:3222 – delete the genesis hash and leave empty hashGenesisBlock = uint256(“”);
Main.h:82,83 – Delete the Genesis blocks hashes hashGenesisBlockOfficial(“”); hashGenesisBlockTestNet(“”);
Do the backup of your coin folder. I usually just compress it. Its good to have backups not to have to follow all the steps again when something goes wrong 🙂
COMPILE AND RUN THE DAEMON
Navigate to the /src/ and run make -f makefile.unix
It may take some time to compile. Just have a cup of coffee.
We will continue to use test net from here as getting test net running is easier due to lower difficulty for finding Genesis block. I have not managed to find the Genesis block on main net without having to lower the difficulty, you may try it yourself later.
You should have your daemon in the /src/ just run: ./YOURCOIND –daemon -testnet
In the /home/.yourcoin/testnet/ run: tail -f debug.log you will see your computer trying to find the genesis block. It may take a bit of time before the result pops up together with assertion error in the main window.
Here I took a bit of leap of faith and suspected that the bock was found, but the information was not printed in the decoded format. Usually the merkle root is at the end of the block information so I just took the last part and put it into Main.cpp:3310 – hashMerkleRoot == uint256(“bbe8d7dc26b86158c2cd5bff003550d5a05e3b67024f42bb5faadad711b342f9”));
(If anyone can explain me exactly what has happened here please do so I can make sure the guide is correct.)
Save and recompile the core using /src/ make -f makefile.unix
Delete the /home/.yourcoin/ folder
After it finish compiling repead the steps we did on our first run:
You should have your daemon in the /src/ just run: ./yourcoind –daemon -testnet
In the /home/.yourcoin/testnet run: tail -f debug.log you will see your computer trying to find the genesis block. It may take a bit of time before the result pops up together with error in the assertion error in the main window. This time the debug log will show full information about the block found.
Update Main.h:83 with block hash preceding by 0x – hashGenesisBlockTestNet(“0x0000000a47f55eb388fe0d465c87e69911feb2946d2f36559ed122923e3d91dc”); (don’t forget we are on testnet still)
Update Main.cpp:3290 with nonce – block.nNonce = 222074003;
Kernel.cpp:14:25 – change the nProtocolSwitchTime need to be set to a time in the future, after PoS starts. So just set these to several days in advance. Use the Epoch Converter to get the correct value. I have not been sure how this work so just set it in year time into future using https://www.unixtimestamp.com/
Save the changes and recompile the daemon again.
GETTING THE NETWORK TO RUN
./yourcoind –daemon -testnet
If you got the same error a me we are all good and almost running!
The blockchain requires two nodes in order to start working, generating block and be alive in general. We are going to create two copies of our daemon to run and connect to each other.
Copy yourcoind to the /home/.yourcoin
Create second copy of .yourcoin directory and rename it to ./yourcoin2
*Rename the daemon in the second copy to yourcoind2
In each directory create empty file yourcoin.conf
yourcoin1.conf should be:
- port=your main net port
- rpcport=your main net rpc port
- port=your testnet port
- rpcport=your testnet rpc port
Save both and exit.
We must specify the data directory so that the 2nd instance doesn’t try to use ‘~/.yourcoin’ and we must also specify that we want to connect to the IP address of our first instance, which, in this case, is localhost. We will be starting the second daemon like this ./YOURCOIND2 -datadir=/home/USER/.YOURCOIN2 -connect=127.0.0.1:YOURMAINNETPORT
Go ahead and start both daemons
Daemon1 – ./YOURCOIND (from the folder where it is placed)
Daemon2 – ./YOURCOIND2 -datadir=/home/USER/.YOURCOIN2 -connect=127.0.0.1:YOURMAINNETPORT (from the folder where 2nd is placed)
USEFUL COMMANDS AT THIS STAGE
ps aux | grep yourcoind – to find running process of daemon
kill -9 ID of the process 38317 for example will stop the daemon.
After you added rpcallow=127.0.0.1 i the .conf files you should be albe stop the daemons by
./YOURCOIND stop, but if you run it before, you have to kill as showed above.
You can go to the testnet folder and run tails -f debug.log to see what is happening
Also watch -n 20 ./YOURCOIND getinfo is good to see whether you are receiving first blocks.
If everything is correct you should be able to soon start finding blocks.
Congratulation. Your coins is ALIVE!
So this is the minimal setup and your blockchain is going. There is few more things to consider.
DNSSEED – if you start the wallet on the server you provided as dnsseed, any node will automatically connect to it. Running the seed on VPS will make anyone who will run the wallet to be connected to network immediately.
QT wallet – you can compile the QT wallet as per original Peercoin instruction found https://github.com/peercoin/peercoin/blob/master/doc/readme-qt.rst as long as you have in your .conf file testnet=1 your QT will automatically starts in testnet also.
Before you compile the QT, make sure to create your own design and logos at:
/src/qt/res/icons – This is the folder that contains all the icons for your wallet
/src/qt/res/images – This is the splash (loading) screen for your new coin
MAINNET – I have not yet try how long it would take to find the genesis on the mainnet, I found workaround by reducing the difficulty here: Main.cpp:L39 and Main.cpp:L40. After I found the block instantly the same way we used on testnet, but the difficutly was to low and I was mining too fast. If you find some reasonable compromise please let me know.
I have used some information from the following guides :
So I hope this guide will help some of you learn more about blockchain, I will post corrections and updates to this guide as I receive them. Sorry if some of the information are not correct. As I said before I’m just learning and those are first steps.
All the best and follow me for future tutorials.
Thanks to the #Peercoin develepers for their hard work, @atmandigital for helping me with some of the problems I encountered and to the guys who wrote previous articles on the topic.
This is how my wallet looks like at the end of the day.
All the best!