DEV Community

loading...
Cover image for Trying to understand blockchain by making one!

Trying to understand blockchain by making one!

damcosset profile image Damien Cosset Originally published at damiencosset.com Updated on ・6 min read

Introduction

Bitcoin and cryptocurrencies made a lot of noise lately. I have been rather disappointed by the turn the cryptocurrencies took, from an amazing concept to what seems just another way to make quick money ( or not... ).

But I became very interested by the technologies enabling cryptocurrencies, and obviously by the concept of a blockchain. The concept is fascinating, and not limited to Bitcoin and friends. We could imagine many applications for such a technology. So, in a proper developer manner, I decided to code one blockchain, or what I think is a blockchain, to understand better what it is.

A simple project

So, what do we need to create a very simple blockchain?

  • A block

A block is what the blockchain is made of. In our case, a block will be composed of a date, an index, some data ( a message in our case ), and the hash of the previous block.

  • Cryptography

To keep informations secure, we need to encrypt our data. For our little project, we will use the js-sha256 package. This process will create a string of 64 characters. Ultimately, our blockchain will be a series of hashes, each composed of 64 characters. As I said earlier, we use the hash of the previous block to encrypt a new block ( that is why we call it a chain ).

  • Difficulty and nonce

We don't just create one hash per block and that's it. A hash must be valid. In our case, a hash will be valid if the first four characters of our hash are 0. If our hash starts with '0000......', it is considered valid. This is called the difficulty. The higher the difficulty, the longer it takes to get a valid hash.

But, if the hash is not valid the first time, something must change in the data we use right? If we use the same data over and over, we will get the same hash over and over and our hash will never be valid. You are right, we use something called nonce in our hash. It is simply a number that we increment each time the hash is not valid. We get our data (date, message, previous hash, index) and a nonce of 1. If the hash we get with these is not valid, we try with a nonce of 2. And we increment the nonce until we get a valid hash.

  • Genesis block

Their must be a first block in our chain. It is called the genesis block. Of course, this block can't use the hash of the previous block because it doesn't exist. We will just give it some arbitrary data to create its hash.

And that is pretty much what we need for our blockchain.

The methods

We will need a few methods to make a functional blockchain:

  • initialize our blockchain => creates the genesis block
  • hash our blocks => a function responsible for creating a valid hash
  • check the validity of a hash => does our hash starts with 'OOOO' ?
  • get the last hash => we need the previous hash to create a new block
  • add a new block => We need to do that at one point, if we want a chain

THE COOOOODE !!

Let's get coding now.

For this little project, I will create two files, one called index.js and another called blockchain.js. The second one will hold our little module to create a blockchain. It's straightforward, let's take a look at it:

const sha256 = require('js-sha256').sha256

const blockchain = (function(){
  const blocks = []

  const initBlockchain = () => {
    const data = 'Hello World!'
    const timestamp = new Date()
    const previousHash = 0
    const index = 0
    hashBlock(data, timestamp, previousHash, index)
  }

  const hashBlock = (data, timestamp, prevHash, index) => {
    let hash = '', nonce = 0

    while( !isHashValid(hash) ){
      let input = `${data}${timestamp}${prevHash}${index}${nonce}`
      hash = sha256(input)
      nonce += 1
    }
    console.log(nonce)
    blocks.push(hash)
  }

  const getLastHash = blocks => blocks.slice(-1)[0]

  const isHashValid = hash => hash.startsWith('0000') // Difficulty

  const addNewBlock = data => {
    const index = blocks.length
    const previousHash = getLastHash(blocks)
    hashBlock(data, new Date(), previousHash, index)
  }

  const getAllBlocks = () => blocks

  return {
    initBlockchain,
    getLastHash,
    blocks,
    getAllBlocks,
    addNewBlock
  }
})()

module.exports = blockchain

Enter fullscreen mode Exit fullscreen mode

So, in this module, I have a few methods. At the top, I import the module that will handle the cryptography part. I have an empty array that will hold my blockchain's blocks, called blocks.

initBlockchain: This method starts the blockchain by creating the first block, the genesis block. I give it a timestamp, a message, the block's index in the blockchain ( 0 ) and a arbitrary previous hash because there are no previous blocks in the chain yet. With all these informations, I can now create the hash for the genesis block.

hashBlock: This method takes all the block's data and creates a hash. As you can see, the first time we run the function for a specific block, the nonce is set to 0. We encrypt our block and check if the hash is valid with isHashValid. In our case, a hash is valid if the four first characters are 0. This is called the difficulty. This is the problem we have to solve to make sure the block can be part of the blockchain. Once the hash is valid, we add it to our blocks array.

addNewBlock: This method is responsible for creating a new block. We only need to give it the message as an argument, because all the other arguments ( index, previousHash, and timestamp) can be found in the blockchain. The method calls hashBlock with the data to create and validate the new block.

getLastHash: The method I call to get the previous hash. We always need the previous hash to create a new block.

getAllBlocks: Just returns all the blocks currently in the blockchain

Great, so let's move to index.js to use our new blockchain!

const blockchain = require('./blockchain')

blockchain.initBlockchain()
blockchain.addNewBlock('First new block')
blockchain.addNewBlock('I love blockchains')
blockchain.addNewBlock('Make me a new hash!!')

console.log(blockchain.getAllBlocks())
Enter fullscreen mode Exit fullscreen mode

We initialize our blockchain, then we create three new blocks. When I run this, I get the following chain in response:

Initializing the blockchain
139355
30720
68789
51486
[ '0000d87875f12e8c00d60cdfc8c21c4867eb1e732d3bb0e4d60bd0febcfafbaf',
  '0000331d80f4e83461bad846e082baa08c5e739edfa19a4880c1dcbe4eed1984',
  '00000dcab247410050e357158edc20555cc0110429023fdadb1d8cda3e06da5e',
  '0000a16968811cf75c33d877e99f460d396c46b5485f669c8e55b193b862106d' ]
Enter fullscreen mode Exit fullscreen mode

The array represent the four blocks. As you can see, every single one of them starts with four zeros, so every single hash is valid. If one of those hashes didn't start with four zeros, I would know right away the hash was invalid, therefore, the data in the corresponding block should probably not be trusted.

There are four numbers here: 139355, 30720, 68789, 51486. These are the nonce for each block. I printed them out to see how many times the function hashBlock ran to come to a valid hash.

The first block, the genesis block, ran 139355 times before having a valid hash! The second, 30720 times. The third 68789 times and the fourth 51486 times.

Conclusion

This is a very simple example of a blockchain. I'm pretty sure I missed a few things here. I also kept things pretty simple because hey, I'm learning! This little project made me understand a few things:

  • If one person decides to modify a previous block, she would have to change every single block after that one. Each block inherits from its parent ( previous hash ), so trying to cheat a blockchain seems complicated.

  • But if a majority of the blockchain's users decide to cheat, they could modify a previous block and all agree to change the rest of the blockchain accordingly. A blockchain seems to work only if the majority decides to follow the rules. Or you could end up with two different blockchains, one where the users decided to stick with the original data, and the other where the users decided to use the modified blockchain.

  • I've heard about the Bitcoin enormous use of power where it came to mining. Mining is the concept of solving the difficulty problem when you encrypt the data. You get the transaction and you try to find a valid hash for that block. As a reward for your effort, you get some bitcoin. I can only imagine the amount of power you would use when the blockchain becomes huge.

Well, that's about what I got from that. It made things a lot clearer for me. Feel free to correct me if i got things wrong!

Discussion (48)

pic
Editor guide
Collapse
wizmer profile image
Benoit Coste

Thanks for this "Blockchain made easy" article. Really interesting.

Collapse
sompylasar profile image
Ivan Babak

I don't quite get one part: from your example, only the hash of the data is stored in the blockchain; isn't the data supposed to be decrypted later? Where are the data messages ("transactions") stored then, if not in the block chain?

Collapse
tintybot profile image
tintybot

well hash defines a unique signature of a block, in real practice, the block also contains an index value, a data(record of transactions), a timestamp , and also the golden nonce value.The cryptographic hash dont account for decryption. Its like the address part of a data-structure, and the data is stored in the data part of the data-structure.

Collapse
anat0lius profile image
Anatoli

Actually the point of the blockchain is to secure the immutability of data, not to encrypt it.

Collapse
pbouillon profile image
Pierre Bouillon

I'm very interested about an answer to your question. How would you implement it in the current example?

Collapse
sompylasar profile image
Ivan Babak

I'm interested in an answer from the author before proposing mine.

Thread Thread
pbouillon profile image
Pierre Bouillon

Too bad we can't tag people

Collapse
ahmed_ezzat12 profile image
Ezzat

thank you for the post it really cleared many concepts i was struggling to understand.

here is the implementation in python

first file

blockchainLib.py

import hashlib
import time

blocks = []


def encrypt_string(hash_string):
    sha_signature = \
        hashlib.sha256(hash_string.encode()).hexdigest()
    return sha_signature


def isValidhash(hash):
    if hash.startswith("0000"):
        return True
    return False


def hashBlock(data, timestamp, previoushash, index):
    _hash = ""
    nonce = 0
    while not isValidhash(_hash):
        _input = data + str(timestamp) + str(previoushash) + str(index) + str(nonce)
        _hash = encrypt_string(_input)
        nonce += 1
        print(nonce)
    blocks.append(_hash)


def getLastHash():
    return blocks[len(blocks) - 1]


def addNewBlock(mmessage):
    _index = len(blocks)
    timestamp = time.time()
    previousHash = getLastHash()
    hashBlock(mmessage, timestamp, previousHash, _index)


def getAllBlocks():
    for i in range(0, len(blocks)):
        print(blocks[i])


def initBlock():
    data = "hello world"
    timestamp = time.time()
    previoushash = 0
    index = 0
    hashBlock(data, timestamp, previoushash, index)

the second file

main.py

#!/bin/python3


import blockchainLib as bl

if __name__ == "__main__":

    bl.initBlock()
    bl.addNewBlock("hello world")
    bl.addNewBlock("hello world 2")
    bl.getAllBlocks()
Collapse
vgrovestine profile image
Vincent Grovestine • Edited

Been dabbling in cryptocurrency mining lately, and never really understood what was going on behind the scenes until reading this. Much thanks!

On a lark, I was inspired to draft a really simple implementation in PHP:

Collapse
eerk profile image
eerk

Awesome explanation, really helpful! I'm just wondering why a hash is only valid if it starts with 0000 characters. I'm also not clear on how to use this blockchain for, say creating my own cryptokittens or some other application. How are the hashes in a blockchain connected to actual data?

Collapse
damcosset profile image
Damien Cosset Author

The 0000 characters are called the difficulty. I chose those characters. They do not mean anything in particular, I could have picked anything. In Bitcoin for example, there is a concept called mining, where you have to 'solve' this difficulty by finding a valid hash. If the answer is found too quickly, the difficulty will be augmented for the next blocks( say 5 zeroes instead of 4 ).

I'll make another article to explain the connexion between hashes and data, I am getting a few questions about this :)

Collapse
toonpt profile image
José Miguel Malaca

thanks for the article ;)
in ruby:

require "digest"

class Blockchain

  def initialize(difficulty = "00")
    @blocks = []
    @difficulty = difficulty
    hash_block("I'm the Genesis block")
  end

  def add_new_block(data)
    hash_block(data, last_hash, @blocks.length)
  end

  def all_blocks
    @blocks
  end

  private

  def hash_block(data, previous_hash=0, index=0)
    hash = ""
    nonce = 1

    while(!valid_hash? hash)
      input = "#{data}#{timestamp}#{previous_hash}#{index}#{nonce}"
      hash = encode input
      nonce += 1
    end

    @blocks << hash
    {hash: hash, nonce: nonce}
  end

  def encode(input)
    Digest::SHA256.base64digest input
  end

  def valid_hash?(hash)
    hash.start_with? @difficulty
  end

  def last_hash
    @blocks.last
  end

  def timestamp
    Time.now.getutc
  end
end
Collapse
pajasevi profile image
Pavel Ševčík

I can only imagine the amount of power you would use when the blockchain becomes huge. - this has actually nothing to do with the size of the blockchain. Computing power needed to solve the puzzle (calculate correct hash for your block) is relative to the total amount of computing power used in the network (for this particular blockchain). The goal is to maintain stable creation of blocks - for example every ~10 minutes in the Bitcoin network.

Collapse
alanguir profile image
Alan Languirand

The revolutionary part is the distributed ledger - i.e. decentralizing one block chain to many clients so that any transaction on any client can be verified against the history of transactions on other clients.

Collapse
alanguir profile image
Alan Languirand • Edited

Nice article! To help me learn this I pulled out the js-sha256 to rely on node's crypto module directly and made some async/functional updates of my own along the way. Could be an interesting comparison for anyone who wants to compare imperative vs. functional and brings up the issue seen in real cryptocurrencies where the first miner to get a valid proof of work causes others to start over now that their 'last hash' value has changed. Code is here:

github.com/alanguir/blockchain/blo...

Collapse
shawnlknight profile image
Shawn Leberknight • Edited

Great article! I've been wanting an good intro into block chain and this was perfect. However, when I ran the index.js file, blockchain.getAllBlocks() returned undefined. I got it to work by updating that function to const getAllBlocks = () => blocks.

Collapse
damcosset profile image
Damien Cosset Author

You are right, I updated the code in the article. Thanks for the catch!

Collapse
skillslide profile image
SkillSlide

Thanks for the breakdown. It seems simple enough. What's the revolutionary part of blockchains then, the part that Satoshi figured out? Did Satoshi just put out a proof that this is a valid way to do things?

Collapse
stefandorresteijn profile image
Stefan Dorresteijn

The revolutionary part of blockchain technology (or at least one of its revolutionary features) is that you never have to trust a single user of the network. You only have to trust the technology because if that works, it's impossible to cheat the system.

Collapse
vasilvestre profile image
Valentin Silvestre

I don't really get it. You can explain a bit more please ?

Thread Thread
obscuremind profile image
The Dark Side

I think it's about decentralization, in a p2p network everyone has a copy of the blockchain (in case) and if one changes its pair this will generate an incongruity with the other pairs scattered in the nodes (computer, device) of the network, and your fake couple it would be excluded, therefore, no one should worry if a node is honest because he himself would denounce and punish himself by excluding himself from the network.

Collapse
szymach profile image
Piotr Szymaszek

Two things:

  1. In the "Genesis block" section you have "Their must be", it should be "There must be".
  2. "check the validity of a hash => does our hash starts with 'OOOO'" weirdly this gets formatted like it has four letters "O" instead of zeros?

Aside from that, it is a good article and thank you for posting it :)

Collapse
seniorjoinu profile image
Alexander

Thanks for this article, but i think the devil is in details. Blockchain itself is a simple pattern, but it has nothing to do with real world blockchain powered p2p networks. In real application you need to spend much more code and time with such things like establishing secure socket connection, managing resources and implementing an idea of your cryptosystem (what it is and why it should help people live their lives in happiness).

P.S. there is no need in self-executing function if you use a node's require/exports system.

Collapse
dhruv profile image
Dhruv

So a blockchain is an encrypted Linked List?

Collapse
damcosset profile image
Damien Cosset Author

Mhmm, I guess you could call it like that.

Collapse
obscuremind profile image
The Dark Side

the blockchain itself is not encrypted, everyone can read (search: blockchain explore), it would be better to say that the blockchain is a list of concatenated hashes.

Collapse
lavigi profile image
eva

That is absolutely brilliant, Damien. Nothing like seeing it with your own eyes in order to understand it. Many thanks :-)

To help out anyone who is not at all familiar with node (hello, anyone there? ;-) ) here's a very simple way to run this:

  1. Create a folder.
  2. In it, create both files index.js and blockchain.js as instructed in the article. Copy & paste respective code.
  3. Get a command prompt or a terminal to the folder that contains both files.
  4. Run npm init -y (this will create the package.json file)
  5. Run npm install js-sha256 (this will install the required module and update package.json)
  6. Just run the project with node index.js

Hope it helps.

Collapse
kartikarora profile image
Kartik Arora

This post did what all whitepapers couldn't - Explain the concept!. Great article Damien, thank you so much!

Collapse
loladynamic profile image
Abigail

this is pretty cool. thanks to Blockchain

Collapse
pratikaambani profile image
Pratik Ambani

Would anybody like to volunteer to write the same in Java?

Collapse
maciejprzerwa profile image
Maciej Przerwa • Edited

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

public class BlockchainExample {

//list of hash values
List<String> blocks = new ArrayList<String>();

public void initBlockchain() {
    String msg = "Hello world";
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
    String previousHash = "0";
    String index = "0";

    hashBlock(msg, timeStamp, previousHash, index);
}

public void hashBlock(String msg, String timestamp, String prevHash, String index) {

    String hash = "";
    Integer nonce = 0;

    while(!isHashValid(hash)) {
        String input = msg+timestamp+prevHash+index+nonce.toString();
        hash = sha256(input);
        nonce+=1;
    }
    System.out.println(nonce.toString());
    blocks.add(hash);   
}

public String getLastHash() {
    return blocks.get(blocks.size()-1);
}

public boolean isHashValid(String hash) {
    if (hash.startsWith("0000")) return true;
    else return false;
}

public void addNewBlock(String msg){
    Integer in = blocks.size();
    String previousHash = getLastHash();
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());

    hashBlock(msg, timeStamp, previousHash, in.toString());
}


public void getAllBlocks() {
    for(int i=0;i<blocks.size();i++){
        System.out.println(blocks.get(i));
    } 
}


public String sha256(String password) {
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA-256");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    md.update(password.getBytes());

    byte byteData[] = md.digest();

    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < byteData.length; i++) {
     sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
    }

    return sb.toString();
}


public static void main(String[] args) {

    BlockchainExample be = new BlockchainExample();

    be.initBlockchain();
    be.addNewBlock("First new block");
    be.addNewBlock("Second new block");

    be.getAllBlocks();
}

}

Collapse
eric7giants profile image
Eric7Giants

New to Java and I was referencing this for a Security course. I'm getting BlockchainExample cannot be resolved to a type.

Thread Thread
maciejprzerwa profile image
Maciej Przerwa

Hi there, could you specify in which line you are getting this error?
And also, did you copy all the code? Not only part on black? There are lines at the top

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

public class BlockchainExample {

and also one
}
at the end.
I have checked it minute ago - code works.

Collapse
kolagrey profile image
Grey

Neat!!! Thanks for the the simplistic approach to explaining what one formerly considered complex. Cheers!

Collapse
obscuremind profile image
The Dark Side

it is not complex, it is complicated, the blockchain is complex in nature because a block is linked to the previous one. I hope I have made the concept.

Collapse
vientang profile image
Vien

Great article in simplifying a complicated process re: blockchain

Collapse
pbouillon profile image
Pierre Bouillon

Very helpful article !
Not sure about it but I tried my own in Python3

Collapse
maciejprzerwa profile image
Maciej Przerwa

I don't get one thing. How to retrieve information from this Blockchain (the data Strings?)

Collapse
ztickm profile image
Salim MAHBOUBI

Great article.
I just have one small remark, the header image you used illustrates a kind of cyclic graph, which has nothing to do with blockchains as far as I know. This can be misleading.

Collapse
eternalprofits profile image
eternalprofits

Thank you for the article! very helpful.
Here is a block application building hackathon coming on this weekend July 14, 15. Let me know if anyone else is joining: bit.ly/2L2olS9

Collapse
vishnuvizz profile image
vishnuvizz

I have a doubt!! Bitcoin!!!!
If people from multiple mining pool trying to find nounce for certain block, then how are they going to agree to validate the same transaction in that block? if they didn't agree to mine with same transactions, then how is blockchain going to verify that they did valid mining(I meant not cheating). There is still a possibility that they can cheat right? If other mining pool people took diff set of transaction to mine for a block, then obviously they ll get diff hash and so they can't compare with them with actual hash. and If only one pool would get incentive (12.5BTC) then how after one mining a block, some other pool is going to waste its compute power in verifying the transaction. Even if it did so, how is it going to resist to change as change is already done in the blockchain.

Someone, please help me out...

Collapse
txd481 profile image
Tanya Daskova

Did we get an answer to how we retrieve the original data? How to see the messages in each block? Other than that, really good article! Well done!

Collapse
ebraheemijaz profile image
ebraheemijaz

very Interesting and best for beginners

Collapse
sunitasn profile image
Sunita Singhal

Very much impressed with the article.
Does each block contain one transaction in case of bitcoin?
How the bitcoin is generated? Who will generate?

Collapse
dudusray profile image
Kelvin Murithi

Clap! Clap! Clap! Clap! Clap! Clap! Clap!

Collapse
giacomosorbi profile image
Giacomo Sorbi

Please fix "Their must" => "There must", plus "OOOO" => "0000".

Brilliant article nevertheless :)