Python dili ile basit Blokzincir uygulaması yazma
Tags: python, blokzincir, blockchain
Published: 2021-05-17 16:10:04

Bir süredir boş vakitlerimde blokzincir'e bakıyordum. Tabi ki birikim olarak "coin"'ler değil de biraz daha teknik konular. Bu kapsamda hem öğrenmek için hem de aktarabilmek için küçük bir blokzincir uygulaması yapmak istedim.

Herhangi bir algoritmanın en hızlı şekilde uygulanması için Python dilinin kullanılmasının çok hoş olduğunu düşünerek bu dille yapılan örnekleri inceledim ve olabildiğince basit olanı seçmeye çalıştım. Bu nedenle bu yazıyı büyük bir "coin" altyapısı olarak değil öğrenme olarak düşünmeniz gerekir.

# Python ile blokzincir'e giriş

Python ile belki onlarca çeşit alternatif olmasına rağmen belgelendirmede şifreleme algoritmaları için hashlib kütüphanesi kullanılmış. Bloklarımız ise json formatında tutulması için yine bu kütüphane kullanılıyor. Çeşitli yerlerde de time kütüphanesiyle zaman ile ilgili işlemler yapılacaktır.

# Blokzincir sınıfı oluşturma

En temelinde basit bir sınıf oluşturmamız gerekir. Aşağıdaki gibi bir sınıf oluşturalım. Bu sınıf ilk oluşturulurken içinde zincir ve bekleyen işlemler diye 2 dizi oluşmakta. Ve tabi ki temel bir yeni blok eklenmekte.

```python
class Blockzincir(object):
    def __init__(self):
        self.zincir = []
        self.bekleyen_islemler = []
        self.yeni_blok(onceki_saglama="Herhangi bir içerik", delil=100)
```

# Yeni blok ekleme fonksiyonu

Yeni adımda sınıfta giriş olarak kullandığımız yeni_blok() fonksiyonunu oluşturarak başlıyoruz. Yeni blok oluşturulurken bekleyen işlemleri görüyor ve bu işlemleri blok içinde ekliyor. (işlemler adı altında) Ve tabi ki bunun bir zaman damgası ve bir önceki sağlama fonksiyonun kontrolü sağlanıyor.

```python
    def yeni_blok(self, delil, onceki_saglama=None):
        blok = {
            'index': len(self.zincir) + 1,
            'timestamp': time(),
            'transactions': self.bekleyen_islemler,
            'proof': delil,
            'previous_hash': onceki_saglama or self.saglama(self.zincir[-1]),
        }
        self.bekleyen_islemler = []
        self.zincir.append(blok)

        return blok
```

# Son blok'u çekme fonksiyonu

Yeni bir işlem fonksiyonunda kullanılacak son_blok() fonksiyonunu zincir dizisindeki son blok json'unu almak için hazırlıyoruz.

```python
    @property
    def son_blok(self):
        return self.zincir[-1]
```

# Yeni bir işlem fonksiyonu

Şimdi gönderici, alıcı ve gönderilecek büyüklüğün girildiği bir yeni işlem fonksiyonu oluşturuyoruz.

```python
    def yeni_islem(self, gonderici, alici, miktar):
        islem = {
            'gönderici': gonderici,
            'alıcı': alici,
            'miktar': miktar
        }
        self.bekleyen_islemler.append(islem)
        return self.son_blok['index'] + 1
```

Görüldüğü gibi aslında işlem fonksiyonu işlemi sadece bekleyen işlemlere eklemekte.

# Sağlama (hash) fonksiyonu

Sağlama, yani hash kısmı tüm uygulamamızın en önemli kısımlarından birisi. Burada çok basit şekilde sha256'lı bir şifreleme yöntemi seçildi. Sağlama fonksiyonu bir blok değeri girdisini alıp sağlama hex değeri çıktısı vermekte. Ve bu fonksiyonu, yeni blok ekleme fonksiyonu içinde zincirdeki son blok değerine göre sağlama yapılması için kullanılıyor.

```python
    def saglama(self, blok):
        string_object = json.dumps(blok, sort_keys=True)
        blok_string = string_object.encode()

        raw_saglama = hashlib.sha256(blok_string)
        hex_saglama = raw_saglama.hexdigest()

        return hex_saglama
```

# Ve Uygulama

Ve şimdi uygulama yaparsak örneğin her bir blok içinde 3 işlem yaptığımızı düşünelim ve her 3 işlemden sonra bir blok oluşturup zincire ekliyoruz. Daha sonradan bu blok içindeki tüm işlemlerin sağlaması yapılıp bir sonraki zincir bloğuna eklenmiş oluyor. Ayrıca örnekteki yeni blok oluştururken delil (proof) oluşturmak da konuya bir açı daha katmakta. Bunu yapmadan da geliştirilen basit algoritmalar bulunmakta.

```python
blokzincir = Blockzincir()
t1 = blokzincir.yeni_islem("Ali", "Veli", '5 bloklira')
t2 = blokzincir.yeni_islem("Zeki", "Deli", '1 bloklira')
t3 = blokzincir.yeni_islem("Deli", "Ali", '3 bloklira')
blokzincir.yeni_blok(12345)

t4 = blokzincir.yeni_islem("Ali", "Deli", '0.5 bloklira')
t5 = blokzincir.yeni_islem("Veli", "Zeki", '3 bloklira')
t6 = blokzincir.yeni_islem("Zeki", "Deli", '1 bloklira')
blokzincir.yeni_blok(6789)

jsonStr = json.dumps(blokzincir.zincir)
print(jsonStr)

## blockid sağlaması kontrolü
#print(blokzincir.saglama(blokzincir.zincir[0]))
```

# Çıktı

Çıktı aşağıdaki gibi olması gerekmekte

```json
[
  {
    "index": 1,
    "timestamp": 1621265942.8971791,
    "transactions": [],
    "proof": 100,
    "previous_hash": "Herhangi bir içerik olsun"
  },
  {
    "index": 2,
    "timestamp": 1621265942.8971846,
    "transactions": [
      {
        "gönderici": "Ali",
        "alıcı": "Veli",
        "miktar": "5 bloklira"
      },
      {
        "gönderici": "Zeki",
        "alıcı": "Deli",
        "miktar": "1 bloklira"
      },
      {
        "gönderici": "Deli",
        "alıcı": "Ali",
        "miktar": "3 bloklira"
      }
    ],
    "proof": 12345,
    "previous_hash": "f9a5874b5b3415ea7a9ab323a24de7104cc076c1e34ef24e386235feb2b8d67d"
  },
  {
    "index": 3,
    "timestamp": 1621265942.8972323,
    "transactions": [
      {
        "gönderici": "Ali",
        "alıcı": "Deli",
        "miktar": "0.5 bloklira"
      },
      {
        "gönderici": "Veli",
        "alıcı": "Zeki",
        "miktar": "3 bloklira"
      },
      {
        "gönderici": "Zeki",
        "alıcı": "Deli",
        "miktar": "1 bloklira"
      }
    ],
    "proof": 6789,
    "previous_hash": "6e92837e2be20a929e85a976eb93222ada2050b273324fffa5a77081b6f4d78e"
  }
]
```

# Kaynak

https://medium.com/coinmonks/python-tutorial-build-a-blockchain-713c706f6531