Trying to understand blockchain by making one!

Damien Cosset on December 12, 2017

Introduction Bitcoin and cryptocurrencies made a lot of noise lately. I have been rather disappointed by the turn the cryptocurrencies t... [Read Full]
markdown guide
 

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

 

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?

 

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.

 

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

 
 

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

 

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

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:

 

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?

 

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 :)

 

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.

 

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
 

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.

 

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

 

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.

 

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

 

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?

 

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.

 

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

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.

 

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.

 
 

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.

 
 

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 :)

 

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

 

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.

 

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

 
 

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

 

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();
}

}

 

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

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.

 

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

 

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.

 

Great article in simplifying a complicated process re: blockchain

 
 

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

 
 

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!

 

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

Brilliant article nevertheless :)

 
code of conduct - report abuse