I Bitcoin vengono gestiti da programmi informatici in grado di sbloccare fondi in cambio di una witness valida. Si chiamano Bitcoin script e codificano le condizioni di spesa che definiscono cosa sia o non sia una witness valida. Ogni transazione si basa su questo meccanismo. Assicurarsi che questo sistema funzioni significa assicurarsi che le transazioni funzionino. Come garantiamo che questi programmi siano corretti, specialmente quando codificano condizioni di spesa complesse? Come possiamo tenere traccia della complessità? Con programmi con una struttura ad albero come Miniscript sono una delle soluzioni a questo problema.
La struttura ad albero è tra le più importanti strutture di dati, ed è rappresentabile come un grafo di nodi connessi da archi. Ciascun nodo è connesso a zero o multipli nodi figli ma a un solo nodo genitore. L’albero “cresce” da uno speciale root node che non ha genitori. Pertanto, prendendo un qualsiasi nodo e osservando i suoi discendenti noteremo un albero più piccolo. In maniera ricorsiva, un albero è a sua volta composto da diversi alberi più piccoli. Ciò significa che se possiamo rappresentare i dati come un albero, possiamo elaborarli tramite algoritmi ricorrenti in grado di scomporli gradualmente. In questo modo possiamo rendere operazioni di analisi dati molto più semplici.
La ricerca di alberi in Bitcoin
Miniscript è un sottoinsieme di Bitcoin Script che impone una struttura ad albero agli script.Tale struttura identifica il ruolo di ciascuna delle sotto-parti dell’albero. Alcune parti richiedono una firma, altre un hash preimage, altre ancora impongono un timelock e alcune combinano diverse parti per dare vita a condizioni più complesse. Osservando la struttura ad albero, è facile intuire il significato di uno script. Ciascuna parte adempie a un ruolo che può essere osservato nell’albero.
Ecco un esempio di Bitcoin script e struttura ad albero di Miniscript (in cima).
Questa struttura additiva sembra essere davvero utile. Le proprietà di uno script possono essere analizzate staticamente e comprovate per induzione spostandosi all’interno dell’albero. È facile dimostrare come uno script ammetta o rigetti una certa witness, oppure sia soggetto a una determinata fee, o ancora che usi più di un certa quantità limite di risorse durante sua esecuzione. È persino possibile combinare due script in uno solo che ne combini la composizione delle condizioni di spesa. Con questo toolkit possiamo codificare condizioni di spesa complesse con la certezza a priori che lo script risultante sia corretto.
Bitcoin Script non ha tutte queste comodità, il che lo rende più complesso e rischioso da usare. Il significato di uno script viene implicitamente definito da un’implementazione in C++. In generale, agli script manca una struttura chiara e di conseguenza risultano difficili da comprendere. Inoltre, i Bitcoin Script da soli non sono nemmeno in grado di effettuare operazioni fondamentali come moltiplicazioni o concatenazioni. Questi ostacoli, come è facile immaginare, rendono difficile la libera codifica delle condizioni di spesa.
Miniscript migliora le funzionalità base di Bitcoin Script imponendo una struttura ad albero agli script. Così facendo, possiamo creare script di piccole dimensioni e ben noti, in grado di codificare chiavi, hash o timelock, al contempo escludendo script esotici ma poco interessanti. Dal momento che Miniscript è essenzialmente un Bitcoin Script su cui viene impostata una struttura predeterminata, esso è già ora utilizzabile senza bisogno di alcun soft fork. Solo i wallet che intendono generare e usare questi script necessitano di essere aggiornati.
Oltre i limiti
Che cosa possiamo fare più di Miniscript, preservandone le stesse proprietà? Come possiamo rendere il sistema più potente senza modificare la sua struttura? Queste domande ci hanno portato a Simplicity, un linguaggio blockchain del tutto nuovo ideato per essere un’alternativa a Bitcoin Script.
I programmi di Simplicity hanno una struttura ad albero: il root node rappresenta il programma nel suo complesso mentre ciascun nodo fa la propria parte nel calcolo. Concretamente, un parent node ha accesso ai calcoli dei propri figli e raggruppa i risultati secondo alcune funzioni. Il processo inizia dalle foglie, dove vengono restituiti valori costanti quali public key o witness data. L’aggregazione continua dal basso verso l’alto fino a quando il risultato complessivo viene calcolato alle radici.
Ecco uno schizzo di un programma di Simplicity che corrisponde allo script Bitcoin dall’alto. È da notare come la sua struttura assomigli a quella ad albero di Miniscript. I veri programmi di Simplicity sono più dettagliati (and, or, key and older consistono di frammenti di programmi più piccoli chiamati combinator), ma se zoomiamo in fuori, vediamo come Simplicity e Miniscript si assomigliano.
Simplicity è abbastanza generico da poter calcolare funzioni booleane arbitrarie. Ciascuna di queste può essere vista come una condizione di spesa, una funzione che accetta o rifiuta una witness. Simplicity può esprimere covenant, deleghe, zero-knowledge proof e molto altro. Questo potere espressivo potrebbe intimidire, ma possiamo sempre effettuare controlli per garantirne la correttezza. Simplicity ha una semantica esplicita, pertanto è facile capire che cosa faccia un determinato programma. Non ci sono sorprese. La struttura ad albero facilita l’analisi statica e di verificarne le proprietà. Siamo in grado di mostrare come un determinato programma sia economico da eseguire e in grado di codificare correttamente una certa condizione di spesa. Praticamente abbiamo a disposizione lo stesso toolkit di Miniscript, ma per un maggior numero di programmi.
Diversamente da Miniscript, Simplicity richiederebbe un soft fork per poter essere utilizzato su Bitcoin. Si troverebbe vicino a Bitcoin Script (Miniscript) in un nuovo tipo di foglia Taproot. Lo step successivo è innanzitutto quello di implementare Simplicity in Elements, la piattaforma open source su cui si basa Liquid, per testare il suo potenziale per Bitcoin. In questo modo sarà possibile anche stabilire il design finale del linguaggio.
Un ponte tra i linguaggi
Stiamo costruendo un ponte tra Miniscript e Simplicity. La struttura ad albero di Miniscript è facile da replicare all’interno di Simplicity. In questo modo possiamo convertire gli script di Bitcoin in programmi Simplicity e far diventare Miniscript un suo sottoinsieme. Potrai creare programmi da script esistenti, controllare se un programma e uno script siano semanticamente equivalenti e infine affinare i tuoi programmi per andare oltre le attuali capacità di Miniscript. Per tutti coloro che hanno già dimestichezza con Miniscript, sarà un’ottima introduzione al mondo di Simplicity. Spiegheremo nel dettaglio questo nuovo ponte in un post dedicato, sempre all’interno della serie.
Il futuro in un albero
I programmi con una struttura ad albero come Miniscript sono facili da leggere e analizzare. Una serie di tool lavora su questi programmi e ci aiuta a garantirne la correttezza. Simplicity sta seguendo queste orme e infatti consente calcoli arbitrari mediante strutture ad albero. È molto più potente di Miniscript ma presenta comunque buone prestazioni grazie alla sua struttura. Le migliori proprietà di Miniscript si ritrovano ora in Simplicity. Il risultato è un linguaggio che trae vantaggio dalla struttura ad albero ma che al contempo consente calcoli arbitrari.
Il nostro futuro in un albero. Stiamo lavorando senza sosta per rendere Simplicity una realtà e convertire Miniscript in Simplicity attraverso un bridge è un ottimo punto di partenza. Seguici per ricevere aggiornamenti su come utilizzarlo!