Artık "blockchain çağı" denilen bir dönemde yaşıyoruz. Bu teknolojinin geleceğimize etkisi hem ilginç hem de heyecan verici olacak. Eğer siz de bu serüvende bir geliştirici olarak yer almayı planlıyorsanız bilinmesi gerekenleri sıraladık. Eğer geliştirici olma konusunda kararlıysanız beklentilerinizi buna göre şekillendirmeniz gerek. Öncelikle bu zaman alacak bir iş. Vaktinizi ve kaynaklarınızı kendinizi eğitmeye adamanız gerekiyor. Ayrıca çabuk sonuçlar beklememek önemli. Blok zinciri geliştiricisi olmak bir gecede olunacak bir iş değil.
![Blockchain Geliştiricisi Olmak: Diller, Püf Noktalar ve Temeller 2 blockchain](https://evrenatlasi.com/wp-content/uploads/2020/04/blockchain-1024x576.jpg)
1. Temelleri Anlamak
Blockchain teknolojisi gibi yeni ve devrimci olan her şeyde en büyük engellerden biri sisteme entegre olmuş çeşitli kavramlarla tanışmaktır.
Yeni başlayan biriyseniz o zaman aşina olmanız gereken belirli terimler var:
- Blockchain: Her bloğun merkezi bir denetim olmaksızın değer verileri içerdiği bir bloklar zinciridir. Kriptografik olarak güvenli ve değişmezdir.
- Merkezsiz: Blockchain'in merkezsiz olduğu ifade edilir, çünkü hiçbir şeyi denetleyen merkezi bir otorite yoktur.
- Uzlaşma Mekanizması: Merkezi olmayan bir ağın belirli konularda mutabakata vardığı mekanizma.
- Madenciler: Hesaplama gücünü blokları kazmak için kullanan kişiler.
Bunların ardından Bitcoin'in nasıl çalıştığını anlamanız gerek. Bitcoin blok zinciri teknolojisinin en yaygın, en iyi ve en zarif uygulamalarından biri. Blockchain teknolojisinin ne kadar etkili olduğunu gösteren büyük örneklerin en başında geliyor.
Satoshi Nakamoto'nun Bitcoin whitepaper'ını okumanız tavsiye edilir. Kağıdı PDF dosyası olarak burada bulabilirsiniz.
2. Alım-Satım Sürecini Öğrenmek
Bugün bu alanda çalışan çok sayıda geliştiricinin aslında kripto paralarla hiçbir deneyimi olmadığını bilmek şaşırtıcı. Bir kere bile kullanmadığınız bir platform üzerinde yenilik ve iyileştirme yapmanızı beklemek gerçekçi olmaz.
Ülkemizde ya da dünyada faaliyet gösteren borsalardan birine giderek biraz coin almayı deneyin. Hemen büyük bir portföy oluşturmanıza gerek yok. Yalnızca birkaç adet alıp sürecin nasıl çalıştığını görmeniz yeterli.
Sonrasında ise portföyünüz halihazırda çok büyük olmadığından coin'lerinizi basit bir çevrimiçi cüzdanda saklayın. Tüm seçenekler arasında kullanması en basit olanlardır. Oluşturması çok kolay zira tek yapılması gereken herhangi bir borsada bir hesap açmak. Dahası bu cüzdana internete bağlı olduğunuz sürece herhangi bir sunucudan ya da cihazdan erişirsiniz.
Ancak burada tek bir sorun var. Cüzdanınızın özel anahtarı bir başka sunucuda saklanır. Bir anlamda cüzdanınızı hacker'lara gümüş tepside sunmak gibi bir şeydir. O nedenle büyük miktarlarda coin'lerin çevrimiçi cüzdanlarda saklanması tavsiye edilmez. Yalnızca borsa işlemlerinde ihtiyaç duyacağınız kadar düşük bir miktarı bırakın.
Geniş portföyler söz konusu olduğunda ise soğuk cüzdanlar işin içine girmekte. Bunlara cold wallet deniliyor ve fiziksel cüzdan görevini görüyorlar. ICO kurmak isteyenlerin bilmesi gereken başlıca şeylerin başında cüzdanlar var, özellikle çoklu imzalı (multi-sig) olanlar daha iyidir.
3. Kodlamaya Geçelim
Blok zinciri geliştiricisi olarak işin arka tarafında (back-end) çok sayıda zorlukla karşılaşacaksınız. Halka açık blok zincirleri oluşturmak ve bunları yönetmek aşağıdaki bazı nedenlerden ötürü kolay bir iş değil.
(Devam etmeden önce David Schwartz'ın blok zinciri yazılımı geliştirmede C++ kullanmayla ilgili CPPCON 2016'da yaptığı uzun konuşmayı izleyebilirsiniz.)
1. neden: Güvenlik
Blok zinciri tıpkı David Schwartz'ın söylediği gibi kale gibi olmalıdır. Öncelikle mevcut kod herkes tarafından görülecektir. Yani herhangi bir kimse isterse kodu kontrol edip açıklara ve zayıflıklara göz atabilir. Ancak diğer açık kaynak kodlara kıyasla blok zincirindeki potansiyel bir açığın sonuçları daima devasa olur. Hacker içeri sızarak sistemdeki milyonlarca doları cebe indirebilir. Bu tarz güvenlik endişelerinden dolayı blok zincirini geliştirmek genellikle çok yavaş ilerleyen bir süreçtir.
2. neden: Performans
Blok zinciri her zaman mümkün olan en yüksek kapasitede çalışmalıdır. Ancak bunun gerçekleşmesi için seçilen dil de çok yönlü olmalı. Örneğin blok zincirinde eş zamanlı yapılabilen bazı görevler varken paralel olarak yerine getirelemeyen şeyler de mevcut.
"Paralelleştirilebilir" görevlere en iyi örnek dijital imza doğrulamasıdır. İmza doğrulama için gerekenler anahtar, işlem ve imzadır. Sadece bu üç veri ile doğrulamaları paralel şekilde gerçekleştirebilirsiniz.
Ancak blok zincirindeki tüm fonksiyonlar bu şekilde çalışamaz. Mesela birden çok işlem paralel olarak yürütülemez; çünkü "çift harcama" (double spending) gibi hataları önlemek için teker teker ele alınmaları gerekir. Bazı diller paralel işlemlerde iyiyken bazıları paralel olmayan işlemlerde iyiler.
3. neden: İzolasyon
Deterministik davranış kavramını ele alalım.
Eğer A + B = C ise, o zaman koşullar ne olursa olsun A + B daima C'ye eşit olmalı. Buna deterministik davranış denir.
Hash fonksiyonları deterministiktir, yani A'nın hash'i her zaman H(A) olur.
Yani blok zinciri geliştirmede tüm işlemler determinist olmalı. Bir gün bir şekilde davranan ve sonra ertesi gün başka bir şekilde davranan bir işlem olamaz. Benzer şekilde iki farklı makinede iki farklı şekilde çalışan akıllı sözleşmeler de olamaz.
Bunun tek çözümü izolasyondur. Temel olarak akıllı sözleşmelerinizi ve işlemlerinizi deterministik olmayan unsurlardan ayıklarsınız.
Bu ihtiyaçların çoğunu yerine getiren bazı diller var. Bir blockchain geliştiricisiyseniz C++ ve JavaScript ile ilgili bazı temel bilgilere kesinlikle sahip olmanız gerek.
C++ biraz modası geçmiş gibi görünse de yukarıda tarif ettiğimiz tüm işlevleri mükemmel şekilde yerine getiriyor. Satoshi Nakamoto Bitcoin kaynak kodunu C++ ile yazdı.
HTML ve CSS ile birlikte Javascript web içeriği üretiminde üç temel teknolojiden biri. Javascript genellikle yüksek etkileşimli web sayfaları oluşturmak için kullanılıyor.
Şimdi Javascript Kullanarak Çok Basit Bir Blok Zinciri Nasıl Oluşturulur Görelim
Bir blok nasıl hazırlanır? Basit bir blok nelerden oluşur? Aşağıdaki basit kripto para kodunda her blok şu bilgi parçalarını içeriyor:
- Dizin: Blok numarasını bilmek için.
- Zaman damgası: Oluşturulma zamanını bilmek için.
- Veri: Bloğun içindeki veriler.
- Previous Hash: Önceki bloğun hash'i.
- Hash: Mevcut bloğun hash'i.
Devam etmeden önce bu programımda kullanılan belirli terimleri anlayalım:
- This: "this" anahtar sözcüğü bir fonksiyonun içerisinde kullanılır ve fonksiyonu çağıran nesnenin içindeki bilgilere erişmenizi sağlar.
- Constructor: Bir nesneyi bir sınıf içinde oluşturmaya ve başlatmaya yardımcı olan özel bir fonksiyondur. Her sınıf sadece bir constructor ile sınırlıdır.
Bunlar Tamam, Şimdi Bir Blok Oluşturalım:
const SHA256 = require("crypto-js/sha256");
class Block {
constructor(index, timestamp, data, previousHash = ") {
this.index = index;
this.previousHash = previousHash;
this.timestamp = timestamp;
this.data = data;
this.hash = this.calculateHash();
}
calculateHash() {
return SHA256(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)).toString();
} }
Kodun Analizi
Tamam, şimdi burada gördüğünüz şey bir adet blok. Kodun ilk satırında crypto-js kütüphanesini çağırdık çünkü sha256 hash fonksiyonu JavaScript'te mevcut değildi.
Ardından belirli değerlere sahip olacak nesneleri bulmak için sınıfın içinde bir constructor oluşturduk. CalculateHash() fonksiyonu muhtemelen gözünüze çarpmıştır. Tam olarak yaptığı şey şu:
Bir bloktaki tüm içerikleri alıp hash'lerini oluşturuyor ve böylece o bloğun genel bir hash'ini elde etmiş oluyoruz. Bloğun verilerini hash'e çevirmek içinse önce string haline getiriyor ve bunun için JSON.stringify fonksiyonundan yardım alıyoruz.
Şimdi blok tamamlandı ve kullanıma hazır. Sırada blokları birlikte bir blockchain'e bağlamak var.
Blok Zincirini Oluşturmak ve Blok Zinciri Geliştiricisi Olmak
class Blockchain {
//bölüm 1, Genesis bloğunun oluşturulması
constructor() {
this.chain = [this.createGenesisBlock()];
}
createGenesisBlock() {
return new Block(0, "01/01/2017", "Genesis block", "0");
}
//bölüm 2, yeni blokların eklenmesi
getLatestBlock() {
return this.chain[this.chain.length – 1];
}
addBlock(newBlock) {
newBlock.previousHash = this.getLatestBlock().hash;
newBlock.hash = newBlock.calculateHash();
this.chain.push(newBlock);
}
//bölüm 3, zincirin doğrulanması
isChainValid() {
for (let i = 1; i < this.chain.length; i++) {
const currentBlock = this.chain[i];
const previousBlock = this.chain[i – 1];
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
if (currentBlock.previousHash !== previousBlock.hash) {
return false;
} }
return true;
} }
Kodun Analizi
Yukarıdaki zincirde birçok şey olup bitiyor. Bunları bölümlere ayırarak ele alalım.
1. kısım: Genesis bloğu
Genesis bloğu nedir?
Genesis bloğu blok zincirinin birinci bloğudur ve özel olmasının nedeni tüm bloklar kendinden önceki bloğa işaret ederken, genesis bloğu hiçbir şeye işaret etmez. Yani yeni bir zincir oluşturulduğu anda genesis bloğu da oluşmuş olur.
Ayrıca, "createGenesisBlock()" fonksiyonunu da görebilirsiniz. Bloğun verisi bu fonksiyonun içine elle yazılıyor.
createGenesisBlock() {
return new Block(0, "12/04/2018", "Genesis block", "0");
}
2. kısım: Blokları Eklemek
Önce blok zincirindeki son bloğun ne olduğunu bulmamız lazım. Bunun için getLatestBlock() fonksiyonunu kullanıyoruz.
getLatestBlock() {
return this.chain[this.chain.length – 1];
}
//Son bloğu belirlediğimize göre yeni blokları nasıl ekleyeceğimizi görelim.
addBlock(newBlock) {
newBlock.previousHash = this.getLatestBlock().hash;
newBlock.hash = newBlock.calculateHash();
this.chain.push(newBlock);
}
Peki yeni blokları nasıl ekledik ve söz konusu bloğun geçerli olup olmadığını nasıl kontrol edeceğiz?
Bloğun içeriğini hatırlayın. Bir blok önceki bloğun hash'ine sahipti.
Burada yapacağımız şey kolay. Yeni bloğun önceki hash değerini son bloğun hash değeri ile kıyaslamak.
Eğer bu iki değer eşleşirse yeni blok geçerli kabul edilir ve ardından blok zincirine eklenir.
3. kısım: Zinciri Doğrulamak
Şimdi kimsenin blok zincirimizi kurcalamadığından ve her şeyin kararlı çalıştığından emin olalım.
Birinci bloktan son bloğa kadar gitmek için "for" işlevini kullanıyoruz. Genesis bloğu 0. blok kabul ediliyor.
for (let i = 1; i < this.chain.length; i++) {
const currentBlock = this.chain[i];
const previousBlock = this.chain[i – 1];
//Kodun bu kısmında iki terim tanımlıyoruz, şu anki blok ve son blok. Ve şimdi de bu değerlerin hash'ini bulacağız.
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
if (currentBlock.previousHash !== previousBlock.hash) {
return false;
} }
return true;
}
Eğer mevcut bloğun "previousHash" değeri son bloğun "Hash" değerine eşit değilse fonksiyon False getirecek, aksi halde ise True olacak.
Blok Zincirini Kullanmak
Şimdi blok zincirini kullanarak ungoCoin'ini oluşturacağız.
let ungoCoin = new Blockchain();
ungoCoin.addBlock(new Block(1, "11/04/2018", { amount: 4 }));
ungoCoin.addBlock(new Block(2, "11/04/2017", { amount: 8 }));
Hepsi bu.
Kodun Analizi
Blok zincirini kullanan yeni bir kripto para oluşturduk ve buna ungoCoin adını verdik. Bu yeni nesnenin doğuşuyla Constructor aktive edildi ve sonuç olarak Genesis bloğu otomatik olarak oluşturuldu.
Ardından iki blok daha ekledik ve onlara basit veriler yerleştirdik. Burada önemli olan C++, Javascript, C# veya Go gibi blockchain dostu dilleri kullanmak.
4. Akıllı Sözleşmeleri Anlamak
Akıllı sözleşmenin tanımı nedir?
Vikipedi'ye göre akıllı sözleşme "bir sözleşmenin performansını veya müzakeresini kolaylaştırmayı, doğrulamayı ve yürütmeyi amaçlayan bir bilgisayar protokolü"dür. İlk olarak Amerikalı kriptocu Nick Szabo tarafından 1996'da ortaya atılan bu fikir bugün Ethereum ile yaygınlaştı.
Peki akıllı sözleşmede aranan başlıca özellikler neler?
Blok zinciri üzerinde çalışan her şeyin değişmez olması ve bütünlüğünden ödün vermeden birden çok düğüm üzerinde çalışması gerekir. Sonuç olarak, bir akıllı sözleşme şu üç işlevselliğe sahip olmalı:
- Deterministik
- Sonlanabilir
- Yalıtılmış
Deterministik
Her defasında belirli bir girdiye aynı çıktıyı veren bir program kararlıdır. Bir program farklı bilgisayarlarda aynı girdi grubuna aynı çıktıyı verdiği sürece deterministik kabul edilir.
Ancak bir programın deterministik olmayan bir şekilde hareket edebileceği çeşitli anlar da var:
Deterministik olmayan sistem işlevlerini çağırma: Bir programcı kendi programında belirsiz bir işlevi çağırdığında.
Deterministik olmayan veri kaynakları: Program belirsiz bir veri kaynağıyla karşılaşırsa daha fazla determinist kalamaz. Örneğin, programın bir Google aramasının ilk 10 sorgusunu topladığını varsayalım. Aramalar değişmeye devam ettikçe veriler de değişir.
Dinamik çağrılar: Bir program ikinci bir programı çağırdığında buna dinamik çağrı denir. Hangi programın hedef alındığı yürütme esnasında belirlendiğinden doğası gereği belirsiz durumdur.
Sonlanabilirlik
Matematiksel mantıkta "sonlanma problemi" denen bir sorun var. Temel olarak, belirli bir programın işlevini mevcut süre boyunca yürütüp yürütemeyeceğini bilmemek bir yetersizliktir. 1936'da Alan Turing, Cantor'un Diyagonal Sorunu'nu kullanarak belirli bir programın bir zaman sınırı içinde görevini bitirip bitiremeyeceğini bilmenin bir yolu olmadığını açıkladı.
Bu akıllı sözleşmelerde de karşılaşılan bir problem. Çünkü tanım gereği sözleşmeler belirli bir zaman sınırı içinde sona erdirilebilir olmalılar. Sözleşmeyi harici olarak sonlandıran ve kaynakların tükenmesine neden olacak sonsuz bir döngüye girmesini önleyen bazı yöntemler var:
- Turing uyumsuz: Bu tarz bir blok zinciri sınırlı işlevselliğe sahip olur. Sonsuz döngüye geçmez ya da zıplama gerçekleştirmez.
- Talimat ve ücret ölçer: Program, uygulamaya geçirdiği tüm talimatların sayısını tutabilir ve belirli bir sayı geçildikten sonra görevini sonlandırabilir. Başka bir yöntem ise Ücret ölçerdir. Burada sözleşmeler ön ödemeli bir ücretle başlatılır. Her talimatın yürütülmesi belirli bir ücret gerektirir. Harcanan ücret önden ödenen ücreti aşarsa sözleşme feshedilir.
- Zamanlayıcı: Burada bir zamanlayıcı söz konusudur. Eğer sözleşme verilen süreyi aşarsa harici olarak feshedilir.
İzole
Bir blockchain'de herkes akıllı sözleşme başlatabilir. Ancak bu sebepten ötürü sözleşmeler bilerek veya bilmeyerek virüs ve hatalar içerebilirler. Sözleşme izole edilmezse bu tüm sisteme zarar verir. Bu nedenle tüm ekosistemi herhangi bir olumsuz etkiden korumak için sözleşmenin izole edilmesini sağlamak çok önemli.
Genellikle akıllı sözleşmeler iki sistemden biri kullanılarak çalıştırılır:
- Sanal makineler: Ethereum bunu kullanıyor.
- Docker: Fabric bunu kullanıyor.
Özellikle Ethereum gelişimiyle ilgileniyorsanız o zaman Solidity dilini öğrenmeniz şart.
Dapp'lerin (Merkezsiz uygulamalar) nasıl yapılacağını öğrenmek veya ICO sahasına girmek isteyen herkes için Solidity'yi öğrenmek mutlak bir zorunluluk. Solidity dili Gavin Wood, Christian Reitwiessner Alex Beregszászi, Yoichi Hirai ve Ethereum ana ekibinde bulunmuş çok sayıda üye tarafından geliştirildi.
Solidity, ECMAScript (Javascript)'e çok benzeyen bir sözdizimine sahip. Ethereum Tasarım Mantığı dokümanında EVM'in (Ethereum Sanal Makinesi) akıllı sözleşmelerde tam bir determinizm arayacak şekilde geliştirildiği belirtilir.
5. Topluluklarla Bir Arada Olun
Geliştirici olmanın en önemli adımlarından biri de topluluklarla iç içe olmak. Reddit forumlarına, Github sayfalarına ve StackExchange'e üye olun. Şirketlerin bir blockchain geliştiricisinde neler aradığını öğrenin. Diğer geliştiricilerle bağlantı kurun ve teknolojiyle ilgili haberleri yakından takip edin.