PHP ile Blockchain (Blokzinciri) yazıyoruz. Bölüm 2: Proof-of-Work (İş Kanıtı)

Ulugbek Miniyarov
5 min readMay 27, 2018

--

Bu yazı ingilizceden çevrilmiştir. Kod kaynağını buradan inceleyebilirsiniz.

Giriş

Bir önceki yazımızda, blockchain veri tabanının özü olan çok basit bir veri yapısı oluşturduk. Her blok bir öncekine bağlı şekilde blockchain’e bloklar ekledik. Yalnız, bizim blockchain yapımızın önemli bir açığı vardı: zincire blok eklemek kolay ve ucuz. Blockchain ve Bitcoin'in temel taşlarından biri, yeni blokların eklenmesi zor bir iş olmasıdır. Bugün bu açığı düzelteceğiz.

Proof-of-Work

Blockchain’in en önemli özelliği, blok eklemek için uzun sürebilen bir hesaplama yapmak zorunda olmanızdır. Blockchain’i güvenli ve tutarlı kılan da bu zorluktur. Ayrıca, bu zorlu hesaplama için bir ödül ödenir. Hesaplamayı yapanlara madenci deniliyor. İnsanlar Bitcoin’den bu şekilde para kazanıyor.

Bu mekanizma gerçek hayattaki para kazanmaya çok benzer: Kişi ödül almak ve hayatlarını sürdürmek için çok çalışmak zorunda. Blockchain’de, ağın bazı katılımcıları (madenciler) ağı sürdürmek, ona yeni bloklar eklemek ve hesaplamaları için bir ödül almaya çalışırlar. İşlerinin sonucu olarak blockchain’e güvenli bir şekilde yeni blok eklenir, bu da stabil bir veritabanı sağlar. İşi bitiren kişinin bunu kanıtlamak zorunda olduğuna dikkat etmek gerekir.

Bütün bu “zorlu hesaplama ve kanıtlama” mekanizmasına proof-of-work denir. Çok zordur çünkü çok fazla hesaplama gücü gerektirir: yüksek performanslı bilgisayarlar bile hızlı bir şekilde hesaplayamaz. Dahası Bitcoin’de 1 saatte 6 blok hesaplanabilmesi için zaman zaman (yaklaşık 2 haftada bir) bu zorluk artar. Böyle hesaplamanın amacı, yeni eklenecek blok için belli bir gereksinimi karşılayan hash’i bulmaktır. Hash’in amacı da hesaplamanın kanıtı olmasıdır. Böylece, asıl zorluk bir kanıt bulmakta.

Son bir not, Proof-of-Work algoritmaları belirli bir gereksinimi karşılamalıdır: hesaplaması zor, kanıtın doğrulaması kolay olmalı. Kanıt başkalarına verildiğinde onu doğrulamak için fazla zaman harcanmamalı.

Hash

Bu paragrafta, hash’i ele alacağız. Hakkında bilgi sahibi iseniz, bu bölümü atlayabilirsiniz.

Hash, belirtilen veri için bir hash (karma) hesaplama işlemidir. Bir hash bir verinin benzersiz temsilidir. Rastgele uzunlukta veriyi alan ve sabit uzunlukta bir hash üreten fonksiyondur. Bir hash fonksiyonunun bazı temel özellikleri:

  1. Orijinal veri bir hash’ten geri yüklenemez. Kısacası, hashing şifreleme değildir.
  2. Belirtilen veri sadece bir hash’e sahip olabilir ve hash benzersizdir.
  3. Belirtilen veride bir bayt bile değişirse tamamen farklı bir hash çıkar.

Hash fonksiyonları aynı zamanda yaygın olarak veri tutarlılığını kontrol etmek için kullanılır. Çoğu yazılım sağlayıcıları yazılımlarına ek olarak checksum yayınlar. Bir dosyayı indirdikten sonra, onu bir hash fonksiyonuna verebilir ve üretilen hash ile yazılım geliştiricisinin sağladığı hash değerini karşılaştırabilirsiniz.

Blockchain’de, blok tutarlılığını garanti etmek için hash kullanılır. Hash fonksiyonunun girdi verisi önceki bloğun hash’ini içerir, böylece zincirdeki bir bloğu değiştirilemez (ya da en azından oldukça zor) kılar. Değiştirmek isteyen, tüm blokların hash’lerini yeniden hesaplamalıdır.

Hashcash

Bitcoin, ilk olarak e-posta spamini önlemek için geliştirilen Proof-of-Work algoritması olan Hashcash’i kullanır. Hashcash aşağıdaki adımlara bölünebilir:

  1. Herkesçe bilinen bir veriyi alın (e-posta örneğinde, alıcının e-posta adresi; Bitcoin örneğinde, blok içindeki bilgiler).
  2. Bir sayaç ekleyin. Sayaç 0'dan başlasın.
  3. veri + sayaç kombinasyonundan oluşan bir hash üretin.
  4. Üretilen hash’in önceden belirlediğiniz gereksinimi karşıladığını kontrol edin.

4.1. Eğer karşılıyorsa, tamamdır.

4.2. Aksi halde sayacı artırın ve 3. ve 4. adımları tekrarlayın.

Böylece bu bir kaba kuvvet (brute-force) algoritmasıdır: sayacı değiştir, yeni hash’i hesapla, kontrol et, sayacı arttır, hash’i hesapla vs. Haliyle hashcash’in hesaplanması zordur.

Şimdi hash’in sağlaması gereken şartlara daha yakından bakalım. Orijinal Hashcash uygulamasında “ilk 20 bitin sıfır olması gerekir” gibidir. Bitcoin’de, tasarım gereği, ağa sürekli katılan madenciler sayesinde artan hesaplama gücüne rağmen her 10 dakikada bir blok oluşturulmalıdır.

Bu algoritmayı göstermek için önceki örnekte verdiğimiz veriyi alalım (“I love donuts”) ve 3 sıfır-bayt ile başlayan bir hash bulalım:

onaltılık sistemde ca07ca değerine denk gelen sayaç sayısı ondalık sistemde 13240266 sayısına eşittir.

Burada hash fonksiyonu olarak SHA256 kullandık. Bitcoin de bu hash fonksiyonunu kullanmaktadır.

Uygulama

Teoriyle işimiz bitti, kod yazalım! İlk olarak, madenciliğin zorluluğunu tanımlayalım:

const TARGET_ZEROS = 4;

Bitcoin’de “target bits” (hedef bitler), bloğun hash hesaplandığı sıradaki zorluk sayısını tutan blok başlığıdır. Daha önce bahsettiğimiz gibi Bitcoin’de her 2016 blok’ta (her blok 10 dakikada hesaplandığını varsayarsak 2 haftaya denk gelir) hedef ayarlanması (kalibrasyonu) yapılıyor. Şimdilik hedef ayarlama algoritması yazmayacağımız için zorluğu bir sabit olarak tanımlayabiliriz.

Proof-of-Work uygulamamız basit olması açısından hedef bitler yerine biz hesaplanan hash’in hexadecimal değerindeki ilk 2 hexadecimal değerinin 0'a denk gelmesini bir gereksinim olarak kabul edeceğiz. Burada 2 seçmemizin sebebi hash hesaplamamız uzun sürmemesi açısından. Aksi halde çok uzun sürebilir.

Burada bir ProofOfWork sınıfı yaratıyoruz ve hesaplanacak bloğu veriyoruz. TARGET_ZEROS kısmında ilk 4 karakterin 0 ile eşleşmesi gerektiğini veriyoruz. Hesaplama yaparken bir üst sınırı koymamız gerek aksi halde düşük ihtimal de olsa sınırsız hesaplama yapılabilir.

f80867f6efd4484c23b0e7184e53fe4af6ab49b97f5293fcd50d5b2bfa73a4d00000002f7c1fe31cb82acdc082cfec47620b7e4ab94f2bf9e096c436fc8cee06

Burada 2 hash’in ilki “I like donuts” cümlesinin hash değeridir. 2. ise “I like donutsca07ca” cümlesinin hash değeridir. Gördüğünüz gibi ilk 4 karakteri 0 ve bu bizim gereksinimimizi karşılıyor. İşte bu bizim iş kanıtımızdır.

Hedef sıfırlar bizim için bir sınırdır. Yükselttikçe daha zorlaşır hash hesaplaması.

Şimdi de bloğumuzu hash’lemek için hazırlayalım.

Bu kısım gördüğünüz gibi basit: blok verilerini hedef 0 sayısı ve nonce ile birleştiriyoruz. Kriptografik terim olannonce aslında yukarda açıklamasını yaptığımız Hashcash’teki sayaçtır.

Tüm hazırlıklar tamamlandığına göre, PoW algoritmasının çekirdeğini uygulayalım:

İlk başta nonce değerimizi tanımlıyoruz. Sonra da MAX_NONCE değerine kadar sınırlı bir döngü çalıştırıyoruz. Hedef zorluğumuz düşük olmasına rağmen sınırlı bir döngü koymak iyidir.

Döndü içinde yapılan:

  1. Veriyi hazırlama
  2. SHA256 ile hash’leme
  3. Hash değeri gereksinimi karşılıyor olmasının kontrolü

Daha önce bahsettiğimiz kadar basit. Şimdi de yeni blok oluşturma esnasındaki setHash fonksiyonu yerine PoW algoritmasını çalıştıralım.

Yukarda nonce değerini bulduğumuzda block özelliğine kaydettiğimizi farketmişsinizdir. Bloğun kanıtını onaylamak için nonce değeri şarttır. Yeni blok yapımız:

Pekala her şeyin yolunda gidip gitmediğini görmek için programı çalıştıralım:

Yes! Her bloğun hash değeri 4 sıfır ile başladığını görebilirsiniz ve bu hashleri bulmak az da olsa zaman aldı.

Yapılması gereken bir şey daha var: İşin ispatını doğrulamak.

Daha önce bulduğumuz nonce değeri de burada kullanılıyor. Hadi tekrar bir kontrol edelim çıktılar düzgün mü:

Çıktı:

Sonuç

Blockchain’imiz gerçek mimarisine bir adım daha yaklaştı: blokların eklenmesi artık bir çalışma gerektiriyor, bu nedenle madencilik yapmak mümkün. Fakat yine de bazı önemli özelliklerden yoksun: blockchain veritabanı diske kaydolmuyor, cüzdan yok, adres yok, işlemler yok ve herhangi bir konsensüs mekanizması yok. Tüm bu şeyleri gelecekteki makalelerde uygulayacağız. Şimdilik mutlu madencilikler!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Ulugbek Miniyarov
Ulugbek Miniyarov

Written by Ulugbek Miniyarov

Engineering, Staff @acquia, former Chief Software Architect @enuygun, Creator @lugattj and @zudvpn

No responses yet

Write a response