Bitcoin Smart Contract 101
Affronteremo la teoria e la pratica che ci permette di utilizzare il linguaggio Bitcoin Script per creare uno Smart Contract che consegna i suoi bitcoin solo a chi conosce una password.
Last updated
Was this helpful?
Affronteremo la teoria e la pratica che ci permette di utilizzare il linguaggio Bitcoin Script per creare uno Smart Contract che consegna i suoi bitcoin solo a chi conosce una password.
Last updated
Was this helpful?
Il codice Bitcoin Script che scriveremo e', anche se banale, uno Smart Contract!
Entrare in Hansel, eseguire
Prima di procedere siamo costretti ad introdurre tre aspetti fondamentali
i passaggi necessari per sviluppare lo Smart Contract
cosa sono le UTXO
cosa significa PS2H
Paragonare il processo da svolgere per creare ed eseguire uno Smart Contract (SC) Bitcoin al processo di una web app e' arduo, proviamoci!
(SC build/compile) Trasformare il redeem script
Nella sua rappresentazione esadecimale
In Script Hash tramite l'applicazione di SHA256+RIPEMD-160
(SC deploy) Pubblicazione di una transazione che invia bitcoin all'indirizzo (4.3) vincolandoci dei bitcoin.
L'esecuzione dello Smart Contract avviene quando si vuole accedere ai fondi - eg. inviandoli ad un nuovo indirizzo Bitcoin - a lui assegnati: si crea una transazione contenente il sorgente del redeem script assieme ai valori di input e la si invia ai nodi della rete.
Se il sorgente del redeem script presentato per l'esecuzione corrisponde allo Script Hash dal quale e' stato derivato il Bitcoin address, e la sua esecuzione utilizzando i valori di input ha esito positivo, abbiamo a disposizione i bitcoin assegnati allo Smart Contract e possiamo consegnarli ad un altro indirizzo Bitcoin.
Nei passaggi seguenti alterneremo teoria e coding pratico, gli snippet che trovate colorati eseguiteli dentro Hansel o Gretel.
Un concetto, anomalo rispetto ai sistemi di pagamento ai quali siamo abituati, riguarda la gestione del saldo in Bitcoin.
Parlando di pagamenti classici, quando ne riceviamo uno, che sia un bonifico o contante, l'ammontare ricevuto va a sommarsi ad un conto unico al quale abbiamo accesso. Quando dobbiamo inviare denaro preleviamo dal conto unico la quantita' che ci interessa e la consegnamo al beneficiario.
In Bitcoin l'ammontare di un pagamento ricevuto non va ad unirsi ad un conto unico, rimane indipendente, per questo si utilizza il termine UTXO. Quando vogliamo creare un pagamento in Bitcoin, invece che prelevare dal conto, si seleziona una gruppo di UTXO i quali saldi sono sufficienti per colmare il pagamento verso il beneficiario desiderato.
Potenzialmente, ed e' anche prassi diffusa e caldamente consigliata, tutte le volte che ricevete un pagamento potete generare un indirizzo Bitcoin dedicato. Essendo le UTXO visibili pubblicamente sulla blockchain di Bitcoin, la differrenzazione dei beneficiari - anche facenti capo ad una sola entita' - permette di migliorare la privacy finanziaria.
In Bitcoin, nel momento che si crea una UTXO, si deve indicare il beneficiario associandovi un identificativo chiamato Bitcoin address.
Esistono differenti tipologie di Bitcoin address, P2SH e' una di queste.
Il beneficiario di una UTXO P2SH e' un listato di codice Bitcoin Script.
PS2H e' l'acronimo di Pay to Script Hash
Tramite i passaggi che vedremo piu' avanti il codice sorgente dello script viene trasformato in Script Hash e successivamente in Bitcoin address.
Grazie a questo approccio solo chi e' a conoscenza del codice sorgente dello script, e degli eventuali parametri di input, potra' riscattare i bitcoin che hanno come beneficiario tale script.
Dopo aver sottratto con un sotterfugio i bitcoin dalla strega, Hansel decide di bloccare la parte destinata a Gretel utilizzando una password.
Per far questo Hansel crea un address P2SH prevedendo
come parametri di input un unico valore, lo SHA256 della loro parola segreta che risulta essere "fegatini"
come business logic (redeem script) l'esecuzione di un ulteriore SHA256 sul parametro di input e il confronto del risultato con il valore SHA256(SHA256('fegatini')) da lui precalcolato
Solo chi fornisce la giusta password può sbloccare interamente il tesoro!
Riuscirà la nostra Gretel a ricordarsi dei fegatini, sbloccare i bitcoin e vivere felice e contenta con Hansel e suo padre taglialegna a bordo di una LAMBO? 🚘
Abbiamo detto che Hansel vuole realizzare uno script che verifica se e' stato fornito un parametro di input che corrisponde ad un determinato digest.
A grandi linee potremmo rappresentare la funzione che verifica la password cosi'
Il corpo della nostra funzione diventerebbe qualcosa del genere
Il primo doppio SHA256 e' costante quindi possiamo calcolarlo
Il corpo della nostra funzione diventa quindi
per essere piu' concisi potremmo
Come detto in precedenza nel redeem script non dobbiamo descrivere i parametri di input, quindi sara' composto da
OP_SHA256
, il quale ricade nella sezione crypto, ha il compito di effettuare un'operazione di pop (estrazione dello stack), applicare la funzione crittografica SHA256 ed effettuare l'operazione di push (inserimento nello stack) del risultato.
Successivamente abbiamoOP_EQUAL
facente parte delle opcodes di Bitwise logic.
OP_EQUAL
esegue due volte l'operazione di pop. Successivamente esegue l'operazione di push con valore 1 se i valori estratti tramite pop sono uguali oppure 0 se sono diversi.
Salviamolo in una variabile per comodita'
Come descritto poco sopra, la transazione è bloccata da una password che Gretel deve forinire.
con il quale otteniamo 273c25751f15926d6064916b8765461d77a6d525ee3fd25a37b88755c6d4db20
Per una rapida verifica possiamo dare in pasto a btcc redeem script e parametri di input.
Successivamente possiamo verificare tutta l'esecuzione con l'ausilio di btcdeb.
A sinistra vi comparira' una rappresentazione dello script di Hansel, compreso dei parametri di input; sulla destra viene visualizzato lo stack che all'avvio di ogni Smart Contract Bitcoin e' vuoto.
Digitate
step
e premete invio per eseguire lo script un passaggio alla volta!
Per uscire da btcdeb usate la shortcut
CTRL+D
Possiamo usare btcc, questa volta pero' utilizzeremo solo il redeem script senza il parametro di input
otteniamo a820cef813adf3b25b5f92ab0ced01fcbaa5bc6a6cdb64693566ca775f44192799d787
Risultato 0482e32347749e785e203e1c663b190c1db89071
.
Per completare il Bitcoin address bisogna prependere un prefisso e codificare il tutto in Base58Check.
Il prefisso serve ad indicare se operiamo in mainnet o testnet/regtest e che tipo di Bitcoin address stiamo utilizzando.
Il playground opera in regtest, il prefisso che ci interessa e' Testnet script hash che corrisponde al valore esadecimale c4
.
Possiamo svolgere quindi l'encoding utilizzando base58
e finalmente ottenere il nostro indirizzo P2SH!
2Msf5VFsuGZBthnwXvUGxajtJKgiGd5GDQi
Adesso abbiamo bisogno di inviare bitcoin al nostro indirizzo P2SH.
Aprendo http://localhost:8094/regtest/address/2Msf5VFsuGZBthnwXvUGxajtJKgiGd5GDQi possiamo verificare di aver ricevuto UTXO al nostro address.
Aprendo dal blockchain regtest explorer una qualsiasi delle transazioni associate possiamo verificare che lo Script Hash e' quello desiderato ovvero 0482e32347749e785e203e1c663b190c1db89071
Siamo arrivati all'ultimo passaggio! L'esecuzione dello Smart Contract!
Adesso dobbiamo creare una transazione che, fornendo password e redeem script, permette di utilizzare la UTXO associata al P2SH ed invia i bitcoin ad un nuovo indirizzo.
Partiamo con il passaggio semplice, creiamo un indirizzo
Adesso dobbiamo selezionare la transazione, fra tutte quelle ricevute dal nostro indirizzo P2SH, che ha raggiunto la coinbase maturity.
Adesso viene il bello! Dobbiamo costruire una transazione che fa uso di
La UTXO di TXID_WITH_MATURITY
REDEEM_SCRIPT_COMPILED
BENEFICIARIO
A scopo dimostrativo abbiamo predisposto un file bash che svolge i passaggi necessari
L'output del file bash e' la transazione, gia' pronta nel suo formato esadecimale.
Ci viene in soccorso btcdeb!
La transazione da inviare potere recuperarla con
Questo passaggio si puo' fare utilizzando la chiamata RPC sendrawtransaction
oppure tramite http://localhost:8094/regtest/tx/push.
Attualmente la transazione si trova in mempool, possiamo visualizzare la mempool tramite i link qui sulla sinistra.
Per confermare la transazione e farla uscire dalla mempool bastera' minare un blocco.
interpretare l'stdout ed i sorgenti dello script per capire cosa succede