Osman sönmez
blockchainTurk
Published in
7 min readMar 18, 2019

--

Ethereum Private POA (Proof-of-Authority) Network Kurmak

Blockchain üzerinde kurumsal uygulamalar oluşturmak için en çok kullanılan Blockchain teknolojilerinden birisi olarak Ethereum karşımıza çıkıyor. Çok kullanılmasının en önemli nedenleri programlanabilir olması, hem data hemde para’yı tutabilmesidir. Tek bir ethereum adresinde ayrı ayrı birimlerden parayı tutabilmesi ise operasyonların tek bir adres üzerinden yapılabilmesinden dolayı önemli bir esneklik sağlıyor.

Tek bir Ethereum adresinde ayrı ayrı birimlerden ör: USD,TL,EUR gibi düşünülebilir para tutulabiliyor, bu ise operasyonların tek bir adres üzerinden yapılabilmesinden dolayı önemli bir esneklik sağlıyor. Yani size para gönderecek birisinin adresinizi ve hangi birimden para göndereceğini bilmesi yeterli oluyor.

Kurumsal uygulamalarda Ethereum network’ü kurmak için dikkat edilmesi gereken en önemli husus consensus mekanizmasının doğru kurulmasıdır. Consensus Türkçe’ye çevirirsek fikir birliği mekanizması demektir. Yani oluşturulan blokların nasıl oluşturulacağının ve zincire kabul edilebilmesinin şartlarının ne olacağının kararının verilmesidir.

Enerji sarfiyatının minimuma indirilmesi için consensus mekanizmasının doğru seçilmesi gerekmektedir. Private network tarafında kullanılan consensus mekanizması Proof-of-Authority olarak kurulmalıdır. Ethereum engine olarak Clique engine kullanılmalıdır.

Private network olarak adlandırılan bu networkler genellikle bir kurum tarafından kullanılmak için veya birden fazla kurumun aralarında kullanmak için kurdukları network’tür. Dışarıdan müdahelelere kapatılması veya sınırlandırılması gerekmektedir.

Proof-of-Authority mekanizmasında Bloklar miner(madenci) olarak çalışan düğüm tarafından oluşturuluyor. Networkü ayağa kaldırırken(genesis.json içerisinde) blokların Chain’e (zincire) eklenebilmesi için birden fazla node(düğüm) tarafından onaylanmasını isteyebilirsiniz. Bu düğümlere sealer deniyor. Yani imzalayan mühürleyen anlamında. Bu mühürler olmadan blok ethererum zincirine eklenmiyor. Örnek vermek gerekirse bir kişi A bankasından işlem yapıyor ve işlemin gerçekleşmesi içinde B bankasının onayı gerekiyor. A bankasını ve B bankasını network’te sealer olarak tanımlarsanız A bankası bloğu oluşturup yollasa bile B bankası onaylamadan işlem gerçekleşmiş sayılmaz. Doğal olarak B bankası onaylayınca ilgili işlem gerçekleşir. Hatta araya birde merkez bakası gibi bir mekanizma koyup merkez bankası onaylamadan işlem gerçekleşmez derseniz merkez bankasını da sealer olarak tanımlamalısınız. Gördüğünüz gibi işlemler onaycılar mekanizmasından geçtikten sonra zincire ekleniyor ve gerçekleşiyor. İşin güzel tarafı bütün bunlar gerçekleşirken çok karmaşık yapıların mimarilerin içinde boğulmanıza gerek kalmıyor. Sadece bir düğümü ayağa kaldırmak ve network’e dahil etmek yeterli oluyor.

Ben kurulum yaparken resmi Ethereum implementasyonlarından Go dili ile geliştirilen Go Ethereum implementasyonunu kullandım. Go Ethereum kurulumunu https://ethereum.github.io/go-ethereum/install/ adresinden takip edebilirsiniz.

Private network kurmak için öncelikle genesis.json dosyasını oluşturmalısınız. genesis.json dosyası düğümler ilk ayağa kalkarken ihtiyaçları olan configurasyonu vermeniz içindir.

Genesis.json dosyasını oluşturmak için puppeth kullanabilirsiniz. Github üzerinden puppeth https://github.com/puppeth/go-ethereum kodunu indirip build ederseniz puppeth için çalıştırılabilir dosya oluşmuş olacaktır.

Ben MACOS üzerinde çalıştığım için komutları ve kurulumları MAC-OS’a göre yaptım. Linux kurulumlarıda aşağı yukarı aynı şekilde yapılıyor belki windows üzerinde ufak farklılıklar olabilir.

https://github.com/puppeth/go-ethereum indirdiğim kodu build edip bin klasöründe ihtiyacım olan dosyaların oluştuğunu gördüm. Burada dikkat etmeniz gereken birkaç noktayı söyleyeceğim. Go implementasyonunu indirdiğim için build yaparken Go engine’e ihtiyacınız olacaktır. Öncesinde

brew install go

komutu terminalde çalıştırarak go kurulumu yapmanızı öneririm. Problem çıkarsa sudo ile denemenizi öneririm.

Ben yıllarca Windows üzerinde çalıştığım için MAC-OS üzerinde bunları yaparken biraz zorlanıyorum eğer linux üzerinde çalışıyorsanız bunlar sizin için çocuk oyuncağı olacaktır.

Terminal üzerinde go ethereum/build/bin klasöründe Puppeth’i run ediyorum.

L52850MAC:~ osmansonmez$ cd go-ethereum/build/binL52850MAC:bin osmansonmez$ puppeth

Network name’i girip devam ediyorum. İsim olarak newgenesis veriyorum.

Açılan ekrandan 2. seçenek ile devam ediyorum. (Configure new genesis)

1. seçenek ile devam ediyorum. (Create new genesis from stratch)

2. seçenek ile yani proof-of-authority seçeneği ile devam ediyorum.

Kalan sorulara devam ediyorum. İlk soru blok üretme süresi ne kadar olacak yani kaç saniyede bir blok üretilecek ben 5 saniye olarak veriyorum. 2. soru ise hangi hesaplar sealer olacak. Yani A bankası ve B bankasının public key’leri yani adreslerini burada gireceğiz. bunun için 2 tane ethereum adresi oluşturmamız gerekiyor.

Adres oluşturmak için ethereum go’nun geth komutunu kullanacağız. Bunun için yeni bir terminal açmamız lazım. Terminalde geth komutları ile 2 adet ethereum hesabı oluşturacağız.

Account oluşturmak için komutumuz: geth account new

komutu terminalde yazdığımızda bize hesap için şifre sormaktadır. şifreyi girdikten sonra bize hesabı oluşturmaktadır.

Oluşturduğumuz hesapları puppeth ekranında sırasıyla girelim. Ben iki adet sealer olacağı için iki adet hesap belirledim. Hesap şifrelerini sakın unutmayınız çünkü daha sonra kullanacağız.

Adres 1 :df6cc60abfdfdef40be53c75962b666a9febd3ef

Adres 2 :29e97a93c40d91a6cc86a03668bebecc3b989494

puppeth üzerinden iki adet hesabı sealer yaptık aynı zamanda bu iki hesaba sabit olarak bir miktar ethereum yüklemesini söyledik.

Devam eden sorular başka prefunded hesaplar olacak mı bu soruya no yanıtını verdim ve benden network Id ‘yi istedi. NetworkId olarak 1881’ i verdim. NetworkId değeri aynı network’e dahil olmak isteyen node’lar için önemli bir değerdir. Ben bu değeri 1881 olarak belirledim.

Daha sonra yine puppeth üzerinden manage existing genesis ve Export genesis configuration seçenekleri ile devam edilirse puppeth içerisinde yer alan default klasöründe newgenesis.json dosyasının oluştuğunu göreceksiniz ve içeriği aşağıdaki gibi olacaktır.

newgenesis.json dosyasının içeriği{
“config”: {
“chainId”: 1915,
“homesteadBlock”: 1,
“eip150Block”: 2,
“eip150Hash”: “0x0000000000000000000000000000000000000000000000000000000000000000”,
“eip155Block”: 3,
“eip158Block”: 3,
“byzantiumBlock”: 4,
“constantinopleBlock”: 5,
“clique”: {
“period”: 5,
“epoch”: 30000
}
},
“nonce”: “0x0”,
“timestamp”: “0x5c8ea683”,
“extraData”: “0x000000000000000000000000000000000000000000000000000000000000000029e97a93c40d91a6cc86a03668bebecc3b989494df6cc60abfdfdef40be53c75962b666a9febd3ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”,
“gasLimit”: “0x47b760”,
“difficulty”: “0x1”,
“mixHash”: “0x0000000000000000000000000000000000000000000000000000000000000000”,
“coinbase”: “0x0000000000000000000000000000000000000000”,
“alloc”: {
“29e97a93c40d91a6cc86a03668bebecc3b989494”: {
“balance”: “0x200000000000000000000000000000000000000000000000000000000000000”
},
“df6cc60abfdfdef40be53c75962b666a9febd3ef”: {
“balance”: “0x200000000000000000000000000000000000000000000000000000000000000”
}
},
“number”: “0x0”,
“gasUsed”: “0x0”,
“parentHash”: “0x0000000000000000000000000000000000000000000000000000000000000000”
}

newgenesis.json dosyasını oluşturduk. Aslında işin en büyük kısmını tamamladık sayılır. Artık 2 node’lu network’ü ayağa kaldırmak kaldı. Ben tamamını localde ayağa kaldıracağım. Dilerseniz kubernetes, docker veya openshift ortamında da ayağa kaldırabilirsiniz. Ben çok uzatmamak adına ilk etapta local’de ayağa kaldıracağım.

Öncelikle boot node ayağa kaldıracağım. Boot node nedir?

Boot node network’te bulunan node’ların birbirlerini bulabilmeleri için ayakta olan kayıt node’udur. Herhangi bir transaction veya miner rolü yoktur. Esasında olay ayağa kalkan herhangi bir node’un boot node’a ben burdayım diye haber vermesidir ve kendisini kaydetmesidir. Node’lar boot node aracılığı ile birbirlerinin adreslerini edinirler ve peer to peer haberleşme bu sayede sağlanır.

Yeni bir terminal açıp boot node’u ayağa kaldıralım.

komutlar :

1- bootnode -genkey boot.key2- bootnode -nodekey boot.key -verbosity 9 -addr :30304

2- bootnode -nodekey boot.key -verbosity 9 -addr :30304

bootnode 127.0.0.1:30304 portunda ayağa kalktı.Peki diğer node’lar bootnode’u nasıl bulacaklar ve onunla nasıl haberleşecekler?

Bunun için enode isimli bir adres oluşturmamız gerekiyor. Bu da çok basit formatı aşağıdaki gibi olacaktır.

“enode://<your node public key>@<your node public ip>:30304”

Bize boot nodumuzun public key bilgisi lazım.Terminali açalım ve aşağıdaki komutu girelim.

bootnode -nodekey boot.key -writeaddress

Komutu çalıştırınca bize yeni bir public key oluşturacaktır.

b19a42e8bf96953a0e365fbfbea7fba8aab55a057c086d12bd8584115e6e8b66e9a98d739e021eba2fb4b6f3eb451ffeef1287950cd596a80c88fbddc26ea6dc

Yani boot node adresimiz aşağıdaki gibi oluşmuş olacaktır.

enode://b19a42e8bf96953a0e365fbfbea7fba8aab55a057c086d12bd8584115e6e8b66e9a98d739e021eba2fb4b6f3eb451ffeef1287950cd596a80c88fbddc26ea6dc@127.0.0.1:30304

Şimdi Node’ları ayağa kaldıralım. Bunun için iki adet farklı klasöre ihtiyacımız olacaktır.

Node1 ve Node2 olarak 2 adet klasör açalım.

İlk komutumuz ilk node’u yani Node1'i başlayacak konuma getirmek olacaktır. Burada daha önce oluşturduğumuz newgenesis.json dosyası gerekli olacaktır.

newgenesis.json dosyasını node1 ve node2 klasörlerine kopyalayalım.

Yeni bir terminal açalım ve node1 ve node2'yi ayarlayalım.

Node1 ayarlanıyor.

komut1 : geth — datadir node1/ init node1/newgenesis.json

Node2 ayarlanıyor.

komut2: geth — datadir node2/ init node2/newgenesis.json

Komutları çalıştırınca node1 ve node2 klasörlerinde geth, keystore gibi klasörlerin oluştuğunu göreceksinizdir.

Şimdi node’ları ayağa kaldırma zamanı:)

Hatırlıyorsanız her iki node’u sealer olarak oluşturacaktık ve ilk başta newgenesis.json dosyasını oluştururken 2 adet ethereum hesabı oluşturmuştuk. Hesapları oluştururken şifre vermiştik. Şimdi node’ları ayağa kaldırırken bu hesapların bilgileri ve şifresi gerekiyor. Sebebi ise node ‘un transaction’u onaylarken vereceğimiz hesap ile onaylayacak olmasıdır. Yani mühürleyecek olmasıdır.

Hatırlıyorsanız hesapları geth komutu ile oluşturmuştuk. Hesaplar oluşunca geth’in kurulduğu ethereum klasöründe bulunan keystore klasöründe hesapların bilgilerinin hesap ismiyle bir dosyada tutulduğunu göreceksinizdir.

29e97a93c40d91a6cc86a03668bebecc3b989494 hesabının keystore dosyasını node1/keystore altına,

df6cc60abfdfdef40be53c75962b666a9febd3ef hesabının keystore dosyasını node2/keystore altına kopyalayalım.

node1/ ve node2/ altında bu hesapların şifrelerini tutmak için password.txt isimli bir dosya oluşturalım ve ilgili hesabın şifresini bu dosyaya yazalım.

Node1'i ayağa kaldırmak için komutu oluşturalım. Uzun çizgiler tire tire burda düzgün çıkmamış.

geth — networkid 1881 — datadir “node1/” — bootnodes ‘enode://b19a42e8bf96953a0e365fbfbea7fba8aab55a057c086d12bd8584115e6e8b66e9a98d739e021eba2fb4b6f3eb451ffeef1287950cd596a80c88fbddc26ea6dc@127.0.0.1:30304 — port 30305 — ipcdisable — syncmode full — rpc — rpcaddr 0.0.0.0 — rpccorsdomain “*” — rpcport 8546 — unlock 29e97a93c40d91a6cc86a03668bebecc3b989494 — password node1/password.txt — mine — keystore ‘node1/keystore’ console

Komutu çalıştırınca node1 ayağa kalkar fakat herhangi bir mine işlemi yapmadığını ve blok oluşturmadığını göreceksinizdir. Sebebi ise bütün sealer node’ların ayakta olmamasıdır.

İkinci sealer node yani node2'yi ayağa kaldıralım.

geth — networkid 1881 — datadir “node2/” — bootnodes ‘enode://b19a42e8bf96953a0e365fbfbea7fba8aab55a057c086d12bd8584115e6e8b66e9a98d739e021eba2fb4b6f3eb451ffeef1287950cd596a80c88fbddc26ea6dc@127.0.0.1:30304’ — port 30306 — ipcdisable — syncmode full — rpc — rpcaddr 0.0.0.0 — rpccorsdomain “*” — rpcport 8547 — unlock df6cc60abfdfdef40be53c75962b666a9febd3ef — password node2/password.txt — mine — keystore ‘node2/keystore’ console

İki adet sealer node ayağa kaldırdık. İsterseniz bir tanede transaction node ayağa kaldıralım. Yani mine işlemi yapmasın. Gelen transactionları kabul etsin.

geth — networkid 1881 — datadir “node3/” — bootnodes ‘enode://b19a42e8bf96953a0e365fbfbea7fba8aab55a057c086d12bd8584115e6e8b66e9a98d739e021eba2fb4b6f3eb451ffeef1287950cd596a80c88fbddc26ea6dc@127.0.0.1:30304’ — port 30307 — ipcdisable — syncmode full — rpc — rpcaddr 0.0.0.0 — rpccorsdomain “*” — rpcport 8548 — unlock console

2 adet miner bir adet transaction node ile networkümüzü kurmuş bulunuyoruz.

Hızlıca komutun üzerinde geçelim

geth

— networkid 1881 (1881 nolu network ayağa kalktı)

— datadir “node1/” (node1 klasöründe veriler duracak demektir.)

— bootnodes ‘enode://b19a42e8bf96953a0e365fbfbea7fba8aab55a057c086d12bd8584115e6e8b66e9a98d739e021eba2fb4b6f3eb451ffeef1287950cd596a80c88fbddc26ea6dc@127.0.0.1:30304

— port 30305 (peer to peer olarak diğer node’larla bu port üzerinden iletişim kuracak. )

— rpc — rpcaddr 0.0.0.0 — rpccorsdomain “*” — rpcport 8546 (rpc protokolü 8546 portu üzerinden olacak)

— unlock 29e97a93c40d91a6cc86a03668bebecc3b989494 (miner bu hesapla işlemleri imzalayacak ve onaylayacak bundan dolayı hesabı unlock olarak bırakıyoruz. Bu hesapta ether olamamasına dikkat edin unlock olduğu için dışarıdan müdahelelere açıktır.)

— password node1/password.txt (hesabın şifresi)

— mine (node miner olsun demektir.)

— keystore ‘node1/keystore’ (hesabın private key bilgisi)

Networkü kurarken ufak tefek problemlerle karşılaşmış olabilirsiniz ama yinede yılmadan çalıştırmaya çalışınız bir problem yaşarsanız lütfen sonmezosman@gmail adresine istediğiniz zaman mail atabilirsiniz.

--

--