Laborator 2

Tematica laboratorului

Aspecte introductive

Dupa finalizarea migrarii Ethereum de la mecanismul Proof-of-Work (PoW) la mecanismul Proof-of-Stake (PoS) arhitectura unui nod participant in reteaua Ethereum a fost modificata fundamental. In linii mari, spre deosebire de variantele precedente corespondente PoW unde un nod avea de regula o implementare unitara, in cazul suportului pentru PoS un nod participant implica rularea unui client de executie si a unui client de consens.
Clientul de executie pastreaza majoritatea functionalitatilor ce au ramas comune cu versiunile anterioare in operarea retelei: primirea initiala si emiterea tranzactiilor in retea, procesarea acestora, stocarea starii conturilor si executarea operatiilor asupra acestora, si in general ceea ce tine de operarea EVM.
Clientul de consens a preluat functionalitatile de coordonare ce corespund protocolului implementat pentru PoS si comunicarea in retea a unui bloc de tranzactii - tranzactii care sunt pasate pentru verificare individuala catre clientul de executie, existand un canal local de comunicare intre cei doi clienti. Clientul de consens include de regula si o componenta ce poate asigura pentru nod un rol de validator pentru noile blocuri. Acest rol prin analogie poate fi asemanat cu cel de miner din PoW - nodul validator in cauza poate propune un nou bloc si obtine recompense. Rularea si ca validator implica insa din partea nodului respectiv o contributie ca "stake" in Ether, si participarea intr-un protocol mai complex ce implica votul (atestarea) pentru blocurile noi. Mai multe detalii privind mecanismul PoS sunt prezentate in curs.

Scopul acestui laborator este de a oferi o prezentare introductiva a unui client de executie. Rularea locala a unui astfel de client fie individual, fie intr-o mini-retea privata Ethereum, poate fi utila pentru teste si simulari de executie a unor tranzactii, mai apropiate de situatia practica ce exista intr-un mediu real de productie. Layerul de executie functioneaza in esenta independent de protocolul de consens. Este necesara insa confirmarea de noi blocuri pentru a asigura operarea retelei.

Geth (Go-Ethereum) reprezinta una dintre cele mai populare implementari pentru un client de executie Ethereum (conform ethernodes.org). Cea mai simpla varianta de a rula o retea privata de test in prezent folosind Geth este prin intermediul Kurtosis, un orchestrator de servicii construit peste Docker. In cele ce urmeaza vom puncta principalele actiuni implicate in rularea unei retele private bazata pe Geth folosind Kurtosis pe Linux. Alternativ Geth poate fi instalat de sine statator, conform indicatiilor din laboratorul anterior si configurat pentru rulare impreuna cu un client de consens (ex. Lighthouse, Teku, etc).

1. Instalarea Docker si a Kurtosis

Pentru Docker, este in principiu suficienta instalarea pachetelor necesare pentru Docker Engine conform indicatiilor de la aceasta adresa (in particular pasii 1 si 2). Instructiunile pentru instalarea Kurtosis sunt disponibile la aceasta adresa (in particular sectiunea II folosind apt).

2. Rularea unei retele de test bazate pe un nod Geth

Ulterior instalarii Kurtosis rularea unei retele de test se poate face intr-o enclava izolata prin Docker, prin intermediul unui pachet Kurtosis mentinut public pe Github ce foloseste implicit un nod Geth si un client de consens Lighthouse, dupa cum urmeaza:

kurtosis run --enclave [nume enclava] github.com/ethpandaops/ethereum-package

Aceasta rulare va avea afisate in final un numar de servicii pornite printre care si o instanta Geth, identificata in mod obisnuit prin el-1-geth-lighthouse. Consultarea logurilor rularii instantei Geth, pot fi observate prin:

kurtosis service logs [nume enclava] el-1-geth-lighthouse

Accesul la un shell in enclava respectiva pentru comenzi directe asupra instantei Geth se poate face prin:

kurtosis service shell [nume enclava] el-1-geth-lighthouse

3. Crearea unui cont Ethereum nou via Geth

Rularea anterioara a Kurtosis ofera implicit acces la un set de conturi pre-initializate pe reteaua privata creata (care nu sunt accesibile insa direct pe nodul Geth). Conturile respective si cheile privata sunt disponibile la aceasta adresa.
Pentru crearea altor conturi ce vor opera pe blockchain-ul respectiv se poate folosi urmatoarea comanda in shellul deschis pe directorul de date implicit folosit de Geth:

geth --datadir /data/geth/execution-data/ account new --password <(echo $mypassword)

Comanda va genera o pereche cheie publica/privata ce poate fi folosita pentru operarea de tranzactii pe platforma. Cheia publica va fi utilizata pentru a genera o adresa asociata contului. Cheia privata va fi criptata cu o parola specificata in variabila de mypassword definita la nivel de shell (poate fi vida) si va fi retinuta pe disc, in subdirectorul "keystore" din directorul de date al comenzii anterioare.

Public address of the key:   0x9559cc76596beb3eBA56b3389f76C5DD7ECeE797
Path of the secret key file: /data/geth/execution-data/keystore/
UTC--2019-09-29T23-21-07.222169511Z--9559cc76596beb3eba56b3389f76c5dd7ecee797

- You can share your public address with anyone. Others need it to interact with you.
- You must NEVER share the secret key with anyone! The key controls access to your funds!
- You must BACKUP your key file! Without the key, it's impossible to access account funds!
- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!

Afisarea conturilor asociate unui director de date Ethereum se face prin comanda:

geth -datadir /data/geth/execution-data/ account list

O alta varianta ce poate fi utilizata alternativ pentru crearea de conturi este utilitarul clef dedicat pentru operatiile ce implica credentiale, care este integrat in mod obisnuit la instalarea geth, dar nu si disponibil implicit in pachetul Kurtosis de mai sus:

clef newaccount --keystore [cale/director/keystore]

4. Accesarea si interactiunea cu nodul Geth rulat

Urmatoarea comanda executata in shellul Kurtosis ofera acces in mod direct la o consola JavaScript de control a instantei Geth:

geth --datadir /data/geth/execution-data/ attach

Nodul Geth ofera prin o serie de biblioteci, API-uri interne expuse pentru comenzi, precum : eth,web3,admin,net,txpool,debug si altele dar accesul in acest mod direct prin Kurtosis impune de regula restrictii considerabile, precum imposibilitatea de a rula operatii ce necesita semnare, ca initierea unei tranzactii.

API-urile disponibile din aceste biblioteci pentru control la consola unui nod Geth sunt detaliate la urmatoarele adrese:

Cateva exemple de baza functionale in mod direct la consola JavaScript ar fi:

  • Listarea conturilor:
    eth.accounts
  • Verificarea balantei unui cont:
    web3.fromWei(eth.getBalance([adresa cont - ex.: eth.accounts[0]]),"ether")
  • Observarea informatiilor dintr-o tranzactie efectuata:
    eth.getTransaction("[hash-ul tranzactiei]")

Pentru executia unei tranzactii de transfer de fonduri, se poate conecta Metamask la instanta Geth, printr-o noua retea locala (http://127.0.0.1) cu portul RPC mentionat in urma rularii Kurtosis pentru serviciul ce corespunde Geth (el-1-geth-lighthouse). In Metamask se pot importa atat conturile pre-initializate mentionate in sectiunea anterioara, pe baza cheii private, cat si cele create direct pe nodul Geth. Pentru cele create direct pe nodul Geth, este insa necesara extragerea cheii private ce a fost criptata si stocata in directorul keystore pentru fiecare nod. Aceasta se poate face folosind scriptul Python de mai jos dupa instalarea bibliotecii Python web3 (pe sistemul de operare propriu, in shellul Kurtosis acest lucru nu e posibil implicit):

pip install web3

Scriptul Python pentru extragerea cheii unde se presupune ca gethkey este fisierul ce contine cheia criptata din keystore, iar parola folosita a fost una vida:

from web3.auto import w3
with open("gethkey") as keyfile:
  encrypted_key = keyfile.read()
  private_key = w3.eth.account.decrypt(encrypted_key, '')
       
import binascii
print(binascii.b2a_hex(private_key))

Ulterior cheia privata poate fi importata in MetaMask, ceea ce va adauga contul creat pe nodul Geth.

Remix poate fi conectat similar cu un simulator local la instanta Geth folosind aceleasi date ca si in Metamask, dar in acest mod poate fi folosit doar pentru interogarea datelor de pe blockchain sau apeluri fara scriere. Pentru apelurile ce implica tranzactii, Remix poate fi conectat prin Metamask, iar tranzactiile semnate folosind Metamask (ce include cheile private in urma importurilor).

5. Alte variante de operare a unei retele de test

Geth poate fi utilizat si pentru operarea unei retele de test private cu mai multe noduri prin intermediul Kurtosis. Aceasta necesita un fisier explicit de configurare network_params.yaml, in care pot fi specificate mai multe componente/servicii ce pot fi orchestrate la rulare de Kurtosis, un exemplu fiind urmatorul, ce ruleaza doua instante Geth cu Lighthouse pentru consens si un serviciu aditional Dora ce poate fi folosit ca block explorer pentru reteaua creata:

participants:
  - el_type: geth
    cl_type: lighthouse
    count: 2
network_params:
  network_id: "585858"
additional_services:
  - dora

Rularea efectiva se face specificand fisierul respectiv:

kurtosis run --enclave [nume enclava] github.com/ethpandaops/ethereum-package --args-file network_params.yaml

Mai multe optiuni privind configurarile posibile pot fi consultate in pagina Github a pachetului Kurtosis la aceasta adresa.
Accesul la nodurile Geth poate fi facut ulterior similar descrierii de mai sus. Starea blockchain-ului poate fi examinata prin serviciul Dora de tip explorer, in browser local la portul afisat in urma rularii Kurtosis.

Alti clienti de executie, precum Besu, mai suporta moduri bazate pe consens de tip PoW sau PoA pentru retele private de test, ce pot face uneori mai facila o rulare (detalii aici). Utilitatea insa a unei astfel de retele private de test e data de o apropiere cat mai mare de o configuratie reala, Ethereum in prezent folosind PoS, iar Geth fiind printre clientii de executie majoritari.

© 2024 Emanuel Onica. Parts of design by W3Layouts