Python ile Kayıtzinciri (Blockchain)'de İş Kanıtı(Proof of Work) örneği¶Barış Sanlı, www.barissanli.com , barissanli2@gmail.com¶Bu kodu yazalı sanırım 1 yıldan fazla olmuş. Aşağıdaki kod sıra ile SHA256 (şaa256 okunur) kullanarak, metinlerin özetini çıkarır. Sonra ProofOfWork (İş kanıtı)nda yer alan bulmacayı çözmeyi gösterir. Daha önce Dünya Enerji Konseyi'nde verdiğim Kayıtzinciri/Blockchain dersinde demo olarak kullanmıştım [link] Önce Kütüphaneler¶Kodumuza başlamadan önce iki kütüphaneyi yükleyeceğiz.Biri hashlib diğeri de time. Asıl işlemleri hashlib yapıyor, time ise sadece süre ölçmekte kullanılacak In [1]:
# özüt çıkarmak için
import hashlib
# süre de ölçelim
import time
Özütler¶Özütleri anlaması biraz zor olabilir. Özüt dediğimiz tek taraflı bir fonksiyondur. Yani girdinin DNAsını çıkarır. Bu DNA, 16lı düzende bir sayı dizinidir. Ama DNA'dan girdiyi bulamazsınız. Sadece aynı girdiyi kullanarak, aynı DNA'yı üretirsiniz. Mesela Windows şifreleri açık halde tutmaz. Onların DNA'larını yani SHA256 gibi özütlenmiş hallerini tutar. Ancak şifre doğru girilirse aynı SHA256 üretilir, bu da kaydedilmiş SHA256 kodu ile karşılaştırılır, doğruluğu tespit edilir.
Bunun için kullanacağımız fonksiyon hashlib.sha256 Dikkat edilmesi gereken nokta ise metinden önce b konarak, unicode metinin özütlenebilir dizine çevrilmesidir In [23]:
hashlib.sha256(b'baris')
Out[23]:
İsterseniz bir de b olmadan deneyelim In [24]:
hashlib.sha256('baris')
Gördüğümüz gibi hata mesajı : Unicode-objects must be encoded before hashing" oluştu. Bu sebeple metinlerin önünde b yi unutmayalım Şimdi ise metinin okunabilir, yani 16lık sayı dizinini görmeye çalışalım, bunun için de hexdigest alt fonksiyonunu çağırmamız yeterli olacaktır. In [25]:
hashlib.sha256(b'baris,67').hexdigest()
Out[25]:
Bu sayı dizininden girilen metnin "baris,67" olduğunu bulamayız. Tek tek tüm karakter ve sayıları denememiz gerekir. Ancak buraya "baris,67" yazan yine aynı metni girdiğinde aynı sayı dizinini oluşturur. İş Kanıtı(Proof of Work) - Zorluk Derecesi¶Bitcoinde de yer alan Proof of Work, İş kanıtı veya ispatı, aslında bir emek sarfedildiğinin ispatı olarak da anlaşılabilir. Ne için emek harcanmıştır? Bir karakter dizininden özel bir DNA kodu üretmek için. Özütlerin en önemli özelliği, tahmin edilemez olması gibidir. Yani girdiyi bir karakter veya bir bit değiştirince sonuç inanılmaz değişir. İnanmayanlar için deneyelim. Önce 0 girelim sonra 1... In [27]:
hashlib.sha256(b'0').hexdigest()
Out[27]:
In [28]:
hashlib.sha256(b'1').hexdigest()
Out[28]:
Yani kasa hırsızlığı yöntemleri ile özüt tahmin edemezsiniz. Yani rakamlara bakarak hedefe yaklaşıp yaklaşmadığınızı söyleyemezsiniz In [31]:
hashlib.sha256(b'Bu metin 9 Subat Cumartesi gece 22:07:32 de Baris Sanli tarafindan yazildi').hexdigest()
Out[31]:
Şimdi ise sonuna sadece . yani nokta koyalım bakalım sonuç ne olacak In [32]:
hashlib.sha256(b'Bu metin 9 Subat Cumartesi gece 22:07:32 de Baris Sanli tarafindan yazildi.').hexdigest()
Out[32]:
Bir metinde baf..... ile başlayan bir DNA elde ederken, 1 nokta en sona koyunca sonuç inanılmaz değişti 711...... li bir diziye dönüştü Bulmacasını çözeceğimiz metin, kendi web sitemin ismi olacak. Sıra ile bu metinden sonra bir sayı ekleyeceğiz. Çıkan sonuçların ilk karakterlerine bakacağız. zorluk ta belirtildiği sayıda sıfır (0) ile başlıyorsa, bulmacayı çözdük demektir. Dikkat etmeniz gereken zorluk sayısı 6'nın üzerine çıktıkca bekleme artacaktır. Aşağıdaki kod ne yapıyor?
In [38]:
hashlib.sha256(str("www.barissanli.com,1").encode("utf-8")).hexdigest()
Out[38]:
Sabit metin ve zorluk derecemizi belirleyelim In [39]:
kayit="www.barissanli.com"
zorluk=5
Şimdi 100 milyona kadar sayıları tek tek koyarak özüt alıp sonuca bakalım. Eğer beş sıfır (00000) yani zorluk"0"* ile başlayan bir metin var ise
o zaman programı sonlandır, cevabı yaz In [37]:
for i in range(0,100000000):
mesaj=kayit+","+str(i)
ozet=hashlib.sha256(str(mesaj).encode("utf-8")).hexdigest()
if(ozet[0:zorluk]==("0"*zorluk)):
print(mesaj+" Hash="+ozet)
break
In [40]:
hashlib.sha256(str(mesaj).encode('utf-8')).hexdigest()
Out[40]:
Zorluk derecesi ve süre¶Bu sıfır bulma bulmacasında zorluk derecesi arttıkça daha fazla zaman harcanıyor, yani daha fazla bilgisayar gücü ve kWh, enerji. Şimdi yukarıdaki düzeneği bir fonksiyon haline getirerek önce işimizi kolaylaştıralım Fonksiyonumuzun ismi ProofOfWork ve iki girdisi var msg ve zorluk In [62]:
def ProofOfWork(msg, zorluk):
start=time.time()
for i in range(0,100000000):
mesaj=msg+","+str(i)
ozet=hashlib.sha256(str(mesaj).encode("utf-8")).hexdigest()
if(ozet[0:zorluk]==("0"*zorluk)):
print(mesaj+" Hash="+ozet)
end=time.time()
print(zorluk,". zorluk derecesinde toplam zaman", (end-start)," saniye")
return i
break
Şimdi "baris" mesajını, 2. zorluk derecesi yani baştaki ilk iki karakter 0 olacak şekilde çalıştıralım In [63]:
ProofOfWork("baris",2)
Out[63]:
Görüldüğü üzere 2 sıfır ile başlayan DNA veya özütü bulmak milisaniyeler mertebesinde zaman alıyor. Şimdi 00 ile başlayan DNA bulma işinden 00000'la başlayan DNA bulmaya kadar geçen zamanlara bakalım In [45]:
for zorluk in range(1,6):
ProofOfWork("baris",zorluk)
Dikkat ettiminiz mi? başında 4 sıfır olan metni bulmak 1.2 saniye sürerken, 5 tane sıfır olanı bulmak 8.1 saniye sürdü. Yani 1 sıfır eklemek tam 7 kat daha fazla zaman aldı. Bitcoin'de iki blok yani kayıt arasındaki zaman azaldıkça, bulmaca zorluğu arttırılır. Yani daha çok sıfır olan bir bulmacanın çözülmesi istenir. Süre uzarsa da bu 0 sayısı azaltılır. İşlem denemesi¶Şimdi de bir işlem denemesi yapalım. Yani isim-web sayfası değil de bir işlem listesi oluşturarak, bunlardan DNA çıkaralım Bir bloğu ikiye ayıralım, önce başı sonra da işlemlerin yer aldığı ana kısım yer alsın. Bloğun başında:
İlk bloğumuz doğuş bloğu, yani herhangi bir öncüsü olmadığı için dilediğimiz rakamları seçebiliriz In [59]:
sira=0
ozut=0
denge=0
Şimdi de kayıt oluşturalım In [60]:
islem = "Kayıt sırası:"+str(sira)+"\n"
islem+= "Özüt:"+str(ozut)+"\n"
islem+= "Denge:"+str(denge)+"\n"
islem+= "-----------------------------\n"
islem+= "1 Barış’tan Mehmet’e 10\n"
islem+= "2 Ali’den Ayşe’ye 2\n"
islem+= "3 Seyit’ten İbo’ya 5"
hashlib.sha256(islem.encode("utf-8")).hexdigest()
Out[60]:
Gördüğünüz gibi kayıdı sıradan özüt alma yaparsak rastgele DNA'sını oluşturuyor. Bu doğuş özütü olsun şimdi bunu ekrana yazalım In [61]:
print(islem)
Daha önce yukarıda yazdığımız iş kanıtı kodunu kullanalım In [82]:
zorluk=4
sira=1
ozut=0
for denge in range(0,100000000):
islem = "Kayıt sırası:"+str(sira)+"\n"
islem+= "Özüt:"+str(ozut)+"\n"
islem+= "Denge:"+str(denge)+"\n"
islem+= "-----------------------------\n"
islem+= "1 Barış’tan Mehmet’e 10\n"
islem+= "2 Ali’den Ayşe’ye 2\n"
islem+= "3 Seyit’ten İbo’ya 5"
ozet=hashlib.sha256(str(islem).encode("utf-8")).hexdigest()
if(ozet[0:zorluk]==("0"*zorluk)):
print(islem+"\n\n\n Hash="+ozet)
break
ilk_blok=islem
ilk_ozut=ozet
Yani yukarıdaki metinde, denge 65216 olunca tüm mesajın DNAsı 4 tane sıfır ile başlıyor. Şimdi ikinci kayıdımıza geçerken bir önceki özütü bu kayıdın özüt satırına yerleştiriyoruz. Dikkat ederseniz işlemler de yeni işlemler oluyor. In [83]:
zorluk=4
sira=2
ozut=ozet
for denge in range(0,100000000):
islem = "Kayıt sırası:"+str(sira)+"\n"
islem+= "Özüt:"+str(ozut)+"\n"
islem+= "Denge:"+str(denge)+"\n"
islem+= "-----------------------------\n"
islem+= "1 Ali’den Ayşe’ye 2\n"
islem+= "2 Barış’tan Mehmet’e 10\n"
islem+= "3 Seyit’ten İbo’ya 5"
ozet=hashlib.sha256(str(islem).encode("utf-8")).hexdigest()
if(ozet[0:zorluk]==("0"*zorluk)):
print(islem+"\n\n\n Hash="+ozet)
break
ikinci_blok=islem
ikinci_ozut=ozet
İkinci kayıdımızda ilk kayıttan çıkan özütümüzü aldık ve bu kayıdın başlık kısmındaki özüt satırına ekledik. Tüm bir Bitcoin mantığı da basitçe bu. Gerçi Bitcoin daha güvenli olsun diye iki defa SHA256 yapıyor Sonuç¶İki blokluk yani kayıtlık bir işlem dizesinde İş kanıtı ile kısaca kayıtzinciri/blockchain mantığını göstermiş olduk. Şimdi kısaca tekrar iki bloğumuza da bakalım
In [88]:
print(ilk_blok+"\n\n\n Bu kayıdın özütü:"+ilk_ozut+"\n\n Bu özüt de bir sonraki bloğa eklenecek")
In [89]:
print(ikinci_blok+"\n\n\n"+ikinci_ozut+"\n\n Bu özüt de bir sonraki bloğa eklenecek")
Kısaca Bitcoin benzer prensiple çalışıyor. Umarım bu anlamanıza yardımcı olmuştur Barış Sanlı, www.barissanli.com , barissanli2@gmail.com¶ |