Build a blockchain with C++

So, you might have heard a lot about something called a blockchain lately and wondered what all the fuss is about. A blockchain is a ledger which has been written in such a way that updating the data contained within it becomes very difficult, some say the blockchain is immutable and to all intents and purposes they’re right but immutability suggests permanence and nothing on a hard drive could ever be considered permanent. Anyway, we’ll leave the philosophical debate to the non-techies; you’re looking for someone to show you how to write a blockchain in C++, so that’s exactly what I’m going to do.

Before I go any further, I have a couple of disclaimers:

  1. This tutorial is based on one written by Savjee using NodeJS; and
  2. It’s been a while since I wrote any C++ code, so I might be a little rusty.

The first thing you’ll want to do is open a new C++ project, I’m using CLion from JetBrains but any C++ IDE or even a text editor will do. For the interests of this tutorial we’ll call the project TestChain, so go ahead and create the project and we’ll get started.

If you’re using CLion you’ll see that the main.cpp file will have already been created and opened for you; we’ll leave this to one side for the time being.

Create a file called Block.h in the main project folder, you should be able to do this by right-clicking on the TestChain directory in the Project Tool Window and selecting: New > C/C++ Header File.

Inside the file, add the following code (if you’re using CLion place all code between the lines that read #define TESTCHAIN_BLOCK_H and #endif):

These lines above tell the compiler to include the cstdint, and iostream libraries.

Add this line below it:

This essentially creates a shortcut to the std namespace, which means that we don’t need to refer to declarations inside the std namespace by their full names e.g. std::string, but instead use their shortened names e.g. string.

So far, so good; let’s start fleshing things out a little more.

A blockchain is made up of a series of blocks which contain data and each block contains a cryptographic representation of the previous block, which means that it becomes very hard to change the contents of any block without then needing to change every subsequent one; hence where the blockchain essentially gets its immutable properties.

So let’s create our block class, add the following lines to the Block.h header file:

Unsurprisingly, we’re calling our class Block (line 1) followed by the public modifier (line 2) and public variable sPrevHash (remember each block is linked to the previous block) (line 3). The constructor signature (line 5) takes three parameters for nIndexIn, and sDataIn; note that the const keyword is used along with the reference modifier (&) so that the parameters are passed by reference but cannot be changed, this is done to improve efficiency and save memory. The GetHash method signature is specified next (line 7) followed by the MineBlock method signature (line 9), which takes a parameter nDifficulty. We specify the private modifier (line 11) followed by the private variables _nIndex, _nNonce, _sData, _sHash, and _tTime (lines 12–16). The signature for _CalculateHash (line 18) also has the const keyword, this is to ensure the method cannot change any of the variables in the block class which is very useful when dealing with a blockchain.

Now it’s time to create our Blockchain.h header file in the main project folder.

Let’s start by adding these lines (if you’re using CLion place all code between the lines that read #define TESTCHAIN_BLOCKCHAIN_H and #endif):

They tell the compiler to include the cstdint, and vector libraries, as well as the Block.h header file we have just created, and creates a shortcut to the std namespace.

Now let’s create our blockchain class, add the following lines to the Blockchain.h header file:

As with our block class, we’re keeping things simple and calling our blockchain class Blockchain (line 1) followed by the public modifier (line 2) and the constructor signature (line 3). The AddBlock signature (line 5) takes a parameter bNew which must be an object of the Block class we created earlier. We then specify the private modifier (line 7) followed by the private variables for _nDifficulty, and _vChain (lines 8–9) as well as the method signature for _GetLastBlock (line 11) which is also followed by the const keyword to denote that the output of the method cannot be changed.

Ain't nobody got time for that!Since blockchains use cryptography, now would be a good time to get some cryptographic functionality in our blockchain. We’re going to be using the SHA256 hashing technique to create hashes of our blocks, we could write our own but really – in this day and age of open source software – why bother?

To make my life that much easier, I copied and pasted the text for the sha256.h, sha256.cpp and LICENSE.txt files shown on the C++ sha256 function from Zedwood and saved them in the project folder.

Right, let’s keep going.

Create a source file for our block and save it as Block.cpp in the main project folder; you should be able to do this by right-clicking on the TestChain directory in the Project Tool Window and selecting: New > C/C++ Source File.

Start by adding these lines, which tell the compiler to include the Block.h and sha256.h files we added earlier.

Follow these with the implementation of our block constructor:

The constructor starts off by repeating the signature we specified in the Block.h header file (line 1) but we also add code to copy the contents of the parameters into the the variables _nIndex, and _sData. The _nNonce variable is set to -1 (line 2) and the _tTime variable is set to the current time (line 3).

Let’s add an accessor for the block’s hash:

We specify the signature for GetHash (line 1) and then add a return for the private variable _sHash (line 2).

As you might have read, blockchain technology was made popular when it was devised for the Bitcoin digital currency, as the ledger is both immutable and public; which means that, as one user transfers Bitcoin to another user, a transaction for the transfer is written into a block on the blockchain by nodes on the Bitcoin network. A node is another computer which is running the Bitcoin software and, since the network is peer-to-peer, it could be anyone around the world; this process is called ‘mining’ as the owner of the node is rewarded with Bitcoin each time they successfully create a valid block on the blockchain.

To successfully create a valid block, and therefore be rewarded, a miner must create a cryptographic hash of the block they want to add to the blockchain that matches the requirements for a valid hash at that time; this is achieved by counting the number of zeros at the beginning of the hash, if the number of zeros is equal to or greater than the difficulty level set by the network that block is valid. If the hash is not valid a variable called a nonce is incremented and the hash created again; this process, called Proof of Work (PoW), is repeated until a hash is produced that is valid.

So, with that being said, let’s add the MineBlock method; here’s where the magic happens!

We start with the signature for the MineBlock method, which we specified in the Block.h header file (line 1), and create an array of characters with a length one greater that the value specified for nDifficulty (line 2). A for loop is used to fill the array with zeros, followed by the final array item being given the string terminator character (\0), (lines 3–6) then the character array or c-string is turned into a standard string (line 8). A do…while loop is then used (lines 10–13) to increment the _nNonce and _sHash is assigned with the output of _CalculateHash, the front portion of the hash is then compared the string of zeros we’ve just created; if no match is found the loop is repeated until a match is found. Once a match is found a message is sent to the output buffer to say that the block has been successfully mined (line 15).

We’ve seen it mentioned a few times before, so let’s now add the _CalculateHash method:

We kick off with the signature for the _CalculateHash method (line 1), which we specified in the Block.h header file, but we include the inline keyword which makes the code more efficient as the compiler places the method’s instructions inline wherever the method is called; this cuts down on separate method calls. A string stream is then created (line 2), followed by appending the values for _nIndex, _tTime, _sData, _nNonce, and sPrevHash to the stream (line 3). We finish off by returning the output of the sha256 method (from the sha256 files we added earlier) using the string output from the string stream (line 5).

Right, let’s finish off our blockchain implementation! Same as before, create a source file for our blockchain and save it as Blockchain.cpp in the main project folder.

Add these lines, which tell the compiler to include the Blockchain.h file we added earlier.

Follow these with the implementation of our blockchain constructor:

We start off with the signature for the blockchain constructor we specified in Blockchain.h (line 1). As a blocks are added to the blockchain they need to reference the previous block using its hash, but as the blockchain must start somewhere we have to create a block for the next block to reference, we call this a genesis block. A genesis block is created and placed onto the _vChain vector (line 2). We then set the _nDifficulty level (line 3) depending on how hard we want to make the PoW process.

Now it’s time to add the code for adding a block to the blockchain, add the following lines:

The signature we specified in Blockchain.h for AddBlock is added (line 1) followed by setting the sPrevHash variable for the new block from the hash of the last block on the blockchain which we get using _GetLastBlock and its GetHash method (line 2). The block is then mined using the MineBlock method (line 3) followed by the block being added to the _vChain vector (line 4), thus completing the process of adding a block to the blockchain.

Let’s finish this file off by adding the last method:

We add the signature for _GetLastBlock from Blockchain.h (line 1) followed by returning the last block found in the _vChain vector using its back method (line 2).

Right, that’s almost it, let’s test it out!

Remember the main.cpp file? Now’s the time to update it, open it up and replace the contents with the following lines:

This tells the compiler to include the Blockchain.h file we created earlier.

Then add the following lines:

As with most C/C++ programs, everything is kicked off by calling the main method, this one creates a new blockchain (line 2) and informs the user that a block is being mined by printing to the output buffer (line 4) then creates a new block and adds it to the chain (line 5); the process for mining that block will then kick off until a valid hash is found. Once the block is mined the process is repeated for two more blocks.

Time to run it! If you are using CLion simply hit the ‘Run TestChain’ button in the top right hand corner of the window. If you’re old skool, you can compile and run the program using the following commands from the command line:

If all goes well you should see an output like this:

Congratulations, you have just written a blockchain from scratch in C++, in case you got lost I’ve put all the files into a Github repo. Since the original code for Bitcoin was also written in C++, why not take a look at its code and see what improvements you can make to what we’ve started off today?

If you have any questions or comments – as always – I’d love to hear them; please put them in the comments below.

(Visited 1,544 times, 1 visits today)

61 Comments

  1. Magma13 January 23, 2018 at 2:29 pm

    My output stops at

    Mining block 1…

    What do you think can be the problem?

    Reply
    1. Dave Nash - Site Author April 10, 2018 at 9:24 am

      Blocks take time to be mined, if you want the output to be shown faster decrease the value for nDifficulty.

      Reply
  2. Gabi February 18, 2018 at 3:48 pm

    Hello. How i can view all mined blocks ?

    Reply
    1. Dave Nash - Site Author April 10, 2018 at 9:24 am

      Hi Gabi, that’s a little outside the scope of this tutorial; feel free to fork the repo and add the necessary code!

      Reply
  3. thomas February 21, 2018 at 9:50 am

    how can i store the blocks in my hard drive and also share the ledger to all the nodes in the network

    Reply
    1. Dave Nash - Site Author April 10, 2018 at 9:26 am

      Hi Thomas, over to you; feel free to fork the repo and add the code you need!

      Reply
      1. Sam April 26, 2018 at 12:47 pm

        Hi, Dave! I didn’t understand your answer to Thomas, so I repeat the question again.
        How are the blocks stored on the hard drive and then retrieved?
        What kind of file should the blockchain be? Does every blockchain system use its own type which might be decoded by its own applications?
        Should only newly created block or the whole ledger be shared on the network?
        Thanks in advance.

        Reply
        1. Dave Nash - Site Author May 19, 2018 at 1:21 pm

          Hi Sam, this example keeps everything in memory; nothing is written to the file system. You might want to check the source code for Bitcoin to see how it handles file system and network access.

          Reply
  4. Stephanie February 23, 2018 at 12:30 am

    I really like what you have going on here, but I find it really difficult to follow because you don’t explain what your variables mean or why you need them. Some are easy to guess at, but not all.

    Reply
    1. Dave Nash - Site Author April 10, 2018 at 9:28 am

      Hi Stephanie, which variables are you having trouble with?

      Reply
  5. Pedram March 4, 2018 at 6:05 pm

    where emplace_back is defined?

    Reply
  6. sakshi March 21, 2018 at 10:30 am

    header file such as ctime and sstream should be included for time(nullptr) and string stream respectively

    Reply
    1. Dave Nash - Site Author April 10, 2018 at 9:27 am

      Feel free to fork the repo and make the changes you think are missing!

      Reply
  7. 伍唤宇 April 3, 2018 at 4:31 pm

    Thank you, I never find a Chinese example in C++, now I find the first one in English though, but really easy to understand

    Reply
  8. 伍唤宇 April 4, 2018 at 10:57 am

    should “char cstr[nDifficulty + 1];” be changed to “char * cstr= new char[nDifficulty + 1];”? I thought nDifficulty is not a constant

    Reply
    1. d00dz May 4, 2018 at 9:35 am

      I think is shorter use …. string str(nDifficulty, ‘0’);

      Reply
  9. Yaduvendra Singh April 16, 2018 at 9:27 pm

    Thanks Dave ! Great example of using C++ for block chain.

    Reply
  10. alexis April 27, 2018 at 4:49 am

    !Great it is working on linux debian 9.0¡

    Reply
  11. KS May 3, 2018 at 6:51 am

    Thx Dave! Easy to understand and expandable!

    Reply
  12. LordOfDarkess May 16, 2018 at 6:49 pm

    I really like the idea that block mines itself 😉

    Reply
  13. nFactorial May 19, 2018 at 12:48 pm

    Hi! You can to help me to replace vector with Simple linked list?

    Reply
      1. nFactorial May 19, 2018 at 2:15 pm

        for a project at school, i need list

        Reply
      2. Stephen August 2, 2018 at 8:46 am

        Awesome article and code Dave! Although vector has great advantage over list with erase and insert, with blockchain’s special property: the blocks cannot be deleted and always add new blocks to the end of the chain. Which means only push_back method is used in blockchain, so I think it’s should be fine to use list versus vector right?
        Anyways, great work I learned a lot!

        Reply
  14. nFactorial May 21, 2018 at 4:35 pm

    _vChain.emplace_back(Block(0, “Genesis Block”)); Here adding element 0 to next block?

    Reply
  15. Guillermo May 31, 2018 at 2:51 am

    I am getting an error at:
    char cstr[nDifficulty + 1];

    Also:
    stringstream ss;
    ss <<

    I have them in the Block.cpp file.

    Reply
    1. Dave Nash - Site Author June 2, 2018 at 11:06 am

      What’s the error? Also, what command are you running to compile the code?

      Reply
  16. Rajendra Maharjan June 8, 2018 at 5:45 pm

    I got the same error as mentioned by Guillermo above. Here is the error. I am running this project in CLion in windows. After using #include , the 2nd error mentioned above got resolved.
    block.cpp
    error C2131: expression did not evaluate to a constant
    note: failure was caused by non-constant arguments or reference to a non-constant symbol
    note: see usage of ‘nDifficulty’
    error C3863: array type ‘char [nDifficulty+]’ is not assignable
    error C3863: array type ‘char [nDifficulty+]’ is not assignable
    NMAKE : fatal error U1077: ‘C:\PROGRA~2\MICROS~1.0\VC\bin\cl.exe’ : return code ‘0x2’
    Stop.
    NMAKE : fatal error U1077: ‘”C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe”‘ : return code ‘0x2’
    Stop.
    NMAKE : fatal error U1077: ‘”C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe”‘ : return code ‘0x2’
    Stop.
    NMAKE : fatal error U1077: ‘”C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe”‘ : return code ‘0x2’
    Stop.

    Reply
    1. Dave Nash - Site Author July 26, 2018 at 6:07 pm

      I haven’t tried compiling the code on Windows, I recommend using a unix machine

      Reply
  17. Joao June 13, 2018 at 2:05 pm

    Great tutorial, Sr!

    Reply
  18. Ender0224 June 18, 2018 at 9:52 am

    hello Dave
    thanks so much for your kind share.
    will you go on update the rep for more details and function? or you just give a good example and stay here?

    Reply
    1. Dave Nash - Site Author July 26, 2018 at 6:08 pm

      I have no plans to update the code

      Reply
  19. shawn July 9, 2018 at 6:14 pm

    Hello Dave,

    I have the same issues as Guillermo.
    I am relatively new to coding so this might seem relatively simple to you:
    – I am using Microsoft Visual Studio.
    – ndifficulty is underligned and it says that the expression must have a constant value.
    – ss is underligned and it says “incomplete type not allowed”

    Thank you in advance!

    Reply
    1. Dave Nash - Site Author July 26, 2018 at 6:09 pm

      I have not tried compiling the code in Visual Studio, I recommend using a unix machine

      Reply
    2. Leo September 7, 2018 at 9:19 pm

      “– ndifficulty is underligned and it says that the expression must have a constant value.”
      you should use dynamic allocation of memory. (new[], delete[] will help you)

      “– ss is underligned and it says “incomplete type not allowed””
      #include

      Reply
      1. javier April 12, 2019 at 8:17 am

        I add #include in Block.cpp, and then i can compile

        Reply
  20. Bob September 5, 2018 at 9:58 am

    Hi, this explanation is awesome, and I can’t thank you enough for posting it. Not only is your code clear, it makes the concept of block chains themselves so simple to understand. Thanks much for this code and for taking the time to make this entry!

    Reply
  21. StewPead September 17, 2018 at 9:16 am

    I got errors:

    C:\Users\RJay\AppData\Local\Temp\ccWgRhMX.o:main.cpp:(.text+0x1da): undefined reference to `Blockchain::AddBlock(Block)’
    collect2.exe: error: ld returned 1 exit status

    and
    “_nIndex” is not a nonstatic data member or base class of class “Block”

    Im using Visual Studio Code.

    Reply
    1. Dave Nash - Site Author November 18, 2018 at 3:55 pm

      I’ve not tried compiling the code on a Windows machine, did you try running the code from the Github repo too?

      Reply
  22. Unnati September 18, 2018 at 9:21 am

    Hi
    could u please tell me from here how to design a bitcoin, since its implemented using blockchain.
    thanks.

    Reply
    1. Dave Nash - Site Author November 18, 2018 at 3:41 pm

      Thanks for your suggestion, but at present I have no plans to write a tutorial on how to design a coin. You might want to take what you’ve learned here in this tutorial and examine the Bitcoin code over on Github, that might help give you an idea on how to proceed.

      Reply
  23. udit September 30, 2018 at 2:10 pm

    once we get a block mined, at owners end how can we get our string back from, the blockchain ? owner must know what he is writing in ledger !

    Reply
    1. Dave Nash - Site Author November 18, 2018 at 3:50 pm

      If you take a look at the code in the tutorial, you will notice that I place the blocks inside a vector; so you should be able to get the string back to show to the user.

      Reply
  24. darludi58 October 22, 2018 at 6:59 pm

    Result using codelite on ubuntu, what’s wrong?

    Command line is empty. Build aborted.Command line is empty. Build aborted.MESSAGE: Entering directory `/home/map/Dev/BlockChain’
    /bin/sh -c ‘/usr/bin/make -f/home/map/Dev/BlockChain/Makefile -j 32’
    ———-Building project:[ BlockChain – ]———-
    make[2]: *** No rule to make target ‘src/Main.cpp’, needed by ‘CMakeFiles/BlockChain.dir/src/Main.cpp.o’. Stop.
    make[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/BlockChain.dir/all] Error 2
    make: *** [/home/map/Dev/BlockChain/Makefile:84: all] Error 2
    ====0 errors, 0 warnings====

    Reply
    1. Dave Nash - Site Author November 18, 2018 at 3:52 pm

      Hey, I haven’t tried compiling the code on Ubuntu; are you using the compile command in the tutorial? Also, have you tried pulling down the code from Github and compiling that?

      Reply
  25. Jackson October 24, 2018 at 12:30 pm

    Can we convert completely or partially the above block chain code into parallel code using OpenMP or Multithreading? Any places you can suggest which can be parallelised? Thanks.

    Reply
    1. Dave Nash - Site Author November 18, 2018 at 3:52 pm

      That’s a little outside the scope of this tutorial, I’d be interested to hear how you get on though!

      Reply
  26. junior October 26, 2018 at 5:45 pm

    i have an error message when a compile the code:

    unrecognized command line option ‘-stdlib=libc++’

    Reply
    1. Dave Nash - Site Author November 18, 2018 at 3:54 pm

      What are you entering on the command line to get that error?

      Reply
      1. KyawSwarLin September 21, 2019 at 2:21 pm

        Hi sir .how can code with C++ for POS mining algorithm.POW will consume power .So POS may be better.Please show some example of POS in above codes .Thanks you sir.
        And also how about public and private key for this cryptocurrency.

        Reply
        1. Dave Nash - Site Author September 28, 2019 at 11:17 am

          Thanks for your question but I haven’t done any work on Blockchain for well over a year so I cannot comment on PoW vs. PoS, I’m sure there are some examples of using PoS around the internet. This tutorial is just as an introduction of Blockchain written in C++, it’s not written with any cryptocurrency in mind.

          Reply
  27. Anton Anderson January 2, 2019 at 3:32 pm

    I have actually typed out this code as I was reading this fantastic blog article.
    I was able to make it to run on a Windows 10 machine using Visual Studio 2010.

    It works perfectly!

    I recommend to change this line to Block::MineBlock():

    char cstr[nDifficulty + 1];

    To this:

    char* cstr = new char[nDifficulty + 1];

    And if one wants to see Proof of Work (the number of times before a valid hash is accepted then add this line of code:

    cout << "Proof of Work (PoW): " << _nNonce << endl << endl;

    And do not forget to add :

    delete cstr;

    at the end to avoid memory leaks!

    Thank you Dave. This was EXACTLY what I was looking for to learn the basics behind blockchains.

    Now I am ready to dig deeper into learning more about this. I have a posted a link to this blog post at my profile page at Codementor. And I plan to link it on my LinkedIn page as well.

    Again you have my thanks!

    Reply
    1. Dave Nash - Site Author January 12, 2019 at 3:58 pm

      Hey, I’m glad you found the tutorial useful; I’m not a C++ developer so happy to hear feedback with ways to improve it.

      Reply
  28. Nikki January 14, 2019 at 7:48 am

    Will this work on macbook?

    Reply
    1. Dave Nash - Site Author January 21, 2019 at 11:23 pm

      It was written on an iMac, so I don’t see why a MacBook wouldn’t work

      Reply
  29. Chuck January 31, 2019 at 2:22 pm

    Hi
    Could you recommend me any method to calculate hash faster

    Reply
    1. Dave Nash - Site Author September 9, 2019 at 10:34 pm

      You can try reducing the difficulty

      Reply
  30. Ayan Roy February 21, 2019 at 7:09 pm

    Hi. I have a small question. I am mining block of the form “V001,1”. Now I would like to query the blockchain with input such as “V001” and want it to return the value 1. Do you know of anything how I can modify this code to do that ? Thanks in advance

    Reply
    1. Dave Nash - Site Author September 9, 2019 at 10:37 pm

      You’d probably have to keep some kind of index to locate the block you’re looking for, I recommend forking the code on Github and giving it a try

      Reply

Leave A Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.