Úvod do Etherea pro vývojáře v Pythonu, 1. část
Takže jsi slyšel o tomhle Ethereu a jsi připravený vydat se do králičí nory? V tomto příspěvku si rychle projdeme základy blockchainu a pak tě necháme interagovat se simulovaným uzlem sítě Ethereum – číst data z bloků, kontrolovat zůstatky na účtech a odesílat transakce. Cestou si také ukážeme rozdíly mezi tradičními způsoby tvorby aplikací a tímto novým decentralizovaným paradigmatem.
(Nepovinné) předpoklady
Tento příspěvek se snaží být přístupný širokému okruhu vývojářů. Nástroje pro Python sice použijeme, ale jsou jen prostředkem k předání myšlenek – nevadí, pokud nejsi vývojář v Pythonu. Budu však předpokládat, že už pár věcí znáš, abychom se mohli rychle přesunout k částem specifickým pro Ethereum.
Předpoklady:
- Vyznáš se v terminálu,
- Napsal jsi pár řádků kódu v Pythonu,
- na svém počítači máš nainstalovaný Python verze 3.6 nebo vyšší (důrazně doporučujeme použít virtuální prostředí (opens in a new tab)) a
- používal jsi
pip, instalátor balíčků pro Python. I když něco z toho nesplňuješ nebo si neplánuješ kód z tohoto článku zkoušet, nejspíš i tak všechno bez problémů pochopíš.
Stručně o blockchainech
Ethereum lze popsat mnoha způsoby, ale v jeho jádru je blockchain. Blockchainy se skládají z řady bloků, takže začněme u nich. Zjednodušeně řečeno, každý blok na blockchainu Etherea je jen několik metadat a seznam transakcí. Ve formátu JSON to vypadá nějak takto:
1{2 "number": 1234567,3 "hash": "0xabc123...",4 "parentHash": "0xdef456...",5 ...,6 "transactions": [...]7}Každý blok má odkaz na blok, který mu předcházel; parentHash je jednoduše haš předchozího bloku.
Blockchain je v podstatě spojový seznam; každý blok má odkaz na předchozí blok.
Tato datová struktura není nijak nová, ale pravidla (tj. protokoly peer-to-peer), která řídí síť, ano. Neexistuje žádná centrální autorita; síť peerů musí spolupracovat na udržení sítě a soutěžit o to, které transakce zahrnout do dalšího bloku. Takže když chceš poslat nějaké peníze kamarádovi, musíš tuto transakci odvysílat do sítě a pak počkat, až bude zahrnuta do některého z nadcházejících bloků.
Jediný způsob, jak může blockchain ověřit, že peníze byly skutečně poslány od jednoho uživatele k druhému, je použití měny, která je pro daný blockchain nativní (tj. vytvořená a řízená jím). V Ethereu se tato měna nazývá ether a blockchain Etherea obsahuje jediný oficiální záznam o zůstatcích na účtech.
Nové paradigma
Tento nový decentralizovaný technologický stack dal vzniknout novým vývojářským nástrojům. Takové nástroje existují v mnoha programovacích jazycích, ale my se na ně podíváme z pohledu Pythonu. Znovu opakuji: i když Python není tvůj preferovaný jazyk, neměl by být velký problém vše sledovat.
Vývojáři v Pythonu, kteří chtějí interagovat s Ethereem, pravděpodobně sáhnou po Web3.py (opens in a new tab). Web3.py je knihovna, která výrazně zjednodušuje způsob, jakým se připojíš k uzlu Ethereum a poté z něj odesíláš a přijímáš data.
Klienti sítě Ethereum mohou být nakonfigurováni tak, aby byli dosažitelní pomocí IPC (opens in a new tab), HTTP nebo Websockets, takže Web3.py bude muset tuto konfiguraci zrcadlit. Web3.py označuje tyto možnosti připojení jako providery. Budeš si chtít vybrat jednoho ze tří providerů, abys propojil instanci Web3.py se svým uzlem.
Nakonfiguruj uzel Ethereum a Web3.py tak, aby komunikovaly pomocí stejného protokolu, např. IPC v tomto diagramu.
Jakmile je Web3.py správně nakonfigurováno, můžeš začít interagovat s blockchainem. Zde je několik příkladů použití Web3.py jako ukázka toho, co přijde:
1# čtení dat bloku:2w3.eth.get_block('latest')34# odeslání transakce:5w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...})Instalace
V tomto návodu budeme pracovat pouze v interpretu Pythonu. Nebudeme vytvářet žádné adresáře, soubory, třídy ani funkce.
$ určeny ke spuštění v terminálu. (Znak $ nepiš, označuje pouze začátek řádku.)Nejprve si nainstaluj IPython (opens in a new tab) pro uživatelsky přívětivé prostředí k prozkoumávání. IPython nabízí mimo jiné doplňování pomocí tabulátoru, což výrazně usnadňuje zjištění, co všechno je v Web3.py možné.
pip install ipythonWeb3.py je publikován pod názvem web3. Nainstaluj ho takto:
pip install web3Ještě jedna věc – později budeme simulovat blockchain, což vyžaduje několik dalších závislostí. Můžeš si je nainstalovat pomocí:
pip install 'web3[tester]'Máš všechno připravené a můžeme začít!
Poznámka: Balíček web3[tester] funguje až do Pythonu 3.10.xx
Spuštění sandboxu
Otevři si nové prostředí Python spuštěním ipython v terminálu. Je to srovnatelné se spuštěním python, ale s více vychytávkami.
ipythonTím se vypíší informace o verzích Pythonu a IPythonu, které používáš, a pak bys měl vidět výzvu čekající na zadání:
1In [1]:Právě se díváš na interaktivní Python shell. V podstatě je to sandbox, ve kterém si můžeš hrát. Pokud ses dostal až sem, je čas importovat Web3.py:
1In [1]: from web3 import Web3Představení modulu Web3
Kromě toho, že je modul Web3 (opens in a new tab) bránou do Etherea, nabízí i několik pomocných funkcí. Pojďme si jich pár prozkoumat.
V aplikaci pro Ethereum budeš běžně potřebovat převádět nominální hodnoty měn. Modul Web3 poskytuje pro tento účel několik pomocných metod: from_wei (opens in a new tab) a to_wei (opens in a new tab).
Poznámka: Počítače jsou proslulé tím, že špatně zvládají desetinnou matematiku. Aby se tomu předešlo, vývojáři často ukládají dolarové částky v centech. Například položka s cenou 5,99 $ může být v databázi uložena jako 599.
Podobný vzorec se používá při zpracování transakcí v etheru. Avšak místo dvou desetinných míst má ether 18! Nejmenší nominální hodnota etheru se nazývá wei, takže to je hodnota, která se zadává při odesílání transakcí.
1 ether = 1000000000000000000 wei
1 wei = 0,000000000000000001 etheru
Zkus si převést některé hodnoty do a z wei. Všimni si, že existují názvy pro mnoho nominálních hodnot (opens in a new tab) mezi etherem a wei. Jednou z nejznámějších mezi nimi je gwei, protože se v ní často uvádějí transakční poplatky.
1In [2]: Web3.to_wei(1, 'ether')2Out[2]: 100000000000000000034In [3]: Web3.from_wei(500000000, 'gwei')5Out[3]: Decimal('0.5')Další pomocné metody v modulu Web3 zahrnují převodníky datových formátů (např. toHex (opens in a new tab)), pomocné funkce pro adresy (např. isAddress (opens in a new tab)) a hašovací funkce (např. keccak (opens in a new tab)). Mnohým z nich se budeme věnovat později v této sérii. Chceš-li zobrazit všechny dostupné metody a vlastnosti, využij automatické doplňování v IPythonu zadáním Web3. a dvojitým stisknutím klávesy Tab za tečkou.
Komunikace s chainem
Pomocné metody jsou fajn, ale pojďme se přesunout k blockchainu. Dalším krokem je nakonfigurovat Web3.py pro komunikaci s uzlem Etherea. Zde máme možnost použít providery IPC, HTTP nebo Websocket.
Tudy se nevydáme, ale příklad kompletního pracovního postupu s použitím HTTP Provideru by mohl vypadat asi takto:
- Stáhni si uzel Etherea, např. Geth (opens in a new tab).
- Spusť Geth v jednom okně terminálu a počkej, až se synchronizuje se sítí. Výchozí port HTTP je
8545, ale je konfigurovatelný. - Řekni Web3.py, aby se připojil k uzlu přes HTTP na
localhost:8545.w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545')) - Použij instanci
w3k interakci s uzlem.
I když je to jeden ze „skutečných“ způsobů, jak to udělat, proces synchronizace trvá hodiny a je zbytečný, pokud chceš jen vývojové prostředí. Web3.py pro tento účel zpřístupňuje čtvrtého providera, EthereumTesterProvider. Tento tester provider se připojuje k simulovanému uzlu Etherea s uvolněnými oprávněními a falešnou měnou na hraní.
EthereumTesterProvider se připojuje k simulovanému uzlu a je praktický pro rychlé vytvoření vývojového prostředí.
Tento simulovaný uzel se nazývá eth-tester (opens in a new tab) a nainstalovali jsme si ho jako součást příkazu pip install web3[tester]. Konfigurace Web3.py pro použití tohoto tester providera je tak jednoduchá:
1In [4]: w3 = Web3(Web3.EthereumTesterProvider())Teď jsi připravený surfovat na chainu! Takhle se to neříká. To jsem si právě vymyslel. Pojďme na rychlou prohlídku.
Rychlá prohlídka
Nejdříve ze všeho, kontrola funkčnosti:
1In [5]: w3.is_connected()2Out[5]: TrueJelikož používáme tester providera, není to příliš cenný test, ale pokud selže, je pravděpodobné, že jsi při vytváření instance proměnné w3 něco špatně napsal. Zkontroluj si, že jsi zahrnul vnitřní závorky, tj. Web3.EthereumTesterProvider().
Zastávka č. 1: účty
Pro usnadnění tester provider vytvořil několik účtů a předem je nabil testovacím etherem.
Nejprve se podívejme na seznam těchto účtů:
1In [6]: w3.eth.accounts2Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',3 '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',4 '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...]Pokud tento příkaz spustíš, měl bys vidět seznam deseti řetězců, které začínají 0x. Každý z nich je veřejná adresa a je v některých ohledech analogický číslu běžného účtu. Tuto adresu bys poskytl někomu, kdo by ti chtěl poslat ether.
Jak již bylo zmíněno, tester provider předem nabil každý z těchto účtů testovacím etherem. Pojďme zjistit, kolik je na prvním účtu:
1In [7]: w3.eth.get_balance(w3.eth.accounts[0])2Out[7]: 1000000000000000000000000To je hodně nul! Než se s úsměvem vydáš do falešné banky, vzpomeň si na dřívější lekci o nominálních hodnotách měn. Hodnoty etheru jsou vyjádřeny v nejmenší nominální hodnotě, wei. Převeďme to na ether:
1In [8]: w3.from_wei(1000000000000000000000000, 'ether')2Out[8]: Decimal('1000000')Jeden milion testovacích etherů – to pořád není špatné.
Zastávka č. 2: data bloku
Pojďme se podívat na stav tohoto simulovaného blockchainu:
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})O bloku se vrací spousta informací, ale zde je třeba upozornit jen na pár věcí:
- Číslo bloku je nula – bez ohledu na to, jak dávno jsi nakonfiguroval tester providera. Na rozdíl od skutečné sítě Ethereum, která přidává nový blok každých 12 sekund, tato simulace počká, dokud jí nedáš nějakou práci.
transactionsje prázdný seznam ze stejného důvodu: ještě jsme nic neudělali. Tento první blok je prázdný blok, jen aby se spustil chain.- Všimni si, že
parentHashje jen spousta prázdných bytů. To znamená, že se jedná o první blok v řetězci, známý také jako genesis blok.
Zastávka č. 3: transakce
Zasekli jsme se na bloku nula, dokud nebude čekající transakce, tak mu ji dejme. Pošli pár testovacích etherů z jednoho účtu na druhý:
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})To je obvykle bod, kde bys čekal několik sekund, než se tvá transakce zahrne do nového bloku. Celý proces probíhá nějak takhle:
- Odešli transakci a uschovej si haš transakce. Dokud není vytvořen a odvysílán blok obsahující transakci, transakce je „čekající“.
tx_hash = w3.eth.send_transaction({ …}) - Počkej, až bude transakce zahrnuta do bloku:
w3.eth.wait_for_transaction_receipt(tx_hash) - Pokračuj v logice aplikace. Pro zobrazení úspěšné transakce:
w3.eth.get_transaction(tx_hash)
Naše simulované prostředí přidá transakci do nového bloku okamžitě, takže si transakci můžeme hned prohlédnout:
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})Zobrazit všeZde uvidíš některé známé detaily: pole from, to a value by měla odpovídat vstupům našeho volání send_transaction. Další uklidňující věcí je, že tato transakce byla zahrnuta jako první transakce ('transactionIndex': 0) v bloku číslo 1.
Úspěšnost této transakce můžeme také snadno ověřit kontrolou zůstatků na obou zúčastněných účtech. Tři ethery se měly přesunout z jednoho na druhý.
1In [12]: w3.eth.get_balance(w3.eth.accounts[0])2Out[12]: 99999699997900000000000034In [13]: w3.eth.get_balance(w3.eth.accounts[1])5Out[13]: 1000003000000000000000000To druhé vypadá dobře! Zůstatek se změnil z 1 000 000 na 1 000 003 etherů. Ale co se stalo s prvním účtem? Zdá se, že ztratil o něco více než tři ethery. Bohužel, nic v životě není zadarmo, a používání veřejné sítě Ethereum vyžaduje, abys odměnil ostatní účastníky sítě za jejich podporu. Z účtu, který transakci odeslal, byl odečten malý transakční poplatek – tento poplatek je množství spáleného paliva (21 000 jednotek paliva za převod ETH) vynásobené základním poplatkem, který se liší podle aktivity sítě, plus spropitné, které jde validátorovi, který transakci zahrne do bloku.
Více o palivu
A teď výdech
Už jsme u toho nějakou dobu, takže se zdá, že je to dobré místo na přestávku. Králičí nora pokračuje a my budeme pokračovat v průzkumu v druhé části této série. Některé koncepty, které přijdou: připojení ke skutečnému uzlu, chytré kontrakty a tokeny. Máš další otázky? Dej mi vědět! Tvá zpětná vazba ovlivní, kam se odtud vydáme. Žádosti jsou vítány přes Twitter (opens in a new tab).
Stránka naposledy aktualizována: 6. února 2025


