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

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 (

/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.


Go the the DNS settings of the domain you wish to use and add a DNS Record as follows:, 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.


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 ( 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 🙂


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

Save the changes and recompile the daemon again.


./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:

  • rpcuser=anything
  • rpcpassword=anything
  • rpcallowip=
  • server=1
  • daemon=1
  • listen=1
  • dnsseed=0
  • port=your main net port
  • rpcport=your main net rpc port
  • gen=1
  • testnet=1


  • rpcuser=anything
  • rpcpassword=anything
  • rpcallowip=
  • server=1
  • daemon=1
  • port=your testnet port
  • rpcport=your testnet rpc port
  • gen=1
  • testnet=1

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=

Go ahead and start both daemons

Daemon1 – ./YOURCOIND (from the folder where it is placed)

Daemon2 – ./YOURCOIND2 -datadir=/home/USER/.YOURCOIN2 -connect= (from the folder where 2nd is placed)


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= 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 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!


1 vote, average: 5.00 out of 51 vote, average: 5.00 out of 51 vote, average: 5.00 out of 51 vote, average: 5.00 out of 51 vote, average: 5.00 out of 5 (1 votes, average: 5.00 out of 5)
You need to be a registered member to rate this.
(200 total tokens earned)


  1. Zedik Bloodik Post author

    For the main net: If you set the parameters at Main.cpp:L39 and Main.cpp:L40 to (~uint256(0) >> 27) & (~uint256(0) >> 35) you should find the block every few minutes. Lower the numbers to get faster blocks.