Bir Örnek ile BlockChain Nedir

Blockchain veya Türkçe olarak blok zinciri basitçe birbirini takip eden bloklardan oluşan bir dizi. Zincire eklenen her blok zinciri bir önceki bloğa ait şifrelenmiş bir değeri kendi bloğuna alıyor. Böylece her blok mutlaka birbirini takip etmek zorunda. Eğer aradan birini çekerseniz birbirini takip eden şifreler bozulacağı için anlamsız bir kopuş yaşanır. Tabii daha büyük zincirlerde blokları içeren daha büyük blokların içine alarak onlarda birbirini takip etmesi sağlanır. Zincir büyüdükçe değiştirilmesi zorlaşır. Zira bir önce kini referans alma zorunluluğu zamanla geriye doğru güncellemeyi imkansız hale getiriyor.

Söylenecek aktarılacak çok daha fazla konu olsada burada kesmekte fayda var. Şimdi bu kısa girişten sonra az yazıp daha fazla kod göstermeyi tercih edeceğim. Teorik bilgi zaten bir çok kaynakta var.

Ben araştırmalarım da dil bağımsız yapsamda bu örnekte herkesin anlayabileceği bir yapı ve dil seçtim. Dil olarak Java bence herkes tarafından kolaylıkla anlaşılacaktır. Blok ve akışı bir yapıda anlatırken ilk başta göz ardı edebileceğimiz konuları Utils namespace hapsettim. Böylece Main, Service ve Model bizim esas kodumuzu barındırıyor.
 

package com.gazatem.java.blockchain.tutorial.model;
   
  import java.util.Date;
   
  public class Block {
  private String hash;
  private String previousHash;
  private String storedData;
  private long timeStamp;
  private int nonce;
   
  public Block(String storedData,String previousHash ) {
  this.storedData = storedData;
  this.previousHash = previousHash;
  this.timeStamp = new Date().getTime();
  }

En basit haliyle bir Block’ta bir önceki bloğa ait hash, o anki zaman mührü, içerdiği data ve geçerli hash yani şifremiz. Nonce kısmı birazdan ama genel olarak Data Mining ile ilgili bir durum. Bu arada dikkat edersiniz ki en basit haliyle bir bloğu oluşturmak için ihtiyacımız olan 2 şeyi kurucu metod ile yeni modelimize aktarıyorum. Datamız ve bir önce ki Hash.
 

package com.gazatem.java.blockchain.tutorial;
   
  import com.gazatem.java.blockchain.tutorial.model.Block;
  import com.gazatem.java.blockchain.tutorial.service.Calculate;
   
  import java.util.ArrayList;
   
  public class main {
   
  private static Calculate calculate;
  public static ArrayList<Block> blockchain = new ArrayList<Block>();
   
  public static void main(String[] args) {
  int difficulty = 1;
  calculate = new Calculate();
  String previousHash = "";
  for(int i = 0; i < 10; i++){
  Block block = new Block("Sample block no: " + i, previousHash);
  block.setHash(calculate.createHash(block));
  calculate.mineBlock(difficulty, block);
  previousHash = block.getPreviousHash();
  blockchain.add(block);
  System.out.println(i +". "+ block.getHash());
  }
   
  System.out.println("All blocks are hashed...");
  }
   
  }

Bu kısımda amacımız 10 tane block oluşturmak. Bu yüzden basit bir loop oluşturdum. Daha önce bahsettiğim gibi bir blokta en az bir data ve bir önce ki bloka ait Hash içermeli. Ama ilk blokta önceki hash eksik olacaktır. Bu yüzden ilk bloğumuzda önceki hash değeri boş veya 0 geçilmelidir. Zincirimizde bu ilk blokun adın Genesis tir. Genesis BlockChain dünyasında yaratılan ilk bloğa verilen isimdir.

19. satırda bloğumuza ait geçici bir hash oluşturuyoruz. Bu hash SHA1 algoritması ile şifreleniyor. Bu kısımları daha sonra 2. bir yazıda açıklayacağım. Şimdilik Calculate adında bu tip hesaplamaları yapan bir sınıf yarattım ve üstünde çalıştığımız bloğu parametre alan createHash adında bir fonksiyon ekledim. İleride farklı şifrelemeler ile çalışmak isteyebileceğim için ayrı bir servis yazmak işi daha baştan basitleştiriyor.

20. satır en önemli kısım. Adı çok geçen data mining kısmı işte bu. Basit olsun diye ismide Data Mining verdim ama bence isim ile pek örtüşmüyor. İleride başkaları tarafından çözülmesini istediğimiz puzzle tam bu kısımda oluşuyor. Yine hesaplamaları yaptığımız Calculate sınıfına ait mineBlock fonksiyonunu bu sefer difficulty parametresini alarak çağırıyoruz. 2. parametre yine blok objemiz. Bu kısımda Calculate sınıfımızda Blok property olarakta tanımlanabilirdi. Ama ben parametre olarak göndermeyi tercih ettim.

Bu difficulty şimdi ne yapar diye düşünüyorsunuzdur. O zaman hemen kolayca adı gibi işleri zorlaştırmak amacıyla ilave ediyoruz. 19. satırda hatırlayacaksınız, geçici bir hash türettikmiştik. Bu hash’i kolayca hazırlamıştık. Her zaman aynı parametreler aynı hash hesaplanacaktır. Ya biz işleri biraz zorlasak, parametrelerde ufak bir revize yapsak ve ilk bulduğumuz hash değilde daha zor bir kombinasyon yapsak.

İnanın bu kısım için 2 gün bir çok yazı ve kod okudum. Anlamak cidden zor çünkü çok basit. Sadece hash kodumuzun başında ’n’ adet 0 ile dolu bir hash oluşturmak istiyoruz. Örnek olarak hashimizin ilk 4 hanesinin 0000 olmasını istiyoruz diyelim. Bu durumda parametrelerimizin değişmesi gerekiyor. Daha önce nonce adında bir parametreden bahsetmiştim. Geçici hash oluşturulurken bu nonce 0 kabul ediliyor. Ama ilk 4 hanesinin 0000 olmasını arzuladığımız HASH oluşması için bu nonce değerini farklı rakamlar vererek tekrar tekrar hesaplıyoruz.

while(!hash.substring( 0, difficulty).equals(target)) {
nonce ++;
block.setNonce(nonce);
hash = this.createHash(block);
}

Bu while döngüsünde ki gibi zorluk derecemize göre döngümüzde nonce değerini bir artırarak tekrar yeni bir hash oluşturuyoruz. Taa ki bu hash ilk 4 karakteri 0000 oluncaya kadar denemeye devam ediyoruz. Ben emektar laptopumu fazla zorlamamak için 1 ile denedim ve 7–8 saniyede 10 adet zincir oluşturdum.

Kısa tutamaya çalıştığım yazım iyice uzadı. Özellikle Utils lerden bahsetmedim. Çünkü bu sınıf esasında sizin seneryonuza göre değişecektir Amacım kısaca anlatmaktı. Galiba yakın zamanda 2. bir yazı yazarak geri kalan seneryoları eklerim.

Ama esas olarak JavaScript ile tamamen bir RestApi ile bu kodu tekrar yazacağım. Özellikle nonce değerini başkalarının Blokları onaylaması kısmı çok eğlenceli. Zaten işin basit ve kolay kısmı Proof of Work denen özellik. Sizin oluşturduğunuz blokun başkaları tarafından aynı şekilde oluşturulup onaylanması. Bütün bir zincir yapısını Json olarak dışarı almak ve paylaşıma sunmak sonra bu zincirin onaylanması vs eğlenceli ve biraz da zahmetli bir iş.