Transazione P2PKH
Questa guida vuole essere la parte integrativa del video che trovate nel nostro canale Bitcoin In Action. Creeremo una transazione P2PKH utilizzando il nodo Bitcoin con la versione 0.21.0 e analizzeremo come la transazione è validata.
Per rendere le cose più semplici da spiegare, partiremo da una blockchain vuota, quindi prima di lanciare i container, utilizzo il comando ./regtest-delete.sh, e successivamente avvio i container con docker-compose up. Il prossimo passaggio è sarà quello di entrare nel container di hansel, ovvero di un nodo,
1
$ docker exec -ti hansel bash
Copied!
e verificare che la blockchain abbia 0 blocchi, utilizzando il comando:
1
$ bitcoin-cli getblockcount
Copied!
La prima operazione che vado a fare è creare un wallet, con il comando:
1
$ bitcoin-cli createwallet "hansel"
Copied!
Successivamente creo l'address del mittente e l'address del destinatario. Utilizzerò delle variabili d'ambiente per salvare il contenuto.
1
$ ADDR_MITT=$(bitcoin-cli getnewaddress 'mitt' 'legacy')
2
$ ADDR_DEST=$(bitcoin-cli getnewaddress 'dest' 'legacy')
Copied!
In questo momento i miei wallet non hanno nessuna UTXO, ovvero non hanno nessun bitcoin disponibile, quindi mineremo 101 blocchi (in modo tale da soddisfare la COINBASE_MATURITY) utilizzando l'address $ADDR_MITT.
1
$ bitcoin-cli generatetoaddress 101 $ADDR_MITT > /dev/null
Copied!
Adesso ho dei bitcoin a disposizione, o meglio delle UTXO, per visualizzarli posso usare la chiamata listunspent, la quale mi mostra tutte i saldi a disposizione. Utilizzo anche il Json Parser, JQ, per aiutarmi a estrapolare solamente le informazioni necessarie per effettuare la transazione.
Per prima cosa salvo tutta la UTXO all'interno della variabile d'ambiente $UTXO
1
$ UTXO=$(bitcoin-cli listunspent | jq -r .[0])
Copied!
Successivamente creo la transazione utilizzando la chiamata sendtoaddress, utilizzando una fee_rate e decidendo di sottrarre le fees direttamente dall'amount.
1
$ TXID=$(bitcoin-cli -named sendtoaddress address="$ADDR_DEST" amount=$(echo $UTXO | jq -r .amount) fee_rate=25 subtractfeefromamount=true)
Copied!
Adesso possiamo finalmente analizzare la nostra transazione, la quale si troverà nella mempool, e quindi in attesa di essere minata.
Per analizzarla possiamo utilizzare il comando getrawtransaction, e utilizzare la TXID appena ottenuta
1
$ bitcoin-cli getrawtransaction $TXID 2 | jq
Copied!
Nel libro Libro Bitcoin dalla teoria alla pratica e Bitcoin In Action – SegWit, Bitcoin Script e Smart Contracts , spieghiamo byte per byte la transazione. Grazie al nostro docker, è possibile visualizzare la blockchain locale a anche la transazione che è in mempool.
In questo caso la nostra transazione ha come ID 49021cb4a1ebb0c74feaa3a9df2ea7e3e74afeb50df9a630023e8822786add73, inserendola nel campo di ricerca otteniamo un qualcosa di simile:
Come possiamo analizzare lo stack e la sua esecuzione?
Utilizziamo il progetto btcdeb! I vostri parametri potrebbero cambiare, ma se avete seguito alla lettera il tutorial, lanciando questo comando, lo stack si popolerà.
1
$ btcdeb --tx=$(bitcoin-cli getrawtransaction $TXID) --txin=$(bitcoin-cli getrawtransaction $(echo $UTXO | jq -r .txid))
Copied!
Al momento dell'avvio lo stack è vuoto, e premendo e digitando step, si effettua l'operazione successiva.
In questo caso con step, si inserisce prima lo scriptSig, ovvero la firma e successivamente la chiave pubblica compressa.
I vostri valori saranno sicuramente diversi, ma la logica non cambia.
Successivamente abbiamo lo scriptPubKey. Il primo elemento che inseriamo è OP_DUP, che come abbiamo visto nelle precedenti lezioni, duplica l'elemento on top, quindi la nostra chiave pubblica non compressa.
Successivamente, l'operazione che si effettua è HASH160, che ha il compito di prendere l'elemento on top e applicare la funzione crittografica SHA256 e RIPEMD160.
Successivamente si inserisce l'hash della chiave pubblica compressa.
La prossima OP_CODE è OP_EQUALVERIFY, la quale ha il compito di verificare due elementi, e se sono uguale non inserire niente, altrimenti invalida lo stack.
In questo caso sono uguali, e quindi non viene inserito niente e lo stack è ancora valido. Ultimo OP_CODE, OP_CHECKSIG, come è facile intuire, controlla la firma confrontandola utilizzando la chiave pubblica corrispondente.
Se non ricordi come si verifica la firma digitale, guarda questo video.
Le operazioni che si effettuano sono, POP della chiave pubblica, pop della firma, e verifica della firma stessa. Se la verifica va a buon fine, si pusha 1, validando la transazione.
Le operazioni che abbiamo fatto, sono le stesse che abbiamo visto nel video "Come si valida una Transazione P2PKH".
Di seguito è riportata la lavagna utilizzata durante quel video:
Che cosa ci rimane da fare?
Minare!
1
$ bitcoin-cli generatetoaddress 1 $ADDR_MITT
Copied!
A questo punto, utilizzando il nostro explorer, potete analizzare l'ultimo blocco minato, il quale conterrà 2 transazioni, la coinbase e la transazione appena creata.
Copy link