Bir Python geliştiricisi için Ethereum'a giriş, bölüm 1
Şu Ethereum denen şeyi duydunuz ve konuya daha derinlemesine inmeye hazır mı hissediyorsunuz? Bu gönderi, bazı blokzinciri temellerini hızlıca ele alacak, ardından simüle edilmiş bir Ethereum düğümü ile etkileşim kurarak blok verilerini okumanızı, hesap bakiyelerini kontrol etmenizi ve işlem göndermenizi sağlayacaktır. Bu arada, uygulama oluşturmanın geleneksel yolları ile bu yeni merkeziyetsiz paradigma arasındaki farkları vurgulayacağız.
(Esnek) Ön Koşullar
Bu gönderi, geniş bir geliştirici yelpazesi için erişilebilir olmayı hedeflemektedir. Python araçları kullanılacaktır, ama sadece fikirler için bir araç olacaklardır: Bir Python geliştiricisi değilseniz de sorun olmaz. Gelgelelim, Ethereum ile ilgili kısımlara hızlıca geçebilmemiz için bazı şeyleri bildiğinizi varsayacağım.
Varsayımlar:
- Bir terminalde gezinebildiğiniz,
- Birkaç satır Python kodu yazdığınız,
- Python'un 3.6 ya da daha yüksek bir sürümü cihazınızda yüklüdür (bir sanal ortamopens in a new tab kullanılması şiddetle tavsiye edilir), ve
- Python’un paket yükleyicisi olan
pip'i kullandığınız varsayılır. Buna karşın, eğer varsayımlardan herhangi biri doğru değilse veya bu makaledeki kodu yeniden uygulamayı düşünmüyorsanız, büyük ihtimalle yine de gayet iyi şekilde takip edebilirsiniz.
Kısaca Blokzincirler
Ethereum'u tanımlamanın birçok yolu bulunsa da Ethereum, özünde bir blokzincirdir. Blokzincirler bir dizi bloktan oluşur, bu yüzden oradan başlayalım. En basit şekilde, Ethereum blokzincirindeki her bir blok sadece birtakım meta veri ve bir işlemler listesidir. JSON formatında, şöyle bir şeye benzer:
1{2 "number": 1234567,3 "hash": "0xabc123...",4 "parentHash": "0xdef456...",5 ...,6 "transactions": [...]7}Her blok kendinden önceki bloğa doğru bir referansa sahiptir; parentHash kısaca önceki bloğun karmasıdır.
Bir blokzincir esasen bağlantılı bir listedir; her blok, önceki bloğa bir referans içerir.
Bu veri yapısı yeni bir şey değildir ama ağı yöneten kurallar (yani eşler arası protokoller) öyledir. Merkezi bir otorite yoktur; eşler ağı, ağı sürdürmek için iş birliği yapmalı ve bir sonraki bloğa hangi işlemlerin dahil edileceğine karar vermek için rekabet etmelidir. Bu nedenle, bir arkadaşınıza biraz para göndermek istediğinizde, bu işlemi ağa yayınlamanız ve ardından gelecek bir bloğa eklenmesini beklemeniz gerekir.
Blokzincirinin, paranın bir kullanıcıdan diğerine gerçekten gönderildiğini doğrulamasının tek yolu, o blokzincirine özgü (yani, blokzinciri tarafından oluşturulan ve yönetilen) bir para birimi kullanmaktır. Ethereum'da bu para birimine ether denir ve Ethereum blokzinciri, hesap bakiyelerinin tek resmi kaydını içerir.
Yeni bir paradigma
Bu merkeziyetsiz yeni teknoloji yığını, yeni geliştirici araçları ortaya çıkardı. Bu tür araçlar birçok programlama dilinde mevcuttur, ancak biz Python merceğinden bakacağız. Tekrarlamak gerekirse: Python tercih ettiğiniz dil olmasa bile, takip etmek çok zor olmayacaktır.
Ethereum ile etkileşim kurmak isteyen Python geliştiricileri büyük ihtimalle Web3.pyopens in a new tab kullanacaktır. Web3.py, bir Ethereum düğümüne bağlanma ve ondan veri gönderme ve alma şeklinizi büyük ölçüde basitleştiren bir kütüphanedir.
Ethereum istemcileri, IPCopens in a new tab, HTTP veya Websocket'ler tarafından erişilebilir olacak şekilde yapılandırılabilir, bu nedenle Web3.py'nin bu yapılandırmayı yansıtması gerekir. Web3.py bu bağlantı seçeneklerine sağlayıcılar adını verir. Web3.py örneğini düğümünüze bağlamak için üç sağlayıcıdan birini seçmeniz gerekir.
Ethereum düğümünü ve Web3.py'yi aynı protokol aracılığıyla iletişim kuracak şekilde yapılandırın, örneğin bu şemadaki IPC gibi.
Web3.py uygun şekilde yapılandırıldıktan sonra blokzinciri ile etkileşime başlayabilirsiniz. İşte karşılaşacaklarımızın bir ön izlemesi olarak birkaç Web3.py kullanım örneği:
1# blok verisini oku:2w3.eth.get_block('latest')34# bir işlem gönder:5w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...})Kurulum
Bu örnekte, sadece bir Python yorumlayıcısı içinde çalışacağız. Herhangi bir dizin, dosya, sınıf veya fonksiyon oluşturmayacağız.
$ ile başlayan komutların terminalde çalıştırılması amaçlanmıştır. ($ işaretini yazmayın, bu sadece satırın başlangıcını belirtir.)İlk olarak, içinde keşif yapabileceğiniz kullanıcı dostu bir ortam için IPythonopens in a new tab yükleyin. IPython, diğer özelliklerin yanı sıra sekme ile tamamlama özelliği sunarak Web3.py içinde nelerin mümkün olduğunu görmeyi çok daha kolaylaştırır.
pip install ipythonWeb3.py, web3 adı altında yayınlanmıştır. Şu şekilde kurun:
pip install web3Bir şey daha var: Daha sonra birkaç bağımlılık gerektiren bir blokzinciri simüle edeceğiz. Bunları şu şekilde yükleyebilirsiniz:
pip install 'web3[tester]'Başlamaya hazırsınız!
Not: web3[tester] paketi Python 3.10.xx sürümüne kadar çalışır.
Bir sanal alan başlatın
Terminalinizde ipython çalıştırarak yeni bir Python ortamı açın. Bu, python çalıştırmaya benzer, ancak daha fazla kullanışlı özellikle birlikte gelir.
ipythonBu, çalıştırmakta olduğunuz Python ve IPython sürümleri hakkında bazı bilgileri yazdıracaktır, ardından girdi bekleyen bir bilgi istemi görmelisiniz:
1In [1]:Şu anda interaktif bir Python kabuğuna bakıyorsunuz. Aslında içinde oynamanız için bir sanal alandır. Buraya kadar geldiyseniz, Web3.py'yi içe aktarmanın zamanı geldi:
1In [1]: from web3 import Web3Web3 modülüne giriş
Ethereum'a bir geçit olmasının yanı sıra, Web3opens in a new tab modülü birkaç kolaylaştırıcı fonksiyon sunar. Birkaçını keşfedelim.
Bir Ethereum uygulamasında, genellikle para birimi birimlerini dönüştürmeniz gerekir. Web3 modülü, tam da bunun için birkaç yardımcı metot sunar: from_weiopens in a new tab ve to_weiopens in a new tab.
Not: Bilgisayarlar, ondalık matematiği işlemede çok kötüdür. Bunu aşmak için geliştiriciler genellikle dolar tutarlarını sent olarak saklar. Örneğin fiyatı $5.99 olan bir ürün veritabanında 599 olarak saklanabilir.
ether cinsinden işlemler gerçekleştirilirken de benzer bir düzen kullanılır. Ancak ether, iki ondalık basamak yerine 18 ondalık basamağa sahiptir! Ether'ın en küçük birimine wei denir, bu nedenle işlem gönderirken belirtilen değer budur.
1 ether = 1000000000000000000 wei
1 wei = 0.000000000000000001 ether
Bazı değerleri wei'ye ve wei'den dönüştürmeyi deneyin. Ether ve wei arasında birçok para birimi birimi için isimler olduğunuopens in a new tab unutmayın. Bunlar arasında daha iyi bilinenlerden biri gwei'dir, çünkü genellikle işlem ücretleri bu şekilde gösterilir.
1In [2]: Web3.to_wei(1, 'ether')2Out[2]: 100000000000000000034In [3]: Web3.from_wei(500000000, 'gwei')5Out[3]: Decimal('0.5')Web3 modülündeki diğer yardımcı metotlar arasında veri biçimi dönüştürücüleri (örneğin, toHexopens in a new tab), adres yardımcıları (örneğin, isAddressopens in a new tab) ve karma fonksiyonları (örneğin, keccakopens in a new tab) bulunur. Bunların çoğu serinin devamında ele alınacaktır. Kullanılabilir tüm yöntemleri ve özellikleri görüntülemek için Web3. yazıp noktadan sonra iki kez sekme tuşuna basarak IPython'un otomatik tamamlama özelliğinden faydalanın.
Zincirle konuşun
Kolaylık sağlayan bu yöntemler güzel olsa da artık blokzincire geçelim. Sonraki adım, Web3.py'yi bir Ethereum düğümü ile iletişim kuracak şekilde yapılandırmaktır. Burada IPC, HTTP veya Websocket sağlayıcılarını kullanma seçeneğimiz bulunuyor.
Bu yolu kullanmayacağız ancak HTTP Sağlayıcısını kullanan eksiksiz bir iş akışı örneği şöyle görünebilir:
- Bir Ethereum düğümü indirin, örneğin, Gethopens in a new tab.
- Geth'i bir terminal penceresinde başlatın ve ağı senkronize etmesini bekleyin. Varsayılan HTTP bağlantı noktası
8545'tir, ancak yapılandırılabilir. - Web3.py'ye HTTP aracılığıyla
localhost:8545üzerindeki düğüme bağlanmasını söyleyin.w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545')) - Düğümle etkileşim kurmak için
w3örneğini kullanın.
Bu, bunu yapmanın "gerçek" bir yolu olsa da, senkronizasyon işlemi saatler sürer ve yalnızca bir geliştirme ortamı istiyorsanız gereksizdir. Web3.py bu amaçla dördüncü bir sağlayıcı sunar: EthereumTesterProvider. Bu test sağlayıcısı, rahat izinlere ve oynamak için sahte para birimine sahip simüle edilmiş bir Ethereum düğümüne bağlanır.
EthereumTesterProvider, simüle edilmiş bir düğüme bağlanır ve hızlı geliştirme ortamları için kullanışlıdır.
Bu simüle edilmiş düğüme eth-testeropens in a new tab denir ve biz onu pip install 'web3[tester]' komutunun bir parçası olarak kurduk. Web3.py'yi bu test sağlayıcısını kullanacak şekilde yapılandırmak şu kadar basittir:
1In [4]: w3 = Web3(Web3.EthereumTesterProvider())Artık zincirde sörf yapmaya hazırsınız! İnsanlar böyle bir şey söylemez. Bunu az önce kafamdan uydurdum. Hadi hızlı bir tur atalım.
Hızlı tur
Her şeyden önce, hızlı bir kontrol yapalım:
1In [5]: w3.is_connected()2Out[5]: TrueTest sağlayıcısını kullandığımız için bu çok değerli bir test değildir ancak başarısız olursa, muhtemelen w3 değişkenini başlatırken yanlış bir şeyler yazmışsınızdır. İç parantezleri eklediğinizden emin olun, yani Web3.EthereumTesterProvider().
Tur durağı #1: hesaplar
Kolaylık sağlamak için test sağlayıcısı bazı hesaplar oluşturdu ve bunları test ether'i ile önceden yükledi.
İlk olarak, bu hesapların bir listesini görelim:
1In [6]: w3.eth.accounts2Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',3 '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',4 '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...]Bu komutu çalıştırırsanız 0x ile başlayan on diziden oluşan bir liste görmelisiniz. Her biri bir açık adrestir ve bazı yönlerden bir çek hesabındaki hesap numarasına benzer. Bu adresi size ether göndermek isteyen birine verirsiniz.
Belirtildiği gibi, test sağlayıcısı bu hesapların her birine bir miktar test ether'ini önceden yüklemiştir. İlk hesapta ne kadar olduğunu öğrenelim:
1In [7]: w3.eth.get_balance(w3.eth.accounts[0])2Out[7]: 1000000000000000000000000Bir sürü sıfır var! Güle oynaya sahte bankaya gitmeden önce, daha önceki para birimi birimleri dersini hatırlayın. Ether değerleri, en küçük birim olan wei ile temsil edilir. Bunu ether'e çevirin:
1In [8]: w3.from_wei(1000000000000000000000000, 'ether')2Out[8]: Decimal('1000000')Bir milyon test ether'i — yine de fena değil.
Tur durağı #2: blok verisi
Simüle edilmiş blokzincirinin durumuna bir göz atalım:
1In [9]: w3.eth.get_block('latest')2Out[9]: AttributeDict({3 'number': 0,4 'hash': HexBytes('0x9469878...'),5 'parentHash': HexBytes('0x0000000...'),6 ...7 'transactions': []8})Bir blok hakkında birçok bilgi döndürülür, ancak burada dikkat edeceğimiz sadece birkaç şey var:
- Test sağlayıcısını ne kadar süre önce yapılandırmış olursanız olun, blok numarası sıfırdır. Her 12 saniyede bir yeni blok ekleyen gerçek Ethereum ağının aksine, bu simülasyon siz ona yapacak bir iş verene kadar bekleyecektir.
transactionsboş bir listedir, aynı nedenle: henüz hiçbir şey yapmadık. Bu ilk blok, sadece zinciri başlatmak için kullanılan bir boş bloktur.parentHash'in sadece bir yığın boş bayttan ibaret olduğuna dikkat edin. Bu, zincirdeki ilk blok olduğunu ve genesis blok olarak da bilindiğini gösterir.
Tur durağı #3: işlemler
Bekleyen bir işlem olana kadar sıfırıncı blokta kalacağımız için ona bir işlem verelim. Bir hesaptan diğerine birkaç test ether'ı gönderin:
1In [10]: tx_hash = w3.eth.send_transaction({2 'from': w3.eth.accounts[0],3 'to': w3.eth.accounts[1],4 'value': w3.to_wei(3, 'ether'),5 'gas': 210006})Bu noktada genellikle işleminizin yeni bir bloğa dahil edilmesi için birkaç saniye beklersiniz. Tam süreç hemen hemen şöyle işler:
- Bir işlem gönderin ve işlem karmasını saklayın. İşlemi içeren blok oluşturulup yayınlanıncaya kadar işlem "beklemede" kalır.
tx_hash = w3.eth.send_transaction({ … }) - İşlemin bir bloğa dahil edilmesini bekleyin:
w3.eth.wait_for_transaction_receipt(tx_hash) - Uygulama mantığına devam edin. Başarılı işlemi görüntülemek için:
w3.eth.get_transaction(tx_hash)
Simüle edilmiş ortamımız, işlemi anında yeni bir bloğa ekleyecektir, böylece işlemi hemen görebiliriz:
1In [11]: w3.eth.get_transaction(tx_hash)2Out[11]: AttributeDict({3 'hash': HexBytes('0x15e9fb95dc39...'),4 'blockNumber': 1,5 'transactionIndex': 0,6 'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',7 'to': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',8 'value': 3000000000000000000,9 ...10})Tümünü gösterBurada bazı tanıdık ayrıntılar göreceksiniz: from, to ve value alanları send_transaction çağrımızın girdileriyle eşleşmelidir. Diğer güven verici kısım ise bu işlemin 1 numaralı blok içindeki ilk işlem ('transactionIndex': 0) olarak dahil edilmiş olmasıdır.
Ayrıca, ilgili iki hesabın bakiyelerini kontrol ederek bu işlemin başarısını kolayca doğrulayabiliriz. Üç ether, birinden diğerine geçmiş olmalıdır.
1In [12]: w3.eth.get_balance(w3.eth.accounts[0])2Out[12]: 99999699997900000000000034In [13]: w3.eth.get_balance(w3.eth.accounts[1])5Out[13]: 1000003000000000000000000İkincisi iyi gözüküyor! Bakiye, 1.000.000'dan 1.000.003 ether'a döndü. Peki ilk hesaba ne oldu? Üç ether'dan biraz daha fazlasını kaybetmiş görünüyor. Ne yazık ki, hayatta hiçbir şey bedava değildir ve Ethereum genel ağını kullanmak, eşlerinizi destekleyici rolleri için tazmin etmenizi gerektirir. İşlemi gönderen hesaptan küçük bir işlem ücreti kesildi. Bu ücret, yakılan gaz miktarı (bir ETH transferi için 21.000 birim gaz) ile ağ etkinliğine göre değişen bir taban ücretin çarpımına, işlemi bloğa dahil eden doğrulayıcıya giden bir bahşişin eklenmesiyle hesaplanır.
Gaz hakkında daha fazla bilgi
Biraz soluklanalım
Bir süredir bu işle uğraştığımız için şu anda biraz mola vermek iyi gelebilir. Derine dalmaya devam ediyoruz ve bu serinin ikinci bölümünde keşfe devam edeceğiz. Yakında ele alacağımız bazı kavramlar: gerçek bir düğüme bağlanma, akıllı sözleşmeler ve jetonlar. Yukarıdakilerle ilgili sorularınız mı var? Bana sorabilirsiniz! Geribildiriminiz konunun ilerleyişini etkileyecektir. İsteklerinizi Twitteropens in a new tab üzerinden iletebilirsiniz.
Sayfanın son güncellenmesi: 6 Şubat 2025


