1. Crearea unui blockchain


Inapoi la pagina de programare

Un blockchian (lanț de blocuri) este chiar ce îi spune si numele = o listă de blocuri între care există o legătură.
Un bloc contine mai multe informații:
– datele prorpiu-se
– propria semnătură
– semnătura blocului precedent
După cum se observă, fiecare bloc conține semnătura celui precedent. Mai mult însă de atât, propria semnătura este calcultă luând în considerare și semnătura precedentă.
Să presupunem că avem un lanț de 10 blocuri și modificăm datele din blocul al cincilea. Modificând datele, se modifică si semnătura acestui bloc, deci blocul al șaselea va avea o semnătură precedentă diferită. Mai mult decât atât, deoarece smnătura blocului șase se calculează pe baza semnăturii blocului cinci, și aceasta va fi diferită. Astfel semnătura precedentă a blocului șapte va fi diferită și așa mai departe tot lanțul de la blocul cinci la blocul zece va avea semnăturile modificate.
Asta înseamnă ca dacă modificăm datele din orice bloc, toate blocurile de după vor avea altă semnătură, ceea ce se poate verifica ușor și astfel se descoperă modificarea = lanțul este rupt !!!
Important ! semnătură = hash

În continuare vom folosi Java pentru a crea un lanț de blocuri.

Vom crea o clasă = Block care va conține toate informațiile necesare în acest moment:

public class Block {

    private String hash; //semnătura blocului 
    private String previousHash; //semnătura blocului precedent
    private String data; //datele conținute de bloc (mesajul)
    private long timestamp; //data și ora la care a fost creat blocul
}

Să adaugăm metode de setter si getter:

public class Block {

    private String hash; //semnătura blocului 
    private String previousHash; //semnătura blocului precedent
    private String data; //datele conținute de bloc (mesajul)
    private long timestamp; //data și ora la care a fost creat blocul

    public String getHash() {
        return hash;
    }

    public void setHash(String hash) {
        this.hash = hash;
    }

    public String getPreviousHash() {
        return previousHash;
    }

    public void setPreviousHash(String previousHash) {
        this.previousHash = previousHash;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }
}

Vom adăuga și un constructor – fiecare bloc va fi creat be baza semnăturii blocului precedent și a datelor pe care vrem să le conțină:

    //Constructor
    public Block(String data, String previousHash) {
        this.data = data;
        this.previousHash = previousHash;
        this.timestamp = new Date().getTime();
    }

Blocul nostru trebuie să conțină și propria semnătură, pe care insa ar trebui sa o calculăm pe baza informațiilor pe care le avem. Pentru acest exemplu vom folosi algoritmul SHA256, dar, evident, poate fi folosit oricare altul.

Într-o nouă clasă – să-i spunem Utile vom pune toate funcțiile de care vom avea nevoie în crearea si operațiile cu blocuri. O primă functie necesară este cea care pornind de la un String generează o semnătură(hash) aplicând algoritmul SHA256

  
import java.security.MessageDigest;

public class Utile {

    //Aplică Sha256 unui String și întoarce ca rezultat semnătura. 
    private static String applySha256(String input) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            //Applies sha256 to our input, 
            byte[] hash = digest.digest(input.getBytes("UTF-8"));
            StringBuffer hexString = new StringBuffer(); 
            for (int i = 0; i < hash.length; i++) {
                String hex = Integer.toHexString(0xff & hash[i]);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Acum putem aplica această funcție la calculul semnăturii blocului nostru.  Dar ce anume să folosim? Obligatoriu semnătura precedentă (prevoiusHash) și datele conținute de blocul nostru (data). Vom mai adăuga și timestamp-ul. In aceeași clasă Utile mai punem si funcția:

 
    public static String calculateHash(Block block) {
        String calculatedhash = applySha256(
                block.getPreviousHash()
                + Long.toString(block.getTimestamp())
                + block.getData()
        );
        return calculatedhash;
    }

Vom aplica această metoda chiar în constructorul de la clasa Block, pentru a calcula semnătura blocului. Clasa Block va arăta acum astfel:

import java.util.Date;

public class Block {

    private String hash; //semnătura blocului 
    private String previousHash; //semnătura blocului precedent
    private String data; //datele conținute de bloc (mesajul)
    private long timestamp; //data și ora la care a fost creat blocul

    //Constructor
    public Block(String data, String previousHash) {
        this.data = data;
        this.previousHash = previousHash;
        this.timestamp = new Date().getTime();
        hash = Utile.calculateHash(this);
    }

    public String getHash() {
        return hash;
    }

    public void setHash(String hash) {
        this.hash = hash;
    }

    public String getPreviousHash() {
        return previousHash;
    }

    public void setPreviousHash(String previousHash) {
        this.previousHash = previousHash;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }
}

Este timpul sa vedem ce am făcut până acum. Vom folosi o funcție de printare in Utile:

    public static void printBlock(Block block) {
        System.out.println("**********START BLOCK***********");
        System.out.println("date= " + block.getData());
        System.out.println("data creare= " + sdf.format(new Date(block.getTimestamp())));
        System.out.println("semnatura= " + block.getHash());
        System.out.println("semnatura precedenta= " + block.getPreviousHash());
        System.out.println("**********END BLOCK***********");
    }

unde sdf este un SimpleDateFormat – de exemplu:

   private static final SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy hh:mm:ss");

In sfârșit, să adaugăm intr-un main 3 blocuri și sa le vizualizăm. Vom avea o mică problemă – primul bloc nu are un predecesor ! – ca urmare vom alege o semnătura precedenta de o formă fixă – de exemplu „0”:

      public static void main(String[] args) {
        Block block1 = new Block("primul mesaj", "0");
        Utile.printBlock(block1);
        Block block2 = new Block("al doilea mesaj", block1.getHash());
        Utile.printBlock(block2);
        Block block3 = new Block("al treilea mesaj", block2.getHash());
        Utile.printBlock(block3);
    }

În urma rulării, ar trebui sa obțineti ceva de genul:

**********START BLOCK***********
date= primul mesaj
data creare= 08.05.2018 10:39:18
semnatura= cee7dbfb21a176a70e422c53ce83fd4dfe9b58f64e1b933c8647469a66edcf7c
semnatura precedenta= 0
**********END BLOCK***********
**********START BLOCK***********
date= al doilea mesaj
data creare= 08.05.2018 10:39:18
semnatura= 55cee0d1570e1ef032fe4162a4d1d8b5196a143bc691701d6145408e7eb415ed
semnatura precedenta= cee7dbfb21a176a70e422c53ce83fd4dfe9b58f64e1b933c8647469a66edcf7c
**********END BLOCK***********
**********START BLOCK***********
date= al treilea mesaj
data creare= 08.05.2018 10:39:18
semnatura= 5a0d2a7b1952a50d89da896021fc65d4d5251d05e3f98bfa228eed1c3ad42c3e
semnatura precedenta= 55cee0d1570e1ef032fe4162a4d1d8b5196a143bc691701d6145408e7eb415ed
**********END BLOCK***********

Mai departe ar trebui să avem posibilitatea de a verifica dacă un lanț este valid sau nu. Folosiți link-ul de mai jos pentru a ajunge pe pagina respectivă.

Următorul pas – verificarea integrității lanțului

Inapoi la pagina de programare

Lasă un răspuns

Fii primul care lasă un comentariu

avatar
  Subscribe  
Notificare