introduzione
Il Bitcoin viene talvolta definito denaro programmabile. A causa della sua natura digitale, consente agli utenti un ampio grado di flessibilità quando si tratta di stabilire le condizioni su come spendere i fondi.
Parliamo di portafogli e monete quando discutiamo di Bitcoin. Ma potremmo anche pensare ai portafogli come a chiavi, alle monete come assegni e alla blockchain come a una fila dopo l’altra di casseforti chiuse. Ogni cassaforte ha una fessura sottile, in modo tale che chiunque possa depositare assegni o guardare dentro per vedere quanto valore ha la cassaforte. Tuttavia, solo il detentore delle chiavi potrà accedere all'interno.
Quando un possessore di chiavi vuole dare soldi a qualcun altro, apre la sua scatola. Creano un nuovo assegno che fa riferimento a quello più vecchio (che viene poi distrutto) e lo chiudono in una scatola che il destinatario può aprire. Per spenderlo, il nuovo destinatario ripete il processo.
In questo articolo daremo uno sguardo più da vicino a Script, il linguaggio di programmazione interpretato dai nodi della rete Bitcoin. Lo script è ciò che governa il meccanismo di blocco/sblocco menzionato per le casseforti.
Come funziona Bitcoin?
Seguendo la nostra analogia dall'alto, potresti dire che ci sono due parti in ogni transazione: una chiave (per aprire la tua scatola) e un lucchetto. Usi la tua chiave per aprire la scatola che contiene l'assegno che desideri inviare, quindi ne aggiungi una nuova a una nuova scatola con un lucchetto diverso. Per spendere dalla nuova scatola, hai bisogno di un'altra chiave.
Abbastanza semplice. Puoi anche ottenere qualche variazione sui tipi di serrature nel sistema. Forse alcune casseforti richiedono che tu fornisca più chiavi, e forse altre hanno bisogno che tu dimostri di conoscere un segreto. Ci sono un sacco di condizioni che le persone possono impostare.
La nostra chiave è ciò che chiamiamo scriptSig. Il lucchetto è il nostro scriptPubKey. Se osserviamo questi componenti un po’ più in dettaglio, scopriremo che in realtà sono costituiti da bit di dati e blocchi di codice. Se combinati, creano un piccolo programma.
Quando effettui una transazione, stai trasmettendo quella combinazione alla rete. Ogni nodo che lo riceve controllerà il programma, che gli dirà se la transazione è valida. In caso contrario, verrà semplicemente scartato e non sarai in grado di spendere i fondi bloccati.
Gli assegni (monete) in tuo possesso sono chiamati output delle transazioni non spesi (UTXO). I fondi possono essere utilizzati da chiunque sia in grado di fornire la chiave adatta alla serratura. Nello specifico, la chiave è scriptSig e il blocco è scriptPubKey.
Se gli UTXO sono nel tuo portafoglio, probabilmente avranno una condizione secondo cui solo la persona che può dimostrare la proprietà di questa chiave pubblica può sbloccare questi fondi. Per sbloccarlo, fornisci uno scriptSig che include una firma digitale, utilizzando la chiave privata mappata alla chiave pubblica specificata in scriptPubKey. Tutto questo diventerà più chiaro a breve.
Comprendere lo stack Bitcoin
Lo script è ciò che è noto come linguaggio basato su stack. Tutto ciò significa che, quando leggiamo una serie di istruzioni, le posizioniamo in quella che può essere pensata come una colonna verticale. L'elenco A, B, C, ad esempio, risulterebbe in una pila con A in basso e C in alto. Quando le istruzioni ci dicono di fare qualcosa, operiamo su uno o più elementi iniziando dalla cima dello stack.

Gli elementi A, B e C vengono aggiunti e “estratti” dallo stack.
Possiamo distinguere tra i dati (cose come firme, hash e chiavi pubbliche) e le istruzioni (o codici operativi). Le istruzioni rimuovono i dati e fanno qualcosa con essi. Ecco un esempio molto semplice di come potrebbe apparire uno script:
<xyz> <md5 hasher> <d16fb36f0911f878998c136191af705e> <controlla se uguale>
In rosso abbiamo i dati e in blu abbiamo i codici operativi. Leggiamo da sinistra a destra, quindi prima mettiamo nello stack la stringa <xyz>. Il prossimo è l'hasher <md5> codice operativo. Questo non esiste in Bitcoin, ma diciamo che rimuove l'elemento superiore dello stack (<xyz>) e lo esegue l'hashing utilizzando l'algoritmo MD5. Quindi, l'output viene aggiunto nuovamente allo stack. L'output qui sembra essere d16fb36f0911f878998c136191af705e.
Che coincidenza! Il nostro prossimo elemento da aggiungere è <d16fb36f0911f878998c136191af705e>, quindi ora il nostro stack ha due elementi identici. Infine, <check if equal> fa uscire due elementi dall'alto e controlla se sono uguali. Se lo sono, aggiunge <1> allo stack. In caso contrario, aggiunge <0>.
Siamo arrivati alla fine del nostro elenco di istruzioni. Il nostro script avrebbe potuto fallire in due modi: se l'elemento rimanente fosse uno zero o se uno degli operatori ne avesse causato il fallimento quando alcune condizioni non erano soddisfatte. In questo esempio non avevamo operatori di questo tipo e ci ritroveremo con un elemento diverso da zero (<1>), quindi il nostro script era valido. Queste regole valgono anche per le transazioni Bitcoin reali.
Quello era solo un programma inventato. Diamo un'occhiata ad alcuni di quelli reali ora.
Pagamento a Pubkey (P2PK)
Pay-to-Pubkey (P2PK) è incredibilmente semplice. Si tratta di bloccare i fondi su una particolare chiave pubblica. Se volessi ricevere fondi in questo modo, forniresti al mittente la tua chiave pubblica, anziché un indirizzo Bitcoin.
La primissima transazione tra Satoshi Nakamoto e Hal Finney nel 2009 è stata P2PK. La struttura è stata ampiamente utilizzata agli albori di Bitcoin, ma al giorno d'oggi Pay-to-Pubkey-Hash (P2PKH) l'ha ampiamente sostituita.
Lo script di blocco per una transazione P2PK segue il formato <chiave pubblica> OP_CHECKSIG. Abbastanza semplice. Potresti aver intuito che OP_CHECKSIG verifica la presenza di una firma rispetto alla chiave pubblica fornita. Pertanto, il nostro scriptSig sarà un semplice <signature>. Ricorda, scriptSig è la chiave della serratura.

Non potrebbe essere molto più semplice di così. Una firma viene aggiunta allo stack, seguita da una chiave pubblica. OP_CHECKSIG li apre entrambi e verifica la firma rispetto alla chiave pubblica. Se corrispondono, aggiunge un <1> allo stack. Altrimenti aggiunge un <0>.
Per ragioni che approfondiremo nella sezione successiva, P2PK non è più realmente utilizzato.
Pay-to-Pubkey-Hash (P2PKH)
Pay-to-Pubkey-Hash (P2PKH) è ora il tipo di transazione più comune. A meno che tu non stia facendo di tutto per scaricare software arcaico, è probabile che il tuo portafoglio lo faccia per impostazione predefinita.
Lo scriptPubKey in P2PKH è il seguente:
OP_DUP OP_HASH160 <hash chiave pubblica> OP_EQUALVERIFY OP_CHECKSIG
Prima di introdurre scriptSig, analizziamo cosa faranno i nuovi codici operativi:
OP_DUP
OP_DUP apre il primo elemento e lo duplica. Quindi, li aggiunge entrambi allo stack. In genere, questo viene fatto in modo da poter eseguire un'operazione sul duplicato senza alterare l'originale.
OP_HASH160
Questo fa apparire il primo elemento e ne esegue l'hashing due volte. Il primo round eseguirà l'hashing con l'algoritmo SHA-256. L'output SHA-256 viene quindi sottoposto ad hashing con l'algoritmo RIPEMD-160. L'output risultante viene aggiunto nuovamente allo stack.
OP_EQUALVERIFY
OP_EQUALVERIFY combina altri due operatori: OP_EQUAL e OP_VERIFY. OP_EQUAL visualizza due elementi e controlla se sono identici. Se lo sono, aggiunge 1 alla pila. In caso contrario, aggiunge uno 0. OP_VERIFY apre l'elemento in alto e controlla se è vero (cioè diverso da zero). In caso contrario, la transazione fallisce. Combinato, OP_EQUALVERIFY fa sì che la transazione fallisca se i primi due elementi non corrispondono.
Questa volta, lo scriptSig si presenta così:
<firma> <chiave pubblica>
È necessario fornire una firma e la chiave pubblica corrispondente per sbloccare gli output P2PKH.

Puoi vedere cosa sta succedendo nella GIF sopra. Non è molto diverso da uno script P2PK. Stiamo solo aggiungendo un ulteriore passaggio per verificare che la chiave pubblica corrisponda all'hash nello script.
C'è qualcosa da notare, tuttavia. In uno script di blocco P2PKH, la chiave pubblica non è visibile: possiamo solo vedere il suo hash. Se andiamo in un blockchain explorer e osserviamo un output P2PKH che non è stato speso, non possiamo determinare la chiave pubblica. Viene rivelato solo quando il destinatario decide di trasferire i fondi.
Questo ha un paio di vantaggi. Il primo è che l’hash della chiave pubblica è semplicemente più facile da passare rispetto a una chiave pubblica completa. Satoshi lo ha lanciato nel 2009 proprio per questo motivo. L'hash della chiave pubblica è quello che oggi conosciamo come indirizzo Bitcoin.
Il secondo vantaggio è che gli hash di chiave pubblica potrebbero fornire un ulteriore livello di sicurezza contro l’informatica quantistica. Poiché la nostra chiave pubblica non è nota finché non spendiamo i fondi, è ancora più difficile per gli altri calcolare la chiave privata. Per ottenerlo dovrebbero invertire i due cicli di hashing (RIPEMD-160 e SHA-256).
➠ Vuoi iniziare con la criptovaluta? Acquista Bitcoin su Binance!
Pay-to-Script-Hash (P2SH)
Pay-to-Script-Hash (P2SH) è stato uno sviluppo molto interessante per Bitcoin. Consente al mittente di bloccare i fondi sull'hash di uno script: non è necessario che sappia cosa fa effettivamente lo script. Prendi il seguente hash SHA-256:
e145fe9ed5c23aa71fdb443de00c7d9b4a69f8a27a2e4fbb1fe1d0dbfb6583f1
Non è necessario conoscere l’input dell’hash per vincolarvi i fondi. Chi spende, tuttavia, deve fornire lo script utilizzato per eseguirne l'hashing e deve soddisfare le condizioni di tale script.
L'hash precedente è stato creato dal seguente script:
<moltiplica per 2> <4> <controlla se uguale>
Se vuoi spendere le monete legate a quello scriptPubKey, non fornisci solo quei comandi. È inoltre necessario uno scriptSig che renda lo script completato valutato su True. In questo esempio, si tratta di un elemento che <moltiplica per 2> per ottenere un risultato di <4>. Naturalmente, ciò significa che il nostro scriptSig è solo <2>.
Nella vita reale, lo scriptPubKey per un output P2SH è:
OP_HASH160 <redeemScript hash> OP_EQUAL
Nessun nuovo operatore qui. Ma abbiamo <redeemScript hash> come nuovo elemento. Come suggerisce il nome, è un hash dello script che dobbiamo fornire per riscattare i fondi (chiamato redimeScript). Lo scriptSig cambierà a seconda di cosa c'è nel redimeScript. In genere, però, scoprirai che si tratta di una combinazione di firme e chiavi pubbliche allegate, seguite dal redimeScript (obbligatorio):
<firma> <chiave pubblica> <redeemScript>
La nostra valutazione differisce leggermente dall’esecuzione dello stack che abbiamo visto finora. Succede in due parti. Il primo controlla semplicemente che tu abbia fornito l’hash corretto.

Noterai che non facciamo nulla con gli elementi che precedono il riscattoScript. Non sono utilizzati a questo punto. Abbiamo raggiunto la fine di questo mini-programma e l'elemento superiore è diverso da zero. Ciò significa che è valido.
Ma non abbiamo ancora finito. I nodi di rete riconoscono questa struttura come P2SH, quindi hanno effettivamente gli elementi di scriptSig in attesa in un altro stack. È lì che verranno utilizzate la firma e la chiave pubblica.
Finora abbiamo trattato il riscattoScript come un elemento. Ma ora verranno interpretate come istruzioni, che potrebbero essere qualsiasi cosa. Prendiamo l'esempio di uno script di blocco P2PKH, al quale dobbiamo fornire la <firma> e la <chiave pubblica> che corrisponde a un hash della chiave <pubblica> all'interno di <redeemScript>.

Una volta che il tuo riscattoScript è stato espanso, puoi vedere che abbiamo una situazione che assomiglia esattamente a una normale transazione P2PKH. Da lì, eseguilo come faresti con uno normale.
Qui abbiamo dimostrato quello che viene chiamato script P2SH(P2PKH), ma difficilmente ne troverai uno in circolazione. Niente ti impedisce di crearne uno, ma non ti dà alcun vantaggio aggiuntivo e finisce per occupare più spazio in un blocco (e, quindi, costa di più).
P2SH generalmente è utile per cose come transazioni multifirma o compatibili con SegWit. Le transazioni multisig possono avere dimensioni molto grandi poiché potrebbero richiedere più chiavi. Prima dell'implementazione di Pay-to-Script-Hash, un mittente dovrebbe elencare tutte le possibili chiavi pubbliche nel proprio script di blocco.
Ma con P2SH, non importa quanto complesse siano le condizioni di spesa. L'hash del riscattoScript ha sempre una dimensione fissa. I costi vengono quindi trasferiti agli utenti che desiderano sbloccare lo script di blocco.
La compatibilità SegWit è un altro caso in cui P2SH torna utile (entreremo nei dettagli su come differisce la struttura della transazione nella sezione successiva). SegWit era un soft fork che ha comportato una modifica ai formati di blocco/transazione. Poiché si tratta di un aggiornamento opzionale, non tutti i software del portafoglio riconoscono le modifiche. Non importa se i client racchiudono l'hash dello script SegWit in P2SH. Come per tutte le transazioni di questo tipo, non è necessario sapere quale sarà il riscatto di sblocco.
Transazioni SegWit (P2WPKH e P2WSH)
Per un'introduzione più completa a SegWit, consulta A Beginner's Guide to Segregated Witness.
Per comprendere il formato delle transazioni in SegWit, devi solo sapere che non abbiamo più solo uno scriptSig e uno scriptPubKey. Ora abbiamo anche un nuovo campo chiamato testimone. I dati che abbiamo utilizzato per conservare lo scriptSig vengono spostati nel testimone, quindi lo scriptSig è vuoto.
Se ti sei imbattuto in indirizzi che iniziano con "bc1", questi sono quelli che chiamiamo nativi SegWit (in contrapposizione a quelli solo compatibili con SegWit, che iniziano con "3" poiché sono indirizzi P2SH).
Pay-to-Witness-Pubkey-Hash (P2WPKH)
Pay-to-Witness-Pubkey-Hash (P2WPKH) è la versione SegWit di P2PKH. Il nostro testimone si presenta così:
<firma> <chiave pubblica>
Noterai che questo è lo stesso dello scriptSig di P2PKH. Qui, lo scriptSig è vuoto. Nel frattempo, lo scriptPubKey è simile al seguente:
<OP_0> <hash chiave pubblica>
Sembra un po’ strano, vero? Dove sono i codici operativi per permetterci di confrontare la firma, la chiave pubblica e il suo hash?
Non mostriamo operatori aggiuntivi qui, perché i nodi che ricevono la transazione sanno cosa farne in base alla lunghezza dell'hash <chiave pubblica>. Calcoleranno la lunghezza e capiranno che deve essere eseguita nello stesso stile di una buona vecchia transazione P2PKH.
I nodi non aggiornati non sanno come interpretare la transazione in quel modo, ma non importa. Secondo le vecchie regole, non c'è nessun testimone, quindi leggono uno scriptSig vuoto e alcuni dati. Lo valutano e lo contrassegnano come valido: per quanto li riguarda, chiunque potrebbe spendere il risultato. Questo è il motivo per cui SegWit è considerato un soft fork retrocompatibile.
Pay-to-Witness-Script-Hash (P2WSH)
Pay-to-Witness-Script Hash (P2WSH) è il nuovo P2SH. Se sei arrivato fin qui, probabilmente puoi capire come apparirà, ma lo esamineremo comunque. Il nostro testimone è ciò che normalmente inseriremo nello scriptSig. In un P2WSH che racchiude una transazione P2PKH, ad esempio, potrebbe assomigliare a questo:
<firma 1> <chiave pubblica>
Ecco il nostro scriptPubKey:
<OP_0> <script hash>
Valgono le stesse regole. I nodi SegWit leggono la lunghezza dell'hash dello script e determinano che si tratta di un output P2WSH, che viene valutato in modo simile a P2SH. Nel frattempo, i vecchi nodi lo vedono semplicemente come un output che chiunque può spendere.
Pensieri conclusivi
In questo articolo, abbiamo imparato qualcosa sugli elementi costitutivi di Bitcoin. Riassumiamoli velocemente:
Tipo di script | Descrizione |
|---|---|
Pagamento a Pubkey (P2PK) | Blocca i fondi su una particolare chiave pubblica |
Pay-to-Pubkey-Hash (P2PKH) | Blocca i fondi su un particolare hash di chiave pubblica (ad esempio un indirizzo) |
Pay-to-Script-Hash (P2SH) | Blocca i fondi sull'hash di uno script che il destinatario può fornire |
Pay-to-Witness-Pubkey-Hash (P2WPKH) | La versione SegWit di P2PK |
Pay-to-Witness-Script-Hash (P2WSH) | La versione SegWit di P2SH |
Una volta che approfondisci Bitcoin, inizi a capire perché ha così tanto potenziale. Le transazioni possono essere costituite da molti componenti diversi. Manipolando questi elementi costitutivi, gli utenti hanno una grande flessibilità quando si tratta di stabilire le condizioni su come e quando i fondi possono essere spesi.
➠ Domande sulla sceneggiatura? Vai su Ask Academy!



