Glossario / Riferimento per sviluppatori
OP_CHECKSIG
- Che cos'è OP_CHECKSIG?
- OP_CHECKSIG prende dalla pila una chiave pubblica e una firma e verifica che la firma copra questa transazione: è il controllo che dimostra davvero che i bitcoin sono tuoi.
Quasi ogni bitcoin mai speso è passato attraverso questo unico opcode, il byte 0xac. Costruisce un digest della transazione in base al byte di sighash incollato in fondo alla firma, controlla la firma con la chiave pubblica e mette sulla pila vero o falso. Se mette falso, la spesa non avviene, ed è tutto ciò che significa possedere bitcoin nel codice.
Come funziona
OP_CHECKSIG estrae due elementi, prima la chiave pubblica e sotto di essa la firma, poi svolge tre compiti distinti che di solito vengono ridotti a uno.
Per prima cosa decide che cosa è stato firmato. L'ultimo byte di una firma non fa parte della firma: è un indicatore che dice quali parti della transazione ha coperto il digest. Il valore di gran lunga più comune è 0x01, che significa tutti gli input e tutti gli output, quindi modificare qualsiasi parte della transazione dopo la firma la invalida. La ricetta per costruire quel digest è stata sostituita due volte, con il BIP-143 per le spese SegWit versione 0 e di nuovo con il BIP-341 per Taproot, entrambe le volte per impedire che il costo dell'hashing crescesse con il quadrato della dimensione della transazione.
In secondo luogo controlla la codifica, e bitcoin è insolitamente severo su questo punto. Una firma legacy deve essere codificata in DER valido, lunga al massimo 72 byte incluso il byte dell'indicatore, con il valore S nella metà inferiore dell'ordine della curva. La regola di codifica rigorosa è arrivata con il BIP-66 a luglio 2015, e il passaggio ha reso orfani sei blocchi in un solo pomeriggio perché diversi grandi pool costruivano su intestazioni di blocco che non avevano validato. Resta la dimostrazione più chiara che il mining e la validazione sono compiti diversi.
In terzo luogo verifica. Le spese legacy e quelle SegWit versione 0 usano ECDSA su secp256k1. Tapscript usa invece una firma Schnorr di 64 byte secondo il BIP-340, richiede che un controllo fallito metta sulla pila un elemento vuoto e non qualsiasi altra cosa, e addebita allo script 50 unità di peso di budget per ogni firma controllata.
Dove lo vedi
OP_CHECKSIG chiude quasi ogni script esistente. Un output legacy termina con esso, una spesa SegWit nativa a chiave singola esegue lo stesso modello con lo stesso opcode finale anche se quei byte non compaiono mai sulla catena, e gli script di commitment di Lightning terminano con esso dopo i rami di timelock e di revoca.
L'eccezione vale la pena di conoscerla quando consulti un block explorer. Una spesa Taproot per percorso di chiave non esegue alcuno script: il nodo controlla una sola firma direttamente con la chiave di 32 byte presente nell'output. Non c'è assembly da mostrare né opcode da indicare, ed è proprio per questo che quel tipo di spesa è il più economico e il più privato disponibile, e che un indirizzo bc1p speso solo dal suo proprietario appare sulla catena identico a qualsiasi altro.
OP_CHECKSIG vs OP_CHECKSIGADD
OP_CHECKSIGADD esiste perché OP_CHECKSIG non può essere contato. In uno script multi-parte devi sapere quante delle firme presentate erano valide, e il vecchio design rispondeva con un unico opcode che inghiottiva in una volta un intero elenco di chiavi e firme. Tapscript lo ha sostituito con un opcode che verifica una firma e ne aggiunge una a un totale progressivo sulla pila, così una policy 2 di 3 diventa una breve sequenza che termina con un confronto con 2. Il cambiamento non è cosmetico: contare una firma alla volta è ciò che permette di verificare le firme Schnorr in batch, e dalla verifica in batch deriva la velocità di validazione di Taproot.