Vai al contenuto principale

Aiuta ad aggiornare questa pagina

🌏

C'è una nuova versione di questa pagina, ma al momento è solo in inglese. Aiutaci a tradurre l'ultima versione.

Traduci la pagina
Visualizza in inglese

Nessun bug qui!🐛

Questa pagina non è stata tradotta. Per il momento, è stata intenzionalmente lasciata in inglese.

Un'introduzione ad Ethereum per sviluppatori con Python, parte 1

primi passipythonweb3.py
Principiante
✍️Marc Garreau
📚Snake charmers
📆8 settembre 2020
⏱️12 minuti letti

Quindi hai sentito parlare di questo Ethereum e sei pronto ad avventurarti nella tana del coniglio? Questo post coprirà rapidamente alcune basi della blockchain, portandoti a interagire con un nodo simulato di Ethereum: leggere i dati del blocco, verificare i saldi dei conti e inviare transazioni. Lungo il percorso, evidenzieremo le differenze tra metodi tradizionali di costruzione delle app e questo nuovo paradigma decentralizzato.

Prerequisiti (soft)

Questo post aspira ad essere accessibile ad un'ampia gamma di sviluppatori. Tireremo in ballo gli strumenti di Python, ma sono solo un veicolo per le idee - non importa se non sei uno sviluppatore Python. Tuttavia, farò solo alcune premesse sulle basi che dovresti già avere, così da poter passare rapidamente alle parti specifiche di Ethereum.

Premesse:

  • sai muoverti in un terminale,
  • hai scritto qualche riga di codice Python,
  • hai la versione 3.6 o superiore di Python installata nella tua macchina (l'uso di un ambiente virtuale è fortemente consigliato), e
  • hai usato pip, l'installatore di pacchetti di Python. Se alcune di queste premesse non rispondessero alla tua situazione o se non fossi interessato a riprodurre il codice in questo articolo, probabilmente puoi comunque seguirlo senza problemi.

Blockchain, in breve

Ci sono molti modi per descrivere Ethereum, ma il suo fulcro è costituito dalla blockchain. Le blockchain sono composte da una serie di blocchi, quindi iniziamo da qui. In termini più semplici, ogni blocco sulla blockchain di Ethereum è semplicemente una serie di metadati e un elenco di transazioni. In formato JSON, somiglia a qualcosa del genere:

1{
2 "number": 1234567,
3 "hash": "0xabc123...",
4 "parentHash": "0xdef456...",
5 ...,
6 "transactions": [...]
7}
8
📋 Copia

Ogni blocco contiene un riferimento al blocco precedente; il parentHash è semplicemente l'hash del blocco precedente.

Un diagramma raffigurante una blockchain che include i dati in ogni blocco

Una blockchain è fondamentalmente un elenco collegato; ogni blocco si riferisce al precedente.

Questa struttura di dati non è nulla di nuovo, ma le regole (ovvero i protocolli peer-to-peer) che governano la rete lo sono. Non esiste alcuna autorità centrale; la rete di pari deve collaborare per sostenere la rete e competere per decidere quali transazioni includere nel blocco successivo. Quindi, se desideri inviare denaro a un amico, dovrai trasmettere la transazione alla rete, quindi attendere che venga inclusa in un blocco successivo.

L'unico modo per la blockchain di verificare che il denaro sia realmente inviato da un utente all'altro è usare una valuta nativa a quella blockchain (es., creata e governata da essa). In Ethereum, questa valuta è detta ether e la blockchain di Ethereum contiene solo il registro ufficiale dei saldi dei conti.

Un nuovo paradigma

Questa nuova tecnologia decentralizzata ha generato nuovi strumenti per sviluppatori. Questi esistono in molti linguaggi di programmazione, ma per il momento guarderemo attraverso la lente di Python. Per ribadire: anche se Python non è il tuo linguaggio preferito, non dovrebbe esser troppo difficile proseguire.

Gli sviluppatori di Python che desiderano interagire con Ethereum, probabilmente sceglieranno Web3.py. Web3.py è una libreria che semplifica notevolmente la connessione a un nodo di Ethereum e l'invio e la ricezione di dati da esso.

I client di Ethereum sono configurabili per esser raggiungibili da IPC, HTTP, o Websocket, quindi Web3.py dovrà rispecchiare tale configurazione. Web3.py si riferisce a queste opzioni di connessione come provider. Occorre scegliere uno dei tre provider per collegare l'istanza di Web3.py al tuo nodo.

Un diagramma che mostra come web3.py usa IPC per connettere la tua applicazione a un nodo di Ethereum

Configura il nodo di Ethereum e Web3.py per comunicare tramite lo stesso protocollo, ad es. IPC in questo diagramma.

Una volta configurato correttamente Web3.py, puoi iniziare a interagire con la blockchain. Ecco un paio di esempi di utilizzo di Web3.py come anticipazione di ciò che vedremo tra poco:

1# read block data:
2w3.eth.get_block('latest')
3
4# send a transaction:
5w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...})
6
📋 Copia

Installazione

In questa guida, lavoreremo solo all'interno di un interprete Python. Non creeremo cartelle, file, classi o funzioni.

Innanzi tutto, installa IPython per un ambiente user-friendly da esplorare. IPython offre il completamento delle schede, tra le altre funzionalità, facilitando notevolmente la visualizzazione di cosa è possibile in Web3.py.

$ pip install ipython

Web3.py è pubblicato sotto il nome web3. Installalo come segue:

$ pip install web3

Un'altra cosa: più avanti simuleremo una blockchain, il che richiede un paio di altre dipendenze. Puoi installarle tramite:

$ pip install 'web3[tester]'

È tutto pronto per iniziare!

Aprire un sandbox

Apri un nuovo ambiente di Python eseguendo ipyton nel tuo terminale. Ciò è comparabile ad eseguire python, ma con qualche fronzolo in più.

$ ipython

Questo produrrà una serie di informazioni sulle versioni di Python e IPython in uso, poi dovresti vedere una richiesta d'inserimento in attesa:

1In [1]:
2
📋 Copia

Ciò che vedi ora è una shell interattiva di Python. Essenzialmente, è una sandbox in cui giocare. Se sei arrivato fin qui, è il momento di importare Web3.py:

1In [1]: from web3 import Web3
2
📋 Copia

Introduzione al modulo Web3

Oltre all'essere un gateway per Ethereum, il modulo Web3 offre alcune funzioni di convenienza. Esploriamone alcune.

In un'applicazione di Ethereum, normalmente occorre convertire le denominazioni della valuta. Il modulo Web3 fornisce un paio di metodi utili a questo scopo: fromWei e toWei.

Prova a convertire dei valori da e verso wei. Nota che esistono nomi per molte delle denominazioni tra ether e wei. Una delle più note è gwei, spesso utilizzata per rappresentare le commissioni di transazione.

1In [2]: Web3.toWei(1, 'ether')
2Out[2]: 1000000000000000000
3
4In [3]: Web3.fromWei(500000000, 'gwei')
5Out[3]: Decimal('0.5')
6
📋 Copia

Altri metodi d'utilità sul modulo Web3 includono i convertitori di formato dei dati (ad es. toHex), helper di indirizzo (ad es. isAddress) e funzioni di hash (es., keccak). Molti di questi saranno affrontati in seguito nella serie. Per visualizzare tutti i metodi e le proprietà disponibili, usa l'autocompilazione di Python digitando Web3 e premi il tasto tab due volte dopo il punto.

Comunicare con la catena

I metodi di convenienza sono fantastici, ma passiamo alla blockchain. Il prossimo passaggio è configurare Web3.py per comunicare con un nodo di Ethereum. Qui abbiamo l'opzione di usare i provider IPC, HTTP o Websocket.

Non percorreremo questo percorso, ma un esempio di flusso di lavoro completo usando il Provider HTTP potrebbe somigliare a una cosa di questo tipo:

  • Scarica un nodo di Ethereum, ad es. Geth.
  • Avvia Geth in una finestra del terminale e attendi che si sincronizzi alla rete. La porta HTTP predefinita è 8545, ma è configurabile.
  • Dì a Web3.py di connettersi al nodo tramite HTTP, su localhost:8545. w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))
  • Usa l'istanza w3 per interagire con il nodo.

Questo è uno dei modi "reali" per farlo, mentre il processo di sincronizzazione impiega ore e non è necessario se vuoi solo un ambiente di sviluppo. Web3.py espone un quarto provider per questo scopo, l'EthereumTesterProvider. Questo provider di prova si collega a un nodo simulato di Ethereum con autorizzazioni rilassate e valute false con cui giocare.

Un diagramma che mostra l'EthereumTesterProvider collegare la tua applicazione di web3.py a un nodo simulato di Ethereum

L'EthereumTesterProvider si connette a un nodo simulato ed è utile per gli ambienti di sviluppo rapido.

Quel nodo simulato è detto eth-tester e lo abbiamo installato come parte del comando pip install web3[tester]. Configurare Web3.py per usare questo provider di prova è semplicissimo:

1In [4]: w3 = Web3(Web3.EthereumTesterProvider())
2
📋 Copia

Ora sei pronto a navigare sulla catena! In realtà non si dice così, l'ho inventato io sul momento. Facciamo un rapido tour.

Il tour rapido

Per prima cosa, un bel sanity check:

1In [5]: w3.isConnected()
2Out[5]: True
3
📋 Copia

Poiché stiamo usando il provider di prova, non è un test assolutamente indispensabile, ma se dovesse fallire, c'è la possibilità che abbiamo digitato qualcosa di sbagliato istanziando la variabile w3. Ricontrolla di aver incluso le parentesi interne, ad es.Web3.EthereumTesterProvider().

Fermata #1 del tour: conti

Per convenzione, il fornitore del tester ha creato dei conti e li ha precaricati con ether di prova.

In primo luogo, vediamo un elenco di questi conti:

1In [6]: w3.eth.accounts
2Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf',
3 '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF',
4 '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...]
5
📋 Copia

Se esegui questo comando, vedrai un elenco di dieci stringhe che iniziano per 0x. Ognuno è un indirizzo pubblico ed è, in qualche modo, analogo al numero del conto su un conto corrente. Puoi fornire questo indirizzo a chiunque voglia inviarti ether.

Come menzionato, il fornitore del tester ha precaricato ognuno di questi conti con ether di prova. Scopriamo quanto c'è nel primo conto:

1In [7]: w3.eth.get_balance(w3.eth.accounts[0])
2Out[7]: 1000000000000000000000000
3
📋 Copia

Sono molti zeri! Prima di correre alla velocità della luce alla banca finta, ricordati la lezione di poco fa sulle denominazioni della valuta. I valori dell'ether sono rappresentati nella più piccola denominazione, ovvero il wei. Convertila in ether:

1In [8]: w3.fromWei(1000000000000000000000000, 'ether')
2Out[8]: Decimal('1000000')
3
📋 Copia

Un milione di ether di prova, comunque una cifra di tutto rispetto.

Fermata del tour #2: dati del blocco

Diamo una sbirciatina allo stato di questa blockchain simulata:

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})
9
📋 Copia

Vengono restituite molte informazioni su un blocco, ma qui vale la pena di sottolineare solo un paio di cose:

  • Il numero del blocco è zero, non importa quanto tempo fa tu abbia configurato il provider di prova. A differenza della vera rete di Ethereum, che aggiunge un nuovo blocco ogni 12 secondi, questa simulazione attenderà finché non le darai qualcosa da fare.
  • transactions è un elenco vuoto, per lo stesso motivo: non abbiamo ancora fatto nulla. Questo primo blocco è un blocco vuoto, giusto per dare il via alla catena.
  • Nota che il parentHash è solo un mucchio di byte vuoti. Questo significa che è il primo blocco nella catena, anche noto come blocco di genesi.

Fermata #3 del tour: transazioni

Siamo bloccati al blocco zero finché non si verifica una transazione in sospeso, quindi diamogliene una. Invia qualche ether di prova da un conto all'altro:

1In [10]: tx_hash = w3.eth.send_transaction({
2 'from': w3.eth.accounts[0],
3 'to': w3.eth.accounts[1],
4 'value': w3.toWei(3, 'ether'),
5 'gas': 21000
6})
7
📋 Copia

Questo è tipicamente il punto in cui dovresti aspettare diversi secondi affinché la tua transazione sia inclusa in un nuovo blocco. L'intero processo va più o meno come indicato sotto:

  1. Invia una transazione e mantieni l'hash della transazione. Finché il blocco contenente la transazione non viene creato e trasmesso, la transazione è "in sospeso". tx_hash = w3.eth.send_transaction({ … })
  2. Attendi che la transazione sia inclusa in un blocco: w3.eth.wait_for_transaction_receipt(tx_hash)
  3. Prosegui la logica dell'applicazione. Per visualizzare la transazione riuscita: w3.eth.get_transaction(tx_hash)

Il nostro ambiente simulato aggiungerà la transazione in un nuovo blocco istantaneamente, quindi possiamo visualizzare immediatamente la transazione:

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})
11
Mostra tutto
📋 Copia

Vedrai qualche dettaglio familiare qui: i campi from, to e value dovrebbero corrispondere agli input della tua chiamata send_transaction. L'altra parte rassicurante è che questa transazione è stata inclusa come prima transazione ('transactionIndex': 0) nel blocco numero 1.

Possiamo anche verificare facilmente il successo di questa transazione controllando i saldi dei due conti coinvolti. Tre ether dovrebbero essersi spostati dal primo al secondo.

1In [12]: w3.eth.get_balance(w3.eth.accounts[0])
2Out[12]: 999996999999999999969000
3
4In [13]: w3.eth.get_balance(w3.eth.accounts[1])
5Out[13]: 1000003000000000000000000
6
📋 Copia

Quest'ultima parte sembra a posto! Il saldo è passato da 1.000.000 a 1.000.003 ether. Ma cos'è successo al primo conto? Sembra aver perso lievemente di più di tre ether. Ahimè, niente nella vita è gratis e per usare la rete pubblica di Ethereum occorre compensare i tuoi pari per il loro ruolo di supporto. Una piccola commissione di transazione è stata detratta dal conto, rendendo la transazione pari a un importo di 31000 wei.

E respira

Ci siamo soffertmati su questo argomento per un po' di tempo, quindi sembra un buon momento per prendersi una pausa. La tana del coniglio non è finita e continueremo a esplorarla nella seconda parte di questa serie. Tra i prossimi concetti che affronteremo: connettersi a un nodo reale, smart contract e token. Hai domande d'approfondimento? Fammelo sapere! Il tuo feedback influenzerà il contenuto della seconda parte. Le richieste sono benvenute tramite Twitter.

Ultima modifica: , Invalid DateTime
Modifica la pagina

Questa pagina è stata utile?