diff --git a/it/01_0_Introduzione.md b/it/01_0_Introduzione.md new file mode 100644 index 000000000..a1379e988 --- /dev/null +++ b/it/01_0_Introduzione.md @@ -0,0 +1,75 @@ +# Capitolo Uno: Introduzione all'apprendimento di Bitcoin Core (& Lightning) dalla linea di comando +## Introduzione + +Le modalità di pagamento di beni e servizi sono cambiate radicalmente negli ultimi decenni. Mentre un tempo tutte le transazioni venivano effettuate in contanti o con assegni, oggi diversi metodi di pagamento elettronico sono la norma. Tuttavia, la maggior parte di questi pagamenti elettronici avviene ancora attraverso sistemi centralizzati, in cui le società di carte di credito, le banche o persino le istituzioni finanziarie basate su Internet come Paypal conservano lunghi elenchi di transazioni e individui e hanno il potere di censurare le transazioni che non gradiscono. + +Questi rischi di centralizzazione sono stati alcuni dei principali catalizzatori della creazione delle criptovalute, la prima e la più importante delle quali è Bitcoin. Bitcoin offre pseudonimato, rende difficile la correlazione delle transazioni; e rende praticamente impossibile la censura da parte di singole entità. Questi vantaggi l'hanno resa una delle valute con la crescita più rapida al mondo. Questa crescita, a sua volta, ha fatto sì che Bitcoin diventasse d'interesse per imprenditori e sviluppatori, desiderosi di creare nuovi servizi per la comunità Bitcoin. + +Se sei uno di questi imprenditori o sviluppatori, allora questo corso fa per te, perché si tratta di imparare a programmare Bitcoin. È un corso introduttivo che spiega tutte le sfumature e le caratteristiche di Bitcoin. Inoltre, adotta un approccio molto specifico, offrendo lezioni su come lavorare _direttamente_ con Bitcoin Core e con il server c-lightning utilizzando le loro interfacce RPC. (Remote Procedure Call) + +Perché non utilizzare alcune delle librerie più complete presenti in vari linguaggi di programmazione? Perché non crearne una propria da zero? Perché lavorare con le criptovalute è pericoloso. Non ci sono reti di sicurezza. Se accidentalmente pagate commissioni troppo alte o perdete una chiave di firma o create una transazione non valida o commettete una serie di potenziali errori, perderete le vostre monete per sempre. Gran parte della responsabilità ricade ovviamente su di voi come programmatori di criptovalute, ma può essere minimizzata lavorando con le interfacce per criptovalute più robuste, sicure e protette in circolazione, quelle create dagli stessi team di programmazione delle criptovalute: ``bitcoind`` e ``lightningd``. + +Gran parte di questo libro tratta quindi di come eseguire lo script di Bitcoin (e di Lightning) direttamente dalla riga di comando. Alcuni capitoli successivi trattano linguaggi di programmazione più sofisticati, ma continuano a interagire direttamente con i _demoni_ ``bitcoind`` e ``lightningd`` utilizzando RPC o interagendo con i file che creano. In questo modo si può salire sulle spalle dei giganti e utilizzare la loro tecnologia di fiducia per imparare a creare i propri sistemi di fiducia. + +## Livello di competenza richiesto + +Per la maggior parte di questo corso non è necessario essere particolarmente tecnici . Tutto ciò che serve è confidenza con i comandi di base sulla linea di comando UNIX. Se avete familiarità con comandi come `ssh`, `cd` e `ls`, il corso vi fornirà il resto. + +Una parte minoritaria di questo corso richiede conoscenze di programmazione e, se necessario, si consiglia di saltare queste sezioni, come illustrato nella sezione successiva. + +## Panoramica degli argomenti + +A grandi linee, questo libro è suddiviso nelle seguenti sezioni: + +| Part | Description | Skills | +|-------|---------|---------| +| **Parte Uno: Preparazione per Bitcoin** | Comprendere le basi di Bitcoin e configurare un server per l’uso. | Riga di comando | +| **Parte Due: Utilizzo di Bitcoin-CLI** | Utilizzo di Bitcoin-CLI per la creazione di transazioni. | Riga di comando | +| **Parte Tre: Bitcoin Scripting** | Espandere il tuo lavoro su Bitcoin utilizando gli script. | Concetti di programmazione | +| **Parte Quattro: Utilizzo di Tor** | Migliorare la sicurezza del tuo nodo con Tor | Riga di comando | +| **Parte Cinque: Programmazione con RPC** | Accesso a RPC da C e altri linguaggi. | Programmazione in C | +| **Parte Sei: Utilizzo di Lightning-CLI** | Utilizzo di Lightning-CLI per la creazione di transazioni. | Riga di comando | +| **Appendici** | Utilizzo di configurazioni Bitcoin meno comuni. | Riga di comando | + +## Come usare questo corso + +Da dove si comincia? Questo libro è stato pensato per essere letto in sequenza. Basta seguire i link "Cosa c'è dopo?" alla fine di ogni sezione e/o cliccare sui link delle singole sezioni in ogni pagina del capitolo. La migliore comprensione di questo corso si ottiene se si costruisce un server Bitcoin (come da Capitolo 2) e poi si esaminano tutti gli esempi nel corso del libro: provare gli esempi è un'eccellente metodologia di apprendimento. + +Se avete diversi livelli di abilità o volete imparare cose diverse, potete passare a parti diverse del libro: + +* Se si dispone già di un ambiente Bitcoin pronto per essere utilizzato, passa a [Capitolo Tre: Comprendere le Configurazioni di Bitcoin](03_0_Comprendere_le_Configurazioni_di_Bitcoin.md). +* Se vi interessa solo lo scripting di Bitcoin, passate a [Capitolo Nove: Introduzione script di Bitcoin](09_0_Introduzione_script_di_Bitcoin.md). +* Se volete solo leggere dell'uso dei linguaggi di programmazione, saltate a [Capitolo Sedici: Parlare con Bitcoind](16_0_Parlare_con_Bitcoind.md). +* Se invece non volete fare programmazione, saltate assolutamente i capitoli 15-17 durante la lettura e forse anche i capitoli 9-13. Il resto del corso dovrebbe avere senso anche senza di essi. +* Se siete interessati solo a Lightning, fate un salto su [Capitolo dicianove: Comprendere La Configurazione Lightning](19_0_Comprendere_La_Configurazione_Lightning.md). +* Se volete leggere i nuovi contenuti principali aggiunti per la v2 del corso (2020), dopo la v1 (2017), leggete: + [Capitolo 3.5: Comprendere il Descriptor](03_5_Comprendere_il_Descriptor.md) + [Capitolo 4.6: Creare una Transazione Segwit](04_6_Creare_una_Transazione_Segwit.md) + [Capitolo 7: Ampliare le Transazioni Bitcoin con PSBTs](07_0_Ampliare_le_Transazioni_Bitcoin_con_PSBTs.md) + [Capitolo 9.5: Programmare una P2WPKH](09_5_Programmare_una_P2WPKH.md) + [Capitolo 10.5: Programmare uno Script Segwit](10_5_Programmare_uno_Script_Segwit.md) + [Capitolo 14: Usare Tor](14_0_Usare_Tor.md) + [Capitolo 15: Usare i2p](15_0_Usare_i2p.md) + [Capitolo 16: Parlare con Bitcoind](16_0_Parlare_con_Bitcoind.md) + [Capitolo 17: Programmare Bitcoin con Libwally](17_0_Programmare_Bitcoin_con_Libwally.md) + [Capitolo 18: Parlare a Bitcoind in Altri Linguaggi](18_0_Parlare_a_Bitcoind_in_Altri_Linguaggi.md) + [Capitolo 19: Comprendere la Configurazione Lightning](19_0_Comprendere_la_Configurazione_Lightning.md) + e + [Capitolo 20: Usare Lightning](20_0_Usare_Lightning.md) + +## Perché usare questo corso + +Ovviamente, state seguendo questo corso perché siete interessati a Bitcoin. Oltre a fornire le conoscenze di base, ha anche aiutato i lettori a partecipare (o a creare) progetti open-source e a trovare lavoro nella programmazione di Bitcoin. Alcuni stagisti di Blockchain Commons hanno imparato a conoscere Bitcoin grazie a questo corso, così come alcuni membri del nostro team di programmazione. + +## Come sostenere questo corso + +* Si prega di usare [Problemi](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) per qualsiasi domanda. Blockchain Commons non ha un team di supporto attivo e quindi non possiamo rispondere a problemi o domande individuali, ma le esamineremo nel tempo e le utilizzeremo per migliorare le future iterazioni del corso. +* Si prega di utilizzare [PRs](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/pulls) per correggere errori di battitura o comandi errati (o modificati). Per le modifiche tecniche o di riga di comando, è molto utile usare la sezione commenti della PR per spiegare perché si è agito in questo modo, in modo semplificare la comprensione della richiesta senza dover fare ricerche. +* Per favore usa la nostra [Area di discussione della comunità](https://github.com/BlockchainCommons/Community/discussions) per parlare di carriere e competenze. Blockchain Commons offre occasionalmente degli stage, come discusso nel nostro repo della Comunità. +* Per favore [Diventa mecenate](https://github.com/sponsors/BlockchainCommons) se questo corso ti è stato utile o se vuoi contribuire a formare la prossima generazione di programmatori blockchain. + +## Cosa c'è dopo? + +Se desiderate un'introduzione di base a Bitcoin, alla crittografia a chiave pubblica, all'ECC, alle blockchain e a Lightning, leggete il documento [Introduzione a Bitcoin](01_1_Introduzione_a_Bitcoin.md) interludio. + +Altrimenti, se siete pronti a immergervi nel corso, andate su [Configurare Bitcoin-Core VPS](02_0_Configurare_Bitcoin-Core_VPS.md). diff --git a/it/01_1_Introduzione_a_Bitcoin.md b/it/01_1_Introduzione_a_Bitcoin.md new file mode 100644 index 000000000..78ededa5b --- /dev/null +++ b/it/01_1_Introduzione_a_Bitcoin.md @@ -0,0 +1,148 @@ +# Interludio: Introduzione a Bitcoin + +Prima di iniziare a programmare Bitcoin (e Lightning), è necessario avere una conoscenza di base di cosa sono e come funzionano. Questa sezione fornisce una panoramica. All'interno del documento troverete ulteriori definizioni; questa ha solo lo scopo di gettare le basi. + +## Riguardo a Bitcoin + +Bitcoin è un sistema programmatico che consente il trasferimento della valuta bitcoin. È abilitato da un sistema decentralizzato e peer-to-peer di nodi, che comprendono nodi completi, portafogli e minatori. Lavorando insieme, garantiscono che le transazioni in bitcoin siano veloci e non ripudiabili. Grazie alla natura decentralizzata del sistema, queste transazioni sono anche resistenti alla censura e, se ben utilizzate, possono offrire altri vantaggi come la pseudonimia e la non correlazione. + +Ovviamente Bitcoin è il cuore di questo libro, ha dato inizio a molti altri sistemi tra cui la blockchain e Lightning, entrambi sono descritti in dettaglio in questo tutorial. Sono escluse da questo tutorial molte altre criptovalute come Ethereum o Litecoin. + +**_Come vengono trasferite le monete?_** La valuta Bitcoin non è costituita da monete fisiche. È una serie infinita di riassegnazioni di proprietà. Quando una persona invia monete a un'altra, il trasferimento viene memorizzato come una transazione. È la transazione che registra effettivamente la proprietà del denaro, non un token locale nel portafoglio del proprietario o nel suo computer. + +**_A chi si possono inviare monete?_** La maggior parte delle transazioni in bitcoin prevede l'invio di monete a singole persone (o almeno a singoli indirizzi Bitcoin). Tuttavia, è possibile utilizzare metodologie più complesse per inviare bitcoin a gruppi di persone o a script. Queste metodologie hanno nomi come P2PKH, multisig e P2SH. + +**_Come sono archiviate le transazioni?_** Le transazioni vengono raggruppate in blocchi di dati più grandi, e poi scritti sul libro mastro della blockchain. Un blocco è costruito in modo tale da non poter essere sostituito o riscritto una volta che diversi blocchi sono stati costruiti sopra (dopo) di esso. Questo è ciò che rende le transazioni in bitcoin non ripudiabili: il libro mastro globale decentralizzato in cui tutto viene registrato è di fatto un database permanente e immutabile. + +Tuttavia, il processo di costruzione di questi blocchi è stocastico: è in qualche modo casuale, quindi non si può mai essere certi che una transazione sarà inserita in un blocco specifico. Teoricamente, e in rarissime circonstanze, potrebbero esseci dei cambiamenti nei blocchi, ma solo se sono _molto_ recenti. Quindi, le transazioni diventano non ripudiabili, permanenti e immutabili dopo pochissimo tempo. + +**_Come sono protette le transazioni?_** I fondi contenuti in una transazione Bitcoin sono bloccati da un puzzle crittografico. Questi puzzle sono progettati in modo da poter essere facilmente risolti dalla persona a cui sono stati inviati i fondi. Ciò avviene grazie alla potenza della crittografia a chiave pubblica. Tecnicamente, una transazione è protetta da una firma che dimostra che si è il proprietario della chiave pubblica a cui è stata inviata la transazione: Il rompicapo crittografico risolto è la prova di proprietà. + +I fondi sono ulteriormente protetti dall'uso degli hash. Le chiavi pubbliche non vengono memorizzate nella blockchain fino a quando i fondi non vengono spesi, ma solo gli hash delle chiavi pubbliche. Ciò significa che anche se dovesse arrivare un computer quantistico, le transazioni Bitcoin rimarrebbero protette da questo secondo livello di crittografia. + +**_Come vengono create le transazioni?_** Il cuore di ogni transazione Bitcoin è un linguaggio di scripting simile a FORTH che viene utilizzato per bloccare la transazione. Per spendere nuovamente il denaro, il destinatario fornisce allo script informazioni specifiche che dimostrano che è il destinatario previsto. + +Tuttavia, questi script Bitcoin rappresentano il livello più basso di funzionalità Bitcoin. Gran parte del lavoro di Bitcoin viene svolto attraverso il _demone_ Bitcoin `bitcoind`, che viene controllato attraverso comandi RPC. Molti inviano questi comandi RPC attraverso il programma `bitcoin-cli`, che fornisce un'interfaccia ancora più semplice. I non programmatori non si preoccupano di queste minuzie, ma utilizzano portafogli già programmati con interfacce più semplici. + +### Bitcoin - In breve + +Si potrebbe pensare a Bitcoin come _una sequenza di transazioni atomiche_. Ogni transazione è autenticata da un mittente con la soluzione di un precedente puzzle crittografico memorizzato come script. La nuova transazione viene bloccata dal destinatario con un nuovo enigma crittografico, anch'esso memorizzato come script. Ogni transazione è registrata in un libro mastro globale immutabile. + +## La crittografia a chiave pubblica + +La crittografia a chiave pubblica è un sistema matematico per proteggere i dati e dimostrarne la proprietà attraverso una coppia asimmetrica di chiavi collegate: la chiave pubblica e la chiave privata. + +È importante per Bitcoin (e per la maggior parte dei sistemi blockchain) perché è la base di gran parte della crittografia che protegge i fondi della criptovaluta. Una transazione Bitcoin viene tipicamente inviata a un indirizzo che è una chiave pubblica con hash. Il destinatario è quindi in grado di recuperare il denaro rivelando sia la chiave pubblica che la chiave privata. + +**_Cos'è una chiave pubblica?_** Una chiave pubblica è la chiave che viene data ad altre persone. In un tipico sistema a chiave pubblica, un utente genera una chiave pubblica e una chiave privata, poi dà la chiave pubblica a tutti. I destinatari possono criptare le informazioni con la chiave pubblica, ma non possono decifrarle con la stessa chiave pubblica a causa dell'asimmetria della coppia di chiavi. + +**_Cos'è una chiave privata?_** Una chiave privata è collegata a una chiave pubblica in una coppia di chiavi. In un tipico sistema a chiave pubblica, un utente tiene al sicuro la propria chiave privata e la usa per decifrare i messaggi che sono stati crittografati con la sua chiave pubblica prima di essergli inviati. + +**_Cos'è una firma?_** Un messaggio (o più comunemente un hash di un messaggio) può essere firmato con una chiave privata, creando una firma. Chiunque possieda la chiave pubblica corrispondente può quindi convalidare la firma, verificando che il firmatario possiede la chiave privata associata alla chiave pubblica in questione. _SegWit_ è un formato specifico per la memorizzazione di una firma sulla rete Bitcoin che incontreremo più avanti. + +**_Cos'è una funzione hash?_** Una funzione di hash è un algoritmo spesso utilizzato nella crittografia. È un modo per mappare una grande quantità arbitraria di dati in una piccola quantità fissa di dati. Le funzioni hash utilizzate in crittografia sono unidirezionali e resistenti alle collisioni, il che significa che un hash può essere collegato in modo affidabile ai dati originali, ma i dati originali non possono essere rigenerati dall'hash. Gli hash consentono quindi la trasmissione di piccole quantità di dati per rappresentare grandi quantità di dati, il che può essere importante per l'efficienza e i requisiti di archiviazione.. + +Bitcoin sfrutta la capacità di un hash di mascherare i dati originali, il che consente di nascondere l'effettiva chiave pubblica dell'utente, rendendo le transazioni resistenti al calcolo quantistico. + +### Crittografia a chiave pubblica - In breve + +Un modo di descrivere la crittografia a chiave pubblica è: _Un modo per proteggere i dati in modo che solo una persona autorizzata possa accedervi e che la persona autorizzata possa dimostrare di avere tale accesso_. + +## Riguardo alle ECC + +ECC è l'acronimo di crittografia a curve ellittiche. È un campo specifico della crittografia a chiave pubblica che dipende da calcoli matematici eseguiti con curve ellittiche definite su campi finiti. È più complessa e più difficile da spiegare rispetto alla crittografia a chiave pubblica classica (che utilizzava numeri primi), ma presenta alcuni vantaggi. + +L'ECC non riceve molta attenzione in questo tutorial. Questo perché il tutorial è incentrato sull'integrazione con i server Bitcoin Core e Lightning, che si sono già occupati della crittografia. In effetti, l'intento di questo tutorial è quello di non farvi preoccupare affatto della crittografia, perché è qualcosa di cui volete _davvero_ che si occupino gli esperti. + +**_Cos'è una curva ellittica?_** Una curva ellittica è una curva geometrica che assume la forma `y``2` = `x``3`` + ax + b`. Una curva ellittica specifica viene scelta selezionando valori specifici di `a` e `b`. La curva deve quindi essere esaminata attentamente per determinare se funziona bene per la crittografia. Ad esempio, la curva secp256k1 utilizzata da Bitcoin è definita come `a=0` e `b=7`. + +Qualsiasi linea che interseca una curva ellittica lo farà in 1 o 3 punti... e questa è la base della crittografia a curva ellittica. + +**_Cosa sono i campi finiti?_** Un campo finito è un insieme finito di numeri, in cui tutte le addizioni, sottrazioni, moltiplicazioni e divisioni sono definite in modo che risultino anche altri numeri nello stesso campo finito. Un modo semplice per creare un campo finito è attraverso l'uso di una funzione modulo. + +**_Come viene definita una curva ellittica su un campo finito?_** Una curva ellittica definita su un campo finito ha tutti i punti sulla sua curva disegnati da uno specifico campo finito. Questo assume la forma: `y``2` `% field-size = (x``3`` + ax + b) % field-size` Il campo finito usato per secp256k1 è `2``256`` - 2``32`` - 2``9`` - 2``8`` - 2``7`` - 2``6`` - 2``4`` - 1`. + +**_Come vengono utilizzate le curve ellittiche in crittografia?_** Nella crittografia a curva ellittica, un utente seleziona un numero molto grande (256 bit) come chiave privata. Quindi aggiunge un punto base impostato sulla curva a se stessa tante volte. (Nel secp256k1, il punto base è `G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8`, che fa precedere le due parti della tupla da uno "04" per indicare che il punto dati è in formato non compresso. Se preferisci una definizione geometrica diretta, questo è il punto "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8") Il numero risultante è la chiave pubblica. È quindi possibile utilizzare varie formule matematiche per dimostrare la proprietà della chiave pubblica, data la chiave privata. Come ogni funzione crittografica, questa è una trappola: è facile passare dalla chiave privata alla chiave pubblica e in gran parte impossibile passare dalla chiave pubblica alla chiave privata. + +Questa particolare metodologia spiega anche perché i campi finiti vengono utilizzati nelle curve ellittiche: garantisce che la chiave privata non diventi troppo grande. Si noti che il campo finito per secp256k1 è leggermente inferiore a 256 bit, il che significa che tutte le chiavi pubbliche saranno lunghe 256 bit, proprio come lo sono le chiavi private. + +**_Quali sono i vantaggi della ECC?_** Il vantaggio principale dell’ECC è che consente la stessa sicurezza della classica crittografia a chiave pubblica con una chiave molto più piccola. Una chiave pubblica a curva ellittica da 256 bit corrisponde a una chiave pubblica tradizionale (RSA) da 3072 bit. + +### ECC - In breve + +Un modo di descrivere la ECC è: _un modo per abilitare la crittografia a chiave pubblica che utilizza chiavi molto piccole e matematiche molto oscure._ + +## Cosa sono le Blockchain + +Blockchain è la generalizzazione della metodologia utilizzata da Bitcoin per creare un registro globale distribuito. Bitcoin è una blockchain come lo sono molte alt-coin, ognuna delle quali vive sulla propria rete e scrive sulla propria catena. Anche le sidechain come Liquid sono blockchain. Le blockchain non hanno nemmeno bisogno di avere nulla a che fare con le finanze. Ad esempio, ci sono state molte discussioni sull’utilizzo delle blockchain per proteggere le identità auto-sovrane. + +Sebbene sia necessario comprendere le basi del funzionamento di una blockchain per capire come funzionano le transazioni in Bitcoin, non sarà necessario andare oltre. Poiché le blockchain sono diventate una vasta categoria di tecnologia, è probabile che questi concetti di base siano applicabili a molti altri progetti in questo settore tecnologico in crescita. I comandi di programmazione appresi in questo libro sono specifici per Bitcoin (e Lightning). + +**_Perché si chiama catena?_** Ogni blocco nella blockchain memorizza un hash del blocco precedente. Questo collega il blocco attuale fino al "blocco genesi" originale attraverso una catena ininterrotta. È un modo per creare un ordine assoluto tra dati potenzialmente contrastanti. Ciò fornisce anche la sicurezza della blockchain, poiché ogni blocco è impilato sopra un vecchio blocco, rendendo più difficile ricreare il vecchio blocco a causa degli algoritmi di prova di lavoro (proof-of-work) utilizzati nella creazione dei blocchi. Una volta che diversi blocchi sono stati costruiti sopra un blocco nella catena, la catena stessa diventa essenzialmente irreversibile. + +**_Cos'è un Fork?_** Occasionalmente vengono creati due blocchi nello stesso periodo. Questo crea temporaneamente un fork di un blocco, dove i blocchi attuali potrebbero essere quelli "reali". Di tanto in tanto, una biFORCazione potrebbe espandersi fino a diventare lunga due blocchi, tre blocchi o anche quattro blocchi, ma abbastanza rapidamente un lato della biforcazione viene determinato come quello reale e l'altro rimane "orfano". Questo fa parte del processo stocastico di creazione dei blocchi e dimostra perché diversi blocchi devono essere costruiti sopra un blocco prima che possa essere considerato veramente affidabile e non ripudiabile. + +### Blockchain — In breve + +Un modo di descrivere la blockchain è: _una serie collegata di blocchi di dati immutabili, che vanno indietro nel tempo. Un altro modo è: _una serie collegata di blocchi per ordinare in modo assoluto i dati che potrebbero essere in conflitto _. + +## La Blockchain è adatta a me? + +Se volete effettuare transazioni in bitcoin, ovviamente la blockchain di Bitcoin fa al caso vostro. Tuttavia, più in generale, la blockchain è diventata una parola popolare, anche se non è una bachetta magica per tutti i problemi tecnici. Detto questo, ci sono molte situazioni specifiche in cui la blockchain è una tecnologia superiore. + +Le blockchain probabilmente saranno utili se: + + * Gli utenti non si fidano l'uno dell'altro. + * Oppure: gli utenti sono oltre diversi confini. + * Gli utenti non si fidano delle autorità centralizzate. + * E: gli utenti vogliono controllare il proprio destino. + * Gli utenti desiderano una tecnologia trasparente. + * Gli utenti vogliono condividere qualcosa. + * E: gli utenti desiderano che ciò che viene condiviso venga registrato in modo permanente. + * Gli utenti desiderano transazioni definitive e veloci. + * Ma: gli utenti non hanno bisogno della definitività immediata della transazione. + +Probabilmente le blockchain _non_ saranno utili se: + + * Gli utenti sono fidati: + * Ad esempio: le transazioni avvengono all'interno di un'azienda o di un'organizzazione. + * Ad esempio: le transazioni sono supervisionate da un'autorità centrale. + * È richiesta la segretezza: + * Ad esempio: le informazioni dovrebbero essere segrete. + * Ad esempio: le transazioni dovrebbero essere segrete. + * Ad esempio: gli operatori dovrebbero essere segreti. + * A meno che: una metodologia per la segretezza crittografica venga attentamente considerata, analizzata e testata. + * Gli utenti necessitano di una transazione definitiva immediata. + * es.: in meno di 10 minuti su una rete tipo Bitcoin, in meno di 2,5 minuti su una rete tipo Litecoin, in meno di 15 secondi su una rete tipo Ethereum + +Tieni presente che potrebbero esserci ancora soluzioni per alcune di queste situazioni all'interno dell'ecosistema Bitcoin. Ad esempio, i canali di pagamento stanno affrontando rapidamente le questioni relative alla liquidità e alla definitività dei pagamenti. + +## Riguardo a Lightning + +Lightning è un protocollo di livello 2 (Layer-2) che interagisce con Bitcoin per consentire agli utenti di scambiare i propri bitcoin "off-chain". Presenta sia vantaggi che svantaggi rispetto all’utilizzo di Bitcoin "on-chain". + +Lightning è anche l'obiettivo secondario di questo tutorial. Anche se si tratta principalmente di interagire direttamente con Bitcoin (e il `bitcoind`), presta una certa attenzione a Lightning perché è una tecnologia imminente che probabilmente diventerà un'alternativa popolare a Bitcoin nel prossimo futuro. Questo libro adotta lo stesso approccio a Lightning e Bitcoin: insegna come interagire direttamente dalla riga di comando con un daemon Lightning affidabile. + +A differenza di Bitcoin, in realtà esistono diverse varianti di Lightning. Questo tutorial utilizza l'implementazione [c-lightning](https://github.com/ElementsProject/lightning) conforme allo standard come server Lightning affidabile. + +**_Che cos'è un protocollo Layer-2?_** Un protocollo Bitcoin di layer-2 funziona su Bitcoin. In questo caso, Lightning funziona un livello sopra Bitcoin interagendo con Bitcoin attraverso contratti intelligenti. + +**_Che cos'è un canale Lightning?_** Un canale Lightning è una connessione tra due utenti Lightning. Ciascuno degli utenti blocca un certo numero di bitcoin sulla blockchain utilizzando entrambi una firma multi-sig. I due utenti possono quindi scambiare bitcoin attraverso il loro canale Lightning senza mai scrivere sulla blockchain di Bitcoin. Solo quando vogliono chiudere il loro canale regolano i conti in bitcoin, in base al conteggio finale delle monete. + +**_Che cos'è la Lightning Network?_** Mettendo insieme una serie di canali Lightning si crea "la rete Lightning". Questo permette a due utenti che non hanno creato un canale tra loro di scambiare bitcoin utilizzando Lightning: il protocollo forma una catena di Canali tra i due utenti, poi scambia le monete attraverso la catena utilizzando transazioni a tempo (time-locked). + +**_Quali sono i vantaggi di Lightning?_** Lightning consente transazioni più veloci con commissioni inferiori. Ciò crea la reale possibilità di micropagamenti in bitcoin. Offre anche una migliore privacy, poiché è off-chain e solo il primo e l'ultimo stato della transazione vengono scritti nell registro immutabile di Bitcoin. + +**_Quali sono gli svantaggi di Lightning?_** Lightning è ancora una tecnologia molto nuova e non è stata testata così approfonditamente come Bitcoin. Non è solo una questione di implementazione tecnologica, ma anche se il design stesso può essere modificato in modi inaspettati. + +### Lightning - In breve + +Un modo di descrivere Lightning è: _un modo per effettuare transazioni bitcoin utilizzando canali off-chain tra coppie di persone, in modo che solo lo stato iniziale e finale debba essere scritto sulla blockchain_. + +## Riepilogo: Presentazione di Bitcoin + +Bitcoin è un sistema peer-to-peer che consente il trasferimento di fondi attraverso transazioni bloccate con enigmi. Questi enigmi dipendono dalla crittografia a curva ellittica a chiave pubblica. Quando generalizzi le idee alla base di Bitcoin, ottieni blockchain, una tecnologia che attualmente sta crescendo e innovando. Quando espandi le idee dietro Bitcoin, ottieni protocolli di livello 2 come Lightning, che espandono il potenziale della valuta. + +## Cosa viene dopo? + +Prosegui nella "Preparatevi per Bitcoin" col [Capitolo 2: Configurare Bitcoin Core VPS](02_0_Configurare_Bitcoin-Core_VPS.md). diff --git a/it/02_0_Configurare_Bitcoin-Core_VPS.md b/it/02_0_Configurare_Bitcoin-Core_VPS.md new file mode 100644 index 000000000..fbfc90170 --- /dev/null +++ b/it/02_0_Configurare_Bitcoin-Core_VPS.md @@ -0,0 +1,26 @@ +# Capitolo Due: Instala Bitcoin-Core VPS + +Per iniziare con Bitcoin, è necessario configurare una macchina per avviare Bitcoin. Gli articoli di questo capitolo descrivono come fare, principalmente utilizzando un VPS (Virtual Private Server, Server Virtuale Privato). + +## Obiettivi di questo capitolo: + +Al finalizzare questo capitolo uno svilupatore potra: + + * Decidere tra le cinque piu importanti tipologie di nodi Bitcoin + * Creare un Nodo Bitcoin per sviluppo + * Creare una blockchain temporanea di Bitcoin in locale + +Gli obiettivi di sostegno includono: + + * Comprendere la configurazione della rete di base del VPS + * Decidere quali priorità di sicurezza implementare + * Comprendere la differenza tra nodi potati e non potati + * Comprendere la differenza tra nodi Mainnet, Testnet e Regtest + * Interpretare le basi del file di configurazione di Bitcoin + +## Indice + +In realtà non c'è bisogno di leggere l'intero capitolo. Decida se si desidera eseguire uno StackScript per impostare un nodo su un VPS Linode (§2.2); oppure si desidera avviare la configurazione in un ambiente diverso, ad esempio su una macchina AWS o su un Mac (Sezione 2.2). Quindi, vada alla sezione appropriata. Ulteriori informazioni sulle configurazioni suggerite sono disponibili anche nell' [Appendice 1](A1_0_Comprendere_Bitcoin_Standup.md). + + * [Capitolo 2.1: Configurando Bitcoin Core VPS con Bitcoin StackScript](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md) + * [Capitolo 2.2: Configurando Bitcoin Core sul proprio hardware con altri mezzi](02_2_Configurare_Bitcoin_Core_Altri_Mezzi.md) diff --git a/it/02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md b/it/02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md new file mode 100644 index 000000000..205593fec --- /dev/null +++ b/it/02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md @@ -0,0 +1,288 @@ +# 2.1: Configurando Bitcoin-Core VPS con StackScript + +Questo documento spiega come configurare un VPS (Virtual Private Sever) per avviare un nodo Bitcoin su Linode.com, installato utilizzando uno StackScript automatizzato del [Progetto Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Devi solo inserire alcuni comandi e avviare il tuo VPS. Quasi subito dopo l'avvio, scoprirai che il tuo nuovo nodo Bitcoin scarica i blocchi. + +> :warning: **Pericolo:** Non utilizzare un VPS per un portafoglio bitcoin con fondi reali significativi; Vedere [Perdere facilmente Bitcoin](http://blog.thestateofme.com/2012/03/03/lessons-to-be-learned-from-the-linode-bitcoin-incident/ ). È molto bello poter sperimentare con transazioni bitcoin reali su un nodo live senza vincolare un server proprio su una rete locale. È anche utile essere in grado di utilizzare un iPhone o un iPad per comunicare tramite SSH con il tuo VPS per svolgere alcune semplici attività bitcoin. Ma è necessario un livello di sicurezza più elevato per fondi significativi. + +* Se vuoi capire l'utilità di questo setup, leggi [Appendice 1: Comprendere Bitcoin Standup.md](A1_0_Comprendere_Bitcoin_Standup.md) mentre procedi con l'installazione. +* Se invece vuole eseguire la configurazione su una macchina diversa da un VPS Linode, come una macchina AWS o un Mac, vai a [Capitolo 2.2: Configurare Bitcoin-Core con altri mezzi](02_2_Configurare_Bitcoin_Core_Altri_Mezzi.md) +* Se hai già un nodo Bitcoin funzionando, vai a [Capitolo 3: Capire le configurazioni di Bitcoin](03_0_Comprendere_la_Configurazione_di_Bitcoin.md). + + +## Iniziare con Linode + +Linode è un servizio di Cloud Hosting che offre server Linux veloci ed economici con archiviazione SSD. Li usiamo per questo tutorial principalmente perché i loro StackScripts basati su BASH offrono un modo semplice per configurare automaticamente un nodo Bitcoin senza problemi. + +### Configurando un account Linode + +Vai a questo link per creare un account Linode: + +``` +https://www.linode.com +``` + +Se preferisci, il seguente codice di riferimento ti darà circa un mese di utilizzo gratuito, ottimo per imparare Bitcoin: +Dovrai fornire un indirizzo email e successivamente precaricare denaro da una carta di credito o PayPal per eventuali costi futuri. + +``` +https://www.linode.com/?r=23211828bc517e2cb36e0ca81b91cc8c0e1b2d96 +``` + +Quando avrai finito, dovresti arrivare a [https://cloud.linode.com/dashboard](https://cloud.linode.com/dashboard). + +### Considera abilitare la autenticazione a 2 fattori (Two-Factor Authentication) + +Il tuo server non sara al sicuro se le persone riescono ad accedere al tuo account Linode, quindi valuta la possibilità di impostare l'autenticazione a due fattori per questo. Puoi trovare questa impostazione nella tua pagina [Il mio profilo: password e autenticazione](https://manager.linode.com/profile/auth). Se non lo fai adesso, imposta un promemoria e fallo più tardi. + +## Crea una immmagine Linode utilizando StackScript + +### Carica lo StackScript + +Scarica [Linode Standup Script](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) da [Bitcoin Standup Scripts repo](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Questo script sostanzialmente automatizza tutte le istruzioni di configurazione di Bitcoin VPS. Se vuoi essere particolarmente prudente, leggilo attentamente. Se sei soddisfatto, puoi copiare StackScript nel tuo account andando alla [pagina StackScripts](https://cloud.linode.com/stackscripts?type=account) nel tuo account Linode account e scegliere [Crea Nuovo Stackscript](https://cloud.linode.com/stackscripts/create). Dategli un nome (noi usiamo `Bitcoin Standup`), poi copia e incolla lo script. Scegli Debian 10 come immagine di destinazione e "Salva".. + +### Configurazione iniziale + +Ora sei pronto per creare un Nodo basato su Stackscript. + +1. Nella pagina [Stackscripts page](https://cloud.linode.com/stackscripts?type=account), clicca i tre puntini "..." nella parte destra del tuo nuovo script e seleziona "Deploy New Linode". +2. Inserisci un nome host breve e attinente + * **Nome host breve.** Scegli un nome per il tuo VPS. Ad esempio, "mybtctest". + * **Nome host completo.** Se hai intenzione di includere questo VPS come parte di una rete con record DNS completi, digita il nome host con il suo dominio. Ad esempio, "mybtctest.mydomain.com". Altrimenti, ripeti semplicemente il nome host breve e aggiungi ".local", ad esempio "mybtctest.local". +3. Immettere la password per l'utente "standup". + +4. Scegli un tipo di installazione nelle opzioni avanzate. +* **Tipo di installazione.** Probabilmente è "Mainnet" o "Pruned Mainnet" se stai impostando un nodo per l'utilizzo e "Testnet" o "Pruned Testnet" se stai solo giocando. La maggior parte di questo tutorial darà per scontato che tu abbia scelto "Pruned Testnet", ma dovresti comunque essere in grado di seguire altri tipi. Consulta la [Sinossi](#sinossi-tipi-di-installazione-di-bitcoin) per maggiori informazioni su queste opzioni. (Nota che se hai intenzione di provare i capitoli Lightning, probabilmente vorrai usare un nodo Unpruned, non potato, poiché lavorare con nodi Pruned su Lightning è incerto. Consulta [Capitolo 19](19_0_Comprendere_La_Configurazione_Lightning.md) per i dettagli.) + + + + +* **Chiave pubblica X25519.** Questa è una chiave pubblica da aggiungere all'elenco dei client autorizzati di Tor. Se non la usi, chiunque ottenga il codice QR per il tuo nodo può accedervi. Otterrai questa chiave pubblica da qualsiasi client tu stia utilizzando per connetterti al tuo nodo. Ad esempio, se utilizzi [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2), puoi andare alle sue impostazioni e "Esporta chiave pubblica di autenticazione Tor V3" per utilizzarla qui. +* **Chiave SSH.** Copia qui la chiave SSH del tuo computer locale; questo ti consente di accedere automaticamente tramite SSH all'account standup. Se non hai ancora impostato una chiave SSH sul tuo computer locale, ci sono delle buone istruzioni su [Github](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/). Potresti anche voler aggiungere la tua chiave SSH nel tuo Linode LISH (Linode Interactive Shell) andando su "Linode Home Page / My Preferences / LISH Settings / LISH Keys". L'utilizzo di una chiave SSH ti darà un modo più semplice e sicuro per accedere al tuo server. +* **IP consentiti tramite SSH.** Questo è un elenco separato da virgole di IP a cui sarà consentito l'accesso tramite SSH al VPS. Ad esempio "192.168.1.15,192.168.1.16". Se non inserisci alcun IP, _il tuo VPS non sarà molto sicuro_. Sarà costantemente bombardato da aggressori che cercheranno di entrare e potrebbero anche riuscirci. + +5. Select an Image + * **Target Image.** If you followed the instructions, this will only allow you to select "Debian 10" (though "Debian 9" did also work with previous versions of this Stackscript and might still). +6. Choose a region for where the Linode will be located. + +*The remaining questions all have to do with the mechanics of the VPS deployment and should be left as they are with one exception: bump the Swap Disk from 256MB to 512MB, to ensure that you have enough memory to download the blockchain._ + +Finally, you'll need to fill in a root password, which will be the password used for the root account. + + + + +5. Seleziona un'immagine +* **Immagine di destinazione.** Se hai seguito le istruzioni, questo ti consentirà di selezionare solo "Debian 10" (anche se "Debian 9" funzionava con le versioni precedenti di questo Stackscript, potrebbe ancora funzionare). +6. Scegli una regione in cui verrà posizionato Linode. + +*Le domande rimanenti riguardano tutte la meccanica della distribuzione VPS e dovrebbero essere lasciate così come sono, con un'eccezione: aumenta lo Swap Disk da 256 MB a 512 MB, per assicurarti di avere abbastanza memoria per scaricare la blockchain._ + +Infine, dovrai inserire una password di root, che sarà la password utilizzata per l'account root. + +### Scegli altre opzioni di Standup + +Blockchain Commons è attualmente impegnata ad ampliare i suoi Bitcoin Standup Scripts con opzioni per installare Lightning e altre app Bitcoin degne di nota. Dai un'occhiata a tutte le opzioni extra e vedi se sono cose con cui ti piacerebbe giocare. In particolare, se Lightning è un'opzione, ti consigliamo di installarla, perché renderà molto più semplici [Capitolo 19](19_0_Comprendere_La_Configurazione_Lightning.md) e [Capitolo 20](20_0_Usare_Lightning.md). + + +### Scegli un piano Linode + +Dovrai scegliere un piano Linode. + +Un Linode da 4 GB sarà sufficiente per la maggior parte delle configurazioni, tra cui: Pruned Mainnet, Pruned Testnet e persino non-Pruned Testnet. Tutte utilizzano meno di 50 GB di spazio di archiviazione e 4 GB sono una quantità di memoria confortevole. Questa è la configurazione che suggeriamo. Costa $ 20 al mese. + +Se invece desideri avere una Mainnet non-Pruned in un VPS, dovrai installare un Linode con un disco superiore a 800 G (!), che attualmente è il Linode da 16 GB, che ha 320 G di spazio di archiviazione e 16 G di memoria e costa circa $ 80 al mese. Noi _non_ lo consigliamo. + +La seguente tabella mostra i requisiti minimi + +| Setup | Memory | Storage | Linnode | +|-------|--------|---------|---------| +| Mainnet | 2G | 280G | Linode 16GB | +| Pruned Mainnet | 2G | ~5G | Linode 4GB | +| Testnet | 2G | ~15G | Linode 4GB | +| Pruned Testnet | 2G | ~5G | Linode 4GB | +| Regtest | 2G | ~ | Linode 4GB | + +Nota, potrebbero esserci modi per ridurre entrambi i costi. + +* Per le macchine che suggeriamo come **Linode 4 GB**, potresti essere in grado di ridurle a un Linode 2 GB. Alcune versioni di Bitcoin Core hanno funzionato bene a quella dimensione, alcune hanno occasionalmente esaurito la memoria e poi si sono riprese, e alcune hanno esaurito continuamente la memoria. Ricordati di aumentare quello spazio di swap per massimizzare le probabilità che funzioni. Usalo a tuo rischio e pericolo. +* Per la Mainnet non potata, che suggeriamo come **Linode 16 GB**, probabilmente puoi cavartela con un Linode 4 GB, ma aggiungi [Block Storage](https://cloud.linode.com/volumes) sufficiente per archiviare la blockchain. Questa è sicuramente una soluzione migliore a lungo termine poiché i requisiti di archiviazione della blockchain Bitcoin aumentano continuamente se non esegui il pruning, mentre i requisiti della CPU non lo fanno (o non lo fanno nella stessa misura). Uno storage da 320 GibiByte costerebbe 32 $ al mese, che combinato con un Linode da 4 GB è di 52 $ al mese, invece di 80 $, e cosa più importante, puoi continuare a farlo crescere. Non documentiamo completamente questa configurazione per due motivi (1) non suggeriamo la configurazione mainnet non potata, e quindi sospettiamo che sia una configurazione molto meno comune; e (2) non abbiamo testato come i volumi Linode si confrontano con i loro SSD intrinseci per prestazioni e utilizzo. Ma c'è una documentazione completa sulla pagina Block Storage. Dovresti configurare Linode, eseguire il suo stackscript, ma poi interromperlo per spostare eccessivamente lo storage blockchain su un volume appena commissionato prima di continuare. + +### Esegui la configurazione finale + +L'ultima cosa che devi fare è inserire una password di root. (Se hai dimenticato qualcosa, te lo diremo ora!) + +Fai clic su "Deploy" per inizializzare i dischi e preparare il tuo VPS. L'intera coda dovrebbe essere eseguita in meno di un minuto. Quando è terminata, dovresti vedere nella "Host Job Queue" i pulsanti verdi "Success" che indicano "Disk Create from StackScript - Setting password for root… done." e "Create Filesystem - 256MB Swap Image". + +Ora potresti voler cambiare il nome del tuo Linode VPS dal predefinito `linodexxxxxxxx`. Vai alla scheda Impostazioni e cambia l'etichetta in modo che sia più utile, come il nome host breve del tuo VPS. Ad esempio, potresti chiamarlo `bitcoin-testnet-pruned` per differenziarlo dagli altri VPS nel tuo account. + +## Accedi al tuo VPS + +Se guardi il tuo pannello di controllo Linode, dovresti vedere il nuovo computer avviarsi. Quando il lavoro avrà raggiunto il 100%, potrai effettuare l'accesso. + +Per prima cosa, ti servirà l'indirizzo IP. Fai clic sulla scheda "Linodes" e dovresti vedere un elenco del tuo VPS, il fatto che sia in esecuzione, il suo "piano", il suo indirizzo IP e altre informazioni. + +Vai alla tua console locale e accedi all'account `standup` utilizzando quell'indirizzo: + + + + +``` +ssh standup@[IP-ADDRESS] +``` + +Per esempio: + +``` +ssh standup@192.168.33.11 +``` + +Se hai configurato il tuo VPS per usare una chiave SSH, l'accesso dovrebbe essere automatico (potrebbe richiedere la tua password SSH per sbloccare la chiave). Se non hai configurato una chiave SSH, dovrai digitare la password user1. + +### Attendi qualche minuto + +Ecco un piccolo trucco: _il tuo StackScript è in esecuzione in questo momento_. Lo script BASH viene eseguito la prima volta che il VPS viene avviato. Ciò significa che il tuo VPS non è ancora pronto. + +Il tempo di esecuzione totale è di circa 10 minuti. Quindi, fai una pausa, prenditi un cafferino rilassati per qualche minuto. Ci sono due parti dello script che richiedono un po' di tempo: l'aggiornamento di tutti i pacchetti Debian e il download del codice Bitcoin. Non dovrebbero richiedere più di 5 minuti ciascuna, il che significa che se torni tra 10 minuti, probabilmente sarai pronto per partire. + +Se sei impaziente puoi andare avanti e digitare `sudo tail -f ~root/standup.log`, che visualizzerà l'avanzamento attuale dell'installazione, come descritto nella sezione successiva. + +## Verifica la tua installazione + +Saprai che stackscrpit è stato eseguito quando la `tail` di `standup.log` dice qualcosa del tipo: + +``` +/root/StackScript - Bitcoin is setup as a service and will automatically start if your VPS reboots and so is Tor +/root/StackScript - You can manually stop Bitcoin with: sudo systemctl stop bitcoind.service +/root/StackScript - You can manually start Bitcoin with: sudo systemctl start bitcoind.service +``` + +A quel punto, la tua directory home dovrebbe apparire così: + +``` +$ ls +bitcoin-0.20.0-x86_64-linux-gnu.tar.gz laanwj-releases.asc SHA256SUMS.asc +``` + +Questi sono i vari file che sono stati utilizzati per installare Bitcoin sul tuo VPS. _Nessuno_ di loro è necessario. Li abbiamo lasciati solo nel caso in cui volessi fare delle verifiche aggiuntive. Altrimenti, puoi eliminarli: + +``` +$ rm * +``` + +Verifica la configurazione di Bitcoin + +Per garantire che la versione di Bitcoin scaricata sia valida, StackScript controlla sia la firma che il checksum SHA. Dovresti verificare che entrambi i test siano tornati corretti: + +``` +$ sudo grep VERIFICATION ~root/standup.log +``` + + +Se vedi qualcosa di simile a quanto segue, tutto dovrebbe andare bene: + +``` +/root/StackScript - VERIFICATION SUCCESS / SIG: gpg: Good signature from "Wladimir J. van der Laan (Bitcoin Core binary release signing key) " [unknown] +/root/StackScript - VERIFICATION SUCCESS / SHA: 35ec10f87b6bc1e44fd9cd1157e5dfa4``` +``` +However, if either of those two checks instead reads "VERIFICATION ERROR", then there's a problem. Since this is all scripted, it's possible that there's just been a minor change that has caused the script's checks not to work right. (This has happened a few times over the existence of the script that became Standup.) But, it's also possible that someone is trying to encourage you to run a fake copy of the Bitcoin daemon. So, _be very sure you know what happened before you make use of Bitcoin!_ + + +Tuttavia, se uno di quei due controlli invece dice "VERIFICATION ERROR", allora c'è un problema. Poiché tutto questo è scritto in uno script, è possibile che ci sia stata solo una piccola modifica che ha causato il malfunzionamento dei controlli dello script. (Questo è successo un paio di volte durante l'esistenza dello script che è diventato Standup.) Ma è anche possibile che qualcuno stia cercando di incoraggiarti a eseguire una copia falsa del Bitcoin daemon. Quindi, _assicurati di sapere cosa è successo prima di usare Bitcoin!_ + +### Leggi i log + +Potresti anche voler leggere tutti i file di log di installazione, per assicurarti che non sia successo nulla di inaspettato durante l'installazione. + +È meglio guardare il file di log standard di StackScript, che contiene tutti gli output, inclusi gli errori: + +`$ sudo more ~root/standup.log` + +Nota che è del tutto normale vedere _alcuni_ errori, in particolare quando si esegue il rumorosissimo software gpg e quando varie cose provano ad accedere al dispositivo inesistente `/dev/tty`. + +Se invece vuoi guardare un set di informazioni più piccolo, tutti gli errori dovrebbero essere in: + +`$ sudo more ~root/standup.err` + +Questo continene ancora una discreta quantità di informazioni che non sono errori, ma è veloce da leggere. + +Se tutto sembra a posto, congratulazioni, hai un nodo Bitcoin funzionante usando Linode! + +## Cosa abbiamo fatto + +Sebbene l'immagine Debian 10 predefinita che stiamo usando per il tuo VPS sia stata modificata da Linode per essere relativamente sicura, il tuo nodo Bitcoin installato tramite Linode StackScript è impostato con un livello di sicurezza ancora più elevato. Potresti trovare questo limitante o non essere in grado di fare le cose che ti aspetti. Ecco alcune note a riguardo: + +### Servizi protetti + +L'installazione del tuo VPS Bitcoin è minima e non consente quasi nessuna comunicazione. Ciò avviene tramite il firewall semplice (`ufw`), che blocca tutto tranne le connessioni SSH. C'è anche un po' di sicurezza aggiuntiva possibile per le tue porte RFC, grazie ai servizi nascosti installati da Tor. + + +**Regolazione di UFW.** Probabilmente dovresti lasciare UFW nella sua fase super protetta! Non vuoi usare una macchina Bitcoin per altri servizi, perché tutti aumentano la tua vulnerabilità! Se decidi diversamente, ci sono diverse [guide a UFW](https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands) che ti permetteranno di aggiungere servizi. Come detto, non è complicato. Ad esempio, aggiungere servizi di posta richiederebbe solo l'apertura della porta di posta: `sudo ufw allow 25`. Ma non farlo. + +**Regolazione di Tor.** Potresti voler proteggere meglio servizi come SSH. Consulta [Capitolo 14: Usare Tor](14_0_Usare_Tor.md) per maggiori informazioni su Tor. + +### Shell protette + +Se hai definito "IP consentiti tramite SSH", l'accesso SSH (e SCP) al server è severamente limitato. `/etc/hosts.deny` non consente a nessuno di effettuare l'accesso. _Non consigliamo di cambiare questo_. `/etc/hosts.allow` consente quindi indirizzi IP specifici. Aggiungi semplicemente altri indirizzi IP in un elenco separato da virgole se hai bisogno di offrire più accesso. + +Ad esempio: + +``` +sshd: 127.0.0.1, 192.128.23.1 +``` + +### Aggiornamenti automatici + +Debian è anche impostato per aggiornarsi automaticamente, per garantire che rimanga al passo con le patch di sicurezza più recenti. + +Se per qualche motivo volessi cambiare questa impostazione (_non lo consigliamo_), puoi fare così: + +``` +echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean false" | debconf-set-selections +``` + +_Se vuoi saperne di più su cosa fa lo stackscript di Bitcoin Standup, consulta [Appendice I: Comprendere Bitcoin Standup](A1_0_Comprendere_Bitcoin_Standup.md)._ + +## Giocare con Bitcoin + +Quindi ora probabilmente vuoi giocare con Bitcoin! + +Ma aspetta, il tuo Bitcoin daemon sta probabilmente ancora scaricando blocchi. `bitcoin-cli getblockcount` ti dirà come stai andando al momento: + +``` +$ bitcoin-cli getblockcount +1771352 +``` + +Se è diverso ogni volta che digiti il comando, devi aspettare prima di lavorare con Bitcoin. Attualmente ci vogliono da 1 a 6 ore per una configurazione ridotta, a seconda della tua macchina. + +Ma una volta che si stabilizza su un numero, sei pronto per continuare! + +Tuttavia, potrebbe essere il momento di qualche altro caffè. Ma presto il tuo sistema sarà pronto per partire e sarai pronto per iniziare a sperimentare. + + + + + +## Riepilogo: Impostazione manuale di un VPS Bitcoin-Core + +Creare un VPS Bitcoin-Core con gli script Standup ha reso l'intero processo rapido, semplice e (si spera) indolore. + +## Cosa c'è dopo? + +Hai alcune opzioni per cosa c'è dopo: + +* Leggi [StackScript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) per comprendere la tua configurazione. +* Leggi cosa fa StackScript in [Appendice 1](A1_0_Comprendere_Bitcoin_Standup.md). +* Scegli una metodologia completamente alternativa in [Capitolo 2.2: Configurare Bitcoin Core Altri Mezzi](02_2_Configurare_Bitcoin_Core_Altri_Mezzi.md). * Passa a "bitcoin-cli" con [Capitolo 3: Comprendere le Configurazioni di Bitcoin](03_0_Comprendere_la_Configurazione_di_Bitcoin.md). + +## Sinossi: Tipi di installazione di Bitcoin + +**Mainnet.** Questo scaricherà l'intera blockchain di Bitnet. Sono 800 G di dati (e aumentano ogni giorno). + +**Pruned Mainnet.** Questo taglierà la blockchain che stai memorizzando fino agli ultimi 550 blocchi. Se non stai estraendo o eseguendo un altro servizio Bitcoin, questo dovrebbe essere più che sufficiente per la convalida. + +**Testnet.** Questo ti dà accesso a una blockchain Bitcoin alternativa in cui i Bitcoin non hanno effettivamente valore. È pensato per la sperimentazione e il test. + +**Pruned Testnet.** Questi sono solo gli ultimi 550 blocchi di Testnet... perché anche la blockchain di Testnet è piuttosto grande ora. + +**Private Regtest.** Questa è la modalità di test di regressione, che ti consente di eseguire un server Bitcoin completamente locale. Permette di effettuare test ancora più approfonditi. Non c'è bisogno di potatura qui, perché si partirà da zero. Questa è una configurazione molto diversa, e quindi è trattata in [Appendice 3](A3_0_Usare_Bitcoin_Regtest.md). diff --git a/it/02_2_Configurare_Bitcoin_Core_Altri_Mezzi.md b/it/02_2_Configurare_Bitcoin_Core_Altri_Mezzi.md new file mode 100644 index 000000000..715f42859 --- /dev/null +++ b/it/02_2_Configurare_Bitcoin_Core_Altri_Mezzi.md @@ -0,0 +1,19 @@ +# 2.2: Impostazione di una macchina Bitcoin-Core tramite altri mezzi + +La sezione precedente, [Capitolo 2.1: Configurare Bitcoin-Core VPS con StackScript](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md), presupponeva che avresti creato un nodo completo su un VPS utilizzando uno Stackscript Linode. Tuttavia, puoi effettivamente installare Bitcoin-Core tramite qualsiasi altra metodologia di tua scelta e continuare a seguire i passaggi successivi di questo tutorial. + +Di seguito sono riportate alcune altre metodologie di configurazione di cui siamo a conoscenza: + +* *[Compilare Bitcoin dal Codice Fonte](A2_0_Compilare_Bitcoin_dal_Codice_Fonte.md).* Se preferisci compilare Bitcoin Core a mano, è trattato nell'Appendice 2. +* *[Usare GordianServer-macOS](https://github.com/BlockchainCommons/GordianServer-macOS).* Se hai un Mac moderno, puoi usare l'app *GordianNode* di Blockchain Commons, basata su *BitcoinStandup*, per installare un nodo completo sul tuo Mac. +* *[Usando altri script Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts).* Blockchain Commons offre anche una versione dello script Linode che hai usato che può essere eseguito dalla riga di comando su qualsiasi macchina Debian o Ubuntu. Questo tende a essere lo script all'avanguardia, il che significa che è più probabile che presenti nuove funzioni, come l'installazione Lightning. +* *[Impostazione di un nodo Bitcoin su AWS](https://wolfmcnally.com/115/developer-notes-setting-up-a-bitcoin-node-on-aws/).* @wolfmcnally ha scritto un tutorial passo dopo passo per l'impostazione di Bitcoin-Core con Amazon Web Services (AWS). +* *[Impostazione di un nodo Bitcoin su un Raspberry Pi 3](https://medium.com/@meeDamian/bitcoin-full-node-on-rbp3-revised-88bb7c8ef1d1).* Damian Mee spiega come impostare un nodo completo headless su un Raspberry Pi 3. + +Assicurati di installare su una versione corrente del tuo sistema operativo, per evitare problemi in futuro. Al momento in cui scrivo, questo corso è stato testato su Debian 11. + +## Cosa c'è dopo? + +A meno che tu non voglia tornare a una delle altre metodologie per creare un nodo Bitcoin-Core, dovresti: + +* Passare a "bitcoin-cli" con [Capitolo 3: Comprendere la Configurazione di Bitcoin](03_0_Comprendere_la_Configurazione_di_Bitcoin.md). diff --git a/it/03_0_Comprendere_la_Configurazione_di_Bitcoin.md b/it/03_0_Comprendere_la_Configurazione_di_Bitcoin.md new file mode 100644 index 000000000..1b27b4da3 --- /dev/null +++ b/it/03_0_Comprendere_la_Configurazione_di_Bitcoin.md @@ -0,0 +1,31 @@ +# Capitolo tre: comprendere la configurazione di Bitcoin + +Ora sei pronto per iniziare a lavorare con l'interfaccia della riga di comando `bitcoin-cli`. Ma ciò richiede prima che tu comprenda la configurazione di Bitcoin e le caratteristiche del suo portafoglio, che è ciò che verrà spiegato in questo capitolo. + +Per questo e per i capitoli futuri, presumiamo che tu abbia un VPS con Bitcoin installato e che esegua `bitcoind`. Presumiamo inoltre che tu sia connesso a testnet, consentendo l'accesso ai bitcoin senza utilizzare fondi reali. Puoi farlo con Bitcoin Standup su Linode.com, secondo [Capitolo2.1: Configurare Bitcoin-Core VPS con StackScript](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md), o tramite altri mezzi, secondo [Capitolo 2.2: Configurare Bitcoin Core Altri Mezzi.md](02_2_Configurare_Bitcoin_Core_Altri_Mezzi.md). + +## Obiettivi di questo capitolo + +Dopo aver letto questo capitolo, uno sviluppatore sarà in grado di: + + * Dimostrare che il loro nodo Bitcoin è installato e aggiornato + * Creare un indirizzo per ricevere fondi Bitcoin + * Utilizzare i comandi di base del portafoglio + * Creare un indirizzo da un descrittore + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere il layout di base dei files di Bitcoin + * Utilizzare i comandi di base + * Comprendere cos'è un indirizzo Bitcoin + * Comprendere cos'è un portafoglio + * Scoprire come importare gli indirizzi + +## Sommario + +* [Capitolo 3.1: Verificare la configurazione Bitcoin](03_1_Verificare_la_configurazione_Bitcoin.md) +* [Capitolo 3.2: Capire la configurazione di Bitcoin](03_2_Capire_la_configurazione_di_Bitcoin.md) +* [Capitolo 3.3: Configurare la wallet](03_3_Configurare_la_wallet.md) + * [Interludio: Utilizzare Variabili nella Linea di Comando](03_3_Intermezzo_Utilizzare_Variabili_nella_Linea_di_Comando.md) +* [Capitolo 3.4: Ricivere una Transazione](03_4_Ricivere_una_Transazione.md) +* [Capitolo 3.5: Comprendere il Descriptor](03_5_Comprendere_il_Descriptor.md) diff --git a/it/03_1_Verificare_la_configurazione_Bitcoin.md b/it/03_1_Verificare_la_configurazione_Bitcoin.md new file mode 100644 index 000000000..bd7950101 --- /dev/null +++ b/it/03_1_Verificare_la_configurazione_Bitcoin.md @@ -0,0 +1,102 @@ +# 3.1: Verificare la configurazione di Bitcoin + +Prima di iniziare a giocare con Bitcoin, dovresti assicurarti che tutto sia impostato correttamente. + +## Crea i tuoi alias + +Suggeriamo di creare alcuni alias per facilitare l'utilizzo di Bitcoin. + +Puoi farlo inserendoli nel tuo `.bash_profile`, `.bashrc` o `.profile`. +``` +cat >> ~/.bash_profile < :book: ***Cos'è l'altezza del blocco?*** L'altezza del blocco è la distanza alla quale un particolare blocco si trova dopo il blocco genesi. L'altezza del blocco corrente è l'altezza del blocco più recente aggiunto alla blockchain. + +Puoi farlo esaminando un blocknet explorer, come [Blockcypher Testnet explorer](https://live.blockcypher.com/btc-testnet/). Il suo numero più recente corrisponde al tuo `getblockcount`? Se è così, sei aggiornato. + +Se desideri un alias per visualizzare tutto in una volta, quanto segue attualmente funziona per Testnet, ma potrebbe scomparire in futuro: + +``` +$ echo "alias btcblock='echo \$(bitcoin-cli -testnet getblockcount)/\$(curl -s https://blockstream.info/testnet/api/blocks/tip/height)'" >> .bash_profile +$ source .bash_profile +$ btcblock +1804372/1804372 +``` +> :link: **TESTNET vs MAINNET:** Ricorda che questo tutorial generalmente presuppone che tu stia utilizzando testnet. Se invece utilizzi la rete principale, puoi recuperare l'altezza del blocco corrente con: `curl -s https://blockchain.info/q/getblockcount`. Puoi sostituire la seconda metà dell'alias `btcblock` (dopo `/\$(`) con quella. + +Se non sei aggiornato, ma il tuo `getblockcount` sta aumentando, nessun problema. Il tempo totale di download può richiedere ancora piu tempo, a seconda della configurazione. + +## Opzionale: conosci i tuoi tipi di server + +> **TESTNET vs MAINNET:** quando configuri il tuo nodo, scegli di crearlo come nodo Mainnet, Testnet o Regtest. Anche se questo documento presuppone una configurazione di testnet, vale la pena capire come accedere e utilizzare gli altri tipi di configurazione, anche tutti sulla stessa macchina! Ma, se sei un utente alle prime armi, salta oltre, poiché non è necessario per una configurazione di base. + +Il tipo di configurazione è controllato principalmente tramite il file ~/.bitcoin/bitcoin.conf. Se stai utilizzando testnet, probabilmente contiene questa riga: +``` +testnet=1 +``` +Se stai eseguendo regtest, probabilmente contiene questa riga: +``` +regtest=1 +``` +Tuttavia, se desideri eseguire diversi tipi di nodi contemporaneamente, dovresti lasciare il flag testnet (o regtest) fuori dal file di configurazione. Puoi quindi scegliere se utilizzare la mainnet, la testnet o il regtest ogni volta che esegui bitcoind o bitcoin-cli. + +Ecco una serie di alias che renderebbero tutto più semplice creando un alias specifico per avviare e arrestare bitcoind, per andare alla directory bitcoin e per eseguire bitcoin-cli, per ciascuna rete principale (che non ha flag aggiuntivi), il testnet (che è -testnet) o il tuo regtest (che è -regtest). +``` +cat >> ~/.bash_profile < :link: **TESTNET vs MAINNET:** Se stai utilizzando mainnet, allora _tutto_ verrà inserito nella directory principale `~/.bitcoin`. Queste varie configurazioni _si impilano_ in modo elegante, quindi se stai utilizzando mainnet, testnet e regtest, scoprirai che `~/.bitcoin` contiene il tuo file di configurazione e i tuoi dati mainnet, la directory `~/.bitcoin/testnet3` contiene i tuoi dati testnet e la directory "~/.bitcoin/regtest" contiene i tuoi dati regtest. + +## Conosci i comandi di Bitcoin-cli + +La maggior parte del tuo lavoro iniziale verrà svolto con il comando "bitcoin-cli", che offre un'interfaccia semplice per "bitcoind". Se desideri maggiori informazioni sul suo utilizzo, eseguilo semplicemente con l'argomento "aiuto". Senza altri argomenti, ti mostra tutti i comandi possibili: + +``` +$ bitcoin-cli help +== Blockchain == +getbestblockhash +getblock "blockhash" ( verbosity ) +getblockchaininfo +getblockcount +getblockfilter "blockhash" ( "filtertype" ) +getblockhash height +getblockheader "blockhash" ( verbose ) +getblockstats hash_or_height ( stats ) +getchaintips +getchaintxstats ( nblocks "blockhash" ) +getdifficulty +getmempoolancestors "txid" ( verbose ) +getmempooldescendants "txid" ( verbose ) +getmempoolentry "txid" +getmempoolinfo +getrawmempool ( verbose ) +gettxout "txid" n ( include_mempool ) +gettxoutproof ["txid",...] ( "blockhash" ) +gettxoutsetinfo +preciousblock "blockhash" +pruneblockchain height +savemempool +scantxoutset "action" ( [scanobjects,...] ) +verifychain ( checklevel nblocks ) +verifytxoutproof "proof" + +== Control == +getmemoryinfo ( "mode" ) +getrpcinfo +help ( "command" ) +logging ( ["include_category",...] ["exclude_category",...] ) +stop +uptime + +== Generating == +generatetoaddress nblocks "address" ( maxtries ) +generatetodescriptor num_blocks "descriptor" ( maxtries ) + +== Mining == +getblocktemplate ( "template_request" ) +getmininginfo +getnetworkhashps ( nblocks height ) +prioritisetransaction "txid" ( dummy ) fee_delta +submitblock "hexdata" ( "dummy" ) +submitheader "hexdata" + +== Network == +addnode "node" "command" +clearbanned +disconnectnode ( "address" nodeid ) +getaddednodeinfo ( "node" ) +getconnectioncount +getnettotals +getnetworkinfo +getnodeaddresses ( count ) +getpeerinfo +listbanned +ping +setban "subnet" "command" ( bantime absolute ) +setnetworkactive state + +== Rawtransactions == +analyzepsbt "psbt" +combinepsbt ["psbt",...] +combinerawtransaction ["hexstring",...] +converttopsbt "hexstring" ( permitsigdata iswitness ) +createpsbt [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime replaceable ) +createrawtransaction [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime replaceable ) +decodepsbt "psbt" +decoderawtransaction "hexstring" ( iswitness ) +decodescript "hexstring" +finalizepsbt "psbt" ( extract ) +fundrawtransaction "hexstring" ( options iswitness ) +getrawtransaction "txid" ( verbose "blockhash" ) +joinpsbts ["psbt",...] +sendrawtransaction "hexstring" ( maxfeerate ) +signrawtransactionwithkey "hexstring" ["privatekey",...] ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +testmempoolaccept ["rawtx",...] ( maxfeerate ) +utxoupdatepsbt "psbt" ( ["",{"desc":"str","range":n or [n,n]},...] ) + +== Util == +createmultisig nrequired ["key",...] ( "address_type" ) +deriveaddresses "descriptor" ( range ) +estimatesmartfee conf_target ( "estimate_mode" ) +getdescriptorinfo "descriptor" +signmessagewithprivkey "privkey" "message" +validateaddress "address" +verifymessage "address" "signature" "message" + +== Wallet == +abandontransaction "txid" +abortrescan +addmultisigaddress nrequired ["key",...] ( "label" "address_type" ) +backupwallet "destination" +bumpfee "txid" ( options ) +createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse ) +dumpprivkey "address" +dumpwallet "filename" +encryptwallet "passphrase" +getaddressesbylabel "label" +getaddressinfo "address" +getbalance ( "dummy" minconf include_watchonly avoid_reuse ) +getbalances +getnewaddress ( "label" "address_type" ) +getrawchangeaddress ( "address_type" ) +getreceivedbyaddress "address" ( minconf ) +getreceivedbylabel "label" ( minconf ) +gettransaction "txid" ( include_watchonly verbose ) +getunconfirmedbalance +getwalletinfo +importaddress "address" ( "label" rescan p2sh ) +importmulti "requests" ( "options" ) +importprivkey "privkey" ( "label" rescan ) +importprunedfunds "rawtransaction" "txoutproof" +importpubkey "pubkey" ( "label" rescan ) +importwallet "filename" +keypoolrefill ( newsize ) +listaddressgroupings +listlabels ( "purpose" ) +listlockunspent +listreceivedbyaddress ( minconf include_empty include_watchonly "address_filter" ) +listreceivedbylabel ( minconf include_empty include_watchonly ) +listsinceblock ( "blockhash" target_confirmations include_watchonly include_removed ) +listtransactions ( "label" count skip include_watchonly ) +listunspent ( minconf maxconf ["address",...] include_unsafe query_options ) +listwalletdir +listwallets +loadwallet "filename" +lockunspent unlock ( [{"txid":"hex","vout":n},...] ) +removeprunedfunds "txid" +rescanblockchain ( start_height stop_height ) +sendmany "" {"address":amount} ( minconf "comment" ["address",...] replaceable conf_target "estimate_mode" ) +sendtoaddress "address" amount ( "comment" "comment_to" subtractfeefromamount replaceable conf_target "estimate_mode" avoid_reuse ) +sethdseed ( newkeypool "seed" ) +setlabel "address" "label" +settxfee amount +setwalletflag "flag" ( value ) +signmessage "address" "message" +signrawtransactionwithwallet "hexstring" ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +unloadwallet ( "wallet_name" ) +walletcreatefundedpsbt [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime options bip32derivs ) +walletlock +walletpassphrase "passphrase" timeout +walletpassphrasechange "oldpassphrase" "newpassphrase" +walletprocesspsbt "psbt" ( sign "sighashtype" bip32derivs ) + +== Zmq == +getzmqnotifications +``` +Puoi anche scrivere `bitcoin-cli help [command]` per maggiori informazioni sul commando specifico. Per esempio: +``` +$ bitcoin-cli help getmininginfo +``` +Restituisce un oggetto json contenente informazioni relative al mining. +Risultato: +``` +{ (json object) + "blocks" : n, (numeric) The current block + "currentblockweight" : n, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled) + "currentblocktx" : n, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled) + "difficulty" : n, (numeric) The current difficulty + "networkhashps" : n, (numeric) The network hashes per second + "pooledtx" : n, (numeric) The size of the mempool + "chain" : "str", (string) current network name (main, test, regtest) + "warnings" : "str" (string) any network and blockchain warnings +} +``` +Esempio: +``` +> bitcoin-cli getmininginfo +> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ +``` +> :book: ***Cos'è RPC?*** `bitcoin-cli` è semplicemente una pratica interfaccia che ti consente di inviare comandi a `bitcoind`. Più specificamente, è un'interfaccia che ti consente di inviare comandi RPC (o Remote Procedure Protocol) a `bitcoind`. Spesso, il comando `bitcoin-cli` e il comando RPC hanno nomi e interfacce identici, ma alcuni comandi `bitcoin-cli` forniscono invece scorciatoie per richieste RPC più complesse. In generale, l'interfaccia `bitcoin-cli` è molto più pulita e semplice rispetto al tentativo di inviare comandi RPC manualmente, utilizzando "curl" o qualche altro metodo. Tuttavia, presenta anche dei limiti su ciò che puoi fare. + +## Opzionale: conoscere le informazioni su Bitcoin + +Una varietà di comandi `bitcoin-cli` può fornirti ulteriori informazioni sui tuoi dati bitcoin. Quelli più generali sono: + +`bitcoin-cli -getinfo` restituisce informazioni da diversi RPCs (user-friendly) + +```diff +$ bitcoin-cli -getinfo + +! Chain: test +Blocks: 1977694 +Headers: 1977694 +Verification progress: 0.9999993275374796 +Difficulty: 1 + ++ Network: in 0, out 8, total 8 +Version: 219900 +Time offset (s): 0 +Proxy: N/A +Min tx relay fee rate (BTC/kvB): 0.00001000 + +@@ Wallet: ""@@ +Keypool size: 1000 +Unlocked until: 0 +Transaction fee rate (-paytxfee) (BTC/kvB): 0.00000000 + +# Balance: 0.02853102 + +- Warnings: unknown new rules activated (versionbit 28) + +``` + +Altri comandi per ottenere informazioni su blockchain, mining, rete, portafoglio ecc. +``` +$ bitcoin-cli getblockchaininfo +$ bitcoin-cli getmininginfo +$ bitcoin-cli getnetworkinfo +$ bitcoin-cli getnettotals +$ bitcoin-cli getwalletinfo +``` +Ad esempio `bitcoin-cli getnetworkinfo` ti fornisce una serie di informazioni sulla tua configurazione e sul suo accesso a varie reti: +``` +$ bitcoin-cli getnetworkinfo +{ + "version": 200000, + "subversion": "/Satoshi:0.20.0/", + "protocolversion": 70015, + "localservices": "0000000000000408", + "localservicesnames": [ + "WITNESS", + "NETWORK_LIMITED" + ], + "localrelay": true, + "timeoffset": 0, + "networkactive": true, + "connections": 10, + "networks": [ + { + "name": "ipv4", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "ipv6", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "onion", + "limited": false, + "reachable": true, + "proxy": "127.0.0.1:9050", + "proxy_randomize_credentials": true + } + ], + "relayfee": 0.00001000, + "incrementalfee": 0.00001000, + "localaddresses": [ + { + "address": "45.79.111.171", + "port": 18333, + "score": 1 + }, + { + "address": "2600:3c01::f03c:92ff:fecc:fdb7", + "port": 18333, + "score": 1 + }, + { + "address": "4wrr3ktm6gl4sojx.onion", + "port": 18333, + "score": 4 + } + ], + "warnings": "Warning: unknown new rules activated (versionbit 28)" +} +``` +Sentiti libero di fare riferimento a uno di questi e di utilizzare `bitcoin-cli help` se desideri maggiori informazioni su cosa fanno. + +## Riepilogo: Capire la configurazione di Bitcoin + +La directory `~/.bitcoin` contiene tutti i tuoi file, mentre `bitcoin-cli help` contiene e una varietà di comandi che puoi utilizzare per ottenere maggiori informazioni su come funzionano la tua configurazione e Bitcoin. + +## Ora cosa facciamo? + +Continua "Comprendere la configurazione di Bitcoin" col [Capitolo 3.3: Configurare la Wallet](03_3_Configurare_la_Wallet.md). diff --git a/it/03_3_Configurare_la_Wallet.md b/it/03_3_Configurare_la_Wallet.md new file mode 100644 index 000000000..eeb33f1bb --- /dev/null +++ b/it/03_3_Configurare_la_Wallet.md @@ -0,0 +1,176 @@ +# 3.3: Configurare la Wallet + +Ora sei pronto per iniziare a lavorare con Bitcoin. Per cominciare, dovrai creare una wallet, un portafoglio digitale per inviare e ricevere fondi. + +## Crea una wallet + +> :warning: **AVVERTIMENTO VERSIONE:** Le versioni più recenti di Bitcoin Core, a partire dalla v0.21.0, non creeranno più automaticamente un portafoglio predefinito all'avvio. Quindi, dovrai crearne uno manualmente. Ma se stai utilizzando una versione precedente di Bitcoin Core, è già stato creato un nuovo portafoglio per te, in quel caso puoi passare a [Creare un indirizzo](#Creare-un-indirizzo). + +La prima cosa che devi fare è creare un nuovo portafoglio, cosa che può essere fatta con il comando `bitcoin-cli createwallet`. Creando un nuovo portafoglio, creerai la tua coppia di chiavi pubblica-privata. La tua chiave pubblica è la fonte da cui verranno creati i tuoi indirizzi e la tua chiave privata è ciò che ti consentirà di spendere tutti i fondi che ricevi nei tuoi indirizzi. Bitcoin Core salverà automaticamente tali informazioni in un file `wallet.dat` nella tua directory `~/.bitcoin/testnet3/wallets`. + +Se controlli la directory `wallets`, vedrai che al momento è vuota. + +``` +$ ls ~/.bitcoin/testnet3/wallets +$ +``` +Anche se Bitcoin Core non creerà un nuovo portafoglio per te, comunque caricherà all'avvio, per impostazione predefinita, una wallet senza nome (""). Quindi puoi trarne vantaggio creando un nuovo portafoglio senza nome. + +``` +$ bitcoin-cli -named createwallet wallet_name="" descriptors=false + +{ + "name": "", + "warning": "" +} +``` + +Ora, la tua directory `wallets` si è riempito. +``` +$ ls ~/.bitcoin/testnet3/wallets +database db.log wallet.dat +``` +> :book: ***Cos'è una wallet Bitcoin?*** Un portafoglio Bitcoin è l'equivalente digitale di un portafoglio fisico sulla rete Bitcoin. Memorizza informazioni sulla quantità di bitcoin che possiedi e dove si trovano (indirizzi), nonché i modi in cui puoi utilizzarli per spenderli. Spendere denaro fisico è intuitivo, ma per spendere bitcoin gli utenti devono fornire la _chiave privata_ corretta. Lo spiegheremo in modo più dettagliato piu avanti nel corso, ma quello che dovresti sapere per ora è che questa dinamica della chiave pubblica-privata fa parte di ciò che rende Bitcoin sicuro e senza bisogno di fiducia in terzi. Le informazioni sulla tua coppia di chiavi vengono salvate nel file `wallet.dat`, oltre ai dati sulle preferenze e sulle transazioni. Nella maggior parte dei casi, non dovrai preoccuparti della chiave privata: `bitcoind` la utilizzerà quando sarà necessaria. Tuttavia, questo rende il file `wallet.dat` estremamente importante: se lo perdi, perdi le tue chiavi private e se perdi le chiavi private, perdi i tuoi fondi! + +Ottimo, ora hai un portafoglio Bitcoin. Ma un portafoglio sarà di scarsa utilità per ricevere bitcoin se prima non crei un indirizzo. + +> :warning: **AVVERTIMENTO VERSIONE:** A partire da Bitcoin Core v 23.0, i portafogli `Descriptor` sono diventati l'impostazione predefinita. È fantastico, perché i portafogli descrittori sono molto potenti, tranne per il fatto che attualmente non funzionano con multisig! Quindi li disattiviamo con l'argomento `descrptor=false`. Vedi [Capitolo 3.5: Comprendere il Descriptor](03_5_Comprendere_il_Descriptor.md) per ulteriori informazioni. + +## Creare un indirizzo + +La prossima cosa che devi fare è creare un indirizzo per ricevere i pagamenti. Questo viene fatto con il comando `bitcoin-cli getnewaddress`. Ricorda che se desideri maggiori informazioni su questo comando, devi digitare `bitcoin-cli help getnewaddress`. Attualmente esistono tre tipi di indirizzi: un tipo "legacy" , e due tipi SegWit, cioè "p2sh-segwit" e "bech32". Se non specifichi diversamente, otterrai il valore predefinito, che attualmente è "bech32". + +Tuttavia, nelle prossime sezioni utilizzeremo invece indirizzi "legacy", sia perché "bitcoin-cli" ha avuto alcuni problemi iniziali con le sue prime versioni degli indirizzi SegWit, sia perché altre persone potrebbero non essere in grado di inviare a indirizzi "bech32". È improbabile che tutto ciò costituisca un problema per te adesso, ma per il momento vogliamo iniziare con esempi di transazioni che sono (per lo più) garantiti per funzionare. + +Innanzitutto, riavvia `bitcoind` in modo che il tuo nuovo portafoglio senza nome ("") venga impostato come predefinito e caricato automaticamente. + + +``` +$ bitcoin-cli stop +Bitcoin Core stopping # wait a minute so it stops completely +$ bitcoind -daemon +Bitcoin Core starting # wait a minute so it starts completely +``` + +Ora puoi creare un indirizzo. Puoi richiedere un indirizzo `legacy` con il secondo argomento di `getnewaddress` o con l'argomento denominato `addresstype`. + +``` +$ bitcoin-cli getnewaddress -addresstype legacy +moKVV6XEhfrITAnQCYq6ppT7AaliCOsZ1B +``` + +Tieni presente che questo indirizzo inizia con una "m" (o talvolta una "n") per indicare un indirizzo Legacy testnet. Sarebbe un "2" per un indirizzo P2SH o un "tb1" per un indirizzo Bech32. + +> :link: **TESTNET vs MAINNET:** L'indirizzo mainnet equivalente inizierebbe con "1" (per Legacy), "3" (per P2SH) o "bc1" (per Bech32). + +Prendi nota attentamente dell'indirizzo. Dovrai darlo a chi ti invierà i fondi. + +> :book: ***Che cos'è un indirizzo Bitcoin?*** Un indirizzo Bitcoin è letteralmente il luogo in cui ricevi denaro. È come un indirizzo email, ma per i fondi. Tecnicamente, è una chiave pubblica, che viene adattata a seconda dei diversi schemi di indirizzi. Tuttavia, a differenza di un indirizzo email, un indirizzo Bitcoin dovrebbe essere considerato monouso: usalo per ricevere fondi solo _una volta_. Quando desideri ricevere fondi da qualcun altro o in un altro momento, genera un nuovo indirizzo. Questo è suggerito in gran parte per migliorare la tua privacy. L'intera blockchain è immutabile, il che significa che gli esploratori possono osservare lunghe catene di transazioni nel tempo, consentendo di determinare statisticamente chi sei tu e i tuoi contatti, non importa quanto tu sia attento. Tuttavia, se continui a riutilizzare lo stesso indirizzo, la cosa diventa ancora più semplice. Creando il tuo primo indirizzo Bitcoin, hai anche iniziato a riempire il tuo portafoglio Bitcoin. Più precisamente, hai iniziato a riempire il file `wallet.dat` nella tua directory `~/.bitcoin/testnet3 /wallets`. + +Con un solo indirizzo in mano, puoi passare direttamente alla sezione successiva e iniziare a ricevere fondi. Tuttavia, prima di arrivare a questo, discuteremo brevemente degli altri tipi di indirizzi che incontrerai in futuro e parleremo di alcuni altri comandi della wallet che potresti voler utilizzare in futuro. + +### Conoscere i tuoi indirizzi Bitcoin + +Esistono tre tipi di indirizzi Bitcoin che puoi creare con il comando RPC `getnewaddress`. Qui utilizzerai un indirizzo "legacy" (P2PKH), mentre passerai a un indirizzo SegWit (P2SH-SegWit) o ​​Bech32 nel [Capitolo 4.6: Creare una Transazione Segwit](04_6_Creare_una_Transazione_Segwit.md). + +Come notato sopra, la base di un indirizzo Bitcoin è una chiave pubblica: qualcuno invia fondi alla tua chiave pubblica e poi usi la tua chiave privata per riscattarla. Facile? Tranne che mettere la tua chiave pubblica là fuori non è del tutto sicuro. Al momento, se qualcuno ha la tua chiave pubblica, non può recuperare la tua chiave privata (e quindi i tuoi fondi); questa è la base della crittografia, che utilizza una funzione trap-door per garantire che si possa passare solo dalla chiave privata a quella pubblica e non viceversa. Ma il problema è che non sappiamo cosa ci riserverà il futuro. Solo che sappiamo che i sistemi di crittografia prima o poi vengono danneggiati dall'inarrestabile progresso della tecnologia, quindi è meglio non mettere chiavi pubbliche grezze in rete, per rendere le tue transazioni a prova di futuro. + +Le transazioni Bitcoin classiche hanno creato indirizzi P2PKH che hanno aggiunto un ulteriore passaggio crittografico per proteggere le chiavi pubbliche. + +> :book: ***Che cos'è un indirizzo Legacy (P2PKH)?*** Questo è un indirizzo Legacy del tipo utilizzato dalla prima rete Bitcoin. Lo useremo negli esempi per le prossime sezioni. Si chiama indirizzo _Pay to PubKey Hash_ (o P2PKH) perché l'indirizzo è un hash a 160 bit di una chiave pubblica. L'utilizzo di un hash della tua chiave pubblica come indirizzo crea un processo in due fasi in cui è necessario rivelare sia la chiave privata che quella pubblica per spendere i fondi, aumenta di conseguenza la sicurezza futura. Questo tipo di indirizzo rimane importante per ricevere fondi da persone con software wallet non aggiornato. + +Come descritto più dettagliatamente nel [Capitolo 4.6: Creare una Transazione Segwit](04_6_Creating_a_Segwit_Transaction.md), le guerre sulle dimensioni dei blocchi della fine degli anni 2010 hanno portato a un nuovo tipo di indirizzo: *SegWit*. Questo è il tipo di indirizzo preferito, oggi è completamente integrato in Bitcoin-Core, ma i dettagli li vedremo nel Capitolo 4.6. + +SegWit significa semplicemente "testimone separato" ed è un modo per separare le firme delle transazioni dal resto della transazione per ridurre le dimensioni e il costo della transazione. Alcuni indirizzi SegWit si insinueranno in alcuni dei nostri esempi precedenti al Capitolo 4.6 come indirizzi di devoluzione del resto, "change", che vedrai come indirizzi che iniziano con "tb". Questo va bene perché `bitcoin-cli` supporta interamente il loro utilizzo. + +Esistono due indirizzi di questo tipo: + +> :book: ***Che cos'è un indirizzo P2SH-SegWit (noto anche come Nested SegWit)?*** Questa è la prima generazione di SegWit. Avvolge l'indirizzo SegWit in un scripthash per garantire la compatibilità con le versioni precedenti. Il risultato crea transazioni più piccole di circa il 25% di Bytes in meno (con corrispondenti riduzioni delle commissioni di transazione). + +> :book: ***Cos'è un indirizzo Bech32 (noto anche come Native SegWit, alias P2WPKH)?*** Questa è la seconda generazione di SegWit. È completamente descritto in [BIP 173](https://en.bitcoin.it/wiki/BIP_0173). Crea transazioni ancora più piccole ma, soprattutto, presenta anche alcuni vantaggi nella creazione di indirizzi meno soggetti a errori umani e con una correzione implicita degli errori oltre a ciò. Bech32 *Non* è compatibile con le versioni precedenti come lo era P2SH-SegWit, quindi alcune persone potrebbero non essere in grado di inviar sats a qesti indirizzi. + +Esistono altri tipi di indirizzi Bitcoin, come P2PK (che paga a una semplice chiave pubblica ed è deprecato a causa della sua futura insicurezza) e P2SH (che paga a uno Script Hash e che viene utilizzato dal Nested SegWit di prima generazione indirizzi; lo affronteremo più approfonditamente tra qualche capitolo). + + +## Facoltativo: firma un messaggio + +A volte dovrai dimostrare di verificare un indirizzo Bitcoin (o meglio, di verificare la chiave privata). Questo è importante perché fa sapere alle persone che stanno inviando fondi alla persona giusta. Questo può essere fatto creando una firma con il comando `bitcoin-cli signmessage`, nella forma `bitcoin-cli signmessage [indirizzo] [messaggio]`. Per esempio: + +``` +$ bitcoin-cli signmessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "Hello, World" +HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI= +``` +Riceverai la firma in cambio. + +> :book: ***Cos'è una firma?*** Una firma digitale è una combinazione di un messaggio e di una chiave privata che può poi essere sbloccata con una chiave pubblica. Poiché esiste una corrispondenza uno a uno tra gli elementi di una coppia di chiavi, lo sblocco con una chiave pubblica dimostra che il firmatario controllava la chiave privata corrispondente. + +Un'altra persona può quindi utilizzare il comando "bitcoin-cli verifymessage" per verificare la firma. Inserisce l'indirizzo in questione, la firma e il messaggio: + +``` +$ bitcoin-cli verifymessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" +true +``` +Se corrispondono tutti, l'altra persona sa che può trasferire in sicurezza i fondi alla persona che ha firmato il messaggio inviandolo all'indirizzo. + +Se qualche black hat stesse inventando firme, ciò produrrebbe invece un risultato negativo: +``` +$ bitcoin-cli verifymessage "FAKEV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" +error code: -3 +error message: +Invalid address +``` + +## Opzionale: scarica il tuo portafoglio + +Potrebbe sembrare pericoloso avere tutte le tue insostituibili chiavi private in un unico file. Ecco a cosa serve `bitcoin-cli dumpwallet`. Ti consente di creare una copia del tuo wallet.dat: +``` +$ bitcoin-cli dumpwallet ~/mywallet.txt +``` +Il file `mywallet.txt` nella tua directory home conterrà un lungo elenco di chiavi private, indirizzi e altre informazioni. Intendiamoci, non vorresti MAI inserire questi dati in un semplice file di testo su una configurazione Bitcoin con fondi reali! + +È quindi possibile recuperarlo con `bitcoin-cli importwallet`. +``` +$ bitcoin-cli importwallet ~/mywallet.txt +``` +Ma nota che questo richiede un nodo non potato! +``` +$ bitcoin-cli importwallet ~/mywallet.txt +error code: -4 +error message: +Importing wallets is disabled when blocks are pruned +``` + +## Facoltativo: visualizza le tue chiavi private + +A volte, potresti voler effettivamente guardare le chiavi private associate ai tuoi indirizzi Bitcoin. Forse vuoi poter firmare un messaggio o spendere bitcoin da una macchina diversa. Forse vuoi solo eseguire il backup di alcune importanti chiavi private. Puoi farlo anche con il tuo file di dump, poiché è leggibile dall'uomo. +``` +$ bitcoin-cli dumpwallet ~/mywallet.txt +{ + "filename": "/home/standup/mywallet.txt" +} +``` +Più probabilmente, vuoi solo guardare la chiave privata associata a un indirizzo specifico. Questo può essere fatto con il comando "bitcoin-cli dumpprivkey". + +``` +$ bitcoin-cli dumpprivkey "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" +cTv75T4B3NsG92tdSxSfzhuaGrzrmc1rJjLKscoQZXqNRs5tpYhH +``` +Puoi quindi salvare la chiave in un posto sicuro, preferibilmente in un posto non connesso a Internet. + +Puoi anche importare qualsiasi chiave privata, da dumpwallet o da un dump della chiave individuale, come segue: +``` +$ bitcoin-cli importprivkey cW4s4MdW7BkUmqiKgYzSJdmvnzq8QDrf6gszPMC7eLmfcdoRHtHh +``` +Ancora una volta, aspettatevi che ciò richieda un nodo non potato. Aspettatevi che ciò richieda un po' di tempo, poiché "bitcoind" deve rileggere tutte le transazioni passate, per vedere se ce ne sono di nuove a cui prestare attenzione. + +> :information_source: **NOTA:** Molti wallet moderni preferiscono [codici mnemonici](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) per generare i seed necessari per creare il privato chiavi. Questa metodologia non viene utilizzata "bitcoin-cli", quindi non sarai in grado di generare pratici elenchi di parole per ricordare le tue chiavi private. + +_Hai digitato quell'indirizzo Bitcoin e firmavi i messaggi e ora scaricavi le chiavi, è *troppo*. Se pensi che sia una seccatura, siamo d'accordo. Ed è anche soggetto a errori, un argomento che affronteremo nella sezione successiva._ + +## Riepilogo: configurazione la wallet + +È necessario creare un indirizzo per ricevere fondi. Il tuo indirizzo è memorizzato in un wallet di cui puoi eseguire il backup. Puoi anche fare molto di più con un indirizzo, come scaricare la sua chiave privata o usarlo per firmare messaggi. Ma in realtà, creare quell'indirizzo è _tutto_ ciò che devi fare per ricevere fondi Bitcoin. + +## E ora? + +Prenditi un attimo e da un occhiata a le variabili nella linea di comando, qui: [Utilizzare Variabili nella Linea di Comando](03_3_Intermezzo_Utilizzare_Variabili_nella_Linea_di_Comando.md). diff --git a/it/03_3_Intermezzo_Utilizzare_Variabili_nella_Linea_di_Comando.md b/it/03_3_Intermezzo_Utilizzare_Variabili_nella_Linea_di_Comando.md new file mode 100644 index 000000000..d094ee269 --- /dev/null +++ b/it/03_3_Intermezzo_Utilizzare_Variabili_nella_Linea_di_Comando.md @@ -0,0 +1,40 @@ +# Interludio: utilizzare le variabili nella riga di comando + +La sezione precedente ha dimostrato una serie di comandi della riga di comando utilizzati senza offuscamenti o interferenze. Tuttavia, spesso non è il modo migliore per eseguire Bitcoin dalla riga di comando. Poiché hai a che fare con variabili lunghe, complesse e illeggibili, è facile commettere un errore se le stai copiando (o, satoshi forfend, se le stai digitando a mano). Poiché queste variabili possono fare la differenza tra ricevere e perdere denaro reale, non vuoi commettere errori. Per questi motivi, consigliamo vivamente di utilizzare variabili della riga di comando per salvare indirizzi, firme o altre lunghe stringhe di informazioni ogni volta che è ragionevole farlo. + +Se utilizzi `bash`, puoi salvare le informazioni in una variabile come questa: +``` +$ VARIABLE=$(command) +``` +Questa è una semplice sostituzione di comando, l'equivalente di ``VARIABILE=`comando` ``. Viene eseguito il comando tra parentesi, quindi assegnato alla VARIABILE. + +Per creare un nuovo indirizzo sarebbe quindi simile a questo: +``` +$ unset NEW_ADDRESS_1 +$ NEW_ADDRESS_1=$(bitcoin-cli getnewaddress "" legacy) +``` +Questo comando cancella la variabile `NEW_ADDRESS_1` per sicurezza, quindi la riempiono con i risultati del comando `bitcoin-cli getnewaddress`. + +Dalla tua Shell puoi utilizzare il comando `echo` per controllare il tuo (nuovo) indirizzo: + +``` +$ echo $NEW_ADDRESS_1 +mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE +``` +Poiché hai il tuo indirizzo in una variabile, ora puoi firmare facilmente un messaggio per quell'indirizzo, senza preoccuparti di digitarlo in modo errato. Ovviamente salverai anche quella firma in una variabile! +``` +$ NEW_SIG_1=$(bitcoin-cli signmessage $NEW_ADDRESS_1 "Hello, World") +$ echo $NEW_SIG_1 +IPYIzgj+Rg4bxDwCyoPiFiNNcxWHYxgVcklhmN8aB2XRRJqV731Xu9XkfZ6oxj+QGCRmTe80X81EpXtmGUpXOM4= +``` +Per praticità nella tutorial utilizzeremo questo tipo di salvataggio delle informazioni nelle variabili. + +> :book: ***Quando non è pratico utilizzare le variabili della riga di comando?*** Le variabili della riga di comando non sono pratiche se è necessario utilizzare le informazioni in un posto diverso dalla riga di comando. Ad esempio, salvare la tua firma potrebbe non essere utile se devi semplicemente inviarla a qualcun altro tramite email. Inoltre, alcuni comandi futuri restituiranno oggetti JSON invece di semplici informazioni e le variabili non potranno essere utilizzate per acquisire tali informazioni... almeno non senza _poco_ lavoro in più. + +## Riepilogo: utilizzare le variabili nella riga di comando + +Le variabili di shell possono essere utilizzate per contenere lunghe _Bitcoin strings_, riducendo al minimo le possibilità di errori. + +## Cosa viene dopo? + +[Capitolo 3.4: Ricevere una Transazione](03_4_Ricevere_una_Transazione.md). diff --git a/it/03_4_Ricevere_una_Transazione.md b/it/03_4_Ricevere_una_Transazione.md new file mode 100644 index 000000000..24ac7aa1f --- /dev/null +++ b/it/03_4_Ricevere_una_Transazione.md @@ -0,0 +1,324 @@ +# 3.4: Ricevere una Transazione + +Ora sei pronto per ricevere denaro al nuovo indirizzo che hai impostato. + +## Ottieni dei soldi + +Per fare qualcosa di più, devi ottenere dei soldi. Su testnet questo avviene tramite faucet. Dato che i soldi sono tutti finti, basta andare a un rubinetto, chiedere dei soldi e ti verranno inviati. Ti consigliamo di utilizzare il faucet su https://testnet-faucet.mempool.co/, https://bitcoinfaucet.uo1.net/ o https://testnet.coinfaucet.eu/en/. Se per qualche motivo non sono disponibili, cerca "bitcoin testnet faucet" e dovresti trovarne altri. + +Per utilizzare un faucet, di solito dovrai accedere a un URL e copiare e incollare il tuo indirizzo. Tieni presente che questo è uno di quei casi in cui non sarai in grado di utilizzare le variabili della riga di comando, ahimè. Successivamente, verrà creata una transazione che ti invierà denaro dal faucet. + +> :book: ***Cos'è una transazione?*** Una transazione è uno scambio di bitcoin. Il proprietario di alcuni bitcoin utilizza la sua chiave privata per accedere a quelle monete, quindi blocca la transazione utilizzando la chiave pubblica del destinatario. + +> :link: **TESTNET vs MAINNET:** Purtroppo, non ci sono faucet nella vita reale. Se giocassi sulla rete principale, dovresti andare ad acquistare effettivamente bitcoin presso uno scambio bitcoin o un bancomat, oppure dovresti trovare qualcuno che te li invii. La vita su Testnet è molto più semplice. + +## Verifica i tuoi soldi + +Dopo aver richiesto il tuo denaro, dovresti essere in grado di verificarlo con il comando `bitcoin-cli getbalance`: + +``` +$ getbalance bitcoin-cli +0.00000000 +``` +Ma aspetta, non ci sono ancora? + +Benvenuti nel mondo della latenza Bitcoin. Il problema è che la tua transazione non è stata ancora registrata in un blocco! + +> :book: ***Cos'è un blocco?*** Le transazioni vengono trasmesse attraverso la rete e raccolte in blocchi dai minatori. Questi blocchi sono protetti con una prova di lavoro matematica, che dimostra che la potenza di calcolo è stata spesa come parte della creazione del blocco. È quella prova di lavoro (moltiplicata su molti blocchi, ciascuno costruito sopra l'ultimo) che alla fine mantiene Bitcoin sicuro. + +> :book: ***Cos'è un miner?*** Un miner è un partecipante nella rete Bitcoin che lavora per creare blocchi. È un lavoro retribuito: quando un minatore crea con successo un blocco, riceve una ricompensa una tantum più le commissioni per le transazioni nel suo blocco. L’estrazione mineraria è un grande business. I minatori tendono a funzionare su hardware speciale, accelerato in modi che rendono più probabile che siano in grado di creare blocchi. Tendono anche a far parte dei pool minerari, dove i minatori accettano tutti di condividere i premi quando uno di loro crea con successo un blocco. + +Fortunatamente, `bitcoin-cli getunconfirmedbalance` dovrebbe comunque mostrare il saldo aggiornato purché sia ​​stata creata la transazione iniziale: +``` +$ bitcoin-cli getunconfirmedbalance +0.01010000 +``` +Se anche questo mostra ancora uno zero, probabilmente stai procedendo troppo velocemente attraverso questo tutorial. Aspetta un secondo. Le monete dovrebbero apparire non confermate, quindi passare rapidamente a confermate. Tieni presente che una moneta può passare dal saldo non confermato al saldo confermato quasi immediatamente, quindi assicurati di controllarli entrambi. Tuttavia, se il tuo `getbalance` e il tuo `getunconfirmedbalance` mostrano ancora zero entro dieci minuti, probabilmente c'è qualcosa che non va con il faucet e dovrai sceglierne un altro. + +### Aumenta la confidenza col tuo denaro + +Puoi utilizzare `bitcoin-cli getbalance "*" [n]`, dove sostituisci `[n]` con un numero intero, per vedere se un saldo confermato è profondo 'n' blocchi. + +> :book: ***Cos'è la profondità del blocco?*** Dopo che un blocco è stato costruito e confermato, un altro blocco viene costruito sopra di esso, e un altro... Poiché si tratta di un processo stocastico, c'è qualche possibilità di inversione quando un blocco è ancora nuovo. Pertanto, un blocco deve essere sepolto diversi blocchi in profondità in una catena prima che tu possa sentirti totalmente sicuro dei tuoi fondi. Ciascuno di questi blocchi tende ad essere costruito in una media di 10 minuti... quindi di solito ci vuole circa un'ora affinché una transazione confermata riceva sei blocchi di profondità, che è la misura della piena fiducia in Bitcoin. + +Quanto segue mostra che le nostre transazioni sono state confermate una volta, ma non due volte: +``` +$ bitcoin-cli getbalance "*" 1 +0.01010000 +$ bitcoin-cli getbalance "*" 2 +0.00000000 +``` +Ovviamente, ogni dieci minuti circa questa profondità aumenterà. + +Naturalmente, sul testnet, nessuno è così preoccupato dell'affidabilità dei tuoi fondi. Potrai spendere i tuoi soldi non appena sarà confermato. + +## Verifica il tuo portafoglio + +Il comando `bitcoin-cli getwalletinfo` ti fornisce maggiori informazioni sul saldo del tuo portafoglio: + +``` +$ bitcoin-cli getwalletinfo +{ + "walletname": "", + "walletversion": 169900, + "balance": 0.01010000, + "unconfirmed_balance": 0.00000000, + "immature_balance": 0.00000000, + "txcount": 2, + "keypoololdest": 1592335137, + "keypoolsize": 999, + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "keypoolsize_hd_internal": 1000, + "paytxfee": 0.00000000, + "private_keys_enabled": true, + "avoid_reuse": false, + "scanning": false +} +``` + +## Scopri la ID della transazione + +I tuoi soldi sono entrati nel tuo portafoglio tramite una transazione. Puoi scoprire la ID della transazione (txid) con il comando "bitcoin-cli listtransactions": + +``` +$ bitcoin-cli listtransactions +[ + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 1, + "confirmations": 1, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 73, + "blocktime": 1592600085, + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "walletconflicts": [ + ], + "time": 1592599884, + "timereceived": 1592599884, + "bip125-replaceable": "no" + }, + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.00010000, + "label": "", + "vout": 0, + "confirmations": 1, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 72, + "blocktime": 1592600085, + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "walletconflicts": [ + ], + "time": 1592599938, + "timereceived": 1592599938, + "bip125-replaceable": "no" + } +] + +``` +Questo mostra due transazioni (`8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9`) e (`ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9 f36`) per un importo specifico (`0.01000000` e `0.00010000`), entrambi ricevuti ("receive") dallo stesso indirizzo nel nostro portafoglio (`mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE`) . A proposito, questa è unapratica sconsigliata: dovresti usare un nuovo indirizzo per ogni singola transazione Bitcoin che ricevi. In questo caso ci siamo spazientiti perché il primo rubinetto sembrava non funzionare. + +Puoi accedere a informazioni simili con il comando `bitcoin-cli listunspent`, ma mostra solo le transazioni per i soldi che non hai speso. Questi sono chiamati UTXO e saranno di vitale importanza quando invierai denaro nel mondo Bitcoin: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + }, + { + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "vout": 1, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.01000000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + } +] +``` +Tieni presente che i bitcoin non è un disordine di soldi buttati nelle tue tasche. Ogni singola transazione che ricevi o che invii viene inserita nel registro immutabile della blockchain, in un blocco. Puoi vedere queste singole transazioni quando guardi i tuoi soldi non spesi. Ciò significa che la spesa in bitcoin non è così anonima come potresti pensare. Sebbene gli indirizzi siano abbastanza privati, le transazioni possono essere esaminate mentre entrano ed escono dagli indirizzi. Ciò rende la privacy vulnerabile all’analisi statistica. Introduce inoltre una certa potenziale non fungibilità per i bitcoin, poiché è possibile risalire a una serie di transazioni, anche se non è possibile tracciare uno specifico "bitcoin". + +> :book: ***Perché tutti questi importi di bitcoin sono frazionati?*** I bitcoin vengono prodotti lentamente, quindi ce ne sono relativamente pochi in circolazione. Di conseguenza, ogni bitcoin sulla rete principale vale parecchio (~ $ 60.000 al momento in cui scriviamo). Ciò significa che le persone di solito lavorano in frazioni. In effetti, il 0.0101 nelle monete Testnet varrebbe circa $ 600 se fossero sulla rete principale. Per questo motivo, sono apparsi nomi per quantità minori di bitcoin, inclusi millibitcoin o mBTC (un millesimo di bitcoin), microbitcoin o bit o μBTC (un milionesimo di bitcoin) e `satoshi` (centomilionesimo di bitcoin). . + +## Esamina la tua transazione + +Puoi ottenere maggiori informazioni su una transazione con il comando `bitcoin-cli gettransaction`.: + +``` +$ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9" +{ + "amount": 0.01000000, + "confirmations": 1, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 73, + "blocktime": 1592600085, + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "walletconflicts": [ + ], + "time": 1592599884, + "timereceived": 1592599884, + "bip125-replaceable": "no", + "details": [ + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 1 + } + ], + "hex": "0200000000010114d04977d1b0137adbf51dd5d79944b9465a2619f3fa7287eb69a779977bf5800100000017160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4ffeffffff02df690f000000000017a9145c3bfb36b03f279967977ca9d1e35185e39917788740420f00000000001976a9141b72503639a13f190bf79acf6d76255d772360b788ac0247304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e1330121022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c270b1b00" +} +``` +Il comando `gettransaction` dettaglierà le transazioni presenti nel tuo portafoglio, come questa, che ci è stata inviata. + +Tieni presente che `gettransaction` ha due argomenti facoltativi: +``` +$ bitcoin-cli help gettransaction +gettransaction "txid" ( include_watchonly verbose ) + +Get detailed information about in-wallet transaction + +Arguments: +1. txid (string, required) The transaction id +2. include_watchonly (boolean, optional, default=true for watch-only wallets, otherwise false) Whether to include watch-only addresses in balance calculation and details[] +3. verbose (boolean, optional, default=false) Whether to include a `decoded` field containing the decoded transaction (equivalent to RPC decoderawtransaction) +``` +Impostando questi due su true o false, possiamo scegliere di includere indirizzi watch only nell'output (cosa che non ci interessa) o guardare un risultato più dettagliato (cosa che facciamo). + +Ecco cosa esaminano invece questi dati quando impostiamo `include_watchonly` su `false` e `verbose` su `true`. +``` +$ bitcoin-cli gettransaction "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9" false true +{ + "amount": 0.01000000, + "confirmations": 3, + "blockhash": "00000000000001753b24411d0e4726212f6a53aeda481ceff058ffb49e1cd969", + "blockheight": 1772396, + "blockindex": 73, + "blocktime": 1592600085, + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "walletconflicts": [ + ], + "time": 1592599884, + "timereceived": 1592599884, + "bip125-replaceable": "no", + "details": [ + { + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 1 + } + ], + "hex": "0200000000010114d04977d1b0137adbf51dd5d79944b9465a2619f3fa7287eb69a779977bf5800100000017160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4ffeffffff02df690f000000000017a9145c3bfb36b03f279967977ca9d1e35185e39917788740420f00000000001976a9141b72503639a13f190bf79acf6d76255d772360b788ac0247304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e1330121022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c270b1b00", + "decoded": { + "txid": "8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9", + "hash": "d4ae2b009c43bfe9eba96dcd16e136ceba2842df3d76a67d689fae5975ce49cb", + "version": 2, + "size": 249, + "vsize": 168, + "weight": 669, + "locktime": 1772327, + "vin": [ + { + "txid": "80f57b9779a769eb8772faf319265a46b94499d7d51df5db7a13b0d17749d014", + "vout": 1, + "scriptSig": { + "asm": "0014e85ba02862dbadabd6d204fcc8bb5d54658c7d4f", + "hex": "160014e85ba02862dbadabd6d204fcc8bb5d54658c7d4f" + }, + "txinwitness": [ + "304402201e74bdfc330fc2e093a8eabe95b6c5633c8d6767249fa25baf62541a129359c202204d462bd932ee5c15c7f082ad7a6b5a41c68addc473786a0a9a232093fde8e13301", + "022897dfbf085ecc6ad7e22fc91593414a845659429a7bbb44e2e536258d2cbc0c" + ], + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01010143, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 5c3bfb36b03f279967977ca9d1e35185e3991778 OP_EQUAL", + "hex": "a9145c3bfb36b03f279967977ca9d1e35185e399177887", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N1ev1WKevSsdmAvRqZf7JjvDg223tPrVCm" + ] + } + }, + { + "value": 0.01000000, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1b72503639a13f190bf79acf6d76255d772360b7 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE" + ] + } + } + ] + } +} +``` +Ora puoi vedere tutte le informazioni sulla transazione, inclusi tutti gli input (`vin`) e tutti gli output (`vout`). Una delle cose interessanti da notare è che, sebbene abbiamo ricevuto 0,01 BTC nella transazione, un altro .01010143 è stato inviato a un altro indirizzo. Probabilmente si trattava di un indirizzo di cambio o resto, un concetto che verrà esplorato nella sezione successiva. È abbastanza tipico che una transazione abbia più input e/o più output. + +Esiste un altro comando, `getrawtransaction`, che ti consente di esaminare le transazioni che non sono nel tuo portafoglio. Tuttavia, richiede che tu abbia un nodo non potato e `txindex=1` nel tuo file `bitcoin.conf`. A meno che tu non abbia un serio bisogno di informazioni che non sono nel tuo portafoglio, probabilmente è meglio usare un Bitcoin Explorer per questo genere di cose... + +## Facoltativo: utilizza un Block Explorer + +Anche guardare le informazioni dettagliate di una transazione può essere un po’ intimidatorio. L'obiettivo principale di questo tutorial è insegnare come gestire le transazioni grezze dalla riga di comando, ma saremo felici di parlare di altri strumenti quando applicabili. Uno di questi strumenti è un block explorer, che puoi utilizzare per esaminare le transazioni da un browser web in un formato molto più intuitivo. + +Attualmente, il nostro block explorer preferito è [mempool.space](https://mempool.space). + +Ecco un'altra alternativa, [https://live.blockcypher.com/](https://live.blockcypher.com/). + +Puoi usarlo per cercare le transazioni per un indirizzo: + +[https://mempool.space/it/testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE](https://mempool.space/it/testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE) + +[https://live.blockcypher.com/btc-testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE/](https://live.blockcypher.com/btc-testnet/address/mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE/) + +Puoi anche usarlo per esaminare le singole transazioni: + +[https://mempool.space/it/testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9](https://mempool.space/it/testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9) + +[https://live.blockcypher.com/btc-testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9/](https://live.blockcypher.com/btc-testnet/tx/8e2ab10cabe9ec04ed438086a80b1ac72558cc05bb206e48fc9a18b01b9282e9/) + +Un block explorer generalmente non fornisce più informazioni di quelle che una riga di comando esamina in una transazione grezza; fa semplicemente un buon lavoro nell'evidenziare le informazioni importanti e nel mettere insieme i pezzi del puzzle, comprese le commissioni di transazione dietro una transazione, un altro concetto che tratteremo nelle sezioni future. + +## Riepilogo: ricezione di una transazione + +I rubinetti ti daranno soldi sul testnet. Arrivano come transazioni grezze, che possono essere esaminate con `gettransaction` o un block explorer. Una volta ricevuta una transazione, puoi visualizzare il saldo nel tuo portafoglio. + +## Qual è il prossimo? + +Per un approfondimento su come vengono descritti gli indirizzi, in modo che possano essere trasferiti o creati in parti in una multisig, vedere [Capitolo 3.5: Comprendere il Descriptor](03_5_Comprendere_il_Descriptor.md). + +Ma se è approfondire un po troppo, salta e vai al [Capitolo 4: Inviare Transazioni Bitcoin](04_0_Inviare_Transazioni_Bitcoin.md). diff --git a/it/03_5_Comprendere_il_Descriptor.md b/it/03_5_Comprendere_il_Descriptor.md new file mode 100644 index 000000000..b926266a7 --- /dev/null +++ b/it/03_5_Comprendere_il_Descriptor.md @@ -0,0 +1,152 @@ +# 3.5: Comprendere il Descrittore + +> :information_source: **NOTA:** Questa sezione è stata aggiunta di recente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvertito. + +Potresti aver notato uno strano campo `desc:` nel comando `listunspent` della sezione precedente. Ecco di cosa si tratta (e come può essere utilizzato per trasferire indirizzi). + +> :avviso: **AVVERTIMENTO VERSIONE:** Questa è un'innovazione di Bitcoin Core v 0.17.0 che ha continuato ad essere ampliata attraverso Bitcoin Core 0.20.0. La maggior parte dei comandi in questa sezione provengono dalla versione 0.17.0, ma l'aggiornamento `importmulti` che supporta i descrittori proviene dalla versione 0.18.0. + +## Informazioni sul trasferimento degli indirizzi + +La maggior parte di questo corso presuppone che tu stia lavorando interamente da un singolo nodo in cui gestisci il tuo portafoglio, inviando e ricevendo pagamenti con gli indirizzi creati da quel portafoglio. Tuttavia, non è necessariamente così che funziona il piu ampio ecosistema Bitcoin. Lì, è più probabile che sposti indirizzi tra portafogli e addirittura configuri portafogli watchonly per sorvegliare i fondi controllati da portafogli diversi. + +È qui che entrano in gioco i descrittori. Sono molto utili se stai interagendo con software _diverso_ da Bitcoin Core e hai davvero bisogno di appoggiarti a questo tipo di funzione di compatibilità: vedi [Capitolo 6.1](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md) per un esempio reale di come sia utilizzare i descrittori. + +Lo spostamento degli indirizzi tra portafogli si concentrava su "xpub" e "xprv", e questi sono ancora supportati. + +> :book: ***Cos'è xprv?*** Una chiave privata estesa. Questa è la combinazione di una chiave privata e un codice a catena. È una chiave privata da cui può essere derivata un'intera sequenza di chiavi private figlie. + +> :book: ***Cos'è xpub?*** Una chiave pubblica estesa. Questa è la combinazione di una chiave pubblica e un codice a catena. È una chiave pubblica da cui può essere derivata un'intera sequenza di chiavi pubbliche figlie. + +Il fatto che tu possa avere una "intera sequenza di chiavi figlie" rivela il fatto che "xpub" e "xprv" non sono chiavi standard come abbiamo parlato finora. Sono invece chiavi gerarchiche che possono essere utilizzate per creare intere famiglie di chiavi, basate sull'idea degli HD Wallet. + +> :book: ***Che cos'è un portafoglio HD?*** La maggior parte dei portafogli moderni è basata su [BIP32: portafogli deterministici gerarchici](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). Si tratta di un progetto gerarchico in cui un singolo seme può essere utilizzato per generare un'intera sequenza di chiavi. L'intero portafoglio può quindi essere ripristinato da quel seme, invece di richiedere il ripristino di ogni singola chiave privata. + +> :book: ***Cos'è un derivation path?*** Quando disponi di chiavi gerarchiche, devi essere in grado di definire chiavi individuali come discendenti di un seme. Ad esempio, "[0]" è la chiave 0, "[0/1]" è il primo figlio della chiave 0, "[1/0/1]" è il primo nipote del figlio zero della chiave 0. Alcune chiavi contengono anche un `'` dopo il numero, per indicare che sono rinforzate, cosa che le protegge da un attacco specifico che può essere utilizzato per derivare un `'xprv` da un `'xpub`. Non devi preoccuparti dei dettagli, a parte il fatto che questi `'` ti causeranno problemi di formattazione quando lavori dalla riga di comando. + +> :information_source: **NOTA:** un derivation path definisce una chiave, il che significa che una chiave rappresenta un percorso di derivazione. Sono equivalenti. Nel caso di un descrittore, il percorso di derivazione consente a `bitcoind` di sapere da dove proviene la chiave che segue nel descrittore! + +"xpubs" e "xprvs" si sono rivelati insufficienti quando i tipi di chiavi pubbliche si sono moltiplicati sotto l'[espansione SegWit](04_6_Creare_una_Transazione_Segwit.md), ecco quindi la necessità di "output descriptors". + +> :book: ***Output descriptors? cosa sono?*** Una descrizione precisa di come derivare un indirizzo Bitcoin da una combinazione di una funzione e uno o più input per quella funzione. + +L'introduzione di funzioni nei descrittori è ciò che li rende potenti, perché possono essere utilizzati per trasferire tutti i tipi di indirizzi, dagli indirizzi Legacy con cui stiamo lavorando ora agli indirizzi Segwit e multisig che incontreremo più avanti. Una singola funzione corrisponde a un particolare tipo di indirizzo ed è correlata a regole specifiche per generare quell'indirizzo. + +## Cattura un descrittore + +I descrittori sono visibili in diversi comandi come `listunspent` e `getaddressinfo`: +``` +$ bitcoin-cli getaddressinfo ms7ruzvL4atCu77n47dStMb3of6iScS8kZ +{ + "address": "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ", + "scriptPubKey": "76a9147f437379bcc66c40745edc1891ea6b3830e1975d88ac", + "ismine": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", + "iswatchonly": false, + "isscript": false, + "iswitness": false, + "pubkey": "03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388", + "iscompressed": true, + "ischange": false, + "timestamp": 1592335136, + "hdkeypath": "m/0'/0'/18'", + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "hdmasterfingerprint": "d6043800", + "labels": [ + "" + ] +} +``` +Qui il descriptor è questo `pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk`. + +## Comprendere il descriptor + +Un descrittore è suddiviso in più parti: +``` +function([derivation-path]key)#checksum +``` +Ecco cosa significa tutto ciò: +* **Function.** La funzione utilizzata per creare un indirizzo da quella chiave. In questi casi si tratta di `pkh`, che è l'indirizzo legacy P2PKH standard che hai incontrato in [Capitolo 3.3: Configurare la Wallet](03_3_Configurare_la_Wallet.md). Allo stesso modo, un indirizzo SegWit P2WSH utilizzerebbe "wsh" e un indirizzo P2WPKH utilizzerebbe "wpkh". +* **Derivation Path.** Descrive quale parte di un portafoglio HD viene esportata. In questo caso è un seme con l'impronta digitale `d6043800` e quindi il 18° figlio dello 0° figlio dello 0° figlio (`0'/0'/18'`) di quel seme. Potrebbe esserci anche un'ulteriore derivazione dopo la chiave: `function([derivation-path]key/more-derivation)#checksum` + * Vale la pena notare qui che se mai ottieni un percorso di derivazione senza impronta digitale, puoi inventarlo. È solo che se ce n'è una esistente, dovresti abbinarla, perché se mai dovessi tornare al dispositivo che ha creato l'impronta digitale, dovrai avere la stessa. +* **key**. La chiave o le chiavi che vengono trasferite. Potrebbe trattarsi di qualcosa di tradizionale come "xpub" o "xprv", potrebbe essere semplicemente una chiave pubblica per un indirizzo come in questo caso, potrebbe essere un insieme di indirizzi per una firma multipla o potrebbe essere qualcos'altro. Questi sono i dati fondamentali: la funzione spiega cosa farne. +* **#checksum**. I descrittori sono pensati per essere trasferibili dall'uomo. Questo checksum assicura che sia corretto. + +Vedi [Informazioni di Bitcoin Core sul supporto dei descrittori](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md) per ulteriori informazioni. + +## Esamina un descrittore + +Puoi guardare un descrittore con l'RPC `getdescriptorinfo`: +``` +$ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk" +{ + "descriptor": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", + "checksum": "4ahsl9pk", + "isrange": false, + "issolvable": true, + "hasprivatekeys": false +} +``` +Tieni presente che restituisce un checksum. Se ti viene mai fornito un descrittore senza checksum, puoi ottenerlo con questo comando: +``` +$ bitcoin-cli getdescriptorinfo "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)" +{ + "descriptor": "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", + "checksum": "4ahsl9pk", + "isrange": false, + "issolvable": true, + "hasprivatekeys": false +} +``` +Oltre a fornirti il ​​checksum, questo comando verifica anche la validità del descrittore e fornisce informazioni utili come se un descrittore contiene chiavi private. + +Uno dei poteri di un descrittore è quello di poter derivare un indirizzo in modo regolare. Questo viene fatto con l'RPC `deriveaddresses`. + +``` +$ bitcoin-cli deriveaddresses "pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk" +[ + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ" +] +``` +Noterai che ritorna all'indirizzo con cui abbiamo iniziato (come dovrebbe). + +## Importa un descrittore + +Ma la cosa veramente importante di un descrittore è che puoi portarlo su un'altra macchina (remota) e importarlo. Questo viene fatto con l'RPC `importmulti` utilizzando l'opzione `desc`: + +``` +remote$ bitcoin-cli importmulti '[{"desc": "pkh([d6043800/0'"'"'/0'"'"'/18'"'"']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk", "timestamp": "now", "watchonly": true}]' +[ + { + "success": true + } +] +``` +Innanzitutto noterai il nostro primo uso davvero brutto delle virgolette. Ogni `'` nel percorso di derivazione doveva essere sostituito con `'"'"'`. Aspettati solo di doverlo fare se stai manipolando un descrittore che contiene un percorso di derivazione. (L'altra opzione è scambiare `'` con una `h` per hardened, ma questo cambierà il tuo checksum, quindi se lo preferisci per la sua facilità d'uso, dovrai ottenere un nuovo checksum con `getdescriptorinfo` .) + +In secondo luogo, noterai che lo abbiamo contrassegnato come `watchonly`. Questo perché sappiamo che è una chiave pubblica, quindi non possiamo spendere con essa. Se non avessimo inserito questo flag, `importmulti` ci avrebbe detto qualcosa del tipo: `Mancano alcune chiavi private, gli output saranno considerati watchonly. Se ciò è intenzionale, specifica il flag watchonly.`. + + +> :book: ***Che cos'è un indirizzo watch only?*** Un indirizzo di solo controllo ti consente di controllare le transazioni relative a un indirizzo (o a un'intera famiglia di indirizzi se hai utilizzato un `xpub`), ma non spendere fondi per quegli indirizzi. + +Utilizzando `getaddressesbylabel`, ora possiamo vedere che il nostro indirizzo è stato importato correttamente nel nostro computer remoto! +``` +remote$ bitcoin-cli getaddressesbylabel "" +{ + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ": { + "purpose": "receive" + } +} +``` +## Sommario: Comprendere il Descrittore + +I descrittori ti consentono di passare chiavi pubbliche e private tra portafogli, ma soprattutto ti consentono di definire indirizzi in modo preciso e corretto e di derivare indirizzi di molti tipi diversi da un formato di descrizione standardizzato. + +> :fire: ***Qual è il potere dei descrittori?*** I descrittori ti permettono di importare ed esportare semi e chiavi. È fantastico se vuoi spostarti tra diversi portafogli. Come sviluppatore, ti consentono anche di creare il tipo preciso di indirizzi che ti interessa creare. Ad esempio, lo utilizziamo in [FullyNoded 2](https://github.com/BlockchainCommons/FullyNoded-2/blob/master/Docs/How-it-works.md) per generare un multi-sig da tre seed. + +Faremo un uso reale dei descrittori nel [Capitolo 7.3: Integrazione con Hardware Wallets](07_3_Integrazione_con_Hardware_Wallets.md), quando importeremo indirizzi da un portafoglio hardware. + +## Qual è il prossimo? + +Avanza attraverso "bitcoin-cli" con il [Capitolo 4: Inviare Transazioni Bitcoin](04_0_Inviare_Transazioni_Bitcoin.md). diff --git a/it/04_0_Inviare_Transazioni_Bitcoin.md b/it/04_0_Inviare_Transazioni_Bitcoin.md new file mode 100644 index 000000000..5ee8b56cf --- /dev/null +++ b/it/04_0_Inviare_Transazioni_Bitcoin.md @@ -0,0 +1,30 @@ +# Capitolo quattro: Inviare transazioni Bitcoin + +Questo capitolo descrive tre diversi metodi per inviare bitcoin ai normali indirizzi P2PKH dalla riga di comando, utilizzando solo l'interfaccia bitcoin-cli. + +## Obiettivi di questo capitolo + +Dopo aver letto questo capitolo, uno sviluppatore sarà in grado di: + + * Decidere come inviare denaro tramite Bitcoin + * Crea una transazione grezza "RAW" + * Utilizzare l'aritmetica per calcolare le fee, comissioni di transazione + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere le transazioni e le commissioni di transazione + * Comprendere le transazioni legacy e SegWit + * Utilizzare metodi di base per inviare denaro + * Utilizzare metodi di calcolo automatico delle commissioni per inviare denaro + * Comprendere i pericoli delle transazioni grezze + +## Sommario + + * [Sezione 4.1: Inviare Monete Modo Semplice](04_1_Inviare_Monete_Modo_Semplice.md) + * [Sezione 4.2: Creare una Transazione Grezza](04_2_Creare_una_Transazione_Grezza.md) + * [Intermezzo: Usare JQ](04_2_Intermezzo_Usare_JQ.md) + * [Sezione 4.3: Creare una Transazione Grezza con Alias](04_3_Creare_una_Transazione_Grezza_con_Alias.md) + * [Sezione 4.4: Enviare Monete con Transazione Grezza](04_4_Enviare_Monete_con_Transazione_Grezza.md) + * [Intermezzo: Usare Curl](04_4_Intermezzo_Usare_Curl.md) + * [Sezione 4.5: Inviare Monete con Transazione Grezza Automatizzata](04_5_Inviare_Monete_con_Transazione_Grezza_Automatizzata.md) + * [Sezione 4.6: Creare una Transazione Segwit](04_6_Creare_una_Transazione_Segwit.md) diff --git a/it/04_1_Inviare_Monete_Modo_Semplice.md b/it/04_1_Inviare_Monete_Modo_Semplice.md new file mode 100644 index 000000000..5f77a4d87 --- /dev/null +++ b/it/04_1_Inviare_Monete_Modo_Semplice.md @@ -0,0 +1,106 @@ +# 4.1: Inviare monete in modo semplice + +Il comando `bitcoin-cli` offre tre modi principali per inviare monete: un comando semplice; una transazione grezza; e una transazione grezza con calcolo. Ogni modo ha i propri vantaggi e svantaggi. Questo primo metodo per inviare monete è anche il più semplice. + +## Imposta la commissione di transazione + +Prima di inviare denaro sulla rete Bitcoin, dovresti pensare a quali commissioni di transazione pagherai. + +> :book: ***Che cos'è una commissione di transazione?*** _Non esiste un pranzo gratis_. I minatori incorporano le transazioni nei blocchi perché sono pagati per farlo. Non solo vengono pagati dalla rete per effettuare il blocco, ma vengono anche pagati dagli utenti per includere le loro transazioni. Se non paghi una commissione, la tua transazione potrebbe rimanere bloccata... per sempre (o, fino a quando non verrà salvata da alcuni dei trucchi nel [Capitolo 5](05_0_Controllare_Transazioni_Bitcoin.md). + +Quando utilizzi metodi semplici e automatizzati per creare transazioni, come delineato qui e nel [Capitolo 4.5: Inviare Monete con Transazione Cruda Automatizzata](04_5_Inviare_Monete_con_Transazione_Cruda_Automatizzata.md), Bitcoin calcolerà le commissioni di transazione per te. Questo viene fatto utilizzando le commissioni variabili, in cui "bitcoind" osserva quanto tempo impiegano le transazioni per essere confermate e calcola automaticamente quanto spendere. + +Puoi contribuire a controllarlo inserendo valori razionali nel tuo `~/.bitcoin/bitcoin.conf`. I seguenti valori a basso costo garantirebbero che ci fosse una commissione di transazione minima di 10.000 satoshi per kByte di dati nella transazione e richiederebbero che le commissioni variabili raggiungano un buon importo per portare la transazione da qualche parte nei successivi sei blocchi. +``` +mintxfee=0.0001 +txconfirmtarget=6 +``` +Tuttavia, partendo dal presupposto che non vuoi aspettare mentre lavori su un tutorial, abbiamo adottato i seguenti valori più alti: +``` +mintxfee=0.001 +txconfirmtarget=1 +``` +Dovresti inserirli in `~/.bitcoin/bitcoin.conf`, nella sezione principale, verso l'inizio del file o, se vuoi essere sicuro di non usarlo mai altrove, nella sezione `[test]`. + +Per completare questo tutorial, siamo disposti a spendere 100.000 satoshi per kB su ogni transazione (circa $ 10!) e vogliamo portare ogni transazione al blocco successivo! (Per metterlo in prospettiva, una transazione tipica è compresa tra 0,25 kB e 1 kB, quindi in realtà pagherai più di $ 2,50 circa $ 10... se fossero soldi veri.) + +Dopo aver modificato il tuo file `bitcoin.conf`, ti consigliamo di terminare e riavviare bitcoind. + + +``` +$ bitcoin-cli stop +$ bitcoind -daemon +``` + +## Ottieni un indirizzo + +Hai bisogno di un posto dove inviare le tue monete. Di solito, qualcuno ti invia un indirizzo e magari ti dà una firma per dimostrare di possedere quell'indirizzo. In alternativa, potrebbero fornirti un codice QR da scansionare, in modo da non poter commettere errori durante la digitazione dell'indirizzo. Nel nostro caso, invieremo monete a `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, che è un indirizzo di ritorno per un vecchio faucet Tesetnet. + +> :book: ***Cos'è un codice QR?*** Un codice QR è semplicemente la codifica di un indirizzo Bitcoin. Molti portafogli genereranno codici QR per te, mentre alcuni siti convertiranno un indirizzo in un codice QR (da evitare). Ovviamente, dovresti accettare solo un codice QR da un sito di cui ti fidi assolutamente (nessuno). Potrebbero alterare il codice e ricevere i soldi destinati a te. + +## Invia le monete + +Ora sei pronto per inviare alcune monete. In realtà questo è abbastanza semplice tramite la riga di comando. Basta usare `bitcoin-cli sendtoaddress [address] [amount]`. Quindi, per inviare una piccola moneta all'indirizzo `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi` è sufficiente: +``` +$ txid=$(bitcoin-cli sendtoaddress n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi 0.001) +$ echo $txid +93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8 +``` +> 🙏 Per mantenere in vita i faucet testnet, prova a utilizzare l'indirizzo di ritorno dello stesso faucet che hai utilizzato nel capitolo precedente sulla ricezione delle transazioni. + +Assicurati che l'indirizzo che scrivi sia quello dove vuoi che vadano i soldi. Controlla due volte. Se commetti errori in Bitcoin, non puoi tornare indietro. + +Riceverai un txid indietro quando eseguirai questo comando. + +> ❕ Potresti ritrovarti con un codice di errore se non disponi di fondi sufficienti nel tuo portafoglio per inviare la transazione. A seconda del tuo saldo attuale `bitcoin-cli getbalance` potresti dover modificare l'importo da inviare per tenere conto dell'importo inviato insieme alla commissione di transazione. Se il tuo saldo attuale è 0,001, potresti provare a inviare 0,0001. In alternativa, sarebbe meglio sottrarre la commissione prevista indicata nel messaggio di errore dal saldo attuale. Questa è una buona pratica poiché molti portafogli si aspettano che tu calcoli il tuo importo + le commissioni quando prelevi, anche tra gli exchange più popolari. + +> :warning: **AVVERTENZA:** Il comando `bitcoin-cli` genera effettivamente comandi JSON-RPC quando comunica con bitcoind. Possono essere davvero schizzinosi. Questo è un esempio: se elenchi l'importo del bitcoin senza lo zero iniziale (cioè ".1" invece di "0.1"), `bitcoin-cli fallirà` con un messaggio misterioso. + +> :warning: **AVVERTENZA:** Anche se presti attenzione ai tuoi input, potresti visualizzare il messaggio `"Fee estimation failed. Fallbackfee is disabled." `(Stima della tariffa non riuscita. La tariffa di riserva è disabilitata). Fondamentalmente, ciò significa che il tuo `bitcoind` locale non dispone di informazioni sufficienti per stimare le commissioni. Non dovresti mai vederlo se hai aspettato che la tua blockchain si sincronizzi e configuri il tuo sistema con Bitcoin Standup. Ma se non sei completamente sincronizzato, potresti vedere questo. Potrebbe anche darsi che tu non stia utilizzando un `bitcoin.conf` standard: la voce `blocksonly=1` impedirà al tuo `bitcoind` di stimare le commissioni. + +## Esamina la tua transazione + +Puoi controllare la tua transazione utilizzando il tuo ID transazione: + +``` +{ + "amount": -0.00100000, + "fee": -0.00022200, + "confirmations": 0, + "trusted": true, + "txid": "93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8", + "walletconflicts": [ + ], + "time": 1592604194, + "timereceived": 1592604194, + "bip125-replaceable": "no", + "details": [ + { + "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", + "category": "send", + "amount": -0.00100000, + "vout": 1, + "fee": -0.00022200, + "abandoned": false + } + ], + "hex": "0200000001e982921bb0189afc486e20bb05cc5825c71a0ba8868043ed04ece9ab0cb12a8e010000006a47304402200fc493a01c5c9d9574f7c321cee6880f7f1df847be71039e2d996f7f75c17b3d02203057f5baa48745ba7ab5f1d4eed11585bd8beab838b1ca03a4138516fe52b3b8012102fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9bafeffffff02e8640d0000000000160014d37b6ae4a917bcc873f6395741155f565e2dc7c4a0860100000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac780b1b00" +} +``` +Puoi vedere non solo l'importo trasferito (.001 BTC) ma anche una commissione di transazione (.000222 BTC), che è circa un quarto della commissione minima di .001 BTC/kB impostata, il che suggerisce che la transazione è stata di circa un dimensione di un quarto di kB. + +Mentre aspetti che questa transazione venga cancellata, noterai che `bitcoin-cli getbalance` mostra che tutti i tuoi soldi sono spariti (o, almeno, tutti i tuoi soldi da una singola transazione in entrata). Allo stesso modo, `bitcoin-cli listunspent` mostrerà che un'intera transazione è andata perduta, anche se era superiore a quello che volevi inviare. C'è una ragione per questo: ogni volta che ricevi soldi, devi mandarli tutti insieme, e devi fare un po' di ginnastica se vuoi davvero tenerne una parte! Ancora una volta, `sendtoaddress` si prende cura di tutto questo per te, il che significa che non devi preoccuparti di apportare modifiche finché non invii una transazione grezza. In questo caso, una nuova transazione apparirà con la tua modifica quando la tua spesa verrà incorporata in un blocco. + +## Riepilogo: inviare monete in modo semplice + +Per inviare monete nel modo più semplice, assicurati che le impostazioni predefinite della transazione siano logiche, ottieni un indirizzo e invia le monete lì. Ecco perché lo chiamano facile! + +> :fire: ***Qual è il potere di inviare monete in modo semplice?*** + +> _I vantaggi._ È facile. Non devi preoccuparti di cose arcane come gli UTXO. Non è necessario calcolare manualmente le commissioni di transazione, quindi non è probabile che tu commetta errori che ti costeranno ingenti somme di denaro. Se il tuo unico obiettivo è sederti al computer e inviare denaro, questa è la strada da percorrere. + +> _Gli svantaggi._ Il livello è alto. Hai pochissimo controllo su ciò che sta accadendo e non puoi fare nulla di speciale. Se hai intenzione di scrivere un software Bitcoin più complesso o desideri una comprensione più profonda di come funziona Bitcoin, allora il modo più semplice è solo un noioso diversivo prima di arrivare alle cose vere. + +## Con cosa andiamo avanti? + +Andiamo avanti col'invio di transazioni Bitcoin con [inviare Monete con Transazione Grezza](04_4_inviare_Monete_con_Transazione_Grezza.md). diff --git a/it/04_2_Creare_una_Transazione_Grezza.md b/it/04_2_Creare_una_Transazione_Grezza.md new file mode 100644 index 000000000..86c58d288 --- /dev/null +++ b/it/04_2_Creare_una_Transazione_Grezza.md @@ -0,0 +1,279 @@ +# 4.2 Creazione di una transazione grezza + +Ora sei pronto per creare transazioni grezze (raw) su Bitcoin. Ciò ti consente di inviare denaro ma di elaborare le transazioni con la precisione che desideri. Questa prima sezione si concentra su una semplice transazione one-input, one-output. Questo tipo di transazione _non_ è in realtà così utile, perché raramente vorrai inviare tutto il tuo denaro a una persona (a meno che tu non lo stia semplicemente inoltrando, ad esempio se stai spostando denaro da un portafoglio a un altro). Pertanto, non etichettiamo questa sezione come un modo per inviare denaro. È solo un trampolino di lancio fondamentale per _inviare effettivamente_ denaro con una transazione grezza. + +## Comprendere la transazione Bitcoin + +Prima di immergerti nella creazione effettiva di transazioni grezze, dovresti assicurarti di comprendere come funziona una transazione Bitcoin. Riguarda tutto gli UTXO. + +> :book: ***Cos'è un UTXO?*** Quando ricevi denaro nel tuo portafoglio Bitcoin, appare come una transazione individuale. Ognuna di queste transazioni è chiamata *Unspent Transaction Output* (UTXO). Non importa se vari pagamenti sono stati effettuati allo stesso indirizzo o a più indirizzi: ogni transazione in entrata rimane distinta nel tuo portafoglio come UTXO. + +Quando crei una nuova transazione in uscita, raccogli uno o più UTXO, ognuno dei quali rappresenta una moneta che hai ricevuto. Li usi come input per una nuova transazione. Insieme, il loro importo deve essere uguale a quanto vuoi spendere _o più_. Quindi, generi uno o più output, che danno il denaro rappresentato dagli input a una o più persone. Questo crea nuovi UTXO per i destinatari, che possono quindi utilizzare _quelli_ per finanziare transazioni future. + +Ecco il trucco: _tutti gli UTXO che raccogli vengono spesi per intero!_ Ciò significa che se vuoi inviare solo una parte del denaro in un UTXO a qualcun altro, allora devi anche generare un output aggiuntivo che ti rispedisca il resto! Per ora, non ci preoccuperemo di questo, ma l'uso di un indirizzo di cambio sarà fondamentale quando passeremo dalla teoria alla pratica. + +## Elenca le tue transazioni non spese + +Per creare una nuova transazione raw (grezza), devi sapere quali UTXO hai a disposizione da spendere. Puoi determinare questa informazione con il comando `bitcoin-cli listunspent`: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 20, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + }, + { + "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", + "vout": 1, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00050000, + "confirmations": 3, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 3, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] + +``` + +Questo elenco mostra tre UTXO diversi, del valore di 10000, 50000 e 22000 satoshi. Nota che ognuno ha il suo `txid` distinto e rimane distinto nel portafoglio, anche gli ultimi due, che sono stati inviati allo stesso indirizzo. + +Quando vuoi spendere un UTXO, non è sufficiente conoscere solo l'ID della transazione. Questo perché ogni transazione può avere più output! Ricordi quella prima moneta che il faucet ci ha inviato? Nella transazione, parte del denaro è andata a noi e parte a qualcun altro. Il `txid` si riferisce alla transazione complessiva, mentre un `vout` indica quale dei più output hai ricevuto. In questo elenco, ciascuna di queste transazioni è il `vout` 0 di una transazione precedente, ma _non deve essere necessariamente così_. + +Quindi, txid+vout=UTXO. Questa sarà la base di qualsiasi transazione raw. + +## Scrivi una transazione raw con un output + +Ora sei pronto a scrivere una semplice transazione raw di esempio che mostra come inviare l'intero UTXO a un'altra parte. Come notato, questo non è necessariamente un caso reale molto realistico. + +> :warning: **WARNING:** È molto facile perdere soldi con una transazione raw. Considera tutte le istruzioni sull'invio di bitcoin tramite transazioni raw come _molto_, _molto_ pericolose. Ogni volta che invii effettivamente denaro reale ad altre persone, dovresti invece utilizzare uno degli altri metodi spiegati in questo capitolo. Creare transazioni raw è estremamente utile se stai scrivendo programmi bitcoin, ma _solo_ quando stai scrivendo programmi bitcoin. (Ad esempio: scrivendo questo esempio per una versione di questo tutorial, abbiamo speso accidentalmente la transazione sbagliata, anche se aveva circa 10 volte tanto valore. Quasi tutto è andato perso dai minatori.) + +### Prepara la transazione grezza + +Per le best practice, inizieremo ogni transazione registrando attentamente i txid e i vout che spenderemo. + +In questo caso, spenderemo quella dal valore di 50000 satoshio perché è l'unica con un valore decente. +``` +$ utxo_txid="61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a" +$ utxo_vout="1" +``` + +Dovresti registrare in modo simile l'indirizzo del destinatario, per assicurarti di averlo scritto correttamente. Stiamo di nuovo inviando del denaro al faucet: +``` +$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" +``` +Come sempre, controlla attentamente le tue variabili per assicurarti che siano quelle che ti aspetti! + +``` +$ echo $utxo_txid +61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a +$ echo $utxo_vout +1 +$ echo $recipient +n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +``` +Quel destinatario è particolarmente importante, perché se sbagli, i tuoi soldi sono _andati_! (E come abbiamo già visto, scegliere la transazione sbagliata può comportare la perdita di denaro!) Quindi controlla tutto tre volte. + +### Comprendi la commissione di transazione, la fee + +Ogni transazione ha una commissione associata. È _implicita_ quando invii una transazione raw: l'importo che pagherai come commissione è sempre uguale all'importo del tuo input meno l'importo del tuo output. Quindi, devi diminuire un po' il tuo output rispetto al tuo input per assicurarti che la tua transazione venga eseguita. + +> :warning: **ATTENZIONE:** Questa è la parte molto pericolosa delle transazioni raw!! Poiché spendi automaticamente tutto l'importo negli UTXO che utilizzi, è di fondamentale importanza assicurarti di sapere: (1) esattamente quali UTXO stai utilizzando; (2) esattamente quanti soldi contengono; (3) esattamente quanti soldi stai inviando; e (4) qual è la differenza. Se sbagli e usi l'UTXO sbagliato (con più soldi di quanto pensavi) o se invii troppo poco denaro, l'eccesso è perso. Per sempre. Non commettere questo errore! Conosci i tuoi input e output _precisamente_. O meglio, non usare transazioni raw se non come parte di un programma attentamente ponderato e verificato tre volte. + +> :book: ***Quanto dovresti spendere in fees?*** [Bitcoin Fees](https://bitcoinfees.net/) ha una bella valutazione in tempo reale. Dice che "la commissione di transazione più veloce ed economica è attualmente di 42 satoshi/byte" e che "per la dimensione media della transazione di 224 byte, ciò si traduce in una commissione di 9408 satoshi". + +Attualmente Bitcoin Fees suggerisce una commissione di transazione di circa 10000 satoshi, (0,0001 BTC). Sì, è per la mainnet, non per la testnet, ma vogliamo testare le cose in modo realistico, quindi è quello che useremo. + +In questo caso, significa prendere 50000 BTC nell'UTXO che siamo selezionati, ridurli di 10000 BTC per la fee e inviare i restanti 40000 BTC. (E questo è un esempio del perché i micropagamenti non funzionano sulla rete Bitcoin, perché una commissione di transazione di circa 1$ è piuttosto costosa quando si inviano 4$, figuriamoci se si stava cercando di effettuare un micropagamento di 0,50$. Ma è sempre per questo che abbiamo Lightning.) + +> :warning: **ATTENZIONE:** Più bassa è la commissione di transazione impostata, più tempo ci vorrà prima che la transazione venga incorporata in un blocco. Il sito [Bitcoin Fees](https://bitcoinfees.net/) elenca i tempi previsti, da circa 0 blocchi a 22 blocchi. Poiché i blocchi vengono creati in media ogni 10 minuti, questa è la differenza tra pochi minuti e poche ore! Quindi, scegli una commissione di transazione appropriata per ciò che stai inviando. Nota che non dovresti mai scendere sotto la commissione di inoltro minima, che è 10000 BTC. + +### Scrivi la transazione raw + +Ora sei pronto per creare la transazione raw. Per questo utilizza il comando `createrawtransaction`, che potrebbe sembrare un po' intimidatorio. Questo perché il comando `createrawtransaction` non ti protegge completamente dal `JSON RPC` che usa `bitcoin-cli`. Invece, inserirai un array `JSON` per elencare gli `UTXO` che stai spendendo e un oggetto `JSON` per elencare gli output. + +Ecco il formato standard: +``` +$ bitcoin-cli createrawtransaction +'''[ + { + "txid": "'$your_txid'", + "vout": '$your_vout' + } +]''' +'''{ + "'$your_recipient'": bitcoin_amount + }''' + ``` +Eh sì, ci sono tutti i tipi di virgolette folli lì, ma fidati che faranno la cosa giusta. Usa `'''` per contrassegnare l'inizio e la fine dell'array JSON e dell'oggetto JSON. Proteggi parole normali come `"this"`, ma non devi proteggere numeri normali: `0`. Se sono variabili, inserisci virgolette singole, come `"'$this_word'"` e `'$this_num'`. (Uffa. Ti ci abituerai.) + +Ecco un comando che crea una transazione raw per inviare il tuo $utxo al tuo $recipient + ``` +$ rawtxhex=$(bitcoin-cli createrawtransaction '''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' '''{ "'$recipient'": 0.0004 }''') +$ echo $rawtxhex +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f3610100000000ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +``` + +### Verifica la tua transazione raw + +Dovresti quindi verificare la tua transazione raw con `decoderawtransaction` per assicurarti che faccia la cosa giusta. +``` +$ bitcoin-cli decoderawtransaction $rawtxhex +{ + "txid": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", + "hash": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", + "version": 2, + "size": 85, + "vsize": 85, + "weight": 340, + "locktime": 0, + "vin": [ + { + "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00040000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + ] + } + } + ] +} +``` + +Controlla il `vin`. Stai spendendo la transazione giusta? Contiene l'importo di denaro previsto? (Controlla con `bitcoin-cli gettransaction` e assicurati di guardare il `vout` giusto.) Controlla il tuo `vout`. Stai inviando l'importo giusto? Va all'indirizzo giusto? Infine, fai i calcoli per assicurarti che il denaro sia in pareggio. Il valore dell'UTXO meno l'importo speso è uguale alla commissione di transazione prevista? + +> :information_source: **NOTA - SEQUENZA:** Potresti notare che ogni input ha un numero di sequenza, impostato qui su 4294967295, che è 0xFFFFFFFF. Questa è l'ultima frontiera delle transazioni Bitcoin, perché è un campo standard nelle transazioni che era originariamente destinato a uno scopo specifico, ma non è mai stato completamente implementato. Quindi ora c'è questo intero in giro nelle transazioni che potrebbe essere riutilizzato per altri usi. E, in effetti, lo è stato. Al momento in cui scrivo, ci sono tre diversi utilizzi per la variabile chiamata `nSequence` nel codice Bitcoin Core: abilita RBF, `nLockTime` e timelock relativi. Se non succede nulla di strano, `nSequence` verrà impostato su 4294967295. Impostandolo su un valore inferiore, si segnala che sta succedendo qualcosa di speciale. + +### Firma la transazione raw + +A oggi, la tua transazione raw è solo qualcosa di teorico: potresti inviarla, ma non ti è stato promesso nulla. Devi fare alcune cose per farla uscire sulla rete. + +Per prima cosa, devi firmare la tua transazione raw: + +``` + +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex +{ + "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", + "complete": true +} +$ signedtx="02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000" +``` +Nota che abbiamo catturato manualmente l'esadecimale firmato, anziché cercare di analizzarlo dall'oggetto JSON. Un pacchetto software chiamato "JQ" potrebbe fare di meglio, come spiegheremo in un prossimo interludio. + +### Invia la transazione raw + +Ora hai una transazione raw pronta all'uso, ma non conta finché non la metti effettivamente in rete, cosa che fai con il comando `sendrawtransaction`. Riceverai un txid: + +``` +$ bitcoin-cli sendrawtransaction $signedtx +a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a +``` + +Vedrai immediatamente che l'UTXO e il suo denaro sono stati rimossi dal tuo portafoglio: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 23, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 6, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] + +$ bitcoin-cli getbalance +0.00032000 +``` + +Presto `listtransactions` dovrebbe mostrare una transazione confermata della categoria `send`. +``` + { + "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", + "category": "send", + "amount": -0.00040000, + "vout": 0, + "fee": -0.00010000, + "confirmations": 1, + "trusted": true, + "txid": "a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a", + "walletconflicts": [ + ], + "time": 1592608574, + "timereceived": 1592608574, + "bip125-replaceable": "no", + "abandoned": false + } +``` +Puoi vedere che corrisponde all'indirizzo `txid` e `recipient`. Non solo mostra l'`importo` inviato, ma mostra anche la `commissione` della transazione. E ha già ricevuto una conferma, perché abbiamo offerto una commissione che lo avrebbe rapidamente inserito in un blocco. + +Congratulazioni! Ora sei più povero di qualche satoshi! + +## Riepilogo: creazione di una transazione raw + +Quando le monete entrano nel tuo portafoglio Bitcoin, rimangono come importi distinti, chiamati UTXO. Quando crei una transazione raw per inviare quel denaro, utilizzi uno o più UTXO per pagare (come fondere le monete d'oro e ricomporle a seconda del bisogno). Puoi quindi creare una transazione raw, firmarla e inviarla sulla rete Bitcoin. Tuttavia, questa è solo una base: di solito dovrai creare una transazione raw con più output per inviare effettivamente qualcosa sulla rete Bitcoin! + +## Cosa c'è dopo? + +Ne vale la pena impiegare qualche minuto per capire meglio come [usare JQ](04_2_Intermezzo_Usare_JQ.md). diff --git a/it/04_2_Intermezzo_Usare_JQ.md b/it/04_2_Intermezzo_Usare_JQ.md new file mode 100644 index 000000000..12bd0c822 --- /dev/null +++ b/it/04_2_Intermezzo_Usare_JQ.md @@ -0,0 +1,424 @@ +# Interludio: utilizzo di JQ + +La creazione di una transazione raw ha rivelato come i risultati più complessi di bitcoin-cli non possano essere facilmente salvati in variabili della riga di comando. La risposta è JQ, che consente di filtrare singoli elementi da dati JSON più complessi. + +## Installa JQ + +Per le versioni moderne di Debian, dovresti essere in grado di installare JQ usando `apt-get`: + +``` +# apt-get install jq +``` +> :book: ***Che cos'è JQ?*** cito "`jq` è come `sed` per i dati `JSON`: puoi usarlo per suddividere, filtrare, mappare e trasformare i dati strutturati e giocare con il testo con la stessa facilità di `sed` , `awk`, `grep` e compagnia bella." + +Se funziona, il gioco è fatto! + +Altrimenti, puoi scaricare JQ da un [repository Github](https://stedolan.github.io/jq/). Basta scaricare un file binario per Linux, OS X o Windows, a seconda dei casi. + +Una volta scaricato il binario, puoi installarlo sul tuo sistema. Se stai lavorando su un VPS Debian come suggeriamo, la tua installazione sarà simile a questa: +``` +$ mv jq-linux64 jq +$ sudo /usr/bin/install -m 0755 -o root -g root -t /usr/local/bin jq +``` +## Usa `JQ` per accedere al valore di un oggetto `JSON` tramite chiave + +**Esempio di utilizzo:** _Cattura l'esadecimale da una transazione grezza firmata._ + +Nella sezione precedente, l'uso di "signrawtransaction" ha offerto un esempio di impossibilità di acquisire facilmente i dati in variabili a causa dell'uso dell'output JSON: +``` +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex +{ + "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", + "complete": true +} +``` +Fortunatamente, JQ può facilmente acquisire dati di questo tipo! + +Per utilizzare JQ, esegui `jq` nel backend di una pipe `|` e utilizza sempre l'invocazione standard di `jq -r`. La `-r` dice a JQ di produrre un output grezzo, raw, che funzionerà per le variabili della riga di comando, mentre il `.` dice a jq di produrre l'output. Proteggiamo questo argomento in `' '` perché avremo bisogno di quella protezione in seguito quando le nostre chiamate a `'jq` diventeranno più complesse. + +Per acquisire un valore specifico da un oggetto JSON, elenca semplicemente la chiave dopo `.`: + +``` +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex' +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +``` +Con questo strumento in mano, puoi acquisire informazioni dagli oggetti JSON alle variabili della riga di comando: +``` +$ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex') +$ echo $signedtx +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +``` +È quindi possibile utilizzare tali variabili facilmente e senza errori: +``` +$ bitcoin-cli sendrawtransaction $signedtx +3f9ccb6e16663e66dc119de1866610cc4f7a83079bfec2abf0598ed3adf10a78 +``` +## Utilizza JQ per accedere ai valori di singoli oggetti JSON in un array tramite chiave + +**Esempio di utilizzo:** _Cattura txid e vout per un UTXO selezionato._ + +Ottenere dati da un oggetto JSON è semplice, ma cosa succede se l'oggetto JSON si trova in un array JSON? Il comando `listunspent` offre un ottimo esempio, perché solitamente conterrà un numero di transazioni diverse. E se volessi acquisire informazioni specifiche da _uno_ di essi? + +Quando lavori con un array JSON, la prima cosa che devi fare è dire a JQ a quale indice accedere. Ad esempio, potresti aver esaminato le tue transazioni in "listunspent" e aver deciso di voler lavorare con la seconda. Si usa `'.[1]'` per accedere al secondo elemento. `[ ]` dice che stiamo facendo riferimento a un array JSON e `1` dice che vogliamo il primo indice. +``` +$ bitcoin-cli listunspent | jq -r '.[1]' +{ + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022, + "confirmations": 9, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true +} +``` +È quindi possibile acquisire un singolo valore dall'array selezionato (1)] utilizzando una pipe _all'interno_ degli argomenti JQ; e poi (2) richiedere successivamente il valore specifico, come nell'esempio precedente. Quanto segue catturerebbe il `txid` dal primo oggetto JSON nell'array JSON prodotto da `listunspent`: +``` +$ bitcoin-cli listunspent | jq -r '.[1] | .txid' +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c +``` +Notare attentamente come le virgolette ` ' ' ` stanno dappertutto nelle espressione JQ _inclusa_ la pipe `|` . + +Questo metodo può essere utilizzato per compilare le variabili per un UTXO che desideri utilizzare: +``` +$ newtxid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') +$ newvout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') +$ echo $newtxid +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c +$ echo $newvout +0 +``` +Ecco! Ora potremmo creare una nuova transazione grezza utilizzando il nostro primo UTXO come input, senza dover digitare manualmente nessuna delle informazioni UTXO! + +## Utilizza JQ per accedere ai valori degli oggetti JSON corrispondenti in un array in base alla chiave + +**Esempio di utilizzo:** _Elenca il valore di tutti gli UTXO non spesi._ + +Invece di accedere a un singolo valore specifico in un oggetto JSON specifico, potresti invece accedere a tutto un valore specifico in tutti gli oggetti JSON. Questo viene fatto con `.[]`, dove non è specificato alcun indice. Ad esempio, questo elencherebbe tutti i fondi non spesi: +``` +$ bitcoin-cli listunspent | jq -r '.[] | .amount' +0.0001 +0.00022 +``` + +## Usa JQ per fare calcoli semplici tramite chiave + +**Esempio di utilizzo:** _Somma il valore di tutti gli UTXO non spesi._ + +A questo punto, puoi iniziare a utilizzare l'output JQ per semplici calcoli. Ad esempio, sommando i valori delle transazioni non spese con un semplice script `awk` otterresti l'equivalente di `getbalance`: +``` +$ bitcoin-cli listunspent | jq -r '.[] | .amount' | awk '{s+=$1} END {print s}' +0.00032 +$ bitcoin-cli getbalance +0.00032000 +``` + +## Utilizza JQ per visualizzare più valori di oggetti JSON in un array tramite più chiavi + +**Esempio di utilizzo:** _Elenca le informazioni sull'utilizzo per tutti gli UTXO._ + +JQ può facilmente acquisire singoli elementi da oggetti e array JSON e inserirli in variabili. Questo sarà il suo utilizzo principale nelle sezioni future. Tuttavia, può anche essere utilizzato per ridurre "enormi quantità" di informazioni prodotte da "bitcoin-cli" in "quantità ragionevoli" di informazioni. + +Ad esempio, potresti voler vedere un elenco di tutti i tuoi UTXO (`.[]`) e ottenere un elenco di tutte le loro informazioni più importanti (`.txid, .vout, .amount`): +``` +$ bitcoin-cli listunspent | jq -r '.[] | .txid, .vout, .amount' +ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36 +0 +0.0001 +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c +0 +0.00022 +``` +Ciò rende facile decidere quali UTXO spendere in una transazione grezza, ma non è molto carino. + +Fortunatamente, JQ ti permette anche di essere fantasioso. Puoi utilizzare `{}` per creare nuovi oggetti JSON (per analisi aggiuntive o per un output gradevole). Puoi anche definire il nome della nuova chiave per ciascuno dei tuoi valori. L'output risultante dovrebbe essere molto più intuitivo e meno soggetto a errori (anche se ovviamente meno utile per scaricare informazioni direttamente nelle variabili). + +L'esempio seguente mostra esattamente la stessa analisi di "listunspent", ma con ogni vecchio oggetto JSON ricostruito come un nuovo oggetto JSON abbreviato, con tutti i nuovi valori denominati con le loro vecchie chiavi: +``` +$ bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }' +{ + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "amount": 0.0001 +} +{ + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "amount": 0.00022 +} +``` +Ovviamente potresti rinominare le tue nuove chiavi come ritieni opportuno. Non c'è niente di magico nei nomi originali scelti da Satoshi: +``` +$ bitcoin-cli listunspent | jq -r '.[] | { tx: .txid, output: .vout, bitcoins: .amount }' +{ + "tx": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "output": 0, + "bitcoins": 0.0001 +} +{ + "tx": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "output": 0, + "bitcoins": 0.00022 +} +``` +## Utilizza JQ per accedere agli oggetti JSON in base al valore cercato + +**Esempio di utilizzo:** _Cerca automaticamente gli UTXO utilizzati in una transazione._ + +Le ricerche JQ finora sono state abbastanza semplici: si utilizza una chiave per cercare uno o più valori in un oggetto o array JSON. Ma cosa succede se invece desideri cercare un valore in un oggetto JSON... tramite un altro valore? Questo tipo di ricerca indiretta ha una reale applicabilità quando lavori con transazioni basate su UTXO esistenti. Ad esempio, può consentire di calcolare il valore totale degli UTXO utilizzati in una transazione, cosa di vitale importanza. + +Questo esempio utilizza la seguente transazione raw. Si noti che questa è una transazione grezza più complessa con due input e due output. Impareremo a realizzarli in alcune sezioni; per ora è necessario saper offrire esempi robusti. Nota che a differenza dei nostri esempi precedenti, questo ha due oggetti nell'array "vin" e due nell'array "vout". +``` +$ bitcoin-cli decoderawtransaction $rawtxhex +{ + "txid": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e", + "hash": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e", + "size": 160, + "vsize": 160, + "version": 2, + "locktime": 0, + "vin": [ + { + "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.00000000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 cfc39be7ea3337c450a0c77a839ad0e160739058 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914cfc39be7ea3337c450a0c77a839ad0e16073905888ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mzTWVv2QSgBNqXx7RC56zEhaQPve8C8VS9" + ] + } + }, + { + "value": 0.04500000, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 166692bda9f25ced145267bb44286e8ee3963d26 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914166692bda9f25ced145267bb44286e8ee3963d2688ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mhZQ3Bih6wi7jP1tpFZrCcyr4NsfCapiZP" + ] + } + } + ] +} +``` + +### Recupera i valori + +Supponiamo di sapere esattamente come è costruita questa transazione: sappiamo che utilizza due UTXO come input. Per recuperare il txid per i due UTXO, potremmo usare `jq` per cercare il valore .vin della transazione, quindi fare riferimento all'array 0 di .vin, quindi al valore .txid di quell'array. Successivamente, potremmo fare lo stesso con il primo array, quindi lo stesso con i due valori .vout di .vin. Facile: + +``` +$ usedtxid1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .txid') +$ echo $usedtxid1 +d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c +$ usedtxid2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .txid') +$ echo $usedtxid2 +c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b + +$ usedvout1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .vout') +$ echo $usedvout1 +1 +$ usedvout2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .vout') +$ echo $usedvout2 +1 +``` +Tuttavia, sarebbe meglio avere un caso generale che salvi _automaticamente_ tutti i txid dei nostri UTXO. + +Sappiamo già che possiamo accedere a tutti i file `.txid` utilizzando un valore di array `.[]`. Possiamo usarlo per creare una ricerca generale .txid: +``` +$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) +$ echo ${usedtxid[0]} +d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c +$ echo ${usedtxid[1]} +c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b + +$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) +$ echo ${usedvout[0]} +1 +$ echo ${usedvout[1]} +1 +``` +L'unico vero trucco qui è il modo in cui abbiamo salvato le informazioni utilizzando la shell bash. Invece di salvare in una variabile con `$(command)`, abbiamo invece salvato in un array con `($(command))`. Siamo quindi riusciti ad accedere ai singoli elementi dell'array bash con una costruzione `${variable[n]}`. Potremmo invece accedere all'intero array con `${variable[@]}`. (Sì, nessuno ha mai detto che Bash fosse carino.) + +> :avviso: **ATTENZIONE:** Ricorda sempre che un UTXO è una transazione _più_ un vout. Abbiamo mancato il vout la prima volta che abbiamo scritto questo esempio JQ e ha smesso di funzionare quando ci siamo ritrovati in una situazione in cui ci erano stati inviati due `vout` dalla stessa transazione. + +### Recupera gli oggetti correlati + +Ora puoi utilizzare le informazioni "txid" e "vout" salvate per fare riferimento agli UTXO in "listunspent". Per trovare le informazioni sugli UTXO utilizzati dalla transazione grezza, è necessario esaminare l'intero array JSON (`[]`) delle transazioni non spese. Puoi quindi scegliere (`select`) singoli oggetti JSON che includono (`contains`) i txid. Si _poi_ si selezionano (`select`) le transazioni tra quelle che _anche_ contengono (`contain`) il vout corretto. + +L'uso di un altro livello di pipe è la metodologia standard di JQ: prendi una serie di dati, poi li riduci a tutte le transazioni rilevanti, quindi li riduci ai vout che sono stati effettivamente utilizzati da quelle transazioni. Tuttavia, gli argomenti `select` e `contains` sono qualcosa di nuovo. Mostrano parte della complessità di JSON che va oltre lo scopo di questo tutorial; per ora sappi solo che questa particolare invocazione funzionerà per catturare oggetti corrispondenti. + +Per iniziare in modo semplice, seleziona i due UTXO uno alla volta: +``` +$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[0]}'")) | select(.vout | contains('${usedvout[0]}'))' +{ + "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", + "vout": 1, + "address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH", + "scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac", + "amount": 0.9, + "confirmations": 6, + "spendable": true, + "solvable": true +} +$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[1]}'")) | select(.vout | contains('${usedvout[1]}'))' +{ + "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", + "vout": 1, + "address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q", + "scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac", + "amount": 0.4, + "confirmations": 5, + "spendable": true, + "solvable": true +} +``` +Un semplice bash for-loop potrebbe invece darti _tutti_ i tuoi UTXO: +``` +$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout'))'; done; +{ + "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", + "vout": 1, + "address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH", + "scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac", + "amount": 0.9, + "confirmations": 7, + "spendable": true, + "solvable": true +} +{ + "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", + "vout": 1, + "address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q", + "scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac", + "amount": 0.4, + "confirmations": 6, + "spendable": true, + "solvable": true +} + +``` +Nota che abbiamo utilizzato ancora un altro elemento brutto dell'array `${#usedtxid[*]}` per determinare la dimensione dell'array, quindi abbiamo effettuato l'accesso a ciascun valore nell'array `usedtxid` e a ciascun valore nell'array parallelo `usedvout`, inserendo trasformarli in variabili più semplici per un accesso meno brutto. + +## Usa JSON per calcoli semplici in base al valore + +**Esempio di utilizzo:** _Calcola automaticamente il valore degli UTXO utilizzati in una transazione._ + +Ora puoi fare un ulteriore passo avanti e richiedere il .amount (o qualsiasi altro valore-chiave JSON) dagli UTXO che stai recuperando. + +Questo esempio ripete l'utilizzo degli array `$usedtxid` e `$usedvout` impostati come segue: +``` +$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) +$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) +``` +Lo stesso script "for" può essere utilizzato per scorrere questi array, ma con una pipe aggiunta nel JQ che restituisce il valore `amount` per ciascuno degli UTXO selezionati. +``` +$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done; +0.9 +0.4 +``` +A questo punto puoi anche sommare gli .amounts con uno script `awk`, per vedere realmente quanti soldi ci sono negli UTXO che la transazione sta spendendo: +``` +$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done | awk '{s+=$1} END {print s}' +1.3 +``` +Wow! + +## Usa JQ per calcoli complessi + +**Esempio di utilizzo:** _Calcola la commissione per una transazione._ + +Per calcolare la commissione di transazione completa a questo punto è necessario solo un ulteriore calcolo: determinare quanti soldi passano attraverso il `.vout`. Questo è un semplice utilizzo di JQ in cui devi semplicemente usare `awk` per riassumere il `valore` di tutte le informazioni `vout`: +``` +$ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}' +1.045 +``` +Per completare il calcolo della commissione di transazione, sottrai l'importo .vout .(1.045) dall'importo .vin (1.3). + +Per fare ciò, dovrai installare `bc`: + +``` +$ sudo apt-get install bc +``` + +Mettendo tutto insieme si crea una calcolatrice completa in sole cinque righe di script: +``` +$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) +$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) +$ btcin=$(for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done | awk '{s+=$1} END {print s}') +$ btcout=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}') +$ echo "$btcin-$btcout"| /usr/bin/bc +.255 +``` +E questo è anche un buon esempio del motivo per cui ricontrolli le tue commissioni: avevamo intenzione di inviare una commissione di transazione di 5.000 satoshi, ma invece abbiamo inviato 255.000 satoshi. Ops! + +> :avviso: **ATTENZIONE:** La prima volta che abbiamo scritto questa lezione, abbiamo effettivamente calcolato male la nostra tariffa e non l'abbiamo vista finché non abbiamo eseguito il nostro calcolatore delle tariffe. È *così* facile sbagliare, poi i tuoi soldi sono finiti. (L'esempio sopra è in realtà tratto dalla nostra seconda iterazione della calcolatrice e quella volta abbiamo commesso l'errore di proposito.) + +Per ulteriori magie JSON (e se qualcosa non è chiaro), leggi il [Manuale JSON](https://stedolan.github.io/jq/manual/) e il [Cookbook JSON](https:// github.com/stedolan/jq/wiki/Cookbook). Utilizzeremo regolarmente JQ negli esempi futuri. + +## Crea alcuni nuovi alias + +Il codice JQ può essere un po' ingombrante, quindi dovresti considerare di aggiungere alcune invocazioni più lunghe e interessanti al tuo ~/.bash_profile. + +Ogni volta che stai esaminando una grande massa di informazioni in un oggetto JSON generato da un comando `bitcoin-cli`, valuta la possibilità di scrivere un alias per ridurlo a ciò che vuoi vedere. +``` +alias btcunspent="bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }'" +``` + +## Esegui lo script della commissione di transazione + +Lo [Script di calcolo della tariffa](src/04_2_i_txfee-calc.sh) è disponibile nella directory src-code. Puoi scaricarlo e salvarlo come `txfee-calc.sh`. + +> :avviso: **ATTENZIONE:** Questo script non è stato controllato in modo approfondito. Se hai intenzione di usarlo per verificare le commissioni di transazione reali, dovresti farlo solo come triplo controllo dopo aver già fatto tutti i conti da solo. + +Assicurati che le autorizzazioni sullo script siano corrette: +``` +$ chmod 755 txfee-calc.sh +``` +È quindi possibile eseguire lo script come segue: +``` +$ ./txfee-calc.sh $rawtxhex +.255 +``` +Potresti anche voler creare un alias: +``` +alias btctxfee="~/txfee-calc.sh" +``` + +## Riepilogo: utilizzo di JQ + +JQ semplifica l'estrazione di informazioni da array e oggetti JSON. Può anche essere utilizzato negli script di shell per calcoli abbastanza complessi che ti semplificheranno la vita. + +## Cosa viene dopo? + +Continua a inviare Bitcoin" qui [Capitolo 4.3: Creare una Transazione Grezza con Alias](04_3_Creare_una_Transazione_Grezza_con_Alias.md). + diff --git a/it/04_3_Creare_una_Transazione_Grezza_con_Alias.md b/it/04_3_Creare_una_Transazione_Grezza_con_Alias.md new file mode 100644 index 000000000..06304f989 --- /dev/null +++ b/it/04_3_Creare_una_Transazione_Grezza_con_Alias.md @@ -0,0 +1,99 @@ +# 4.3 Creare una transazione raw con alias + +A volte può essere scoraggiante capire l'ordine giusto per gli argomenti di un comando bitcoin-cli. Fortunatamente, puoi usare _Named Arguments_ come alternativa. + +> :avviso: **AVVERTIMENTO VERSIONE:** Questa è un'innovazione di Bitcoin Core v 0.14.0. Se hai utilizzato i nostri script di installazione, questo è ciò che dovresti avere, ma ricontrolla la tua versione in caso di problemi. C'è anche un bug nell'uso degli argomenti con nome da parte del comando `createrawtransaction` che sarà presumibilmente corretto nella versione 0.14.1. + +## Crea un alias + +Per utilizzare un alias devi eseguire `bitcoin-cli` con l'argomento `-named`. Se prevedi di farlo regolarmente, probabilmente vorrai creare un alias: +``` +alias bitcoin-cli="bitcoin-cli -named" +``` +Come al solito, è per la tua facilità d'uso, ma continueremo a utilizzare tutti i comandi per mantenerne la chiarezza. + +## Prova un alias + +Per sapere quali sono i nomi degli argomenti di un comando, consulta `bitcoin-cli help`. Elencherà gli argomenti nel loro ordine corretto, ma ora fornirà anche i nomi per ciascuno di essi. + +Ad esempio, `bitcoin-cli help getbalance` elenca questi argomenti: + + 1. dummy [used to be account] + 2. minconf + 3. include_watchonly + 4. avoid_reuse + +Quanto segue mostra un utilizzo tradizionale e non intuitivo di "getbalance" utilizzando l'argomento di conferma minima: +``` +$ bitcoin-cli getbalance "*" 1 +``` +Con gli argomenti con nome è piu chiaro vedere cosa stai facendo, e cosi riduci al minimo gli errori: +``` +$ bitcoin-cli -named getbalance minconf=1 +``` + +## Prova una transazione raw + +Ecco come apparirebbero i comandi per l'invio di una transazione grezza con argomenti denominati: + +``` +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00001 }''') +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex +{ + "txid": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", + "hash": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", + "version": 2, + "size": 85, + "vsize": 85, + "weight": 340, + "locktime": 0, + "vin": [ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00001000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + ] + } + } + ] +} + +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +e70dd2aa13422d12c222481c17ca21a57071f92ff86bdcffd7eaca71772ba172 +``` +Ecco! Hai inviato un'altra transazione grezza utilizzando alias `-named`, ma questa volta in modo piu chiaro e riducendo errori. + +> :warning: **AVVERTIMENTO VERSIONE:** È qui che si manifesta il bug in Bitcoin Core 0.14: l'argomento `inputs` per `createrawtransaction` è chiamato erroneamente `transactions`. Quindi, se utilizzi Bitcoin Core 0.14.0, sostituisci l'argomento denominato `inputs` con `transazioni` per questo e gli esempi futuri. Tuttavia, a partire da Bitcoin Core 0.14.1, questo codice dovrebbe funzionare come mostrato. +> **UPDATE** Ormai siamo a luglio del 2024 e abbiamo la versione Bitcoin Core 27.0, funziona tutto. + +## Riepilogo: creazione di una transazione grezza con alias + +Eseguendo `bitcoin-cli` con il flag `-named`, puoi utilizzare alias anziché dipendere da argomenti ordinati. `bitcoin-cli help` qui vedrai sempre il nome giusto per ogni argomento. Ciò può comportare un codice più robusto, più facile da leggere e meno soggetto a errori. + +_Questi documenti utilizzeranno alias per tutti gli esempi futuri, per chiarezza e per stabilire le migliori pratiche. Tuttavia, mostrerà anche tutti gli argomenti nell'ordine corretto. Quindi, se preferisci non utilizzare argomenti con nome, rimuovi semplicemente il flag '-named' e tutti i "name=" e gli esempi dovrebbero continuare a funzionare correttamente._ + +## Con cosa andiamo avanti? + +Continua a inviare bitcoin, guarda come farlo con una transazione raw qui: [Capitolo 4.4 Inviare Monete con Transazione Grezza](04_4_Inviare_Monete_con_Transazione_Grezza.md). diff --git a/it/04_4_Intermezzo_Usare_Curl.md b/it/04_4_Intermezzo_Usare_Curl.md new file mode 100644 index 000000000..19b308874 --- /dev/null +++ b/it/04_4_Intermezzo_Usare_Curl.md @@ -0,0 +1,321 @@ +# Interludio: Usare Curl + +`bitcoin-cli` è in definitiva solo un wrapper. È un modo per interfacciarsi con `bitcoind` dalla riga di comando, fornendo un accesso semplificato ai suoi numerosi comandi RPC. Naturalmente è possibile accedere direttamente a RPC. Ecco di cosa tratta questo interludio: connettersi direttamente a RPC con il comando `curl`. + +Non verrà utilizzato molto nei capitoli futuri, ma è un elemento importante che puoi vedere come un accesso alternativo a `bitcoind` se preferisci. + +## Capire CURL + +`curl`, abbreviazione di `vedi URL`, è uno strumento da riga di comando che ti consente di accedere direttamente agli URL in modo programmatico. È un modo semplice per interagire con server come `bitcoind` che ascoltano le porte su Internet e che parlano una varietà di protocolli. Curl è disponibile anche come libreria per molti linguaggi di programmazione, come C, Java, PHP e Python. Quindi, una volta che sai come lavorare con Curl, avrai una solida base per utilizzare molte API diverse. + +Per utilizzare `curl` con `bitcoind`, devi conoscere tre cose: il formato standard, il nome utente e la password e la porta corretta. + +### Capire il format + +I comandi `bitcoin-cli` sono tutti collegati ai comandi RPC in `bitcoind`. Ciò rende molto semplice la transizione dall'utilizzo di `bitcoin-cli` all'utilizzo di `curl`. Infatti, se guardi una qualsiasi delle pagine di aiuto di `bitcoin-cli`, vedrai che elencano non solo i comandi `bitcoin-cli`, ma anche i comandi paralleli `curl`. Ad esempio, ecco `bitcoin-cli help getmininginfo`: +``` +$ bitcoin-cli aiuta a ottenere informazioni sul mining +getmininginfo + +Restituisce un oggetto json contenente informazioni relative al mining. +Risultato: + +{ (json object) + `blocks` : n, (numeric) The current block + `currentblockweight` : n, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled) + `currentblocktx` : n, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled) + `difficulty` : n, (numeric) The current difficulty + `networkhashps` : n, (numeric) The network hashes per second + `pooledtx` : n, (numeric) The size of the mempool + `chain` : `str`, (string) current network name (main, test, regtest) + `warnings` : `str` (string) any network and blockchain warnings +} + +Esempi: +> bitcoin-cli getmininginfo +> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ +``` +Ecco il comando `curl`, alla fine della schermata di aiuto! Questo comando piuttosto lungo è composto da quattro parti principali: (1) il tuo nome utente; (2) un flag `--data-binary`; (3) un oggetto JSON che dice a `bitcoind` cosa fare, incluso un array di parametri JSON; e (4) un'intestazione HTTP che include l'URL `bitcoind`. + +Quando lavori con `curl`, la maggior parte degli argomenti di `curl` rimarranno gli stessi da comando a comando; in genere cambieranno solo le voci `method` e `params` nell'array JSON. Tuttavia, devi sapere come inserire il tuo nome utente e il tuo indirizzo URL per farlo funzionare in primo luogo! + +_Ogni volta che non sei sicuro su come eseguire il curling di un comando RPC, guarda la guida di bitcoin-cli e vai da lì._ + +### Conosci il tuo nome utente + +Per parlare co'l porto `bitcoind`, hai bisogno di un nome utente e una password. Questi sono stati creati come parte della configurazione iniziale di Bitcoin e possono essere trovati in `~/.bitcoin/bitcoin.conf`. + +Ad esempio, ecco la nostra configurazione attuale: +``` +$ cat ~/.bitcoin/bitcoin.conf +server=1 +dbcache=1536 +par=1 +maxuploadtarget=137 +maxconnections=16 +rpcuser=StandUp +rpcpassword=8eaf562eaf45c33c3328bc66008f2dd1 +rpcallowip=127.0.0.1 +debug=tor +prune=550 +testnet=1 +mintxfee=0.001 +txconfirmtarget=1 +[test] +rpcbind=127.0.0.1 +rpcport=18332 +[main] +rpcbind=127.0.0.1 +rpcport=8332 +[regtest] +rpcbind=127.0.0.1 +rpcport=18443 +``` +Il nostro nome utente è `StandUp` e la tua password è `8eaf562eaf45c33c3328bc66008f2dd1`. + +> **ATTENZIONE:** Chiaramente non è molto sicuro avere queste informazioni in un file di testo. A partire da Bitcoin Core 0.12, puoi invece omettere `rpcpassword` dal tuo file `bitcoin.conf` e fare in modo che `bitcoind` generi un nuovo cookie ogni volta che si avvia. Lo svantaggio è che rende più difficile l'uso dei comandi RPC da parte di altre applicazioni, come quelle descritte in questo capitolo. Quindi per ora ci atterremo alle semplici informazioni `rpcuser` e `rpcpassword`, ma per il software di produzione, considera il passaggio ai cookie. + +Il modo sicuro per RPC con `bitcoind` è il seguente: + +``` +$ curl --user StandUp --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ +Enter host password for user 'bitcoinrpc': +``` +Come notato, ti verrà richiesta la password. + +> :link: **TESTNET vs MAINNET:** Testnet utilizza un URL con porta 18332 e mainnet utilizza un URL con porta 8332. Dai un'occhiata al tuo `bitcoin.conf`, è tutto disposto lì. + +Il modo non sicuro per farlo è il seguente: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ +``` +> **ATTENZIONE:** L'immissione della password sulla riga di comando potrebbe inserire la password nella tabella dei processi e/o salvarla in una cronologia. Questo è ancora meno consigliato che inserirlo in un file, tranne che per i test su testnet. Se vuoi farlo altrove, assicurati di sapere cosa stai facendo! + +### Conosere comandi e parametri + +Con tutto questo in mano, sei pronto per inviare comandi RPC standard con `curl`... ma devi ancora sapere come incorporare i due elementi che tendono a cambiare nel comando `curl`. + +Il primo è `metodo`, ovvero il metodo RPC utilizzato. In genere dovrebbe corrispondere ai nomi dei comandi che hai inserito in `bitcoin-cli` per anni. + +Il secondo è `params`, che è un array di parametri JSON. Questi sono gli stessi argomenti (o argomenti denominati) che hai utilizzato. Costituiscono anche la parte più confusa di `curl`, in gran parte perché sono un array strutturato anziché un semplice elenco. + +Ecco come appariranno alcuni array di parametri: + + * `[]` - Un array vuoto + * `["000b4430a7a2ba60891b01b718747eaf9665cb93fbc0c619c99419b5b5cf3ad2"]` - Un array con dati + * `["'$signedhex'"]` - Un array con una variabile + * `[6, 9999999]` - Un array con due parametri + * `{}` - Un oggetto vuoto + * `[''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.298, "'$changeaddress'": 1.0}'']` - Un array con un array contenente un oggetto e un oggetto semplice + +## Ottenere informazioni + +Ora puoi inviare il tuo primo comando `curl` accedendo all'RPC `getmininginfo`: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ +{"result":{"blocks":1772428,"difficulty":10178811.40698772,"networkhashps":91963587385939.06,"pooledtx":61,"chain":"test","warnings":"Warning: unknown new rules activated (versionbit 28)"},"error":null,"id":"curltest"} +``` + +Tieni presente che abbiamo fornito il metodo, `getmininginfo`, e il parametro, '[]', ma tutto il resto era la riga di comando `curl` standard. + +> **ATTENZIONE:** Se ottieni un risultato come "Impossibile connettersi alla porta 127.0.0.1 8332: connessione rifiutata", assicurati che una riga come `rpcallowip=127.0.0.1` sia nel tuo ~/.bitcoin/bitcoin .conf. Se le cose continuano a non funzionare, assicurati di consentire l'accesso alla porta 18332 (o 8332) da localhost. La nostra configurazione standard del [Capitolo due: Configurare Bitcoin-Core VPS](02_0_Configurare_Bitcoin-Core_VPS.md) dovrebbe fare tutto questo. + +Il risultato è un altro array JSON, che sfortunatamente è brutto da leggere se usi `curl` manualmente. Fortunatamente, puoi ripulirlo semplicemente collegandolo tramite `jq`: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed +100 295 100 218 100 77 72666 25666 --:--:-- --:--:-- --:--:-- 98333 +{ + "result": { + "blocks": 1772429, + "difficulty": 10178811.40698772, + "networkhashps": 90580030969896.44, + "pooledtx": 4, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" + }, + "error": null, + "id": "curltest" +} +``` +Vedrai un po' di report sulla connettività man mano che i dati vengono scaricati, quindi quando i dati raggiungono `jq`, tutto verrà visualizzato in un formato con rientro corretto. (Negli esempi futuri ometteremo le informazioni di download.) + +## Maneggiare il tuo portafoglio + +Anche se accedi direttamente a `bitcoind`, avrai comunque accesso alle funzionalità del portafoglio, perché sono in gran parte archiviate in `bitcoind` stesso. + +### Cercare indirizzi + +Utilizza l'RPC `getaddressesbylabel` per elencare tutti i tuoi indirizzi attuali: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getaddressesbylabel", "params": [""] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": { + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE": { + "purpose": "receive" + }, + "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff": { + "purpose": "receive" + }, + "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B": { + "purpose": "receive" + }, + "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d": { + "purpose": "receive" + }, + "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6": { + "purpose": "receive" + }, + "tb1qmtucvjtga68kgrvkl7q05x4t9lylxhku7kqdpr": { + "purpose": "receive" + } + }, + "error": null, + "id": "curltest" +} +``` +Questo è il nostro primo esempio di parametro reale, `""`. Questo è il parametro `label` richiesto per `getaddressesbylabel`, ma tutti i nostri indirizzi sono sotto l'etichetta predefinita, quindi qui non è stato richiesto nulla di speciale. + +Il risultato è un elenco di tutti gli indirizzi che sono stati utilizzati da questo portafoglio... alcuni dei quali presumibilmente contengono fondi. + +### Cercare i fondi + +Utilizza l'RPC `listunspent` per elencare i fondi che hai a disposizione: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": [ + { + "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", + "vout": 1, + "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", + "amount": 0.0009, + "confirmations": 4, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022, + "confirmations": 19, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } + ], + "error": null, + "id": "curltest" +} +``` +Questo è quasi esattamente lo stesso output che ricevi quando digiti `bitcoin-cli listunspent`, mostrando quanto siano strettamente legate le due interfacce. Se non è necessaria alcuna pulizia o ulteriore aiuto, `bitcoin-cli` restituisce semplicemente l'RPC. Facile! + +### Crea un indirizzo + +Dopo aver saputo dove sono i tuoi fondi, il passo successivo nella creazione di una transazione è ottenere un cambio di indirizzo. A questo punto probabilmente hai capito come funziona e sai che per semplici comandi RPC, tutto ciò che devi fare è modificare il `metodo` è il comando `curl`: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "mrSqN37TPs89GcidSZTvXmMzjxoJZ6RKoz", + "error": null, + "id": "curltest" +} +``` + +> **AVVERTENZA:** L'ordine dei parametri è importante quando si inviano comandi RPC utilizzando curl. C'è solo un argomento per `getrawchangeaddress`, ma considera il suo cugino stretto `getnewaddress`. Richiede due argomenti: prima etichetta, poi tipo. Se inviassimo lo stesso `"params": ["legacy"]` invece di `"params": ["", "legacy"]`, otterremmo un indirizzo `bech32` con l'etichetta `"legacy"` invece di un indirizzo `legacy`, quindi presta attenzione all'ordine! + +A questo punto, possiamo anche tornare alla nostra pratica standard di salvare i risultati in variabili con l'aiuto aggiuntivo di `jq`: + +``` +$ newaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') +$ echo $newaddress +mqdfnjgWr2r3sCCeuTDfe8fJ1CnycF2e6R +``` +Non è necessario preoccuparsi delle informazioni di download. Andrà su `STDERR` e verrà visualizzato sullo schermo, mentre i risultati andranno su `STDOUT` e verranno salvati nella tua variabile. + +## Crea una transazione + +Ora sei pronto per creare una transazione con `curl`. + +### Prepara le tue variabili + +Proprio come con `bitcoin-cli`, per creare una transazione eseguendo i comandi RPC, dovresti prima salvare le tue variabili. L'unico cambiamento qui è che 'curl' crea un oggetto JSON che include un valore-chiave `result`, quindi devi sempre reindirizzare il tag `.result` prima di fare qualsiasi altra cosa. + +Questo esempio imposta le nostre variabili per utilizzare 1,2985 BTC nei fondi elencati nella prima transazione non spesa sopra: + +``` +$ utxo_txid=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .txid') +$ utxo_vout=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .vout') +$ recipient=mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf +$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') + +$ echo $utxo_txid +e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d +$ echo $utxo_vout +1 +$ echo $recipient +mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf +$ echo $changeaddress +n2jf3MzeFpFGa7wq8rXKVnVuv5FoNSJZ1N +``` +### Crea la transazione + +La transazione creata con `curl` è molto simile alla transazione creata con `bitcoin-cli`, ma con alcune sottili differenze: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "02000000010d6acd0356db222ca3a7ee7fa1e3044316223ceec1f64b58aeb2e0de921007e70100000000ffffffff0230750000000000001976a914ac19d3fd17710e6b9a331022fe92c693fdf6659588ac50c30000000000001976a9147021efec134057043386decfaa6a6aa4ee5f19eb88ac00000000", + "error": null, + "id": "curltest" +} +``` + +Il cuore della transazione è, ovviamente, l'array JSON `params`, che stiamo sfruttando appieno per la prima volta. + +Tieni presente che l'intero `params` è alloggiato in `[]` per contrassegnare l'array dei parametri. + +Abbiamo anche variato le citazioni rispetto a come funzionavano le cose in `bitcoin-cli`, per iniziare e terminare ogni array e oggetto all'interno dell'array `params` con `''` invece del nostro tradizionale `'''`. Questo perché l'intero set di argomenti JSON è già racchiuso da un `'`. Come al solito, basta dare un'occhiata alla bizzarra citazione della shell e abituarsi. + +Tuttavia, c'è un'ultima cosa degna di nota in questo esempio, e può essere _esasperante_ se te la perdi. Quando hai eseguito un comando `createrawtransaction` con `bitcoin-cli`, l'array JSON degli input e l'oggetto JSON degli output erano parametri distinti, quindi erano separati da uno spazio. Ora, poiché fanno parte dell'array JSON `params`, sono separati da una virgola (`,`). Perdilo e otterrai un `errore di analisi` senza molte informazioni aggiuntive. + +> **ATTENZIONE:** Hai mai avuto problemi con il debug del tuo `curl`? Aggiungi l'argomento `--trace-ascii /tmp/foo`. Le informazioni complete su ciò che viene inviato al server verranno salvate in `/tmp/foo` (o qualunque nome di file fornisca). + +Dopo aver verificato che le cose funzionino, probabilmente vorrai salvare il codice esadecimale in una variabile: + + +``` +$ hexcode=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') +``` + +### Firma e invia + +Firmare e inviare la transazione utilizzando `curl` è un facile utilizzo dell'RPC `signrawtransactionwithwallet` e `sendrawtransaction`: + +``` +$ signedhex=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "signrawtransactionwithwallet", "params": ["'$hexcode'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .hex') + +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "sendrawtransaction", "params": ["'$signedhex'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", + "error": null, + "id": "curltest" +} +``` +## Riepilogo: accesso a Bitcoind con Curl + +Dopo aver terminato questa sezione, potresti pensare che accedere a `bitcoind` tramite `curl` sia molto simile ad accedervi tramite `bitcoin-cli`... ma più complicato. E avresti ragione. `bitcoin-cli` ha funzionalità RPC piuttosto complete, quindi tutto ciò che fai tramite `curl` probabilmente puoi farlo tramite `bitcoin-cli`. Ecco perché continueremo a concentrarci su `bitcoin-cli` dopo questa digressione. + +Ma ci sono ancora ragioni per cui dovresti usare `curl` invece di `bitcoin-cli`: + +_Qual è il potere di curl?_ Ovviamente, `curl` elimina un livello di indiretto. Invece di lavorare con `bitcoin-cli` che invia comandi RPC a `bitcoind`, invii questi comandi RPC direttamente. Ciò consente una programmazione più solida, perché non devi preoccuparti di quali cose inaspettate potrebbe fare `bitcoin-cli` o di come potrebbe cambiare nel tempo. Tuttavia, stai anche muovendo i primi passi verso l'utilizzo di un linguaggio di programmazione più completo rispetto alle scarse opzioni offerte da uno script di shell. Come vedrai negli ultimi capitoli di questo, potresti effettivamente vedere che le librerie curl sono altre funzioni per accedere ai comandi RPC in una varietà di linguaggi di programmazione: ma è ancora molto lontano. + +## Qual è il prossimo passo? +Scopri un altro modo per "Inviare transazioni Bitcoin" qui: [Capitolo 4.5: InviareMonete con Transazione Grezza Automatizzata](04_5_Inviare_Monete_con_Transazione_Grezza_Automatizzata.md). diff --git a/it/04_4_Inviare_Monete_con_Transazione_Grezza.md b/it/04_4_Inviare_Monete_con_Transazione_Grezza.md new file mode 100644 index 000000000..8dddad99e --- /dev/null +++ b/it/04_4_Inviare_Monete_con_Transazione_Grezza.md @@ -0,0 +1,197 @@ + +# 4.4: Inviare monete con transazioni grezze + +Come notato all'inizio di questo capitolo, l'interfaccia `bitcoin-cli` offre tre modi principali per inviare monete. [Capitolo 4.1](04_1_Inviare_Monete_Modo_Semplice.md) ha parlato dell'invio nel primo modo, utilizzando il comando `sendtoaddress`. Da allora, abbiamo sviluppato dettagli su come inviare monete in un secondo modo, con transazioni grezze. [Capitolo 4.2](04_2_Creare_una_Transazione_Grezza.md) ha insegnato come creare una transazione non elaborata, nel [Interludio](04_2_Intermezzo_Usare_JQ.md) è stato spiegato JQ e nel[Capitolo 4.3](04_3_Creare_una_Transazione_Grezza_con_Alias.md) è stato spiegato come usare alias. + +Ora possiamo metterli insieme e inviare effettivamente fondi utilizzando una transazione grezza. + +## Crea un indirizzo di resto + +La nostra transazione grezza di esempio nella sezione §4.2 era molto semplicistica: abbiamo inviato l'intero UTXO a un nuovo indirizzo. Più frequentemente, vorrai inviare a qualcuno una somma di denaro che non corrisponde a un UTXO. Ma ricorderai che il denaro in eccesso da un UTXO che non viene inviato al destinatario diventa semplicemente una commissione di transazione. Quindi, come puoi inviare a qualcuno solo una parte di un UTXO, mantenendo il _resto_ per te? + +La soluzione è _inviare_ il resto dei fondi a un secondo indirizzo, un indirizzo di resto che hai creato nel tuo portafoglio appositamente per riceverli: + +``` +$ changeaddress=$(bitcoin-cli getrawchangeaddress legacy) +$ echo $changeaddress +mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h +``` +Tieni presente che utilizza una nuova funzione: `getrawchangeaddress`. È in gran parte uguale a `getnewaddress` ma è ottimizzato per l'uso come cambio di indirizzo in una transazione grezza, quindi non fa cose come inserire voci nella tua rubrica. Abbiamo nuovamente selezionato l'indirizzo "legacy", invece di utilizzare l'indirizzo predefinito "bech32", semplicemente per coerenza. Questa è una situazione in cui sarebbe stato del tutto sicuro generare un indirizzo Bech32 predefinito, semplicemente utilizzando `bitcoin-cli getrawchangeaddress`, perché verrebbe inviato e ricevuto da te sul tuo nodo Bitcoin Core che lo supporta pienamente. Ma sposteremo anche questo su Bech32 nel [Capitolo 4.6](04_6_Creare_una_Transazione_Segwit.md). + +Ora hai un indirizzo aggiuntivo nel tuo portafoglio, così puoi ricevere il resto da un UTXO! Per utilizzarlo, dovrai creare una transazione grezza con due output. + +## Scegli un numero sufficiente di UTXO + +La nostra transazione grezza di esempio era semplice anche per un altro aspetto: presupponeva che ci fosse abbastanza denaro in un singolo UTXO per coprire la transazione. Spesso sarà così, ma a volte vorrai creare transazioni che spendono più soldi di quelli che hai in un singolo UTXO. Per fare ciò, è necessario creare una transazione grezza con due (o più) input. + +## Scrivi una vera transazione grezza + +Per riassumere: la creazione di una vera transazione grezza per inviare monete a volte richiederà più input e quasi sempre richiederà più output, uno dei quali è un indirizzo di resto. Creeremo questo tipo di transazione più realistica qui, in un nuovo esempio che mostra un esempio di vita reale di invio di fondi tramite la seconda metodologia di Bitcoin, le transazioni grezze. + +Utilizzeremo il UTXO numero 0 e il numero 2: + +``` +$ bitcoin-cli listunspent +[ +[ + { + "txid": "0619fecf6b2668fab1308fbd7b291ac210932602a6ac6b8cc11c7ae22c43701e", + "vout": 1, + "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + "label": "", + "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", + "amount": 0.00899999, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 15, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + }, + { + "txid": "0df23a9dba49e822bbc558f15516f33021a64a5c2e48962cec541e0bcc79854d", + "vout": 0, + "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + "label": "", + "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", + "amount": 0.00100000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", + "safe": true + } +] + +``` +Nel nostro esempio, invieremo .009 BTC, che è (appena) più grande di uno dei nostri UTXO. Ciò richiede la loro combinazione, quindi l'utilizzo del nostro indirizzo di resto per recuperare i fondi non spesi. + +### Imposta le tue variabili + +Abbiamo già le variabili `$changeaddress` e `$recipient` degli esempi precedenti: + +``` +$ echo $changeaddress +mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h +$ echo $recipient +n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +``` +Dobbiamo anche registrare txid e vout per ciascuno dei nostri due UTXO. Dopo aver identificato gli UTXO che vogliamo spendere, possiamo utilizzare le nostre tecniche JQ per assicurarci che l'accesso ad essi sia privo di errori: +``` +$ utxo_txid_1=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout_1=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') +$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') +``` + +### Scrivere la transazione + +Scrivere la transazione grezza effettiva è sorprendentemente semplice. Tutto quello che devi fare è includere un oggetto JSON aggiuntivo, separato da virgole nell'array JSON di input e un'ulteriore coppia chiave-valore separata da virgole nell'oggetto JSON di output. + +Ecco l'esempio. Nota gli input multipli dopo l'argomento 'inputs' e gli output multipli dopo l'argomento 'outputs'. +``` +$ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.009, "'$changeaddress'": 0.0009 }''') +``` +Siamo stati _molto_ attenti fare i nostri calcoli finanziari. Questi due UTXO contengono 0,00999999 BTC. Dopo aver inviato 0,009 BTC, ci rimarranno 0,00099999 BTC. Abbiamo scelto 0,00009999 BTC come commissione di transazione. Per accogliere tale commissione, impostiamo il resto su .0009 BTC. Se avessimo sbagliato i nostri calcoli e invece avessimo impostato la modifica su .00009 BTC, quei BTC aggiuntivi andrebbero dritti ai minatori! Se ci fossimo dimenticati di apportare il resto, tutto l'eccesso sarebbe scomparso. Quindi, ancora una volta, _fai attenzione_. + +Fortunatamente, possiamo ricontrollare con l'alias `btctxfee` di JQ Interlude: + +``` +$ ./txfee-calc.sh $rawtxhex2 +.00009999 +``` + +### Finire la transazione + +Ora puoi firmare, sigillare e consegnare la tua transazione, che sarà tua (e del faucet): + +``` +$ signedtx2=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex2 | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx2 +e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d +``` + +### Aspettare + +Come al solito, i tuoi soldi continueranno a fluire per un po': il resto non sarà disponibile fino a quando la transazione non verrà effettivamente confermata e ti verrà dato un nuovo UTXO. + +Ma, in 10 minuti o meno (probabilmente), avrai indietro i tuoi soldi rimanenti e sara di nuovo completamente spendibile. Per ora stiamo ancora aspettando: + +``` +$ bitcoin-cli listunspent +[ + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 15, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] +``` +E il resto prima o poi arriverà: +``` +[ + { + "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", + "vout": 1, + "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", + "amount": 0.00090000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 16, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] +``` + +Questo potrebbe anche essere un buon momento per controllare con un blockchain explorer, in modo da poter vedere in modo più intuitivo come sono disposti gli input, gli output e le commissioni di transazione:[e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://live.blockcypher.com/btc-testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d/). + +## Riepilogo: invio di monete con transazioni grezze + +Per inviare monete con transazioni grezze, è necessario creare una transazione grezza con uno o più input (per avere fondi sufficienti) e uno o più output (per recuperare il resto). Quindi, puoi seguire la normale procedura di utilizzo di `createrawtransaction` con argomenti con nome e JQ, come illustrato nelle sezioni precedenti. + +> :fire: ***Qual è il potere di inviare monete con transazioni grezze?*** + +> _I vantaggi._ Ti dà il massimo controllo. Se il tuo obiettivo è scrivere uno script o un programma Bitcoin più intricato, probabilmente utilizzerai transazioni grezze in modo da sapere esattamente cosa sta succedendo. Questa è anche la situazione _più sicura_ per utilizzare transazioni grezze, perché puoi assicurarti a livello di programmazione di non commettere errori. + +> _Gli svantaggi._ È facile perdere soldi. Non ci sono avvisi, protezioni e stop programmati a meno che tu non li scriva. È anche noioso. La formattazione è odiosa, anche utilizzando l'interfaccia `bitcoin-cli` facile da usare, e devi fare molte ricerche e calcoli a mano. + +## Qual è il prossimo? + +Vedere un altro modo alternativo per inserire comandi con [Curl](04_4_Intermezzo_Usare_Curl.md). + +Oppure, preferisci saltare quella che è francamente una digressione, imparare un altro modo per "Inviare transazioni Bitcoin" con [Capitolo 4.5: Inviare Monete con Transazione Grezza Automatizzata](04_5_Inviare_Monete_con_Transazione_Grezza_Automatizzata.md). diff --git a/it/04_5_Inviare_Monete_con_Transazione_Grezza_Automatizzata.md b/it/04_5_Inviare_Monete_con_Transazione_Grezza_Automatizzata.md new file mode 100644 index 000000000..8ee0b461c --- /dev/null +++ b/it/04_5_Inviare_Monete_con_Transazione_Grezza_Automatizzata.md @@ -0,0 +1,178 @@ +# 4.5: Inviare monete con transazioni grezze automatizzate + +Questo capitolo illustra tre modi per inviare fondi tramite l'interfaccia CLI di Bitcoin. [Capitolo 4.1](04_1_Inviare_Monete_Modo_Semplice.md) ha descritto come farlo con un semplice comando e [Capitolo 4.4](04_4_Inviare_Monete_con_Transazione_Grezza.md) ha spiegato in dettaglio come utilizzare una transazione grezza più pericolosa. Questa sezione finale risolve la differenza mostrando come rendere le transazioni grezze più semplici e sicure. + +## Lascia che Bitcoin calcoli per te + +La metodologia per le transazioni grezze automatizzate è semplice: crei una transazione grezza, ma usi il comando "fundrawtransaction" per chiedere a bitcoind di eseguire i calcoli per te. + +Per utilizzare questo comando, dovrai assicurarti che il tuo file ~/.bitcoin/bitcoin.conf contenga variabili razionali per il calcolo delle commissioni di transazione. Consulta [Capitolo 4.1: Inviare Monete Modo Semplice](04_1_Inviare_Monete_Modo_Semplice.md) per ulteriori informazioni a riguardo. + +Per numeri molto conservativi, abbiamo suggerito di aggiungere quanto segue a `bitcoin.conf`: +``` +mintxfee=0.0001 +txconfirmtarget=6 +``` +Per far avanzare il tutorial (e più in generale per spostare velocemente il denaro) abbiamo suggerito quanto segue: +``` +mintxfee=0.001 +txconfirmtarget=1 +``` + +## Crea una transazione grezza semplice semplice + +Per utilizzare `fundrawtransaction` devi prima creare una transazione semplice che elenchi _no_ input e _no_ cambi di indirizzo. Elencherai semplicemente il destinatario e l'importo che desideri inviargli, in questo caso `$recipient` e `0.00020000` BTC. +``` +$ recipient=n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +$ unfinishedtx=$(bitcoin-cli -named createrawtransaction inputs='''[]''' outputs='''{ "'$recipient'": 0.0002 }''') +``` + +## Finanzia la tua transazione semplice + +Quindi dici a 'bitcoin-cli' di finanziare quella transazione semplice: + +``` +$ bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx +{ + "hex": "02000000012db87641c6a21e5a68b20c226428544978e6ac44964d5d8060d7388000c584eb0100000000feffffff02204e0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac781e0000000000001600140cc9cdcf45d4ea17f5227a7ead52367aad10a88400000000", + "fee": 0.00022200, + "changepos": 1 +} +``` +Ciò fornisce molte informazioni utili, ma una volta che sei sicuro di come funziona, ti consigliamo di utilizzare JQ per salvare il tuo esadecimale in una variabile, come al solito: +``` +$ rawtxhex3=$(bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx | jq -r '.hex') +``` +## Verifica la tua transazione finanziata + +Sembra una magia, quindi le prime volte che usi `fundrawtransaction`, probabilmente vorrai verificarlo. + +L'esecuzione di `decoderawtransaction` mostrerà che la transazione grezza è ora strutturata correttamente, utilizzando uno o più dei tuoi UTXO e inviando i fondi in eccesso a un indirizzo di resto: + +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 +{ + "txid": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", + "hash": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", + "version": 2, + "size": 116, + "vsize": 116, + "weight": 464, + "locktime": 0, + "vin": [ + { + "txid": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00020000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + ] + } + }, + { + "value": 0.00007800, + "n": 1, + "scriptPubKey": { + "asm": "0 a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "hex": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r" + ] + } + } + ] +} +``` +La cosa interessante qui è l'indirizzo di resto, che è il secondo "vout". Nota che è un indirizzo "tb1", il che significa che è Bech32; quando abbiamo dato a Bitcoin Core la totale capacità di gestire il nostro resto, lo ha fatto utilizzando il suo tipo di indirizzo predefinito, Bech32, e ha funzionato bene. Ecco perché il nostro indirizzo di resto non è un grosso problema, come vedrai nel [Capitolo 4.6](04_6_Creare_una_Transazione_Segwit.md) , ma ci sono alcuni trucchi per un utilizzo più ampio, di cui parleremo lì. + +Sebbene abbiamo visto la commissione nell'output di `fundrawtransaction`, non è visibile qui. Tuttavia, puoi verificarlo con lo script JQ `txfee-calc.sh` creato in [JQ Interludio](04_2_Intermezzo_Usare_JQ.md): +``` +$ ~/txfee-calc.sh $rawtxhex3 +.000222 +``` +Infine, puoi utilizzare `getaddressinfo` per vedere che l'indirizzo di modifica generato appartiene davvero a te: + +``` +$ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r +{ + "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "ismine": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", + "iswatchonly": false, + "isscript": false, + "iswitness": true, + "witness_version": 0, + "witness_program": "a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "pubkey": "038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5", + "ischange": true, + "timestamp": 1592335137, + "hdkeypath": "m/0'/1'/10'", + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "hdmasterfingerprint": "d6043800", + "labels": [ + ] +} +``` +Nota i risultati di `ismine`. + +## Invia la tua transazione finanziata + +A questo punto potrai firmare e inviare la transazione come di consueto. + +``` +$ signedtx3=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex3 | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx3 +8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa +``` +In pochi minuti avrai indietro il resto: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa", + "vout": 1, + "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "amount": 0.00007800, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", + "safe": true + } +] +``` + +## Riepilogo: invio di monete con transazioni grezze automatizzate + +Se devi inviare fondi con transazioni grezze, allora "fundrawtransaction" ti offre una bella alternativa in cui commissioni, input e output vengono calcolati per te, in modo da non perdere accidentalmente un sacco di soldi. + +> :fire: ***Qual è il potere di inviare monete con transazioni grezze automatizzate?*** + +> _I vantaggi._ Fornisce un buon equilibrio. Se invii fondi manualmente e "sendtoaddress" non offre un controllo sufficiente per qualsiasi motivo, puoi ottenere alcuni dei vantaggi delle transazioni grezze senza i pericoli. Questa metodologia dovrebbe essere utilizzata quando possibile se si inviano transazioni grezze manualmente. + +> _Gli svantaggi._ È un miscuglio. Sebbene esistano alcune opzioni aggiuntive per il comando "fundrawtransaction" che non sono state menzionate qui, il tuo controllo è comunque limitato. Probabilmente non vorrai mai utilizzare questo metodo se stessi scrivendo un programma in cui l'obiettivo è sapere esattamente cosa sta succedendo. + +## Qual è il prossimo argomento? + +Completa il tuo "Invio di transazioni Bitcoin" con [Capitolo 4.6: Creare una Transazione Segwit](04_6_Creare_una_Transazione_Segwit.md). + diff --git a/it/04_6_Creare_una_Transazione_Segwit.md b/it/04_6_Creare_una_Transazione_Segwit.md new file mode 100644 index 000000000..311fa0faa --- /dev/null +++ b/it/04_6_Creare_una_Transazione_Segwit.md @@ -0,0 +1,302 @@ +# 4.6: Creazione di una transazione SegWit + +> :information_source: **NOTA:** Questa sezione è stata aggiunta di recente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvertito. + +C'era una volta, i cieli dei Bitcoin tremavano a causa delle guerre dei blocchi. Le tariffe erano alle stelle e gli utenti erano preoccupati per il ridimensionamento. Gli sviluppatori di Bitcoin Core erano riluttanti ad aumentare semplicemente la dimensione dei blocchi, ma sono giunti a un compromesso: SegWit, the Segregated Witness. Testimone Segregato è un modo elegante per dire "Firma Separata". Crea nuovi tipi di transazioni che rimuovono le firme alla fine della transazione. Combinando questo con dimensioni di blocchi aumentate che sono visibili solo ai nodi aggiornati, SegWit ha risolto i problemi di ridimensionamento per Bitcoin in quel momento (e ha anche risolto un brutto bug di malleabilità che in precedenza aveva reso impraticabile un ridimensionamento ancora migliore con protocolli di livello 2 come Lightning). + +L'inghippo? SegWit utilizza indirizzi diversi, alcuni dei quali sono compatibili con i nodi più vecchi e altri no. + +> :warning: **AVVERTIMENTO VERSIONE:** SegWit è stato introdotto in BitCoin 0.16.0 con quello che all'epoca veniva descritto come "supporto completo". Detto questo, all'epoca c'erano alcuni difetti nella sua integrazione con "bitcoin-cli" che impedivano il corretto funzionamento della firma sui nuovi indirizzi P2SH-SegWit. L'indirizzo Bech32 non compatibile con le versioni precedenti è stato introdotto anche in Bitcoin 0.16.0 ed è stato reso il tipo di indirizzo predefinito in Bitcoin 0.19.0. Tutte queste funzionalità ora dovrebbero funzionare completamente per quanto riguarda le funzioni `bitcoin-cli` (e quindi questo tutorial). + +> Il problema sta nell'interagire con il mondo esterno. Tutti dovrebbero essere in grado di inviare a un indirizzo P2SH-SegWit perché è stato appositamente creato per supportare la compatibilità con le versioni precedenti racchiudendo la funzionalità SegWit in uno script Bitcoin. Lo stesso non vale per gli indirizzi Bech32: se qualcuno ti dice che non è in grado di inviare al tuo indirizzo Bech32, ecco perché, e devi generare un indirizzo `legacy` o P2SH-SegWit per il loro utilizzo. (Molti siti, in particolare gli exchange, non possono nemmeno generare o ricevere indirizzi SegWit, in particolare indirizzi Bech32, ma questo è un problema completamente diverso e non influisce sul tuo utilizzo.) + +## Comprendere una transazione SegWit + +Nelle transazioni classiche, le informazioni sulla firma (testimone) venivano archiviate verso la metà della transazione, mentre nelle transazioni SegWit si trovano in fondo. Ciò va di pari passo con l'aumento delle dimensioni dei blocchi introdotti nell'aggiornamento SegWit. La dimensione del blocco è stata aumentata da 1M a un importo variabile in base al numero di transazioni SegWit presenti in un blocco, partendo da 1M (nessuna transazione SegWit) e arrivando fino a 4M (tutte le transazioni SegWit). Questa dimensione variabile è stata creata per accogliere i nodi classici, in modo che tutto rimanga compatibile con le versioni precedenti. Se un nodo classico vede una transazione SegWit, elimina le informazioni testimone (risultando in un blocco di dimensioni più piccole, sotto il vecchio limite di 1 milione), mentre se un nuovo nodo vede una transazione SegWit, mantiene le informazioni testimone (risultando in una transazione SegWit più grande blocco, fino al nuovo limite di 4M). + +Ecco il cosa e come delle transazioni SegWit. Non che tu abbia bisogno di sapere tutto cio per usarle. La maggior parte delle transazioni sulla rete Bitcoin ora sono SegWit. Sono ciò che utilizzerai nativamente per inviare e ricevere denaro. I dettagli a questo punto non sono più rilevanti dei particolari su come funziona la maggior parte di Bitcoin. + + +## Crea un indirizzo SegWit + +Puoi creare un indirizzo SegWit allo stesso modo di qualsiasi altro indirizzo, con i comandi `getnewaddress` e `getrawchangeaddress`. + +Se devi creare un indirizzo per qualcuno che non può inviare ai nuovi indirizzi Bech32, utilizza il tipo di indirizzo `p2sh-segwit`: + +``` +$ bitcoin-cli -named getnewaddress address_type=p2sh-segwit +2N5h2r4karVqN7uFtpcn8xnA3t5cbpszgyN +``` +Se vedi un indirizzo con il prefisso "2" significa che hai fatto bene. + +> :link: **TESTNET vs MAINNET:** "3" per Mainnet. + +Tuttavia, se la persona con cui stai interagendo ha un cliente completo e aggiornato, sarà in grado di inviare a un indirizzo Bech32, che creerai utilizzando i comandi nel modo predefinito: + +``` +$ bitcoin-cli getnewaddress +tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 +``` +Come abbiamo già visto, gli indirizzi di modifica generati da `bitcoin-cli` interagiscono bene con gli indirizzi Bech32, quindi non ha senso usare il flag `legacy` neanche lì: +``` +$ bitcoin-cli getrawchangeaddress +tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff +``` +Qui, nota che il prefisso univoco "tb1" denotava Bech32. + +> :link: **TESTNET vs MAINNET:** "bc1" per mainnet. + +A `bitcoin-cli` non importa quale tipo di indirizzo stai utilizzando. Puoi eseguire un comando come `listaddressgroupings` e mescolerà liberamente indirizzi di diversi tipi: +``` +$ bitcoin-cli listaddressgroupings +[ + [ + [ + "mfsiRhxbQxcD7HLS4PiAim99oeGyb9QY7m", + 0.01000000, + "" + ] + ], + [ + [ + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + 0.00000000, + "" + ], + [ + "tb1q6dak4e9fz77vsulk89t5z92l2e0zm37yvre4gt", + 0.00000000 + ] + ], + [ + [ + "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + 0.00022000, + "" + ] + ], + [ + [ + "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + 0.00000000 + ], + [ + "mqjrdY5raxKzXQf5t2VvVvzhvFAgersu9B", + 0.00000000 + ], + [ + "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + 0.00000000, + "" + ], + [ + "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + 0.00007800 + ] + ], + [ + [ + "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", + 0.01000000, + "" + ] + ], + [ + [ + "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", + 0.01000000, + "" + ] + ] +] +``` + +## Invia una transazione SegWit nel modo più semplice + +Allora come si invia una transazione Segwit? Esattamente come qualsiasi altra transazione. Non importa se l'UTXO è SegWit, l'indirizzo è SegWit o una combinazione di questi. Puoi aspettarti che `bitcoin-cli` faccia la cosa giusta. Anche se puoi notare le differenze tramite gli indirizzi, non sono importanti per l'interazione con le cose a livello di "bitcoin-cli" o RPC. (E questo è uno dei vantaggi dell'utilizzo della riga di comando e dell'interfaccia RPC, come suggerito in questo tutorial: gli esperti hanno già svolto il duro lavoro per te, comprese cose come come inviare sia agli indirizzi legacy che a quelli Bech32. Utilizza tale funzionalità a proprio vantaggio.) + +Ecco un esempio di invio a un indirizzo SegWit, nel modo più semplice: + +``` +$ bitcoin-cli sendtoaddress tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005 +854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42 +``` +Se guardi la tua transazione, puoi vedere l'uso dell'indirizzo Bech32: +``` +$ bitcoin-cli -named gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42" verbose=true +{ + "amount": -0.00500000, + "fee": -0.00036600, + "confirmations": 0, + "trusted": true, + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "walletconflicts": [ + ], + "time": 1592948795, + "timereceived": 1592948795, + "bip125-replaceable": "no", + "details": [ + { + "address": "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", + "category": "send", + "amount": -0.00500000, + "vout": 1, + "fee": -0.00036600, + "abandoned": false + } + ], + "hex": "0200000002114d5a4c3b847bc796b2dc166ca7120607b874aa6904d4a43dd5f9e0ea79d4ba010000006a47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042dfeffffffa71321e81ef039af490251379143f7247ad91613c26c8f3e3404184218361733000000006a47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7efeffffff026854160000000000160014d591091b8074a2375ed9985a9c4b18efecfd416520a1070000000000160014751e76e8199196d454941c45d1b3a323f1433bd6c60e1b00", + "decoded": { + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "hash": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "version": 2, + "size": 366, + "vsize": 366, + "weight": 1464, + "locktime": 1773254, + "vin": [ + { + "txid": "bad479eae0f9d53da4d40469aa74b8070612a76c16dcb296c77b843b4c5a4d11", + "vout": 1, + "scriptSig": { + "asm": "304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7[ALL] 03ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d", + "hex": "47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d" + }, + "sequence": 4294967294 + }, + { + "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", + "vout": 0, + "scriptSig": { + "asm": "304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a316[ALL] 0339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e", + "hex": "47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01463400, + "n": 0, + "scriptPubKey": { + "asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165", + "hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh" + ] + } + }, + { + "value": 0.00500000, + "n": 1, + "scriptPubKey": { + "asm": "0 751e76e8199196d454941c45d1b3a323f1433bd6", + "hex": "0014751e76e8199196d454941c45d1b3a323f1433bd6", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx" + ] + } + } + ] + } +} +``` +Infatti, entrambi i `vouts` utilizzano indirizzi Bech32: Il destinatario e l'indirizzo di resto generato automaticamente. + +Ma quando torniamo indietro al nostro "vin", scopriamo che proviene da un indirizzo `legacy`. Ma perche non importa: +``` +$ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7" +{ + "amount": 0.01000000, + "confirmations": 43, + "blockhash": "00000000000000e2365d2f814d1774b063d9a04356f482010cdfdd537b1a24bb", + "blockheight": 1773212, + "blockindex": 103, + "blocktime": 1592937103, + "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", + "walletconflicts": [ + ], + "time": 1592936845, + "timereceived": 1592936845, + "bip125-replaceable": "no", + "details": [ + { + "address": "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 0 + } + ], + "hex": "020000000001016a66efa334f06e2c54963e48d049a35d7a1bda44633b7464621cae302f35174a0100000017160014f17b16c6404e85165af6f123173e0705ba31ec25feffffff0240420f00000000001976a914626ab1ca41d98f597d18d1ff8151e31a40d4967288acd2125d000000000017a914d5e76abfe5362704ff6bbb000db9cdfa43cd2881870247304402203b3ba83f51c1895b5f639e9bfc40124715e2495ef2c79d4e49c0f8f70fbf2feb02203d50710abe3cf37df4d2a73680dadf3cecbe4f2b5d0b276dbe7711d0c2fa971a012102e64f83ee1c6548bcf44cb965ffdb803f30224459bd2e57a5df97cb41ba476b119b0e1b00" +} +``` + +## Invia una transazione SegWit nel modo più difficile + +Allo stesso modo puoi finanziare una transazione con un indirizzo Bech32 senza alcuna differenza rispetto alle tecniche che hai imparato finora. Ecco come farlo esattamente con una transazione grezza completa: + +``` +$ changeaddress=$(bitcoin-cli getrawchangeaddress) +$ echo $changeaddress +tb1q4xje3mx9xn7f8khv7p69ekfn0q72kfs8x3ay4j +$ bitcoin-cli listunspent +[ +... + { + "txid": "003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452", + "vout": 0, + "address": "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", + "label": "", + "scriptPubKey": "0014a226e1dfd08537b02de04f667a49bd46f9b9f578", + "amount": 0.01000000, + "confirmations": 5, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/0'/5']0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640)#hd66hknp", + "safe": true + } +] +$ recipient=tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') +$ echo $utxo_txid $utxo_vout +003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452 0 +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.002, "'$changeaddress'": 0.007 }''') +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c +``` +Funziona tutto esattamente come gli altri tipi di transazioni! + +### Riconoscere il nuovo descrittore + +Se guardi il campo `desc`, noterai che l'indirizzo SegWit ha un descrittore di stile diverso da quelli incontrati in [Capitolo 3.5: Comprendere il Descriptor](03_5_Comprendere_il_Descriptor.md). + +Il descrittore legacy descritto nell [Capitolo 3.5] assomigliava a questo: + +`pkh([d6043800/0'/0'/18']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk`. + +Il nostro nuovo descrittore SegWit invece si presenta così: + +`wpkh([d6043800/0'/0'/5']0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640)#hd66hknp"`. + +La cosa importante da notare è che la funzione è cambiata. In precedenza era `pkh`, che è un indirizzo a P2PKH hashed public-key standard. L'indirizzo SegWit è invece `wpkh`, il che significa che è un indirizzo SegWit nativo P2WPKH. Ciò sottolinea il :fuoco: ***potere dei descrittori***. Descrivono come creare un indirizzo da una chiave o altre informazioni, con le funzioni che definiscono in modo inequivocabile come creare l'indirizzo in base al suo tipo. + +## Riepilogo: creare una transazione SegWit + +Non c'è davvero alcuna complessità nella creazione di transazioni SegWit. Internamente sono strutturate in modo diverso rispetto alle transazioni legacy, ma dalla riga di comando non c'è differenza: basta utilizzare un indirizzo con un prefisso diverso. L'unica cosa a cui prestare attenzione è che alcune persone potrebbero non essere in grado di inviare a un indirizzo Bech32 se utilizzano software obsoleto. + +> :fire: ***Qual è il potere di inviare monete con SegWit?*** + +> _I vantaggi._ Le transazioni SegWit sono più piccole e quindi saranno più economiche da inviare rispetto alle transazioni tradizionali a causa delle commissioni inferiori. Bech32 raddoppia questo vantaggio e crea anche indirizzi che sono più difficili da sbagliare durante la trascrizione, e questo è piuttosto importante, dato che l'errore dell'utente è uno dei modi più probabili per perdere i tuoi bitcoin. + +> _Gli svantaggi._ Gli indirizzi SegWit potrebbero non essere supportati dal software Bitcoin obsoleto. In particolare, le persone potrebbero non essere in grado di inviare sats al tuo indirizzo Bech32. + +## Qual è il prossimo tema? + +Prosegui verso "bitcoin-cli" con il [Capitolo 5: Controllare Transazioni Bitcoin](05_0_Controllare_Transazioni_Bitcoin.md). diff --git a/it/05_0_Controllare_Transazioni_Bitcoin.md b/it/05_0_Controllare_Transazioni_Bitcoin.md new file mode 100644 index 000000000..593de6360 --- /dev/null +++ b/it/05_0_Controllare_Transazioni_Bitcoin.md @@ -0,0 +1,23 @@ +# Capitolo cinque: Controllare le transazioni Bitcoin + +L'invio di una transazione non è sempre la fine della storia. Utilizzando i protocolli RBF (replace-by-fee) e CPFP (child-pays-for-parent), uno sviluppatore può continuare a controllare la transazione dopo che è stata inviata, per migliorare l'efficienza o recuperare transazioni bloccate. Questi metodi inizieranno a mettere in luce il vero potere di Bitcoin. + +## Obiettivi di questa sezione + +Dopo aver letto questo capitolo, uno sviluppatore sarà in grado di: + + * Decidere se RBF o CPFP potrebbero aiutare in una transazione + * Creare una transazione sostitutiva utilizzando RBF + * Creare una nuova transazione utilizzando CPFP + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere la Mempool + * Comprendere la differenza tra RBF e CPFP + * Pianificare il potenziale di RBF + +## Sommario + + * [Capitolo 5.1:Guardare le Transazioni Ferme](05_1_Guardare_le_Transazioni_Ferme.md) + * [Capitolo 5.2: Rinviare le Transazioni con RBF](05_2_Rinviare_le_Transazioni_con_RBF.md) + * [Capitolo 5.3: Pagare una Transaccion con CPFP](05_3_Pagare_una_Transaccion_con_CPFP.md) diff --git a/it/05_1_Guardare_le_Transazioni_Ferme.md b/it/05_1_Guardare_le_Transazioni_Ferme.md new file mode 100644 index 000000000..0f75f2103 --- /dev/null +++ b/it/05_1_Guardare_le_Transazioni_Ferme.md @@ -0,0 +1,60 @@ +# 5.1: Guardare le transazioni ferme + +A volte una transazione Bitcoin può fermarsi. Di solito è perché non c'erano commissioni di transazione sufficienti, ma può anche essere a causa di un problema tecnico della rete o del software. + +## Controllare le transazioni + +Dovresti _sempre_ vigilare per assicurarti che le tue transazioni vadano a buon fine. `bitcoin-cli listtransactions` mostrerà tutte le transazioni in entrata e in uscita, mentre `bitcoin-cli gettransaction` con un txid mostrerà una transazione specifica. + +Di seguito viene mostrata una transazione che non è stata inserita in un blocco. Puoi dirlo perché non ha conferme. + +``` +$ bitcoin-cli -named gettransaction txid=fa2ddf84a4a632586d435e10880a2921db6310dfbd6f0f8f583aa0feacb74c8e +{ + "amount": -0.00020000, + "fee": -0.00001000, + "confirmations": 0, + "trusted": true, + "txid": "fa2ddf84a4a632586d435e10880a2921db6310dfbd6f0f8f583aa0feacb74c8e", + "walletconflicts": [ + ], + "time": 1592953220, + "timereceived": 1592953220, + "bip125-replaceable": "no", + "details": [ + { + "address": "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", + "category": "send", + "amount": -0.00020000, + "vout": 0, + "fee": -0.00001000, + "abandoned": false + } + ], + "hex": "02000000014cda1f42a1bd39d8d0ff5958a804bc2bc548b71d7ceadbde53ea15aeaf1e2691000000006a473044022016a7a9f045a0f6a52129f48adb7da35c2f54a0741d6614e9d55b8a3bc3e1490a0220391e9085a3697bc790e94bb924d5310e16f23489d9c600864a32674e871f523c01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff02204e000000000000160014751e76e8199196d454941c45d1b3a323f1433bd6e8030000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919600000000" +``` +Una transazione può essere considerata bloccata o ferma se rimane in questo stato per un periodo di tempo prolungato. Non molti anni fa, potevi essere sicuro che ogni transazione sarebbe andata a buon fine _una volta..._. Ma non è più così a causa del crescente utilizzo di Bitcoin. Ora, se una transazione rimane bloccata troppo a lungo, uscirà dalla mempool e verrà persa dalla rete Bitcoin. + +> :book: ***Cos'è la mempool?*** Mempool (o Memory Pool) è una piscina (pool in inglese) che contiene tutte le transazioni non confermate su un nodo bitcoin. Sono le transazioni che un nodo ha ricevuto dalla rete p2p e che non sono ancora incluse in un blocco. Ogni nodo bitcoin può avere un insieme di transazioni leggermente diverso nel suo mempool: transazioni diverse potrebbero essersi propagate a un nodo specifico. Ciò dipende da quando il nodo è stato avviato l'ultima volta e anche dai suoi limiti su quanto è disposto a memorizzare. Quando un minatore effettua un blocco, utilizza le transazioni dal suo mempool. Quindi, quando un blocco viene verificato, tutti i minatori rimuovono le transazioni in esso contenute dai propri pool. A partire da Bitcoin 0.12, anche le transazioni non confermate possono scadere dai mempool se sono abbastanza vecchie, in genere 72 ore, e a partire dalla versione 0.14.0 il tempo di sfratto è stato aumentato a 2 settimane. I pool minerari potrebbero avere i propri meccanismi di gestione della mempool. + +Questo elenco di tutte le [transazioni non confermate](https://blockchain.info/unconfirmed-transactions) potrebbe non corrispondere al mempool di nessuna singola macchina, ma dovrebbe (principalmente) essere un superset di essi. + +## Decidere cosa fare + +Se la transazione rimane bloccata più a lungo del previsto, in genere puoi fare una di queste tre cose: + +**1. Attendi finché non viene cancellato.** Se hai inviato la transazione con una commissione bassa o media, alla fine dovrebbe andare a buon fine. Come mostrato su [Mempool Space](https://mempool.space), quelli con tariffe inferiori subiranno ritardi. (Dai un'occhiata alla transazione più a sinistra e guarda quanto tempo è rimasta in attesa e quanto ha pagato per la sua commissione.) + +**2. Attendi la scadenza.** Se hai inviato accidentalmente senza alcuna commissione di transazione o se vengono soddisfatti alcuni numeri o altre condizioni, la transazione potrebbe non andare mai a buon fine. Tuttavia, le tue monete non andranno perse. Finché non disponi di un portafoglio che rinvia intenzionalmente transazioni non confermate, dovrebbe essere cancellato dal mempool entro tre giorni circa, quindi puoi riprovare. + +**3. Come mitente utilizza RBF.** Se sei il mittente della transazione e hai aderito a RBF (Replace-By-Fee), puo riprovare con una commissione più alta. Vedere [Capitolo 5.2: Rinviare le Transazioni con RBF](05_2_Rinviare_le_Transazioni_con_RBF.md). + +**4. Come destinatario utilizza CPFP.** In alternativa, se sei il destinatario della transazione, puoi utilizzare CPFP (Child-pays-for-parent) per utilizzare la transazione non confermata come input per una nuova transazione. Vedi [Capitolo 5.3: 05_3 Pagare una Transaccion con CPFP](05_3_Pagare_una_Transaccion_con_CPFP.md). + +## Riepilogo: Guardare le transazioni ferme + +Questa è un'introduzione al potere delle transazioni Bitcoin. Se sai che una transazione è ferma, puoi decidere di liberarla con funzionalità come RBF o CPFP. + +## Cosa viene dopo? + +Continua "Controllo delle transazioni Bitcoin" con [Capitolo 5.2 Rinviare le Transazioni con RBF](05_2_Rinviare_le_Transazioni_con_RBF.md). diff --git a/it/05_2_Rinviare_le_Transazioni_con_RBF.md b/it/05_2_Rinviare_le_Transazioni_con_RBF.md new file mode 100644 index 000000000..61a6458cc --- /dev/null +++ b/it/05_2_Rinviare_le_Transazioni_con_RBF.md @@ -0,0 +1,221 @@ +# 5.2: Nuovo invio di una transazione con RBF + +Se la tua transazione Bitcoin è ferma nella mempool e tu sei il mittente, puoi rinviarla nuovamente utilizzando RBF (replace-by-fee). Tuttavia, non è tutto ciò che RBF può fare: è generalmente una funzionalità potente e multiuso che consente ai mittenti Bitcoin di ricreare transazioni per una serie di motivi. + +> :warning: **AVVISO DI VERSIONE:** Questa è un'innovazione di _Bitcoin Core v 0.12.0_, che ha raggiunto la piena maturità nella wallet di Bitcoin Core con la versione v 0.14.0. Ovviamente, la maggior parte delle persone dovrebbe averlo già utilizzato. + +## Opzione di uso di RBF + +RBF è una funzionalità Bitcoin opzionale. Le transazioni sono idonee all'utilizzo di RBF solo se sono state create con uno speciale flag RBF. Questo viene fatto impostando nel UTXO della transazione un numero di `sequence` qualsiasi (che in genere vengono impostati automaticamente), in modo che sia maggiore di 0 e minore di 0xffffffff-1 (4294967294). + +Ciò si ottiene semplicemente aggiungendo una variabile `sequenza` alle tue entrate dell' UTXO: + +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "sequence": 1 } ]''' outputs='''{ "'$recipient'": 0.00007658, "'$changeaddress'": 0.00000001 }''') +``` +Dovresti firmare e inviare la transazione come al solito: + +``` +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 +``` +Ora, quando guardi la tua transazione, dovresti vedere qualcosa di nuovo: la riga `bip125-replaceable`, che prima era sempre contrassegnata con "no", ora è contrassegnata con `yes`: + +``` +$ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 + +{ + "amount": 0.00000000, + "fee": -0.00000141, + "confirmations": 0, + "trusted": true, + "txid": "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375", + "walletconflicts": [ + ], + "time": 1592954399, + "timereceived": 1592954399, + "bip125-replaceable": "yes", + "details": [ + ], + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" +} +``` +Il flag `bip125-replaceable` rimarrà `yes` finché la transazione non riceverà conferme. A quel punto non è più sostituibile. + +> :book: ***Devo fidarmi delle transazioni senza conferme?*** No, mai. Questo era vero prima della RBF ed era vero dopo la RBF. Le transazioni devono ricevere conferme prima di essere affidabili. Ciò è particolarmente vero se una transazione è contrassegnata come "bip125-replaceable", perché in tal caso può essere... sostituita. + +> :information_source: **NOTA — SEQUENCE:** Questo è il primo utilizzo del valore `nSequence` in Bitcoin. Puoi impostarlo tra 1 e 0xffffffff-2 (4294967293) e abilitare RBF, ma se non stai attento potresti imbatterti nell'uso parallelo di `nSequence` per i timelock relativi. Suggeriamo di impostarlo sempre su "1", che è ciò che fa Bitcoin Core, ma l'altra opzione è impostarlo su un valore compreso tra 0xf0000000 (4026531840) e 0xffffffff-2 (4294967293). Impostandolo su "1" rende effettivamente irrilevanti i relativi timelock, mentre impostandolo su 0xf0000000 o superiore li disattiva. Tutto ciò è spiegato ulteriormente nel [Capitolo 11.3: Usare CSV negli Scripts](11_3_Usare_CSV_negli_Scripts.md) dove si parla di `OP_CHECKSEQUENCEVERIFY`. Per ora, scegli semplicemente uno dei valori non in conflitto per "nSequence". + +### Facoltativo: aderire sempre a RBF + +Se preferisci, puoi _sempre_ optare per RBF. Fallo eseguendo il tuo `bitcoind` con il comando `-walletrbf`. Una volta fatto questo (e riavviato `bitcoind`), tutti gli UTXO dovrebbero avere un numero di sequenza inferiore e la transazione dovrebbe essere contrassegnata come `bip125-replaceable`. + +> :warning: **AVVISO DI VERSIONE:** Il flag walletrbf richiede Bitcoin Core v.0.14.0. + + +## Scopri come funziona RBF + +La funzionalità RBF si basa su [BIP 125](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki), che elenca le seguenti regole per l'utilizzo di RBF: + +> 1. Le transazioni originali segnalano la sostituibilità esplicitamente o tramite ereditarietà come descritto prima. + +Ciò significa che il numero di sequenza deve essere impostato su un valore inferiore a 0xffffffff-1. (4294967294), o lo stesso vale per le transazioni principali non confermate. + +> 2. L'operazione sostitutiva prevede una commissione in assoluto superiore a quella pagata con l'operazione originaria. +> 3. La transazione sostitutiva non contiene nuovi input non confermati che non apparivano in precedenza nel mempool. (Gli input non confermati sono input che tentano di spendere output da transazioni attualmente non confermate.) +> 4. La transazione sostitutiva deve pagare per la propria larghezza di banda in aggiunta all'importo pagato dalle transazioni originali pari o superiore alla tariffa stabilita dall'impostazione della tariffa di inoltro minima del nodo. Ad esempio, se la tariffa di inoltro minima è 1 satoshi/byte e la transazione sostitutiva è di 500 byte in totale, la sostituzione dovrà pagare una tariffa superiore di almeno 500 satoshi rispetto alla somma degli originali. +> 5. Il numero di transazioni originali da sostituire e le transazioni discendenti che verranno eliminate dalla mempool non devono superare un totale di 100 transazioni. + +> :book: ***Che cos'è un BIP?*** Un BIP è una proposta di miglioramento di Bitcoin. È un suggerimento approfondito per una modifica al codice Bitcoin Core. Spesso, quando un BIP è stato sufficientemente discusso e aggiornato, diventerà parte effettiva del codice Bitcoin Core. Ad esempio, BIP 125 è stato implementato in Bitcoin Core 0.12.0. + +L’altra cosa da capire su RBF è che per utilizzarlo è necessario spendere due volte, riutilizzando uno o più degli stessi UTXO. Inviare semplicemente un'altra transazione con un UTXO diverso allo stesso destinatario non risolverà il problema (e probabilmente comporterà una perdita di denaro). Invece, devi creare intenzionalmente un conflitto, in cui lo stesso UTXO viene utilizzato in due transazioni diverse. + +Di fronte a questo conflitto, i miner sapranno utilizzare quello con la tariffa più alta e saranno incentivati ​​a farlo da quella tariffa più alta. + +> :book: ***Che cos'è una doppia spesa?*** Una doppia spesa si verifica quando qualcuno invia gli stessi fondi elettronici a due persone diverse (o, alla stessa persona due volte, in due transazioni diverse). Questo è un problema centrale per qualsiasi sistema di denaro elettronica. In Bitcoin il problema viene risolto dal registro immutabile: una volta che una transazione è sufficientemente confermata, nessun minatore verificherà le transazioni che riutilizzano lo stesso UTXO. Tuttavia, è possibile spendere due volte _prima_ che una transazione venga confermata, motivo per cui desideri sempre una o più conferme prima di finalizzare una transazione. Nel caso di RBF, effettui una doppia spesa intenzionalmente perché una transazione iniziale si è bloccata e i minatori accettano la tua doppia spesa se soddisfi i criteri specifici stabiliti da BIP 125. + +> :warning: **WARNING:** Alcune prime discussioni su questa politica suggerivano che anche il numero `nSequence` fosse aumentato. Questo infatti era l'uso previsto di "nSequence" nella sua forma originale. Questo _non_ fa parte della politica pubblicata in BIP 125. Infatti, l'aumento del numero di sequenza può bloccare accidentalmente la transazione con un relativo blocco temporale, a meno che non si utilizzino numeri di sequenza nell'intervallo da 0xf0000000 (4026531840) a 0xffffffff-2 (4294967293) . + +## Sostituisci una transazione nel modo più difficile: manualmente + +Per creare manualmente una transazione RBF, tutto ciò che devi fare è creare una transazione grezza che: (1) sostituisce una precedente transazione grezza che ha aderito a RBF e che non è confermata; (2) riutilizza uno o più degli stessi UTXO; (3) aumenta le tariffe; e (4) paga la larghezza di banda minima di entrambe le transazioni [che può già essere gestita da (3)]. + +L'esempio seguente riutilizza semplicemente le nostre variabili esistenti, ma diminuisce l'importo inviato al cambio di indirizzo, per aumentare la commissione dagli 0 BTC accidentali della transazione originale a 0,01 BTC eccessivamente generosi nella nuova transazione: + +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "sequence": 1 } ]''' outputs='''{ "'$recipient'": 0.000075, "'$changeaddress'": 0.00000001 }''') +``` +Naturalmente dobbiamo firmarlo nuovamente e rispedirlo: +``` +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b +``` +Ora puoi guardare la tua transazione originale e vedere che presenta `walletconflicts`: +``` +$ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 +{ + "amount": 0.00000000, + "fee": -0.00000141, + "confirmations": 0, + "trusted": false, + "txid": "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375", + "walletconflicts": [ + "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b" + ], + "time": 1592954399, + "timereceived": 1592954399, + "bip125-replaceable": "yes", + "details": [ + ], + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" +} +``` +Ciò rappresenta il fatto che due transazioni diverse stanno entrambe tentando di utilizzare lo stesso UTXO. + +Alla fine, la transazione con la commissione più alta dovrebbe essere accettata: + +``` +$ bitcoin-cli -named gettransaction txid=c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b +{ + "amount": 0.00000000, + "fee": -0.00000299, + "confirmations": 2, + "blockhash": "0000000000000055ac4b6578d7ffb83b0eccef383ca74500b00f59ddfaa1acab", + "blockheight": 1773266, + "blockindex": 9, + "blocktime": 1592955002, + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "walletconflicts": [ + "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375" + ], + "time": 1592954467, + "timereceived": 1592954467, + "bip125-replaceable": "no", + "details": [ + ], + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b010000000001000000024c1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077dcdd98d85f6247450185c2b918a0f434d9b2e647330d741944ecae60d6ff790220424f85628cebe0ffe9fa11029b8240d08bdbfcc0c11f799483e63b437841b1cd0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" +} +``` +Nel frattempo, la transazione originale con la commissione più bassa inizia a raccogliere conferme negative, per mostrare la sua divergenza dalla blockchain: +``` +$ bitcoin-cli -named gettransaction txid=5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375 +{ + "amount": 0.00000000, + "fee": -0.00000141, + "confirmations": -2, + "trusted": false, + "txid": "5b953a0bdfae0d11d20d195ea43ab7c31a5471d2385c258394f3bb9bb3089375", + "walletconflicts": [ + "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b" + ], + "time": 1592954399, + "timereceived": 1592954399, + "bip125-replaceable": "yes", + "details": [ + ], + "hex": "02000000000101fa364ad3cbdb08dd0b83aac009a42a9ed00594acd6883d2a466699996cd69d8b01000000000100000002ea1d000000000000160014d591091b8074a2375ed9985a9c4b18efecfd416501000000000000001600146c45d3afa8762086c4bd76d8a71ac7c976e1919602473044022077007dff4df9ce75430e3065c82321dca9f6bdcfd5812f8dc0daeb957d3dfd1602203a624d4e9720a06def613eeea67fbf13ce1fb6188d3b7e780ce6e40e859f275d0121038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec500000000" +} +``` +I nostri destinatari hanno i loro soldi e la transazione originale non riuscita alla fine uscirà dal mempool. + +## Sostituisci una transazione nel modo più semplice: con bumpfee + +Le transazioni raw sono molto potenti e puoi fare un sacco di cose interessanti combinandole con RBF. Tuttavia, a volte _tutto_ quello che vuoi fare è liberare una transazione che è rimasta in sospeso. Ora puoi farlo con un semplice comando, `bumpfee`. + +Ad esempio, per aumentare la commissione della transazione `4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927` dovresti eseguire: + +``` +$ bitcoin-cli -named bumpfee txid=4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927 +{ + "txid": "75208c5c8cbd83081a0085cd050fc7a4064d87c7d73176ad9a7e3aee5e70095f", + "origfee": 0.00000000, + "fee": 0.00022600, + "errors": [ + ] +} +``` +Il risultato è la generazione automatica di una nuova transazione con una commissione determinata dal file bitcoin.conf: +``` +$ bitcoin-cli -named gettransaction txid=75208c5c8cbd83081a0085cd050fc7a4064d87c7d73176ad9a7e3aee5e70095f +{ + "amount": -0.10000000, + "fee": -0.00022600, + "confirmations": 0, + "trusted": false, + "txid": "75208c5c8cbd83081a0085cd050fc7a4064d87c7d73176ad9a7e3aee5e70095f", + "walletconflicts": [ + "4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927" + ], + "time": 1491605676, + "timereceived": 1491605676, + "bip125-replaceable": "yes", + "replaces_txid": "4460175e8276d5a1935f6136e36868a0a3561532d44ddffb09b7cb878f76f927", + "details": [ + { + "account": "", + "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", + "category": "send", + "amount": -0.10000000, + "vout": 0, + "fee": -0.00022600, + "abandoned": false + } + ], + "hex": "02000000014e843e22cb8ee522fbf4d8a0967a733685d2ad92697e63f52ce41bec8f7c8ac0020000006b48304502210094e54afafce093008172768d205d99ee2e9681b498326c077f0b6a845d9bbef702206d90256d5a2edee3cab1017b9b1c30b302530b0dd568e4af6f2d35380bbfaa280121029f39b2a19943fadbceb6697dbc859d4a53fcd3f9a8d2c8d523df2037e7c32a71010000000280969800000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac38f25c05000000001976a914c101d8c34de7b8d83b3f8d75416ffaea871d664988ac00000000" +} +``` +> :warning: **AVVISO DI VERSIONE:** L'RPC `bumpfee` richiede Bitcoin Core v.0.14.0. + +## Riepilogo: Reinviare una transazione con RBF + +Se una transazione è ferma e non vuoi aspettare che scada del tutto, se hai aderito a RBF, puoi effettuare una doppia spesa utilizzando RBF per creare una transazione sostitutiva (o semplicemente utilizzare `bumpfee`). + +> :fire: ***Qual è il potere di RBF?*** Ovviamente, RBF è molto utile se hai creato una transazione con una commissione troppo bassa e hai bisogno di ottenere quei fondi. Tuttavia, la capacità di sostituire generalmente le transazioni non confermate con quelle aggiornate ha più potere di questo (ed è il motivo per cui potresti voler continuare a utilizzare RBF con transazioni raw, anche dopo l'avvento di `bumpfee`). + +> Ad esempio, potresti inviare una transazione e quindi, prima che venga confermata, combinarla con una seconda transazione. Ciò consente di comprimere più transazioni in una sola, riducendo le commissioni complessive. Potrebbe anche offrire vantaggi alla privacy. Ci sono anche altri motivi per utilizzare RBF, per contratti intelligenti o cut-through di transazione, come descritto nelle [Domande frequenti su Opt-in RBF](https://bitcoincore.org/en/faq/optin_rbf/). + +## Cosa c'è dopo? + +Continua con "Controllo delle transazioni Bitcoin" nel [Capitolo 5.3: Pagare una Transaccion con CPFP](05_3_Pagare_una_Transaccion_con_CPFP.md). diff --git a/it/05_3_Pagare_una_Transaccion_con_CPFP.md b/it/05_3_Pagare_una_Transaccion_con_CPFP.md new file mode 100644 index 000000000..8e85f9fb5 --- /dev/null +++ b/it/05_3_Pagare_una_Transaccion_con_CPFP.md @@ -0,0 +1,130 @@ +# 5.3: Pagare una transazione con CPFP + +Se la tua transazione Bitcoin è bloccata e sei il _destinatario_, puoi compensarla usando CPFP (child-pays-for-parent). Questa è un'alternativa alla possibilità del _mittente_ di farlo con RBF. + +> :warning: **AVVISO DI VERSIONE:** Questa è un'innovazione di Bitcoin Core v 0.13.0, il che significa che la maggior parte delle persone dovrebbe già usarla. + +## Capire come funziona CPFP + +RBF era tutto incentrato sul mittente. Ha sbagliato e ha dovuto aumentare la commissione, oppure voleva essere intelligente e combinare le transazioni per una serie di motivi. Era una potente funzionalità orientata al mittente. In un certo senso, CPFP è l'opposto di RBF, perché dà potere al destinatario che sa che i suoi soldi non sono ancora arrivati ​​e vuole accelerare il processo. Tuttavia, è anche una funzionalità molto più semplice, con un'applicabilità meno ampia. + +Fondamentalmente, l'idea di CPFP è che un destinatario ha una transazione che vuole spendere e non è stata confermata in un blocco. Quindi, include quella transazione non confermata in una nuova transazione e paga una commissione sufficientemente alta da incoraggiare un miner a includere sia la transazione originale (madre) che la nuova transazione (figlia) in un blocco. Di conseguenza, le transazioni madre e figlia vengono cancellate simultaneamente. + +Va notato che CPFP non è una nuova funzionalità del protocollo, come RBF. È solo un nuovo schema di incentivazione che può essere utilizzato per la selezione delle transazioni da parte dei miner. Ciò significa anche che non è affidabile come una modifica del protocollo come RBF: potrebbero esserci motivi per cui la figlia non viene selezionata per essere inserita in un blocco e ciò impedirà alla madre di essere inserita in un blocco. + +## Spendi UTXO non confermati + +Finanziare di una transazione con CPFP è un processo molto semplice che utilizza i metodi con cui hai già familiarità: + + 1. Trova `txid` e `vout` della transazione non confermata. Questa potrebbe essere la parte più complicata, poiché `bitcoin-cli` in genere cerca di proteggerti dalle transazioni non confermate. Il mittente potrebbe essere in grado di inviarti queste informazioni; anche solo con il `txid`, dovresti essere in grado di capire il `vout` in un blockchain explorer. + +Hai un'altra opzione: usa `bitcoin-cli getrawmempool`, che può essere usato per elencare il contenuto dell'intero mempool, dove si troveranno le transazioni non confermate. Potresti doverle esaminare più volte se il mempool è particolarmente occupato. Puoi quindi ottenere maggiori informazioni su una transazione specifica con `bitcoin-cli getrawtransaction` con il flag verbose impostato su `true`: + + ``` +$ bitcoin-cli getrawmempool +[ + "95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd827447881ff79e061" +] + +$ bitcoin-cli getrawtransaction 95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd827447881ff79e061 true +{ + "txid": "95d51e813daeb9a861b2dcdddf1da8c198d06452bbbecfd827447881ff79e061", + "hash": "9729e47b8aee776112a82cec46df7638d112ca51856c53e238a9b1f7af3be4ce", + "version": 2, + "size": 247, + "vsize": 166, + "weight": 661, + "locktime": 1773277, + "vin": [ + { + "txid": "7a0178472300247d423ac4a04ff9165fa5b944104f6d6f9ebc557c6d207e7524", + "vout": 0, + "scriptSig": { + "asm": "0014334f3a112df0f22e743ad97eec8195a00faa59a0", + "hex": "160014334f3a112df0f22e743ad97eec8195a00faa59a0" + }, + "txinwitness": [ + "304402207966aa87db340841d76d3c3596d8b4858e02aed1c02d87098dcedbc60721d8940220218aac9d728c9a485820b074804a8c5936fa3145ce68e24dcf477024b19e88ae01", + "03574b1328a5dc2d648498fc12523cdf708efd091c28722a422d122f8a0db8daa9" + ], + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01000000, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 f079f77f2ef0ef1187093379d128ec28d0b4bf76 OP_EQUAL", + "hex": "a914f079f77f2ef0ef1187093379d128ec28d0b4bf7687", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2NFAkGiwnp8wvCodRBx3smJwxncuG3hndn5" + ] + } + }, + { + "value": 0.02598722, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 8799be12fb9eae6644659d95b9602ddfbb4b2aff OP_EQUAL", + "hex": "a9148799be12fb9eae6644659d95b9602ddfbb4b2aff87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N5cDPPuCTtYq13oXw8RfpY9dHJW8sL64U2" + ] + } + } + ], + "hex": "0200000000010124757e206d7c55bc9e6f6d4f1044b9a55f16f94fa0c43a427d2400234778017a0000000017160014334f3a112df0f22e743ad97eec8195a00faa59a0feffffff0240420f000000000017a914f079f77f2ef0ef1187093379d128ec28d0b4bf768742a727000000000017a9148799be12fb9eae6644659d95b9602ddfbb4b2aff870247304402207966aa87db340841d76d3c3596d8b4858e02aed1c02d87098dcedbc60721d8940220218aac9d728c9a485820b074804a8c5936fa3145ce68e24dcf477024b19e88ae012103574b1328a5dc2d648498fc12523cdf708efd091c28722a422d122f8a0db8daa9dd0e1b00" +} +``` +Guarda l'array `vout`. Trova l'oggetto che corrisponde al tuo indirizzo. (Qui, è l'unico.) Il valore `n` è il tuo `vout`. Ora hai tutto ciò che ti serve per creare una nuova transazione CPFP. + +``` +$ utxo_txid=2NFAkGiwnp8wvCodRBx3smJwxncuG3hndn5 +$ utxo_vout=0 +$ recipient2=$(bitcoin-cli getrawchangeaddress) +``` + 2. Crea una transazione raw usando la tua transazione non confermata come input. + + 3. Raddoppia le commissioni di transazione (o di più). + +Quando esegui questi passaggi, il tutto dovrebbe apparire normale, nonostante tu stia lavorando con una transazione non confermata. Per verificare che tutto andasse bene, abbiamo persino esaminato i risultati della nostra firma prima di salvare le informazioni in una variabile: + +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient2'": 0.03597 }''') + +$ bitcoin-cli -named signrawtransaction hexstring=$rawtxhex | jq -r '.hex' +02000000012b137ef780666ba214842ff6ea2c3a0b36711bcaba839c3710f763e3d9687fed000000006a473044022003ca1f6797d781ef121ba7c2d1d41d763a815e9dad52aa8bc5ea61e4d521f68e022036b992e8e6bf2c44748219ca6e0056a88e8250f6fd0794dc69f79a2e8993671601210317b163ab8c8862e09c71767112b828abd3852e315441893fa0f535de4fa39b8dffffffff01905abd07000000001976a91450b1d90a130c4f3f1e5fbfa7320fd36b7265db0488ac00000000 + +$ signedtx=$(bitcoin-cli -named signrawtransaction hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +6a184a2f07fa30189f4831d6f041d52653a103b3883d2bec2f79187331fd7f0e +``` + + 4. Non è necessario incrociare le dita. Hai verificato che i tuoi dati siano corretti. Da questo punto in poi, le cose sono fuori dal tuo controllo. + +Le tue transazioni potrebbero essere eseguite rapidamente. Potrebbero non esserlo. Tutto dipende dal fatto che i minatori che generano casualmente i blocchi correnti abbiano o meno la patch CPFP. Ma hai dato alle tue transazioni la migliore possibilità. + +Questo è tutto. + +### Fai attenzione alle sfumature + +Sebbene CPFP sia solitamente descritto come un destinatario che utilizza una nuova transazione per pagare una vecchia transazione che non è stata confermata, c'è una sfumatura in questo. + +Un _mittente_ potrebbe utilizzare CPFP per liberare una transazione se ricevesse il resto da essa. Utilizzerebbe semplicemente quel resto come input e l'uso risultante di CPFP libererebbe l'intera transazione. Tieni presente che farebbe meglio a utilizzare RBF finché fosse abilitato, poiché le commissioni totali sarebbero quindi inferiori. + +Un _destinatario_ potrebbe usare CPFP anche se non ha intenzione di spendere immediatamente i soldi, ad esempio se teme che i fondi non possano essere rispediti se la transazione scade. In questo caso, crea semplicemente una transazione secondaria che invia tutti i soldi (meno una commissione di transazione) a un indirizzo di resto. È quello che abbiamo fatto sopra nel nostro esempio. + +## Riepilogo: Pagare una transazione con CPFP + +Puoi sfruttare gli incentivi CPFP per liberare i fondi che ti sono stati inviati ma non sono stati confermati. Usa semplicemente la transazione non confermata come UTXO e paga una commissione di transazione superiore alla media. + +> :fire: ***Qual è il potere di CPFP?*** Principalmente, CPFP è utile solo per sbloccare i fondi quando sei il destinatario e il mittente non puo aiutare per qualsiasi motivo. Non ha le possibilità più potenti di RBF, ma è un modo alternativo per esercitare il controllo su una transazione dopo che è stata inserita nel mempool, ma prima che venga confermata in un blocco. + +## Cosa c'è dopo? + +Vai attraverso "bitcoin-cli" con [Capitolo 6: Ampliare le Transazioni Bitcoin con Multifirme](06_0_Ampliare_le_Transazioni_Bitcoin_con_Multifirme.md). diff --git a/it/06_0_Ampliare_le_Transazioni_Bitcoin_con_Multifirme.md b/it/06_0_Ampliare_le_Transazioni_Bitcoin_con_Multifirme.md new file mode 100644 index 000000000..13a4955b3 --- /dev/null +++ b/it/06_0_Ampliare_le_Transazioni_Bitcoin_con_Multifirme.md @@ -0,0 +1,21 @@ +# Capitolo sei: Ampliare le transazioni Bitcoin con Multisig + +Transazioni Bitcoin di base: (1) inviare fondi; (2) a un singolo destinatario P2PKH o SegWit; (3) da una singola macchina; (4) immediatamente. Tuttavia, tutte e quattro le parti di questa definizione possono essere ampliate utilizzando transazioni Bitcoin più complesse. Questo primo capitolo sulla "Espansione" mostra come cambiare i punti (2) e (3) inviando denaro a un indirizzo che rappresenta più destinatari (o almeno, più firmatari). + +## Obiettivi di questa sezione + +Dopo aver completato questo capitolo, uno sviluppatore sarà in grado di: + +* Creare indirizzi Bitcoin multifirma utilizzando i fondamenti di Bitcoin +* Creare indirizzi Bitcoin multifirma utilizzando meccanismi più semplici + +Gli obiettivi di supporto includono la capacità di: + +* Comprendere come spendere i fondi inviati a un multifirma +* Pianificare la potenza delle transazioni multifirma + +## Indice + +* [Capitolo 6.1: Inviare una Transazione a un Indirizzo Multifirma](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md) +* [Capitolo 6.2: Spendere una Transazione con un Indirizzo Multifirma](06_2_Spendere_una_Transazione_con_un_Indirizzo_Multifirma.md) +* [Capitolo 6.3: Inviare e Ricevere una Multifirma Automatizzata](06_3_Inviare_e_Ricevere_una_Multifirma_Automatizzata.md) diff --git a/it/06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md b/it/06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md new file mode 100644 index 000000000..6582b2c72 --- /dev/null +++ b/it/06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md @@ -0,0 +1,206 @@ +# 6.1: Inviare di una transazione con un Multisig + +Il primo modo per variare la modalità di invio di una transazione di base è utilizzare un multisig. Ciò ti dà la possibilità di richiedere che più persone (o almeno più chiavi private) autorizzino l'uso dei fondi. + +## Come funziona il Multisig: + +In una tipica transazione P2PKH o SegWit, i bitcoin vengono inviati a un indirizzo basato sulla tua chiave pubblica, il che a sua volta significa che è necessaria la relativa chiave privata per sbloccare la transazione, risolvendo il puzzle crittografico e permettendoti di riutilizzare i fondi. Ma cosa succederebbe se potessi invece bloccare una transazione con chiavi private _multiple_? Ciò consentirebbe effettivamente di inviare fondi a un gruppo di persone, dove tutte queste persone devono accettare di riutilizzare i fondi. + +> :book: ***Cos'è una multifirma?*** Una multifirma è una metodologia che consente a più di una persona di creare congiuntamente una firma digitale. È una tecnica generale per l'uso crittografico delle chiavi che va ben oltre Bitcoin. + +Tecnicamente, un puzzle crittografico multifirma viene creato da Bitcoin utilizzando il comando `OP_CHECKMULTISIG` e in genere è incapsulato in un indirizzo P2SH. [Capitolo 10.4 Programmare una Multifirma](10_4_Programmare_una_Multifirma.md) spiegherà in dettaglio come funziona in modo più preciso. Per ora, tutto ciò che devi sapere è che puoi utilizzare il comando `bitcoin-cli` per creare indirizzi multifirma; i fondi possono essere inviati a questi indirizzi proprio come qualsiasi normale indirizzo P2PKH o Segwit, ma saranno necessarie più chiavi private per il riscatto dei fondi. + +> :book: ***Cos'è una transazione multifirma?*** Una transazione multifirma è una transazione Bitcoin che è stata inviata a un indirizzo multifirma, richiedendo quindi le firme di alcune persone del gruppo multifirma per riutilizzare i fondi. + +Le multifirme semplici richiedono che tutti i membri del gruppo firmino l'UTXO quando è speso. Tuttavia, è possibile una maggiore complessità. Le multifirme sono generalmente descritte come "m di n". Ciò significa che la transazione è bloccata con un gruppo di "n" chiavi, ma solo "m" di esse sono necessarie per sbloccare la transazione. + +> :book: ***Cos'è una multifirma m-di-n?*** In una multifirma, sono richieste "m" firme da un gruppo di "n" per formare la firma, dove "m ≤ n". + +## Crea un indirizzo multisig + +Per bloccare un UTXO con più chiavi private, devi prima creare un indirizzo multifirma. Gli esempi qui utilizzati mostrano la creazione (e l'utilizzo) di una multifirma 2 su 2. + +### Creare gli indirizzi + +Per creare un indirizzo multifirma, devi prima preparare gli indirizzi che il multisig combinerà. La best practice suggerisce di creare sempre nuovi indirizzi. Ciò significa che i partecipanti eseguiranno ciascuno il comando `getnewaddress` sul proprio computer: +``` +machine1$ address1=$(bitcoin-cli getnewaddress) +``` +e: +``` +machine2$ address2=$(bitcoin-cli getnewaddress) +``` +Successivamente, uno dei destinatari (o forse una terza parte) dovrà combinare gli indirizzi. + +#### Raccogli le chiavi pubbliche + +Tuttavia, non è possibile creare un multi-sig con gli indirizzi, poiché questi sono gli hash delle chiavi pubbliche: sono invece necessarie le chiavi pubbliche stesse. + +Queste informazioni sono facilmente disponibili con il comando "getaddressinfo". + +Sulla macchina remota, che qui presumiamo sia "macchina2", puoi ottenere le informazioni dall'elenco. +``` +machine2$ bitcoin-cli -named getaddressinfo address=$address2 +{ + "address": "tb1qr2tkjh8rs9xn5xaktf5phct0wxqufplawrfd9q", + "scriptPubKey": "00141a97695ce3814d3a1bb65a681be16f7181c487fd", + "ismine": true, + "solvable": true, + "desc": "wpkh([fe6f2292/0'/0'/1']02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3)#zc64l8dw", + "iswatchonly": false, + "isscript": false, + "iswitness": true, + "witness_version": 0, + "witness_program": "1a97695ce3814d3a1bb65a681be16f7181c487fd", + "pubkey": "02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3", + "ischange": false, + "timestamp": 1592957904, + "hdkeypath": "m/0'/0'/1'", + "hdseedid": "1dc70547f2b80e9bb5fde5f34fb3d85f8d8d1dab", + "hdmasterfingerprint": "fe6f2292", + "labels": [ + "" + ] +} +``` +L'indirizzo `pubkey` (`02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3`) è ciò che è richiesto. Copialo sul tuo computer locale con qualunque mezzo ritieni più efficiente e _meno soggetto a errori_. + +Questo processo deve essere intrapreso per _ogni_ indirizzo da una macchina diversa da quella su cui viene costruito il multisig. Ovviamente, se qualche terza parte sta creando l'indirizzo, dovrai farlo per ogni indirizzo. + +> :avviso: **ATTENZIONE:** l'uso da parte di Bitcoin di hash di chiave pubblica come indirizzi, invece di chiavi pubbliche, rappresenta in realtà un ulteriore livello di sicurezza. Pertanto, l'invio di una chiave pubblica aumenta leggermente la vulnerabilità dell'indirizzo associato, per qualche possibilità futura di compromissione della curva ellittica. Non dovresti preoccuparti di dover inviare occasionalmente una chiave pubblica per un utilizzo come questo, ma dovresti essere consapevole che gli hash della chiave pubblica rappresentano la sicurezza e quindi le chiavi pubbliche effettive non dovrebbero essere inviate in giro, volenti o nolenti. + +Se uno degli indirizzi è stato creato sul tuo computer locale, che qui presumiamo sia `machine1`, puoi semplicemente scaricare l'indirizzo `pubkey` in una nuova variabile. +``` +machine1$ pubkey1=$(bitcoin-cli -named getaddressinfo address=$address1 | jq -r '.pubkey') +``` + +### Crea l'indirizzo + +Ora è possibile creare un indirizzo multisig con il comando `createmultisig`: +``` +machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3"]''' +{ + "address": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr", + "redeemScript": "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae", + "descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y" +} +``` +> :warning: **AVVERTIMENTO VERSIONE:** Alcune versioni di `createmultisig` consentono l'immissione di chiavi o indirizzi pubblici, altre richiedono solo chiavi pubbliche. Attualmente, sembra che entrambi siano consentiti. + +Quando crei l'indirizzo multifirma, elenchi quante firme sono richieste con l'argomento `nrequired` (ovvero "m" in una multifirma "m-of-n"), quindi elenchi l'insieme totale di firme possibili con le `keys` argomento (che è "n"). Tieni presente che le voci "chiavi" probabilmente provengono da luoghi diversi. In questo caso, abbiamo incluso `$pubkey1` dal computer locale e `02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3` da un computer remoto. + +> :information_source: **NOTA — M-OF-N VS N-OF-N:** Questo esempio mostra la creazione di un semplice multisig 2 di 2. Se invece desideri creare una firma m-of-n dove "m < n", modifica il campo `nrequired` e/o il numero di firme nell'oggetto JSON `keys`. Per un multisig 1 su 2, imposteresti `nrequired=1` ed elencheresti anche due chiavi, mentre per un multisig 2 su 3, lasceresti `nrequired=2`, ma aggiungerai un'altra chiave pubblica all'elenco delle "chiavi". + +Se utilizzato correttamente, `createmultisig` restituisce tre risultati, tutti di fondamentale importanza. + +L'_indirizzo_ è ciò che darai alle persone che vogliono inviare fondi. Noterai che ha un nuovo prefisso "2", esattamente come gli indirizzi P2SH-SegWit. Questo perché, come loro, `createmultisig` sta in realtà creando un tipo di indirizzo totalmente nuovo chiamato indirizzo P2SH. Funziona esattamente come un indirizzo P2PKH standard per l'invio di fondi, ma poiché questo è stato creato per richiedere più indirizzi, dovrai fare un po' più di lavoro per spenderli. + +> :link: **TESTNET vs MAINNET:** Su testnet, il prefisso per gli indirizzi P2SH è "2", mentre su mainnet è "3". + +Il _redeemScript_ è ciò di cui hai bisogno per riscattare i fondi (insieme alle chiavi private per "m" degli "n" indirizzi). Questo script è un'altra caratteristica speciale degli indirizzi P2SH e verrà spiegato completamente nel [Capitolo 10.3 Eseguire un Script Bitcoin con P2SH](10_3_Eseguire_un_Script_Bitcoin_con_P2SH.md). Per ora, tieni presente che sono necessari alcuni dati per ottenere i tuoi soldi. + +Il _descrittore_ è la descrizione standardizzata di un indirizzo che abbiamo incontrato nel [Capitolo 3.5 Comprendere il Descriptor](03_5_Comprendere_il_Descriptor.md). Fornisce un modo per importare nuovamente questo indirizzo sull'altra macchina, utilizzando l'RPC "importmulti". + +> :book: ***Cos'è un indirizzo P2SH?*** P2SH sta per Pay-to-script-hash. Si tratta di un tipo di destinatario diverso da un indirizzo P2PKH standard o anche da un Bech32, utilizzato per fondi il cui riscatto si basa su script Bitcoin più complessi. `bitcoin-cli` utilizza l'incapsulamento P2SH per aiutare a standardizzare e semplificare i suoi multisig come `multisig P2SH`, proprio come P2SH-SegWit utilizzava P2SH per standardizzare i suoi indirizzi SegWit e renderli completamente compatibili con le versioni precedenti. + +> :avviso: **ATTENZIONE:** Gli indirizzi multisig P2SH, come quelli creati da `bitcoin-cli`, hanno un limite per "m" e "n" in multisig in base alla dimensione massima dello script di riscatto, che è attualmente 520 byte. In pratica, non lo raggiungerai a meno che tu non stia facendo qualcosa di eccessivo. + +### Salva il tuo lavoro + +Ecco un avvertimento importante: nulla del tuo multisig viene salvato nel tuo portafoglio utilizzando queste tecniche di base. Per riscattare successivamente il denaro inviato a questo indirizzo multifirma, dovrai conservare due informazioni cruciali: + + * Un elenco degli indirizzi Bitcoin utilizzati nel multisig. + * L'output `redeemScript` di `createmultsig`. + +Tecnicamente, `redeemScript` può essere ricreato eseguendo nuovamente `createmultisig` con l'elenco completo delle chiavi pubbliche _nello stesso ordine_ e con il conteggio m-of-n corretto. Ma è meglio conservarlo e risparmiarti stress e dolore. + +### Guarda l'Ordine + +C'è una cosa di cui essere molto cauti: _l'ordine conta_. L'ordine delle chiavi utilizzate per creare un multi-sig crea un hash univoco, vale a dire se inserisci le chiavi in ​​un ordine diverso, produrranno un indirizzo diverso, come mostrato: +``` +$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' +{ + "address": "2NFBQvz57UzKWDr2Vx5D667epVZifjGixkm", + "redeemScript": "52210342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da0321039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b352ae", + "descriptor": "sh(multi(2,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3))#8l6hvjsk" +} +$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey2'","'$pubkey1'"]''' +{ + "address": "2N5bC4Yc5Pqept1y8nPRqvWmFSejkVeRb1k", + "redeemScript": "5221039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3210342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da0352ae", + "descriptor": "sh(multi(2,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03))#audl88kg" +} +``` +Più in particolare, ogni ordinamento crea un _redeemScript_ diverso. Ciò significa che se hai utilizzato queste tecniche di base e non sei riuscito a salvare il _redeemScript_ come ti è stato detto, dovrai passare attraverso un numero sempre crescente di varianti per trovare quella giusta quando provi a spendere i tuoi fondi! + +[BIP67](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) suggerisce un modo per ordinare lessicograficamente le chiavi, in modo che generino sempre le stesse multifirme. ColdCard ed Electrum sono tra i portafogli che già lo supportano. Naturalmente, questo può causare problemi di per sé se non si sa se un indirizzo multisig è stato creato con chiavi ordinate o non ordinate. Ancora una volta, il [descriptor](03_5_Comprendere_il_Descriptor.md) viene in soccorso. Se un multisig non è ordinato, viene creato con la funzione "multi" e se è ordinato viene creato con la funzione "sortedmulti". + +Se guardi il `descriptor` per il multisig che hai creato sopra, vedrai che Bitcoin Core attualmente non ordina i suoi multisig: +``` + "descrittore": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e 78df82f33fa3))#0pazcr4y" +``` +Tuttavia, se importa un indirizzo con tipo `sortedmulti`, farà la cosa giusta, che è il punto centrale dei descrittori! + +> :warning: **AVVISO VERSIONE:** Bitcoin Core comprende la funzione del descrittore `sortedmulti` dalla versione v 0.20.0 in poi. Prova ad accedere al descrittore su una versione precedente di Bitcoin Core e riceverai un errore come "È necessaria una funzione all'interno di P2WSH". + +## Inviare a un indirizzo multisig + +Se hai una multifirma in un comodo formato P2SH, come quello generato da `bitcoin-cli`, può essere inviata esattamente come un normale indirizzo. +``` +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ recipient="2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.000065}''') +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex +{ + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "hash": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "version": 2, + "size": 83, + "vsize": 83, + "weight": 332, + "locktime": 0, + "vin": [ + { + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00006500, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + ] + } + } + ] +} + +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 +``` +Come puoi vedere, non c'era nulla di insolito nella creazione della transazione, e sembrava del tutto normale, anche se con un indirizzo con un prefisso diverso dal normale (`2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr`). Nessuna sorpresa, poiché allo stesso modo non abbiamo notato alcuna differenza quando abbiamo inviato per la prima volta agli indirizzi Bech32 nel [Capitolo 4.6](04_6_Creare_una_Transazione_Segwit.md). + +## Riepilogo: inviare una transazione a un indirizzo Multisig + +Gli indirizzi Multisig bloccano i fondi su più chiavi private, possibilmente richiedendo tutte quelle chiavi private per il riscatto e forse richiedendone solo alcune dal set. Sono abbastanza facili da creare con `bitcoin-cli` ed è del tutto normale inviarli. Questa facilità è dovuta in gran parte all'uso invisibile degli indirizzi P2SH (pay-to-script-hash), un argomento ampio che abbiamo toccato due volte, con gli indirizzi P2SH-SegWit e multisig, e che otterrà di più copertura in futuro. + +> :fire: ***Qual è il potere delle multifirme?*** Le multifirme consentono la modellazione di una varietà di accordi finanziari come società, partenariati, comitati e altri gruppi. Un multisig 1 su 2 potrebbe essere il conto bancario congiunto di una coppia sposata, mentre un multisig 2 su 2 potrebbe essere utilizzato per grandi spese da parte di una società a responsabilità limitata. Le multifirme costituiscono anche una delle basi degli Smart Contracts. Ad esempio, un affare immobiliare potrebbe essere chiuso con un multisig 2 su 3, in cui le firme vengono inviate dall'acquirente, dal venditore e da un agente di deposito a garanzia autorizzato. Una volta che l'agente di deposito a garanzia concorda che tutte le condizioni sono state soddisfatte, libera i fondi per il venditore; o in alternativa, l'acquirente e il venditore possono liberare congiuntamente i fondi. + +## Cosa viene dopo? + +Continua "Espansione delle transazioni Bitcoin" con [Capitolo 6.2: Spendere una Transazione Multifirma.md](06_2_Spendere_una_Transazione_con_un_Indirizzo_Multifirma.md). diff --git a/it/06_2_Spendere_una_Transazione_con_un_Indirizzo_Multifirma.md b/it/06_2_Spendere_una_Transazione_con_un_Indirizzo_Multifirma.md new file mode 100644 index 000000000..94a842d3c --- /dev/null +++ b/it/06_2_Spendere_una_Transazione_con_un_Indirizzo_Multifirma.md @@ -0,0 +1,232 @@ +# 6.2: Spendere una transazione Multifirma + +Il modo classico e complesso di spendere i fondi inviati ad un indirizzo multifirma utilizzando "bitcoin-cli" richiede molto lavoro manuale. + +## Trova i tuoi fondi + +Per cominciare, devi trovare i tuoi fondi; il tuo computer non sa cercarli, perché non sono associati ad alcun indirizzo nel tuo portafoglio. Puoi avvisare `bitcoind` di farlo utilizzando il comando `importaddress`: +``` +$ bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz +``` +Se hai un nodo podato (e probabilmente lo fai), dovrai invece dirgli di non ripetere la scansione: +``` +$ bitcoin-cli -named importaddress address=2NAGfA4nW6nrZkD5je8tSiAcYB9xL2xYMCz rescan="false" +``` +Se preferisci, puoi importare l'indirizzo utilizzando il suo descrittore (e questa è generalmente la risposta migliore e più standardizzata): +``` +$ bitcoin-cli importmulti '[{"desc": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y", "timestamp": "now", "watchonly": true}]' +[ + { + "success": true + } +] +``` +Successivamente i fondi dovrebbero apparire quando esegui `listunspend`... ma non sono ancora facilmente spendibili. (In effetti, il tuo portafoglio potrebbe affermare che non sono affatto "spendibili"!) + +Se per qualche motivo non riesci a incorporare l'indirizzo nel tuo portafoglio, puoi utilizzare `gettransaction` per ottenere informazioni (o guardare un block explorer). +``` +$ bitcoin-cli -named gettransaction txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 verbose=true +{ + "amount": -0.00006500, + "fee": -0.00001000, + "confirmations": 3, + "blockhash": "0000000000000165b5f602920088a7e36b11214161d6aaebf5229e3ed4f10adc", + "blockheight": 1773282, + "blockindex": 9, + "blocktime": 1592959320, + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "walletconflicts": [ + ], + "time": 1592958753, + "timereceived": 1592958753, + "bip125-replaceable": "no", + "details": [ + { + "address": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr", + "category": "send", + "amount": -0.00006500, + "vout": 0, + "fee": -0.00001000, + "abandoned": false + } + ], + "hex": "020000000001011b95a6055174ec64b82ef05b6aefc38f34d0e57197e40281ecd8287b4260dec60000000000ffffffff01641900000000000017a914a5d106eb8ee51b23cf60d8bd98bc285695f233f38702473044022070275f81ac4129e1d167ef7e700739f2899ea4c7f1adef3a4da29436f14fb97e02207310d4ec449eba49f0fa404ae45b9c82431d883490c7a0ed882ad0b5d7a623d0012102883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb00000000", + "decoded": { + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "hash": "bdf4e3bc5d354a5dfa5528f172480976321d989d7e5806ac14f1fe9b0b1c093a", + "version": 2, + "size": 192, + "vsize": 111, + "weight": 441, + "locktime": 0, + "vin": [ + { + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "txinwitness": [ + "3044022070275f81ac4129e1d167ef7e700739f2899ea4c7f1adef3a4da29436f14fb97e02207310d4ec449eba49f0fa404ae45b9c82431d883490c7a0ed882ad0b5d7a623d001", + "02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb" + ], + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00006500, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + ] + } + } + ] + } +} +``` + +## Imposta le tue variabili + +Quando sarai pronto a spendere i fondi ricevuti da un indirizzo multifirma, avrai bisogno di raccogliere _molti_ dati: molto più di quelli di cui hai bisogno quando spendi un normale P2PKH o SegWit UTXO. Ciò è in parte dovuto al fatto che le informazioni sull'indirizzo multisig non sono nel tuo portafoglio e in parte perché stai spendendo denaro inviato a un indirizzo P2SH (pay-to-script-hash), e questo è molto più impegnativo. + +In totale, dovrai raccogliere tre cose: informazioni estese sull'UTXO; il redeemScript; e tutte le chiavi private coinvolte. Ovviamente avrai bisogno anche di un nuovo indirizzo del destinatario. Le chiavi private devono attendere la fase di firma, ma tutto il resto può essere fatto ora. + +### Accedi alle informazioni dell' UTXO + +Per cominciare, prendi `txid` e `vout` per la transazione che vuoi spendere, come al solito. In questo caso, è stato recuperato dalle informazioni `gettransaction` sopra: +``` +$ utxo_txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 +$utxo_vout=0 +``` +Tuttavia, devi accedere anche a una terza informazione sull'UTXO, il suo `scriptPubKey`/`hex`, che è lo script che ha bloccato la transazione. Ancora una volta, probabilmente lo stai facendo guardando i dettagli della transazione: +``` +$ utxo_spk=a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387 +``` + +### Registra lo redeemScript + +Si spera che tu abbia salvato il `redeemScript`. Ora dovresti registrarlo in una variabile. + +Questo è stato tratto dalla nostra creazione dell'indirizzo nella sezione precedente. + +``` +redeem_script="522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae" +``` +### Decidi il tuo destinatario + +Rimanderemo semplicemente i soldi a noi stessi. Questo è utile perché libera i fondi dal multisig, convertendoli in una normale transazione P2PKH che può poi essere confermata da un'unica chiave privata: + +``` +$ recipient=$(bitcoin-cli getrawchangeaddress) +``` +## Crea la tua transazione + +Ora puoi creare la tua transazione. Questo non è diverso dal solito. + +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') +$ echo $rawtxhex +020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b10000000000ffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 +``` + +## Firma la tua transazione + +Ora sei pronto per firmare la tua transazione. Questo è un processo in più fasi perché dovrai farlo su più macchine, ognuna delle quali fornirà le proprie chiavi private. + +### Scarica la tua prima chiave privata + +Poiché questa transazione non utilizza completamente il tuo portafoglio, dovrai accedere direttamente alle tue chiavi private. Inizia su "machine1", dove dovresti recuperare tutte le chiavi private di quell'utente coinvolte nel multisig: +``` +machine1$ bitcoin-cli -named dumpprivkey address=$address1 +cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR +``` +> :warning: **ATTENZIONE:** L'accesso diretto alle chiavi private dalla shell è un comportamento molto pericoloso e dovrebbe essere fatto con estrema cautela se si utilizzano soldi veri. Per lo meno, non salvare le informazioni in una variabile a cui è possibile accedere dal tuo computer. Rimuovere la cronologia della shell è un altro ottimo passo. Al massimo non farlo. + +### Crea la tua prima firma + +Ora puoi creare la tua prima firma con il comando `signrawtransactionwithkey`. Qui è dove le cose sono diverse: dovrai istruire il comando su come firmare. Puoi farlo aggiungendo le seguenti nuove informazioni: + +* Includi un argomento `prevtxs` che includa `txid`, `vout`, `scriptPubKey` e `redeemScript` che hai registrato, ciascuno dei quali è una singola coppia chiave-valore nell'oggetto JSON. +* Includi un argomento `privkeys` che elenca le chiavi private che hai scaricato su questa macchina. + +``` +machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR"]' +{ + "hex": "020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000", + "complete": false, + "errors": [ + { + "txid": "b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521", + "vout": 0, + "witness": [ + ], + "scriptSig": "0047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae", + "sequence": 4294967295, + "error": "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)" + } + ] +} + +``` +Ciò produce errori spaventosi e dice che sta "fallendo". Va tutto bene. Puoi vedere che la firma è stata parzialmente riuscita perché l'`hex` è diventato più lungo. Sebbene la transazione sia stata parzialmente firmata, non viene eseguita perché necessita di più firme. + +### Ripetere per gli altri firmatari + +Ora puoi trasferire la transazione, affinché venga firmata nuovamente da chiunque altro sia richiesto per il multisig. Lo fanno eseguendo lo stesso comando di firma che hai eseguito tu ma: (1) con il codice `hex` più lungo da cui ottieni l'output: (`bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"]' | jq -r '.hex'`); e (2) con le loro chiavi private. + +> :information_source: **NOTA — M-di-N VS N-di-N:** Ovviamente, se hai una firma N-of-N (come la multifirma 2-of-2 in questo esempio), allora tutti devono firmare, ma se hai una multifirma M-di-N dove "M < N", la firma sarà completa quando solo alcuni ("M") dei firmatari avranno firmato. + +Per farlo accedono prima alle loro chiavi private: +``` +machine2$ bitcoin-cli -named dumpprivkey address=$address2 +cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz +``` +In secondo luogo, firmano il nuovo `hex` utilizzando tutti gli stessi valori `prevtxs`: +``` +machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]' +{ + "hex": "020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000d90047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e301473044022000a402ec4549a65799688dd531d7b18b03c6379416cc8c29b92011987084e9f402205470e24781509c70e2410aaa6d827aa133d6df2c578e96a496b885584fb039200147522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000", + "complete": true +} +``` +In terzo luogo, potrebbe essere necessario inviare la "stringa esadecimale" `hexstring` ancora più lunga prodotta ad altri firmatari. + +Ma in questo caso ora vediamo che la firma è `complete`! + +## Invia la tua transazione + +Una volta terminato, dovresti ricorrere alla metodologia JQ standard per salvare la tua `hexstring` e quindi inviarla: +``` +$ signedtx=$(bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]' | jq -r .hex) +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +99d2b5717fed8875a1ed3b2827dd60ae3089f9caa7c7c23d47635f6f5b397c04 +``` + +## Comprendere l'importanza di questa metodologia di firma ampliata + +Ciò ha richiesto un po' di lavoro e, come imparerai presto, la stupidità con le chiavi private, con lo script di riscatto e con lo scriptpubkey non è effettivamente necessaria per riscattare da indirizzi multifirma utilizzando versioni più recenti di Bitcoin Core. Quindi, qual'era il punto? + +Questa metodologia di riscatto mostra un modo standard per firmare e riutilizzare le transazioni P2SH. In breve, per riscattare i fondi P2SH, una `signrawtransactionwithkey` deve: + +1. Includere `scriptPubKey`, che spiega il puzzle crittografico P2SH. +2. Includere `redeemScript`, che risolve il puzzle crittografico P2SH e introduce un nuovo puzzle tutto suo. +3. Essere eseguito su ogni macchina che contiene le chiavi private richieste. +4. Includere le firme pertinenti, che risolvono il puzzle di riscattoScript. + +Qui abbiamo visto questa metodologia utilizzata per riscattare i fondi multisig. In futuro potrai utilizzarlo anche per riscattare i fondi bloccati con altri script P2SH più complessi, come spiegato a partire dal capitolo 9. + +## Riepilogo: spendere una transazione con un indirizzo Multisig + +Si scopre che spendere denaro inviato a un indirizzo multisig può richiedere un bel po' di lavoro. Ma finché hai i tuoi indirizzi originali e il tuo `redeemScript`, puoi farlo firmando una transazione grezza con ogni indirizzo diverso e fornendo ulteriori informazioni lungo il percorso. + +## Qual è il prossimo argomento? + +Continua la "Espansione delle transazioni Bitcoin" con [Capitolo 6.3: Inviare e Ricevere una Multifirma Automatizzata](06_3_Inviare_e_Ricevere_una_Multifirma_Automatizzata.md). diff --git a/it/06_3_Inviare_e_Ricevere_una_Multifirma_Automatizzata.md b/it/06_3_Inviare_e_Ricevere_una_Multifirma_Automatizzata.md new file mode 100644 index 000000000..8a66ef020 --- /dev/null +++ b/it/06_3_Inviare_e_Ricevere_una_Multifirma_Automatizzata.md @@ -0,0 +1,120 @@ +# 6.3: 06_3_Inviare_e_Ricevere_una_Multifirma_Automatizzata.md + +La tecnica standard per creare indirizzi multifirma e per spendere i propri fondi è complessa, ma vale la pena esercitarsi per capire un po' di più su come funzionano e come è possibile manipolarli a un livello relativamente basso. Tuttavia, Bitcoin Core ha reso il multisig un po’ più semplice nelle nuove versioni. + +> :warning: **AVVISO VERSIONE:** Il comando `addmultisigaddress` è disponibile in Bitcoin Core v 0.10 o successiva. + +## Crea un indirizzo multisig nel tuo portafoglio + +Per rendere i fondi inviati agli indirizzi multisig più facili da spendere, devi solo fare qualche preparazione utilizzando il comando `addmultisigaddress`. Probabilmente non è quello che vorresti fare se stessi scrivendo programmi per portafogli multisig, ma se stessi solo cercando di ricevere fondi a mano, potrebbe risparmiarti qualche disaggio. + +### Raccogli le chiavi + +Inizi creando indirizzi P2PKH e recuperando le chiavi pubbliche, come al solito, per ciascun utente che farà parte del multisig: +``` +machine1$ address3=$(bitcoin-cli getnewaddress) +machine1$ echo $address3 +tb1q4ep2vmakpkkj6mflu94x5f94q662m0u5ad0t4w +machine1$ bitcoin-cli -named getaddressinfo address=$address3 | jq -r '.pubkey' +0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc + +machine2$ address4=$(bitcoin-cli getnewaddress) +machine2$ echo $address4 +tb1qa9v5h6zkhq8wh0etnv3ae9cdurkh085xufl3de +machine2$ bitcoin-cli -named getaddressinfo address=$address4 | jq -r '.pubkey' +02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f +``` + +### Crea l'indirizzo Multisig ovunque + +Successivamente crei il multisig su _ogni macchina che contribuisce con le firme_ utilizzando un nuovo comando, `addmultisigaddress`, invece di `createmultisig`. Questo nuovo comando salva alcune informazioni nel tuo portafoglio, rendendo molto più semplice spendere i soldi in seguito. +``` +machine1$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$address3'","02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f"]''' +{ + "address": "tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex", + "redeemScript": "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae", + "descriptor": "wsh(multi(2,[d6043800/0'/0'/15']0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[e9594be8]02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#wxn4tdju" +} + +machine2$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc","'$address4'"]''' +{ + "address": "tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex", + "redeemScript": "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae", + "descriptor": "wsh(multi(2,[ae42a66f]0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[fe6f2292/0'/0'/2']02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#cc96c5n6" +} +``` +Come notato nella sezione precedente, attualmente non importa se si utilizzano indirizzi o chiavi pubbliche, quindi qui abbiamo mostrato l'altro meccanismo, mescolando i due. In ogni caso otterrai lo stesso indirizzo multisig. Tuttavia, _devi utilizzare lo stesso ordine_. Pertanto, è meglio che i membri del multisig controllino tra loro per assicurarsi che tutti abbiano ottenuto lo stesso risultato. + +### Attenzione ai fondi + +Successivamente, i membri del multisig dovranno comunque eseguire "importaddress" per controllare i fondi ricevuti sull'indirizzo multisig: +``` +machine1$ bitcoin-cli -named importaddress address=tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex rescan="false" + +machine2$ bitcoin-cli -named importaddress address=tb1q9as46kupwcxancdx82gw65365svlzdwmjal4uxs23t3zz3rgg3wqpqlhex rescan="false" +``` + +## Rispendi con una transazione automatizzata + +Successivamente, sarai in grado di ricevere fondi sull'indirizzo multifirma normalmente. L'utilizzo di `addmultisigaddress` è semplicemente una questione burocratica da parte dei destinatari: un po' di contabilità per facilitargli la vita quando vogliono spendere i loro fondi. + +Ma rende la vita molto più semplice. Poiché le informazioni sono state salvate nel portafoglio, i firmatari potranno spendere nuovamente i fondi inviati all'indirizzo multifirma esattamente come qualsiasi altro indirizzo... a parte la necessità di firmare su più macchine. + +Inizi raccogliendo le tue variabili, ma non devi più preoccuparti di `scriptPubKey` o `redeemScript`. + +Ecco una nuova transazione inviata al nostro nuovo indirizzo multisig: +``` +machine1$ utxo_txid=b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5acbc +machine1$ utxo_vout=0 +machine1$ recipient=$(bitcoin-cli getrawchangeaddress) +``` +Crea una transazione grezza: +``` +machine1$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') +``` +Poi firmala: +``` +machine1$ bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex +{ + "hex": "02000000000101bcacf598ccaf9d34f8a057eb4be02e8865f817434a41666a9d15f86e75c4f3b90000000000ffffffff0188130000000000001600144f93c831ec739166ea425984170f4dc6bac75829040047304402205f84d40ba16ff49e60a7fc9228ef5917473aae1ab667dad01e113ca0fef3008b02201a50da2c65f38798aea94bcbd5bbf065bc1e38de44bacee69d525dcddcc11bba01004752210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae00000000", + "complete": false, + "errors": [ + { + "txid": "b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5acbc", + "vout": 0, + "witness": [ + "", + "304402205f84d40ba16ff49e60a7fc9228ef5917473aae1ab667dad01e113ca0fef3008b02201a50da2c65f38798aea94bcbd5bbf065bc1e38de44bacee69d525dcddcc11bba01", + "", + "52210297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc2102a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f52ae" + ], + "scriptSig": "", + "sequence": 4294967295, + "error": "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)" + } + ] +} + +``` +Tieni presente che non dovevi più fornire ulteriore aiuto a `signrawtransactionwithkey`, perché tutte quelle informazioni extra erano già nel tuo portafoglio. Ancora più importante, non hai reso vulnerabili le tue chiavi private manipolandole direttamente. Invece il processo era _esattamente_ identico alla ripetizione di un normale UTXO, tranne per il fatto che alla fine la transazione non era completamente firmata. + +### Firmalo su altre macchine + +Il passaggio finale è esportare l'`hex` parzialmente firmato su qualsiasi altra macchina e firmarlo nuovamente: +``` +machine2$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=02000000014ecda61c45f488e35c613a7c4ae26335a8d7bfd0a942f026d0fb1050e744a67d000000009100473044022025decef887fe2e3eb1c4b3edaa155e5755102d1570716f1467bb0b518b777ddf022017e97f8853af8acab4853ccf502213b7ff4cc3bd9502941369905371545de28d0147522102e7356952f4bb1daf475c04b95a2f7e0d9a12cf5b5c48a25b2303783d91849ba421030186d2b55de166389aefe209f508ce1fbd79966d9ac417adef74b7c1b5e0777652aeffffffff0130e1be07000000001976a9148dfbf103e48df7d1993448aa387dc31a2ebd522d88ac00000000 | jq -r '.hex') +``` +Quando tutti quelli richiesti hanno firmato, sei pronto: +``` +machine2$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +3ce88839ac6165aeadcfb188c490e1b850468eff571b4ca78fac64342751510d +``` +Come per la scorciatoia discussa in [Capitolo 4.5: Inviare Monete con Transazione Grezza Automatizzatamd](04_5_Inviare_Monete_con_Transazione_Grezza_Automatizzata.md), il risultato è molto più semplice, ma si perde un po' di controllo del processo. + +## Sommario: Invio e spesa di un Multisig automatizzato + +Esiste un modo più semplice per spendere nuovamente i fondi inviati a indirizzi multisig che richiede semplicemente l'uso del comando `addmultisigaddress` quando crei il tuo indirizzo. Non dimostra le complessità della ripetizione della spesa P2SH e non ti dà un controllo espansivo, ma se vuoi solo ottenere i tuoi soldi, questa è la strada da percorrere. + +## Qual è il prossimo argomento? + +Scopri di più sulla "Espansione delle transazioni Bitcoin" nel [Capitolo 7: Ampliare le Transazioni Bitcoin con PSBTs](07_0_Ampliare_le_Transazioni_Bitcoin_con_PSBTs.md). diff --git a/it/07_0_Ampliare_le_Transazioni_Bitcoin_con_PSBTs.md b/it/07_0_Ampliare_le_Transazioni_Bitcoin_con_PSBTs.md new file mode 100644 index 000000000..b8c92c58c --- /dev/null +++ b/it/07_0_Ampliare_le_Transazioni_Bitcoin_con_PSBTs.md @@ -0,0 +1,24 @@ +# Capitolo sette: Ampliare le transazioni Bitcoin con PSBT + +Nel capitolo precedente è stato discusso come utilizzare multisig per determinare in modo collaborativo il consenso tra più parti. Non è l'unico modo per collaborare alla creazione di transazioni Bitcoin. I PSBT sono una tecnologia molto più recente che ti consente di collaborare in una varietà di fasi, tra cui la creazione, il finanziamento e l'autenticazione di una transazione Bitcoin. + +## Obiettivi di questa sezione + +Dopo aver letto questo capitolo, uno sviluppatore sarà in grado di: + + * Creare transazioni PSBT (Partially Signed Bitcoin Transaction)(Transazioni bitcoin parzialmente firmate) + * Utilizzare gli strumenti dalla riga di comando per completare le PSBT + * Utilizza HWI per interagire con un portafoglio hardware + +Gli obiettivi di supporto includono la capacità di: + + * Capire come le PSBT differiscono dalle multifirme + * Capire l'intero flusso di lavoro con le PSBT + * Pianificare l'usopotenziale delle PSBT + * Comprendere l'uso di un portafoglio hardware + +## Sommario + + * [Capitolo 7.1: Creare una Transazione Bitcoin Parzialmente Firmata](07_1_Creare_una_Transazione_Bitcoin_Parzialmente_Firmata.md) + * [Capitolo 7.2: Usare una Transazione Bitcoin Parzialmente Firmata](07_2_Usare_una_Transazione_Bitcoin_Parzialmente_Firmata.md) + * [Capitolo 7.3: Integrazione con Hardware Wallets](07_3_Integrazione_con_Hardware_Wallets.md) diff --git a/it/07_1_Creare_una_Transazione_Bitcoin_Parzialmente_Firmata.md b/it/07_1_Creare_una_Transazione_Bitcoin_Parzialmente_Firmata.md new file mode 100644 index 000000000..84def9c27 --- /dev/null +++ b/it/07_1_Creare_una_Transazione_Bitcoin_Parzialmente_Firmata.md @@ -0,0 +1,525 @@ +# 7.1: Creare una Transazione Bitcoin Parzialmente Firmata + +> :information_source: **NOTA:** Questa sezione è stata aggiunta di recente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvertito. + +Le transazioni Bitcoin parzialmente firmate (PSBT) sono il modo più nuovo per variare la creazione di transazioni basilari di Bitcoin. Lo fanno introducendo la collaborazione in ogni fase del processo, consentendo alle persone (o ai programmi) non solo di autenticare le transazioni insieme (come con i multisig), ma anche di creare, finanziare e trasmettere facilmente in modo collaborativo. + +> :avviso: **AVVISO VERSIONE:** Questa è un'innovazione di Bitcoin Core v 0.17.0. Le versioni precedenti di Bitcoin Core non saranno in grado di funzionare con il processo di PSBT mentre è in corso (sebbene saranno comunque in grado di riconoscere la transazione finale). Alcuni aggiornamenti e upgrade per le PSBT sono continuati fino alla versione 0.20.0. + +## Scoprire come funzionano le PSBT + +Le `multisig` erano ottime per il caso molto specifico di detenzione congiunta di fondi e di definizione di regole per chi tra i firmatari congiunti potesse autenticare l’uso di tali fondi. Esistono molti casi d'uso, come ad esempio: un conto bancario congiunto con il proprio coniuge (una firma 1 su 2); un requisito fiduciario per il doppio controllo (una firma 2 su 2); e un deposito a garanzia (una firma 2 su 3). + +> :book: ***Cos'è un PSBT?*** Come suggerisce il nome, un PSBT è una transazione che non è stata completamente firmata. Questo è importante, perché una volta firmata una transazione, il suo contenuto viene bloccato. [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) ha definito una metodologia astratta per mettere insieme i PSBT che descrive e standardizza i ruoli nella loro creazione collaborativa. Un *Creatore* propone una transazione; uno o più *Aggiornatori* lo integrano; e uno o più *Firmatari* lo autenticano; prima che un *Finalizatore* lo completi; e un *Estrattore* la trasforma in una transazione per la rete Bitcoin. Potrebbe anche esserci un *Combinatore* che unisce PSBT paralleli di utenti diversi. + +Inizialmente le PSBT potrebbero sembrare simili ai multi-sigs perché hanno un funzionalità in comune: la capacità di firmare congiuntamente una transazione. Tuttavia, sono stati creati per un caso d’uso completamente diverso. Le PSBT riconoscono la necessità che più programmi creino congiuntamente una transazione per una serie di ragioni diverse e forniscono un formato regolarizzato per farlo. Sono particolarmente utili per i casi d'uso che coinvolgono portafogli hardware (Gurda qui nel [Capitolo 7.3](07_3_Integrazione_con_Hardware_Wallets.md)), che sono protetti dall'accesso completo a Internet e tendono ad avere una cronologia delle transazioni minima. + +In generale, le PSBT forniscono una serie di elementi funzionali che migliorano questo caso d'uso: + +1. Forniscono uno _standard_ per la creazione collaborativa di transazioni, mentre le metodologie precedenti (inclusa quella multi-sig del [capitolo 6](06_0_Ampliare_le_Transazioni_Bitcoin_con_Multifirme.md) ) dipendevano dall'implementazione. +2. Supportano una _più ampia varietà di casi d'uso_, compreso il semplice finanziamento congiunto. +3. Supportano _portafogli hardware_ e altri casi in cui un nodo potrebbe non avere una cronologia completa delle transazioni. +4. Consentono facoltativamente la combinazione di _transazioni non serializzate_, senza richiedere il passaggio di un codice esadecimale sempre più grande da utente a utente. + +I PSBT svolgono il loro lavoro integrando le normali informazioni sulle transazioni con una serie di input e output, ognuno dei quali definisce tutto ciò che è necessario sapere su tali UTXO, in modo che anche un portafoglio airgap possa prendere una decisione informata sulle firme. Pertanto, un input elenca la quantità di denaro in un UTXO e cosa è necessario fare per spenderlo, mentre un output fa lo stesso per gli UTXO che sta creando. + +Questa prima sezione descriverà il processo PSBT standard di: Creatore, Aggiornatore, Firmatario, Finalizzatore, Estrattore. Lo farà da una sola macchina, il che lo farà sembrare un modo contorto per creare una transazione grezza. Ma abbi fede, c'è uno scopo in questo! Il [Capitolo 7.2](07_2_Usare_una_Transazione_Bitcoin_Parzialmente_Firmata.md) e il [Capitolo 7.3](07_3_Integrazione_con_Hardware_Wallets.md) mostreranno alcuni esempi reali di utilizzo dei PSBT e trasformeranno questo semplice sistema in un processo collaborativo condiviso tra più macchine che ha effetti reali e crea reali opportunità. + +## Creare una PSBT alla vecchia maniera +#### Ruolo PSBT: Creatore + +Il modo più semplice per creare un PSBT è prendere una transazione esistente e utilizzare `converttopsbt` per trasformarla in un PSBT. Questo non è certamente il modo _migliore_ poiché richiede di effettuare una transazione per un formato (una transazione grezza) e poi convertirla in un altro (PSBT), ma se hai un vecchio software che può generare solo una transazione grezza, potresti dover farlo. + +Crei semplicemente la tua transazione grezza normalmente: + +``` +$ utxo_txid_1=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout_1=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') +$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') +$ echo $utxo_txid_1 $utxo_vout_1 $utxo_txid_2 $utxo_vout_2 +c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b 1 8748eff5f12ca886e3603d9e30227dcb3f0332e0706c4322fec96001f7c7f41c 0 +$ recipient=tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.0000065 }''') +``` +Quindi lo converti: +``` +$ psbt=$(bitcoin-cli -named converttopsbt hexstring=$rawtxhex) +$ echo $psbt +cHNidP8BAHsCAAAAAhuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFgyf4iQ2xw4DIDP8t9IjCePWDjhqgs8fXvSIcAAAAAAP////8BigIAAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBQAAAAAAAAAA +``` +Noterai che la codifica PSBT appare molto diversa dall'esadecimale della transazione. + +Ma se puoi, crea direttamente il PSBT ... + +## Crea un PSBT nel modo più difficile + +#### Ruolo PSBT: Creatore + +La prima metodologia per creare un PSBT senza passare attraverso un altro formato è l'equivalente PSBT di `createrawtransaction`. Si chiama `createpsbt` e ti dà il massimo controllo al costo della massimo lavoro e della massima provabilità di errore. + +La CLI dovrebbe sembrare abbastanza familiare, unica differenza, un nuovo comando RPC: + +``` +$ psbt_1=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.0000065 }''') +``` +Il team di Bitcoin Core si è assicurato che `createpsbt` funzionasse in modo molto simile a `createrawtransaction`, quindi non è necessario imparare un nuovo formato di creazione. + +Puoi verificare che la nuova PSBT sia uguale a quella creata da `converttopsbt`: + +``` +$ echo $psbt_1 +cHNidP8BAHsCAAAAAhuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFgyf4iQ2xw4DIDP8t9IjCePWDjhqgs8fXvSIcAAAAAAP////8BigIAAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBQAAAAAAAAAA +$ if [ "$psbt" == "$psbt_1" ]; then echo "PSBTs are equal"; else echo "PSBTs are not equal"; fi +PSBTs are equal +``` + +## Esaminare una PSBT + +#### Ruolo PSBT: Qualsiasi ruolo + +Allora, che aspetto ha effettivamente il tuo PSBT? Puoi vederlo con il comando `decodepsbt`: + +``` +$ bitcoin-cli -named decodepsbt psbt=$psbt +{ + "tx": { + "txid": "ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3", + "hash": "ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3", + "version": 2, + "size": 123, + "vsize": 123, + "weight": 492, + "locktime": 0, + "vin": [ + { + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "8748eff5f12ca886e3603d9e30227dcb3f0332e0706c4322fec96001f7c7f41c", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00000650, + "n": 0, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + }, + { + } + ], + "outputs": [ + { + } + ] +} +``` + +È importante notare che anche se abbiamo definito i fondamenti della transazione: i `vin` da cui proviene il denaro e i `vouts` del destino, non abbiamo ancora definito gli `input` e gli `input` `output` che costituiscono il cuore di una PSBT e che sono necessari agli utenti offline per valutarli. Questo è previsto: il ruolo del Creatore come definito in [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) è quello di delineare la transazione, mentre il ruolo dell'Updater, _l'aggiornatore_, è iniziare a compilare i dati specifici del PSBT. (Altri comandi combinano i ruoli Creator e Updater, ma `createpsbt` no perché non ha accesso al tuo portafoglio.) + +Puoi anche usare il comando `analyzepsbt` per vedere il suo stato attuale: + +``` +standup@btctest20:~$ bitcoin-cli -named analyzepsbt psbt=$psbt +{ + "inputs": [ + { + "has_utxo": false, + "is_final": false, + "next": "updater" + }, + { + "has_utxo": false, + "is_final": false, + "next": "updater" + } + ], + "next": "updater" +} +``` +Allo stesso modo, `analyzepsbt` ci mostra una PSBT che necessita ancora di lavoro. Diamo un'occhiata a ciascuno dei due `input` (corrispondenti ai due `vin`) e nessuno dei due ha le informazioni di cui ha bisogno. + +## Finalizza un PSBT +#### Ruolo PSBT: Aggiornatore, Firmatario, Finalizzatore + +Esiste un comando `utxoupdatepsbt` che può essere utilizzato per aggiornare gli UTXO, importando manualmente le informazioni sul descrittore, ma non vuoi usarlo a meno che tu non abbia un caso d'uso in cui non hai tutte queste informazioni nei portafogli di tutti coloro che firmeranno il PSBT. + +> :information_source: **NOTA:** Se scegli di aggiornare il PSBT con `utxoupdatepsbt`, dovrai comunque utilizzare `walletprocesspsbt` per firmarlo: è l'unico comando con ruolo firmatario per PSBT disponibile in `bitcoin- cli`. + +Dovresti invece utilizzare `walletprocesspsbt`, che aggiornerà, firmerà e finalizzerà: + +``` +$ bitcoin-cli walletprocesspsbt $psbt +{ + "psbt": "cHNidP8BAHsCAAAAAhuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFgyf4iQ2xw4DIDP8t9IjCePWDjhqgs8fXvSIcAAAAAAP////8BigIAAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBQAAAAAAAQEfAQAAAAAAAAAWABRsRdOvqHYghsS9dtinGsfJduGRlgEIawJHMEQCIAqJbxz6dBzNpfaDu4XZXb+DbDkM3UWnhezh9UdmeVghAiBRxMlW2o0wEtphtUZRWIiJOaGtXfsQbB4lovkvE4eRIgEhArrDpkX9egpTfGJ6039faVBYxY0ZzrADPpE/Gpl14A3uAAEBH0gDAAAAAAAAFgAU1ZEJG4B0ojde2ZhanEsY7+z9QWUBCGsCRzBEAiB+sNNCO4xiFQ+DoHVrqqk9yM0V4H9ZSyExx1PW7RbjsgIgUeWkQ3L7aAv1xIe7h+8PZb8ECsXg1UzbtPW8wd2qx0UBIQKIO7VGPjfVUlLYs9XCFBsAezfIp9tiEfdclVrMXqMl6wAA", + "complete": true +} +``` +Ovviamente, dovrai salvare le informazioni `psbt` utilizzando `jq`: + +``` +$ psbt_f=$(bitcoin-cli walletprocesspsbt $psbt | jq -r '.psbt') +``` + +Puoi vedere che gli `input` sono stati compilati: + +``` +$ bitcoin-cli decodepsbt $psbt_f +{ + "tx": { + "txid": "ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3", + "hash": "ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3", + "version": 2, + "size": 123, + "vsize": 123, + "weight": 492, + "locktime": 0, + "vin": [ + { + "txid": "c6de60427b28d8ec8102e49771e5d0348fc3ef6a5bf02eb864ec745105a6951b", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "8748eff5f12ca886e3603d9e30227dcb3f0332e0706c4322fec96001f7c7f41c", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00000650, + "n": 0, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.00000001, + "scriptPubKey": { + "asm": "0 6c45d3afa8762086c4bd76d8a71ac7c976e19196", + "hex": "00146c45d3afa8762086c4bd76d8a71ac7c976e19196", + "type": "witness_v0_keyhash", + "address": "tb1qd3za8tagwcsgd39awmv2wxk8e9mwryvktqmkkg" + } + }, + "final_scriptwitness": [ + "304402200a896f1cfa741ccda5f683bb85d95dbf836c390cdd45a785ece1f54766795821022051c4c956da8d3012da61b5465158888939a1ad5dfb106c1e25a2f92f1387912201", + "02bac3a645fd7a0a537c627ad37f5f695058c58d19ceb0033e913f1a9975e00dee" + ] + }, + { + "witness_utxo": { + "amount": 0.00000840, + "scriptPubKey": { + "asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165", + "hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "type": "witness_v0_keyhash", + "address": "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh" + } + }, + "final_scriptwitness": [ + "304402207eb0d3423b8c62150f83a0756baaa93dc8cd15e07f594b2131c753d6ed16e3b2022051e5a44372fb680bf5c487bb87ef0f65bf040ac5e0d54cdbb4f5bcc1ddaac74501", + "02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb" + ] + } + ], + "outputs": [ + { + } + ], + "fee": 0.00000191 +} +``` +O per essere più precisi: (1) la PSBT è stata aggiornata con le informazioni `witness_utxo`; (2) la PSBT è stata firmata; e (3) la PSBT è stata finalizzata. + + +## Crea una PSBT in modo semplice +#### Ruolo PSBT: Creatore, Aggiornatore + +Se pensi che dovrebbe esserci un comando equivalente a `fundrawtransaction`, sarai felice di sapere che esiste: `walletcreatefundedpsbt`. Potresti usarlo proprio come `createpsbt`: + +``` +$ bitcoin-cli -named walletcreatefundedpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.0000065 }''' +{ + "psbt": "cHNidP8BAOwCAAAABBuVpgVRdOxkuC7wW2rvw4800OVxl+QCgezYKHtCYN7GAQAAAAD/////HPTH9wFgyf4iQ2xw4DIDP8t9IjCePWDjhqgs8fXvSIcAAAAAAP/////uFwerANKjyVK6WaR7gzlX+lOf+ORsfjP5LYCSNIbhaAAAAAAA/v///4XjOeey0NyGpJYpszNWF8AFNiuFaWsjkOrk35Jp+9kKAAAAAAD+////AtYjEAAAAAAAFgAUMPsier2ey1eH48oGqrbbYGzNHgKKAgAAAAAAABYAFMdy1vlVQuEe8R6O/Hx6aYMK04oFAAAAAAABAR8BAAAAAAAAABYAFGxF06+odiCGxL122Kcax8l24ZGWIgYCusOmRf16ClN8YnrTf19pUFjFjRnOsAM+kT8amXXgDe4Q1gQ4AAAAAIABAACADgAAgAABAR9IAwAAAAAAABYAFNWRCRuAdKI3XtmYWpxLGO/s/UFlIgYCiDu1Rj431VJS2LPVwhQbAHs3yKfbYhH3XJVazF6jJesQ1gQ4AAAAAIABAACADAAAgAABAIwCAAAAAdVmsvkSBmfeHqNAe/wDCQ5lEp9F/587ftzCD1UL60nMAQAAABcWABRzFxRJfFPl8FJ6SxjAJzy3mCAMXf7///8CQEIPAAAAAAAZdqkUf0NzebzGbEB0XtwYkeprODDhl12IrMEwLQAAAAAAF6kU/d+kMX6XijmD+jWdUrLZlJUnH2iHPhQbACIGA+/e40wACf0XXzsgteWlUX/V0WdG8uY1tEYXra/q68OIENYEOAAAAACAAAAAgBIAAIAAAQEfE4YBAAAAAAAWABTVkQkbgHSiN17ZmFqcSxjv7P1BZSIGAog7tUY+N9VSUtiz1cIUGwB7N8in22IR91yVWsxeoyXrENYEOAAAAACAAQAAgAwAAIAAIgICKMavAB+71Adqsbf+XtC1g/OlmLEuTp3U0axyeu/LAI0Q1gQ4AAAAAIABAACAGgAAgAAA", + "fee": 0.00042300, + "changepos": 0 +} +``` +Tuttavia, il grande vantaggio è che puoi usarlo per autofinanziarti tralasciando gli `input`, proprio come `fundrawtransaction`. +``` +$ psbt_new=$(bitcoin-cli -named walletcreatefundedpsbt inputs='''[]''' outputs='''{ "'$recipient'": 0.0000065 }''' | jq -r '.psbt') +$ bitcoin-cli decodepsbt $psbt_new +{ + "tx": { + "txid": "9f2c6205ac797c1020f7f261e3ab71cd0699ff4b1a8934f68b273c71547e235f", + "hash": "9f2c6205ac797c1020f7f261e3ab71cd0699ff4b1a8934f68b273c71547e235f", + "version": 2, + "size": 154, + "vsize": 154, + "weight": 616, + "locktime": 0, + "vin": [ + { + "txid": "8748eff5f12ca886e3603d9e30227dcb3f0332e0706c4322fec96001f7c7f41c", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + }, + { + "txid": "68e1863492802df9337e6ce4f89f53fa5739837ba459ba52c9a3d200ab0717ee", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00971390, + "n": 0, + "scriptPubKey": { + "asm": "0 09a74ef0bae4d68b0b2ec9a7c4557a2b5c85bd8b", + "hex": "001409a74ef0bae4d68b0b2ec9a7c4557a2b5c85bd8b", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qpxn5au96untgkzewexnug4t69dwgt0vtfahcv6" + ] + } + }, + { + "value": 0.00000650, + "n": 1, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.00000840, + "scriptPubKey": { + "asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165", + "hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "type": "witness_v0_keyhash", + "address": "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh" + } + }, + "bip32_derivs": [ + { + "pubkey": "02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb", + "master_fingerprint": "d6043800", + "path": "m/0'/1'/12'" + } + ] + }, + { + "non_witness_utxo": { + "txid": "68e1863492802df9337e6ce4f89f53fa5739837ba459ba52c9a3d200ab0717ee", + "hash": "68e1863492802df9337e6ce4f89f53fa5739837ba459ba52c9a3d200ab0717ee", + "version": 2, + "size": 140, + "vsize": 140, + "weight": 560, + "locktime": 1774654, + "vin": [ + { + "txid": "cc49eb0b550fc2dc7e3b9fff459f12650e0903fc7b40a31ede670612f9b266d5", + "vout": 1, + "scriptSig": { + "asm": "0014731714497c53e5f0527a4b18c0273cb798200c5d", + "hex": "160014731714497c53e5f0527a4b18c0273cb798200c5d" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01000000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 7f437379bcc66c40745edc1891ea6b3830e1975d OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9147f437379bcc66c40745edc1891ea6b3830e1975d88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "ms7ruzvL4atCu77n47dStMb3of6iScS8kZ" + ] + } + }, + { + "value": 0.02961601, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 fddfa4317e978a3983fa359d52b2d99495271f68 OP_EQUAL", + "hex": "a914fddfa4317e978a3983fa359d52b2d99495271f6887", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2NGParh82hE2Zif5PVK3AfLpYhfwF5FyRGr" + ] + } + } + ] + }, + "bip32_derivs": [ + { + "pubkey": "03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/18'" + } + ] + } + ], + "outputs": [ + { + "bip32_derivs": [ + { + "pubkey": "029bb586a52657dd98852cecef78552a4e21d081a7a30e4008ce9b419840d4deac", + "master_fingerprint": "d6043800", + "path": "m/0'/1'/27'" + } + ] + }, + { + } + ], + "fee": 0.00028800 +} +``` +Come puoi vedere, ha creato la PSBT e poi l'ha aggiornata con tutte le informazioni che ha potuto trovare localmente. + +Da lì, devi utilizzare `walletprocesspsbt` per finalizzare, come al solito: + +``` +$ psbt_new_f=$(bitcoin-cli walletprocesspsbt $psbt_new | jq -r '.psbt') +``` + +Successivamente, un'analisi mostrerà che anche questo è quasi pronto: + +``` +$ bitcoin-cli analyzepsbt $psbt_new_f +{ + "inputs": [ + { + "has_utxo": true, + "is_final": true, + "next": "extractor" + }, + { + "has_utxo": true, + "is_final": true, + "next": "extractor" + } + ], + "estimated_vsize": 288, + "estimated_feerate": 0.00100000, + "fee": 0.00028800, + "next": "extractor" +} +``` +Ora vorresti davvero utilizzare `walletcreatefundedpsbt` se stessi creando un programma `bitcoin-cli`? Probabilmente no. Ma è la stessa analisi dell'utilizzo di `fundrawtransaction`. Lascia che Bitcoin Core esegua l'analisi, i calcoli e le decisioni o lo farai tu? + +## Invia una PSBT +#### Ruolo PSBT: Estrattore + +Per finalizzare la PSBT, usa `finalizepsbt`, che trasformerà nuovamente il tuo PSBT in esadecimale. (Assumerà anche il ruolo di Finalizzatore, se ciò non è già accaduto.) +``` +$ bitcoin-cli finalizepsbt $psbt_f +{ + "hex": "020000000001021b95a6055174ec64b82ef05b6aefc38f34d0e57197e40281ecd8287b4260dec60100000000ffffffff1cf4c7f70160c9fe22436c70e032033fcb7d22309e3d60e386a82cf1f5ef48870000000000ffffffff018a02000000000000160014c772d6f95542e11ef11e8efc7c7a69830ad38a050247304402200a896f1cfa741ccda5f683bb85d95dbf836c390cdd45a785ece1f54766795821022051c4c956da8d3012da61b5465158888939a1ad5dfb106c1e25a2f92f13879122012102bac3a645fd7a0a537c627ad37f5f695058c58d19ceb0033e913f1a9975e00dee0247304402207eb0d3423b8c62150f83a0756baaa93dc8cd15e07f594b2131c753d6ed16e3b2022051e5a44372fb680bf5c487bb87ef0f65bf040ac5e0d54cdbb4f5bcc1ddaac745012102883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb00000000", + "complete": true +} +``` +Come al solito, ti consigliamo di salvarlo e quindi di inviarlo + +``` +$ psbt_hex=$(bitcoin-cli finalizepsbt $psbt_f | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$psbt_hex +ea73a631b456d2b041ed73bf5767946408c6ff067716929a68ecda2e3e4de6d3 +``` +## Il flusso di lavoro + +Quando crei software per `bitcoin-cli`, è molto probabile che ricoprirai i cinque ruoli principali dei PSBT con `createpsbt`, `walletprocesspsbt` e `finalizepsbt`. Ecco come appare il flusso: + +![](images/psbt-roles-for-cli-1.png) + +Se scegli di utilizzare la scorciatoia `walletcreatefundedpsbt`, ecco come appare: + +![](images/psbt-roles-for-cli-2.png) + +Infine, se invece hai bisogno di maggiore controllo e scegli di utilizzare `utxoupdatepsbt` (che non è molto documentato qui), hai invece questo flusso di lavoro: + +![](images/psbt-roles-for-cli-3.png) + +## Riepilogo: creare una transazione Bitcoin parzialmente firmata + +La creazione di una PSBT implica un flusso di lavoro piuttosto complesso di creazione, aggiornamento, firma, finalizzazione ed estrazione di una PSBT, dopo di che viene riconvertita in una transazione grezza. Perché dovresti prenderti tutto quel disturbo? Perché vuoi collaborare tra più utenti o più programmi. Ora che hai compreso questo flusso di lavoro, la sezione successiva presenta alcuni esempi reali di come farlo. + +## Qual è il prossimo argomento? + +Continua con "Ampliare le transazioni Bitcoin usando PSBT" nel [Capitolo 7.2: Usare una Transazione Bitcoin Parzialmente Firmata](07_2_Usare_una_Transazione_Bitcoin_Parzialmente_Firmata.md). diff --git a/it/07_2_Usare_una_Transazione_Bitcoin_Parzialmente_Firmata.md b/it/07_2_Usare_una_Transazione_Bitcoin_Parzialmente_Firmata.md new file mode 100644 index 000000000..af1c98dde --- /dev/null +++ b/it/07_2_Usare_una_Transazione_Bitcoin_Parzialmente_Firmata.md @@ -0,0 +1,602 @@ +# 7.2: Usare una transazione Bitcoin parzialmente firmata + +> :information_source: **NOTA:** Questa sezione è stata aggiunta di recente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Letto avvertito. + +Ora che hai imparato il flusso di lavoro di base per generare un PSBT, probabilmente vorrai farci qualcosa. Cosa possono fare i PSBT che i multi-sig (e le normali transazioni grezze) non possonofare? Per cominciare, hai la facilità d'uso di un formato standardizzato, il che significa che puoi utilizzare le tue transazioni "bitcoin-cli" e combinarle con transazioni generate da persone (o programmi) su altre piattaforme. Oltre a ciò, puoi fare alcune cose che semplicemente non sarebbero facili usando altre meccaniche. + +Di seguito sono riportati tre esempi di utilizzo dei PSBT per: multi-sigs, pooling di denaro e coinjoin. + +> :avviso: **AVVISO di VERSIONE:** Questa è un'innovazione di Bitcoin Core v 0.17.0. Le versioni precedenti di Bitcoin Core non saranno in grado di funzionare con il PSBT mentre è in corso (sebbene saranno comunque in grado di riconoscere la transazione finale). + +## Usa una PSBT per spendere fondi MultiSig + +Supponiamo di aver creato un indirizzo multisig, proprio come hai fatto nel [Capitolo 6.3](06_3_Inviare_e_Ricevere_una_Multifirma_Automatizzata.md).. +``` +machine1$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' +{ + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0", + "redeemScript": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "descriptor": "wsh(multi(2,[d6043800/0'/0'/26']038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e,[be686772]03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636))#07zyayfk" +} +machine1$ bitcoin-cli -named importaddress address="tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" rescan=false + +machine2$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' +{ + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0", + "redeemScript": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "descriptor": "wsh(multi(2,[d6043800/0'/0'/26']038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e,[be686772]03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636))#07zyayfk" +} +machine2$ bitcoin-cli -named importaddress address="tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" rescan=false +``` +E hai dei soldi dentro: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "vout": 0, + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0", + "label": "", + "witnessScript": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "scriptPubKey": "0020224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "amount": 0.01999800, + "confirmations": 2, + "spendable": false, + "solvable": true, + "desc": "wsh(multi(2,[d6043800/0'/0'/26']038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e,[be686772]03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636))#07zyayfk", + "safe": true + } +] +``` +Potresti _potresti_ spendere le monere utilizzando i meccanismi visti nel [Capitolo 6](06_0_Ampliare_le_Transazioni_Bitcoin_con_Multifirme.md), dove hai firmato in serie una transazione, ma invece mostreremo il vantaggio dei PSBT per multi-sigs: puoi generare una singola PSBT, consentire tutti di firmare in parallelo e poi a combinare i risultati! Non è più necessario passare faticosamente un hex in continua espansione da persona a persona, il che accelera le cose e riduce le possibilità di errori. + +Per dimostrare questa metodologia, estrarremo quegli 0,02 BTC dal multi-sig e li divideremo tra i due firmatari, ciascuno dei quali ha generato un nuovo indirizzo a tale scopo: +``` +machine1$ bitcoin-cli getnewaddress +tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma +machine2$ bitcoin-cli getnewaddress +tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp +``` +La prima cosa che facciamo è creare un PSBT sulla macchina di nostra scelta. (Non importa quale.) Dobbiamo utilizzare `createpsbt` come visto nel[Capitolo 7.1](07_1_Creare_una_Transazione_Bitcoin_Parzialmente_Firmata.md) per questo, non il più semplice `walletcreatefundedpsbt`, perché abbiamo bisogno del controllo extra della selezione del denaro protetto dal multi -sig. (Questo sarà il caso di tutti e tre gli esempi in questa sezione, il che dimostra perché di solito è necessario utilizzare `createpsbt` per cose complesse.) +``` +machine1$ utxo_txid=53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5 +machine1$ utxo_vout=0 +machine1$ split1=tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma +machine1$ split2=tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp +machine1$ psbt=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$split1'": 0.009998,"'$split2'": 0.009998 }''') +``` +Dovrai quindi inviare $psbt a tutti per la firma: +``` +machine1$ echo $psbt +cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAAAAAA= +``` +Ma devi solo inviarlo una volta! E lo fai contemporaneamente. +Ecco il risultato sulla prima macchina, dove generiamo il PSBT: +``` +machine1$ psbt_p1=$(bitcoin-cli walletprocesspsbt $psbt | jq -r '.psbt') +machine1$ bitcoin-cli decodepsbt $psbt_p1 +{ + "tx": { + "txid": "1687e89fcb9dd3067f75495b4884dc1d4d1cf05a6c272b783cfe29eb5d22e985", + "hash": "1687e89fcb9dd3067f75495b4884dc1d4d1cf05a6c272b783cfe29eb5d22e985", + "version": 2, + "size": 113, + "vsize": 113, + "weight": 452, + "locktime": 0, + "vin": [ + { + "txid": "25e8a26f60cf485768a1e6953b983675c867b7ab126b02e753c47b7db0c4be5e", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00499900, + "n": 0, + "scriptPubKey": { + "asm": "0 cee9f88288a5f4980191a28d7ae08ff584050da7", + "hex": "0014cee9f88288a5f4980191a28d7ae08ff584050da7", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma" + ] + } + }, + { + "value": 0.00049990, + "n": 1, + "scriptPubKey": { + "asm": "0 8d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "hex": "00148d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 2abb5d49ce7e753cbf5a9ffa8cdaf815bf1074f5c0bf495a93df8eb5112f65aa", + "hex": "00202abb5d49ce7e753cbf5a9ffa8cdaf815bf1074f5c0bf495a93df8eb5112f65aa", + "type": "witness_v0_scripthash", + "address": "tb1q92a46jww0e6ne066nlagekhczkl3qa84czl5jk5nm78t2yf0vk4qte328m" + } + }, + "partial_signatures": { + "03f52980d322acaf084bcef3216f3d84bfb672d1db26ce2861de3ec047bede140d": "304402203abb95d1965e4cea630a8b4890456d56698ff2dd5544cb79303cc28cb011cbb40220701faa927f8a19ca79b09d35c78d8d0a2187872117d9308805f7a896b07733f901" + }, + "witness_script": { + "asm": "2 033055ec2da9bbb34c2acb343692bfbecdef8fab8d114f0036eba01baec3888aa0 03f52980d322acaf084bcef3216f3d84bfb672d1db26ce2861de3ec047bede140d 2 OP_CHECKMULTISIG", + "hex": "5221033055ec2da9bbb34c2acb343692bfbecdef8fab8d114f0036eba01baec3888aa02103f52980d322acaf084bcef3216f3d84bfb672d1db26ce2861de3ec047bede140d52ae", + "type": "multisig" + }, + "bip32_derivs": [ + { + "pubkey": "033055ec2da9bbb34c2acb343692bfbecdef8fab8d114f0036eba01baec3888aa0", + "master_fingerprint": "c1fdfe64", + "path": "m" +{ + "tx": { + "txid": "ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16", + "hash": "ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16", + "version": 2, + "size": 113, + "vsize": 113, + "weight": 452, + "locktime": 0, + "vin": [ + { + "txid": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00999800, + "n": 0, + "scriptPubKey": { + "asm": "0 cee9f88288a5f4980191a28d7ae08ff584050da7", + "hex": "0014cee9f88288a5f4980191a28d7ae08ff584050da7", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma" + ] + } + }, + { + "value": 0.00999800, + "n": 1, + "scriptPubKey": { + "asm": "0 8d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "hex": "00148d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01999800, + "scriptPubKey": { + "asm": "0 224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "hex": "0020224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "type": "witness_v0_scripthash", + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" + } + }, + "partial_signatures": { + "038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e": "3044022040aae4f2ba37b1526524195f4a325d97d1317227b3c82aea55c5abd66810a7ec0220416e7c03e70a31232044addba454d6b37b6ace39ab163315d3293e343ae9513301" + }, + "witness_script": { + "asm": "2 038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e 03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636 2 OP_CHECKMULTISIG", + "hex": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "type": "multisig" + }, + "bip32_derivs": [ + { + "pubkey": "03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636", + "master_fingerprint": "be686772", + "path": "m" + }, + { + "pubkey": "038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/26'" + } + ] + } + ], + "outputs": [ + { + "bip32_derivs": [ + { + "pubkey": "02fce26085452d07abc63bd389cb7dba9871e79bbecd08039291226be8232a9000", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/24'" + } + ] + }, + { + } + ], + "fee": 0.00000200 +} +machine1$ bitcoin-cli analyzepsbt $psbt_p1 +{ + "inputs": [ + { + "has_utxo": true, + "is_final": false, + "next": "signer", + "missing": { + "signatures": [ + "be6867729bcc35ed065bb4c937557d371218a8e2" + ] + } + } + ], + "estimated_vsize": 168, + "estimated_feerate": 0.00001190, + "fee": 0.00000200, + "next": "signer" +} + +``` +Questo dimostra che le informazioni UTXO sono state importate, e che c'è una _firma parziale_, ma che la firma del singolo input non è ancora completa. + +Ecco la stessa cosa sull'altra macchina: +``` +machine2$ psbt=cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAAAAAA= +machine2$ psbt_p2=$(bitcoin-cli walletprocesspsbt $psbt | jq -r '.psbt') +machine3$ echo $psbt_p2 +cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAABASu4gx4AAAAAACIAICJMtQOn94NXmbnCLuDDx9k9CQNW4w5wAVw+u/pRWjB0IgIDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZHMEQCIDJ71isvR2We6ym1QByLV5SQ+XEJD0SAP76fe1JU5PZ/AiB3V7ejl2H+9LLS6ubqYr/bSKfRfEqrp2FCMISjrWGZ6QEBBUdSIQONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDiEDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZSriIGA3ifVDQjZw4Wlmf/fh8toql98bCRInLhQtWCRRrOvQY2ENPtiCUAAACAAAAAgAYAAIAiBgONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDgRZu4lPAAAiAgNJzEMyT3rZS7QHqb8SvFCv2ee0MKRyVy8bY8tVUDT1KhDT7YglAAAAgAAAAIADAACAAA== +``` +Tieni presente che abbiamo gestito la firma di questo multi-sig generando un PSBT non firmato ma contenendo l'UTXO corretto, consentendo quindi a ciascuno degli utenti di elaborare quel PSBT per conto proprio, aggiungendo input e firme. Di conseguenza, abbiamo due PSBT, ciascuno dei quali contiene una firma e non l'altra. Ciò non funzionerebbe nel classico scenario multi-sig, perché tutte le firme devono essere serializzate. Qui, invece, possiamo firmare in parallelo e poi utilizzare il ruolo "Combinatore" per mescolarli insieme. + +Andiamo di nuovo su una delle due macchine e ci assicuriamo di avere entrambi i PSBT nelle variabili, quindi li combiniamo: +``` +machine1$ psbt_p2="cHNidP8BAHECAAAAAbU5tQSXtwlf5ZamU+wwrLjHFp1p6WQh7haL/sLFYuxTAAAAAAD/////AnhBDwAAAAAAFgAUzun4goil9JgBkaKNeuCP9YQFDad4QQ8AAAAAABYAFI2GH/borPHKKjs91ZyG8uigq6dcAAAAAAABAIcCAAAAAtu5pTheUzdsTaMCEPj3XKboMAyYzABmIIeOWMhbhTYlAAAAAAD//////uSTLbibcqSd/Z9ieSBWJ2psv+9qvoGrzWEa60rCx9cAAAAAAP////8BuIMeAAAAAAAiACAiTLUDp/eDV5m5wi7gw8fZPQkDVuMOcAFcPrv6UVowdAAAAAAAACICA0nMQzJPetlLtAepvxK8UK/Z57QwpHJXLxtjy1VQNPUqENPtiCUAAACAAAAAgAMAAIAA" +machine2$ psbt_c=$(bitcoin-cli combinepsbt '''["'$psbt_p1'", "'$psbt_p2'"]''') +$ bitcoin-cli decodepsbt $psbt_c +{ + "tx": { + "txid": "ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16", + "hash": "ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16", + "version": 2, + "size": 113, + "vsize": 113, + "weight": 452, + "locktime": 0, + "vin": [ + { + "txid": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00999800, + "n": 0, + "scriptPubKey": { + "asm": "0 cee9f88288a5f4980191a28d7ae08ff584050da7", + "hex": "0014cee9f88288a5f4980191a28d7ae08ff584050da7", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qem5l3q5g5h6fsqv352xh4cy07kzq2rd8gphqma" + ] + } + }, + { + "value": 0.00999800, + "n": 1, + "scriptPubKey": { + "asm": "0 8d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "hex": "00148d861ff6e8acf1ca2a3b3dd59c86f2e8a0aba75c", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q3krplahg4ncu523m8h2eephjazs2hf6ur8r6zp" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01999800, + "scriptPubKey": { + "asm": "0 224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "hex": "0020224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "type": "witness_v0_scripthash", + "address": "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" + } + }, + "partial_signatures": { + "038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e": "3044022040aae4f2ba37b1526524195f4a325d97d1317227b3c82aea55c5abd66810a7ec0220416e7c03e70a31232044addba454d6b37b6ace39ab163315d3293e343ae9513301", + "03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636": "30440220327bd62b2f47659eeb29b5401c8b579490f971090f44803fbe9f7b5254e4f67f02207757b7a39761fef4b2d2eae6ea62bfdb48a7d17c4aaba761423084a3ad6199e901" + }, + "witness_script": { + "asm": "2 038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e 03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636 2 OP_CHECKMULTISIG", + "hex": "5221038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e2103789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd063652ae", + "type": "multisig" + }, + "bip32_derivs": [ + { + "pubkey": "03789f543423670e169667ff7e1f2da2a97df1b0912272e142d582451acebd0636", + "master_fingerprint": "be686772", + "path": "m" + }, + { + "pubkey": "038d73adf2c7ea33f9dc34b77b62b59af433c1de9c763332da79e83e155f96030e", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/26'" + } + ] + } + ], + "outputs": [ + { + "bip32_derivs": [ + { + "pubkey": "02fce26085452d07abc63bd389cb7dba9871e79bbecd08039291226be8232a9000", + "master_fingerprint": "d6043800", + "path": "m/0'/0'/24'" + } + ] + }, + { + "bip32_derivs": [ + { + "pubkey": "0349cc43324f7ad94bb407a9bf12bc50afd9e7b430a472572f1b63cb555034f52a", + "master_fingerprint": "d3ed8825", + "path": "m/0'/0'/3'" + } + ] + } + ], + "fee": 0.00000200 +} +$ bitcoin-cli analyzepsbt $psbt_c +{ + "inputs": [ + { + "has_utxo": true, + "is_final": false, + "next": "finalizer" + } + ], + "estimated_vsize": 168, + "estimated_feerate": 0.00001190, + "fee": 0.00000200, + "next": "finalizer" +} +``` +Ha funzionato! Basta finalizzare e inviare e il gioco è fatto: +``` +machine2$ psbt_c_hex=$(bitcoin-cli finalizepsbt $psbt_c | jq -r '.hex') +standup@btctest2:~$ bitcoin-cli -named sendrawtransaction hexstring=$psbt_c_hex +ee82d3e0d225e0fb919130d68c5052b6e3c362c866acc54d89af975330bb4d16 +``` +Ovviamente, non c'è stato un grande miglioramento nell'usare questo metodo rispetto alla firma seriale di una transazione per un multisig 2 su 2 quando tutti usavano `bitcoin-cli`: avremmo potuto passare una transazione grezza con firme parziali da un utente a l'altro con la stessa facilità con cui invii quel PSBT. Ma questo era il caso più semplice. Man mano che approfondiamo multisig più complessi, questa metodologia diventa sempre migliore. + +Prima di tutto, è indipendente dalla piattaforma. Finché tutti utilizzano un servizio che supporta Bitcoin Core 0.17, saranno tutti in grado di firmare questa transazione, il che non è vero quando i classici multi-sig vengono trasmessi tra piattaforme diverse. + +In secondo luogo, è molto più scalabile. Considera un multisig 3 su 5. Secondo la vecchia metodologia la strringa 'hex' dovrebbe passare da persona a persona, aumentando notevolmente i problemi in caso di rottura di un singolo anello della catena. Qui, gli altri utenti devono semplicemente rispedire i PSBT al Creatore e, non appena ne avrà abbastanza, potrà generare la transazione finale. + +## Usa un PSBT per raggruppare denaro + +I multisig come quello utilizzato nell'esempio precedente vengono spesso utilizzati per ricevere pagamenti per il lavoro collaborativo, che si tratti di royalty per un libro o di pagamenti effettuati a un'azienda. In quella situazione, l’esempio sopra funziona alla grande: i due partecipanti ricevono i loro soldi che poi si dividono. Ma che dire del caso contrario, in cui due (o più) partecipanti vogliono costituire una joint venture e hanno bisogno di finanziarla? + +La risposta tradizionale è creare un multisig, quindi chiedere ai partecipanti di inviarvi i propri fondi individualmente. Il problema è che il primo pagatore deve dipendere dalla buona fede del secondo, e questo non si basa sulla forza di Bitcoin, che non necessita della _fiducia_ altrui. Fortunatamente, con l’avvento dei PSBT, ora possiamo effettuare pagamenti trustless che mettono in comune i fondi. + +> :book: ***Cosa significa trustless?*** "Senza fiducia" significa che nessun partecipante ha bisogno di fidarsi degli altri partecipanti. Si aspettano invece che i protocolli software garantiscano che tutto venga attuato in modo equo e nel modo previsto. Bitcoin è un protocollo trustless perché non è necessario che nessun altro agisca in buona fede; il sistema lo gestisce. Allo stesso modo, i PSBT consentono la creazione trustless di transazioni che mettono in comune o dividono i fondi. + +L'esempio seguente mostra due utenti che hanno ciascuno 0,010 BTC che desiderano raggruppare nell'indirizzo multisig `tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0`, creato sopra. +``` +machine1$ bitcoin-cli listunspent +[ + { + "txid": "2536855bc8588e87206600cc980c30e8a65cf7f81002a34d6c37535e38a5b9db", + "vout": 0, + "address": "tb1qfg5y4fx979xkv4ezatc5eevufc8vh45553n4ut", + "label": "", + "scriptPubKey": "00144a284aa4c5f14d665722eaf14ce59c4e0ecbd694", + "amount": 0.01000000, + "confirmations": 2, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/0'/25']02bea222cf9ea1f49b392103058cc7c8741d76a553fe627c1c43fc3ef4404c9d54)#4hnkg9ml", + "safe": true + } +] +machine2$ bitcoin-cli listunspent +[ + { + "txid": "d7c7c24aeb1a61cdab81be6aefbf6c6a27562079629ffd9da4729bb82d93e4fe", + "vout": 0, + "address": "tb1qfqyyw6xrghm5kcrpkus3kl2l6dz4tpwrvn5ujs", + "label": "", + "scriptPubKey": "001448084768c345f74b6061b7211b7d5fd3455585c3", + "amount": 0.01000000, + "confirmations": 5363, + "spendable": true, + "solvable": true, + "desc": "wpkh([d3ed8825/0'/0'/0']03ff6b94c119582a63dbae4fb530efab0ed5635f7c3b2cf171264ca0af3ecef33a)#gtmd2e2k", + "safe": true + } +] +``` +Impostano variabili per utilizzare tali transazioni: +``` +machine1$ utxo_txid_1=2536855bc8588e87206600cc980c30e8a65cf7f81002a34d6c37535e38a5b9db +machine1$ utxo_vout_1=0 +machine1$ utxo_txid_2=d7c7c24aeb1a61cdab81be6aefbf6c6a27562079629ffd9da4729bb82d93e4fe +machine1$ utxo_vout_2=0 +machine1$ multisig=tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0 + +``` +E creano la PSBT: +``` +machine1$ psbt=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$multisig'": 0.019998 }''') +``` +Ecco come si vede: +``` +machine1$ bitcoin-cli decodepsbt $psbt +{ + "tx": { + "txid": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "hash": "53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5", + "version": 2, + "size": 135, + "vsize": 135, + "weight": 540, + "locktime": 0, + "vin": [ + { + "txid": "2536855bc8588e87206600cc980c30e8a65cf7f81002a34d6c37535e38a5b9db", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "d7c7c24aeb1a61cdab81be6aefbf6c6a27562079629ffd9da4729bb82d93e4fe", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.01999800, + "n": 0, + "scriptPubKey": { + "asm": "0 224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "hex": "0020224cb503a7f7835799b9c22ee0c3c7d93d090356e30e70015c3ebbfa515a3074", + "reqSigs": 1, + "type": "witness_v0_scripthash", + "addresses": [ + "tb1qyfxt2qa877p40xdecghwps78my7sjq6kuv88qq2u86al5526xp6qfqjud0" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + }, + { + } + ], + "outputs": [ + { + } + ] +} +``` +Non importa che le transazioni siano di proprietà di due persone diverse o che le loro informazioni complete appaiano su due macchine diverse. Questo PSBT di finanziamento funzionerà esattamente come il PSBT multisig: una volta che tutte le parti controllanti avranno firmato, la transazione potrà essere finalizzata. + +Ecco il processo, questa volta passando il PSBT parzialmente firmato da un utente all'altro invece di dover combinare le cose alla fine. +``` +machine1$ bitcoin-cli walletprocesspsbt $psbt +{ + "psbt": "cHNidP8BAIcCAAAAAtu5pTheUzdsTaMCEPj3XKboMAyYzABmIIeOWMhbhTYlAAAAAAD//////uSTLbibcqSd/Z9ieSBWJ2psv+9qvoGrzWEa60rCx9cAAAAAAP////8BuIMeAAAAAAAiACAiTLUDp/eDV5m5wi7gw8fZPQkDVuMOcAFcPrv6UVowdAAAAAAAAQEfQEIPAAAAAAAWABRKKEqkxfFNZlci6vFM5ZxODsvWlAEIawJHMEQCIGAiKIAWRXiw68o3pw61/cVNP7n2oH73S654XXgQ4kjHAiBtTBqmaF1iIzYGXrG4DadH8y6mTuCRVFDiPl+TLQDBJwEhAr6iIs+eofSbOSEDBYzHyHQddqVT/mJ8HEP8PvRATJ1UAAABAUdSIQONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDiEDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZSriICA3ifVDQjZw4Wlmf/fh8toql98bCRInLhQtWCRRrOvQY2BL5oZ3IiAgONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDhDWBDgAAAAAgAAAAIAaAACAAA==", + "complete": false +} + +machine2$ psbt_p="cHNidP8BAIcCAAAAAtu5pTheUzdsTaMCEPj3XKboMAyYzABmIIeOWMhbhTYlAAAAAAD//////uSTLbibcqSd/Z9ieSBWJ2psv+9qvoGrzWEa60rCx9cAAAAAAP////8BuIMeAAAAAAAiACAiTLUDp/eDV5m5wi7gw8fZPQkDVuMOcAFcPrv6UVowdAAAAAAAAQEfQEIPAAAAAAAWABRKKEqkxfFNZlci6vFM5ZxODsvWlAEIawJHMEQCIGAiKIAWRXiw68o3pw61/cVNP7n2oH73S654XXgQ4kjHAiBtTBqmaF1iIzYGXrG4DadH8y6mTuCRVFDiPl+TLQDBJwEhAr6iIs+eofSbOSEDBYzHyHQddqVT/mJ8HEP8PvRATJ1UAAABAUdSIQONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDiEDeJ9UNCNnDhaWZ/9+Hy2iqX3xsJEicuFC1YJFGs69BjZSriICA3ifVDQjZw4Wlmf/fh8toql98bCRInLhQtWCRRrOvQY2BL5oZ3IiAgONc63yx+oz+dw0t3titZr0M8HenHYzMtp56D4VX5YDDhDWBDgAAAAAgAAAAIAaAACAAA==" +machine2$ psbt_f=$(bitcoin-cli walletprocesspsbt $psbt_p | jq -r '.psbt') +machine2$ bitcoin-cli analyzepsbt $psbt_f +{ + "inputs": [ + { + "has_utxo": true, + "is_final": true, + "next": "extractor" + }, + { + "has_utxo": true, + "is_final": true, + "next": "extractor" + } + ], + "estimated_vsize": 189, + "estimated_feerate": 0.00001058, + "fee": 0.00000200, + "next": "extractor" +} +machine2$ psbt_hex=$(bitcoin-cli finalizepsbt $psbt_f | jq -r '.hex') +machine2$ bitcoin-cli -named sendrawtransaction hexstring=$psbt_hex +53ec62c5c2fe8b16ee2164e9699d16c7b8ac30ec53a696e55f09b79704b539b5 +``` +Abbiamo utilizzato una PSBT per raccogliere denaro in un multisig senza dover fidarci! + +## Usa una PSBT per CoinJoin + +CoinJoin è un'altra applicazione Bitcoin che richiede fiducia. Qui hai una varietà di parti che non necessariamente si conoscono che uniscono i soldi e li recuperano. + +La metodologia per gestirlo con le PSBT è esattamente la stessa che hai visto negli esempi precedenti, come dimostra il seguente pseudo-codice: +``` +$ psbt=$(bitcoin-cli -named createpsbt inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' }, { "txid": "'$utxo_txid_3'", "vout": '$utxo_vout_3' } ]''' outputs='''{ "'$split1'": 1.7,"'$split2'": 0.93,"'$split3'": 1.4 }''') +``` +Ogni utente inserisce il proprio UTXO e ognuno riceve un output corrispondente. + +Il modo migliore per gestire un CoinJoin è inviare il PSBT di base a tutte le parti (che potrebbero essere numerose), quindi chiedere a ciascuno di firmare il PSBT e rispedirlo a una singola parte che combinerà, finalizzerà e invierà. + +> :book: ***Che cos'è CoinJoin?*** CoinJoin è una metodologia in base alla quale un gruppo di persone può mescolare insieme le proprie monete, contribuendo ad aumentare la fungibilità. Ogni persona inserisce e preleva la stessa quantità di monete (meno le commissioni di transazione) in una transazione tra più persone condotta simultaneamente da un numero elevato di persone. È progettato per essere "trustless" in modo che le parti non abbiano bisogno di conoscersi o fidarsi l'una dell'altra. Un CoinJoin alla fine aumenta l’anonimato rendendo difficile il tracciamento delle monete. Ci sono alcune wallet come sparrow e samourai che supportano il coinjooin e una serie di servizi "whirpool" su larga scala per migliorare l'anonimato. + +## Riepilogo: utilizzo di una transazione Bitcoin parzialmente firmata + +Ora hai visto il processo PSBT che hai imparato in [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) in uso in tre esempi di vita reale: creazione di un multi-sig, pooling di fondi e CoinJoining. Tutto ciò era teoricamente possibile nel Bitcoin classico facendo firmare più persone a transazioni attentamente costruite, ma i PSBT lo rendono standardizzato e semplice. + +> :fire: ***Qual è il potere di un PSBT?*** Un PSBT consente la creazione di transazioni trustless tra più parti e più macchine. Se più di una parte avesse bisogno di finanziare una transazione, se più di una parte avesse bisogno di firmare una transazione, o se una transazione dovesse essere creata su una macchina e firmata su un’altra, allora un PSBT rende tutto semplice senza dipendere dal meccanismi di firma parziale non standardizzati che esistevano prima del PSBT. + +Quest'ultimo punto, sulla creazione di una transazione su una macchina e sulla firma su un'altra, è un elemento dei PSBT a cui non siamo ancora arrivati. È il cuore dei portafogli hardware, dove spesso desideri creare una transazione su un nodo completo, quindi trasferirla a un portafoglio hardware quando è richiesta una firma. Questo è l'argomento dell'ultima sezione (e del nostro quarto esempio di vita reale) in questo capitolo sui PSBT. + +## Cosa segue?? + +Continua con l' "Espansione delle transazioni Bitcoin con PSBT" nel [Capitolo 7.3: Integrazione con hardware wallet](07_3_Integrazione_con_Hardware_Wallets.md). diff --git a/it/07_3_Integrazione_con_Hardware_Wallets.md b/it/07_3_Integrazione_con_Hardware_Wallets.md new file mode 100644 index 000000000..ac653999e --- /dev/null +++ b/it/07_3_Integrazione_con_Hardware_Wallets.md @@ -0,0 +1,480 @@ +# 7.3: Integrazione con hardware wallet + +> :information_source: **NOTA:** Questa sezione è stata aggiunta di recente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Uno dei maggiori poteri dei PSBT è la capacità di trasferire le transazioni ai portafogli hardware. Questo sarà un ottimo strumento di sviluppo per te se continui a programmare con Bitcoin. Tuttavia, non puoi testarlo ora se stai utilizzando una delle configurazioni che suggeriamo per questo corso: una VM su Linode secondo il [Capitolo 2.1](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md) o un'opzione ancora più remota come AWS vista nel [Capitolo 2.2](02_2_Configurare_Bitcoin_Core_Altri_Mezzi.md) - perché ovviamente non avrai alcun modo di collegare un portafoglio hardware alla tua macchina virtuale remota. + +> :book: ***Che cos'è un portafoglio hardware?*** Un portafoglio hardware è un dispositivo elettronico che migliora la sicurezza di una criptovaluta mantenendo tutte le chiavi private sul dispositivo, anziché metterle mai su un computer direttamente collegato a Internet. I portafogli hardware dispongono di protocolli specifici per fornire interazioni online, solitamente gestiti da un programma che comunica con il dispositivo tramite una porta USB. In questo capitolo gestiremo un portafoglio hardware con `bitcoin-cli` e il programma `hwy.py`. + +Hai tre opzioni per muoverti in questo capitolo sui portafogli hardware: (1) leggere senza testare il codice; (2) installa Bitcoin su un computer locale per testare completamente questi comandi; oppure (3) vai direttamente al [Capitolo 8: Ampliare Altre Transazioni Bitcoin](08_0_Ampliare_Altre_Transazioni_Bitcoin.md). Suggeriamo l'opzione n. 1, ma se vuoi davvero sporcarti le mani ti forniremo supporto anche per la n.2 parlando dell'utilizzo di un Macintosh (una piattaforma hardware supportata da +[Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup)) per i test. + +> :avviso: **AVVISO di VERSIONE:** Le PSBT sono un'innovazione di Bitcoin Core v 0.17.0. Le versioni precedenti di Bitcoin Core non saranno in grado di funzionare con il PSBT mentre è in corso (sebbene saranno comunque in grado di riconoscere la transazione finale). L'interfaccia HWI è apparsa in Bitcoin Core v 0.18.0, ma finché utilizzi la nostra configurazione suggerita con Bitcoin Standup, dovrebbe funzionare. + +La metodologia descritta in questo capitolo per l'integrazione con un portafoglio hardware dipende dall'[Bitcoin Hardware Wallet Interface](https://github.com/bitcoin-core/HWI) rilasciata tramite Bitcoin Core e si basa sull'[installazione](https://github.com/bitcoin-core/HWI/blob/master/README.md) e le istruzioni d'[utilizzo](https://hwi.readthedocs.io) si trovano lì. + +> :avviso: **AVVISO:** L'interfaccia HWI è molto nuova e grezza a partire da Bitcoin Core v 0.20.0. Potrebbe essere difficile installarlo correttamente e potrebbero essere presenti errori non intuitivi. Quella che segue è una descrizione di una configurazione funzionante, ma sono stati necessari diversi tentativi per ottenerla correttamente e la configurazione potrebbe variare. + +## Installa Bitcoin Core nel tuo PC + +_Se hai intenzione di leggere semplicemente questa sezione e di non testare questi comandi fino a una data futura quando disponi di un ambiente di sviluppo locale, puoi saltare questa sottosezione, che riguarda la creazione di un'installazione Bitcoin Core su una macchina locale come un Mac o meglio una Macchina Linux._ + +Esistono versioni alternative dello script Bitcoin Standup che hai utilizzato per creare la tua VM che verrà installata su un MacOS o su una macchina Linux non Linode. + +Se disponi di MacOS, puoi installare [Bitcoin Standup MacOS](https://github.com/BlockchainCommons/Bitcoin-Standup-MacOS/blob/master/README.md). + +Se disponi di una macchina Linux locale, puoi installare [Bitcoin Standup Linux Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/README.md). + +Una volta che Bitcoin Standup è in esecuzione sul tuo computer locale, ti consigliamo di sincronizzare la blockchain `Testnet`, supponendo che tu continui a seguire la metodologia standard di questo corso. + +Utilizzeremo un Macintosh e Testnet per gli esempi in questa sezione. + +### Crea un alias per Bitcoin-CLI + +Crea un alias che esegua `bitcoin-cli` dalla directory corretta con eventuali flag appropriati. + +Ecco un esempio di alias da un Mac: +``` +$ alias bitcoin-cli="~/StandUp/BitcoinCore/bitcoin-0.20.0/bin/bitcoin-cli -testnet" +``` +Noterai che non solo ci fornisce il percorso completo, ma garantisce anche che rimaniamo su Testnet. + +## Installa HWI su un computer locale + +_Le seguenti istruzioni presuppongono nuovamente un Mac e puoi saltare questa sottosezione se stai solo leggendo questo capitolo._ + +HWI è un programma Bitcoin Core disponibile in Python che può essere utilizzato per interagire con i portafogli hardware. + +### Installa Python + +Poiché HWI è scritto in `python`, dovrai installarlo insieme ad alcuni programmi ausiliari. + +Se non disponi già degli strumenti da riga di comando "xcode", ti serviranno: +``` +$ xcode-select --install +``` + +Se non hai già il gestore pacchetti Homebrew, dovresti installare anche quello. Le istruzioni attuali sono disponibili sul [sito Homebrew](https://brew.sh/). Al momento della stesura di questo articolo, devi semplicemente farlo: +``` +$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" +``` + +Per la prima installazione, dovresti anche assicurarti che la tua directory `/usr/local/Frameworks` sia creata correttamente: +``` +$ sudo mkdir /usr/local/Frameworks +$ sudo chown $(whoami):admin /usr/local/Frameworks +``` + +Se hai tutto a posto, puoi finalmente installare Python: +``` +$ brew install python +$ brew install libusb +``` + +### Installa l'HWI + +Ora sei pronto per installare HWI, che richiede la clonazione di un repository GitHub e l'esecuzione di uno script di installazione. + +Se non hai `git` già installato sul tuo Mac, puoi farlo semplicemente provando a eseguirlo: `git --version`. + +È quindi possibile clonare il repository HWI: +``` +$ cd ~/StandUp +$ git clone https://github.com/bitcoin-core/HWI.git +``` +Successivamente, è necessario installare il pacchetto e le sue dipendenze: +``` +$ cd HWI +HWI$ python3 setup.py install +``` + +### Crea un alias per HWI + +Ti consigliamo di creare un alias anche qui, variato in base alla posizione di installazione effettiva: +``` +$ alias hwi="~/Standup/HWI/hwi.py --chain test" +``` +Ancora una volta, abbiamo incluso un riferimento a testnet in questo alias. + +## Prepara il tuo Ledger + +_Anche noi abbiamo dovuto scegliere una piattaforma hardware-wallet per questa dimostrazione HWI. La nostra scelta è ricaduta sul Ledger, che è stato a lungo il nostro banco di prova per i portafogli hardware. Consulta le [informazioni sul supporto del dispositivo HWI](https://github.com/bitcoin-core/HWI/blob/master/README.md#device-support) per un elenco di altri dispositivi supportati. Se utilizzi un dispositivo diverso da Ledger, dovrai valutare le tue soluzioni per prepararlo all'utilizzo su Testnet, ma per il resto dovresti essere in grado di continuare con il corso come scritto._ + +Se stai lavorando con Bitcoin sul tuo Ledger, probabilmente non dovrai fare nulla. (Ma non lo suggeriamo per l'uso con questo corso). + +Per lavorare con le monete Testnet, come suggerito da questo corso, dovrai apportare alcuni aggiornamenti: + +1. Vai su Impostazioni sulla tua app Ledger Live (è l'attrezzatura), vai alla scheda "Funzionalità sperimentali" e attiva "Modalità sviluppatore". +2. Vai su "Manager" e installa "Bitcoin Test". La versione attuale richiede che tu abbia prima installato "Bitcoin". +3. Vai su "Manager", scorri fino al tuo nuovo "Bitcoin Test" e "Aggiungi account" + +## Collegamento a un registro + +Affinché un Ledger sia accessibile, devi effettuare il login con il tuo PIN e poi richiamare l'app che desideri utilizzare, in questo caso l'app "Bitcoin Test". Potrebbe essere necessario ripeterlo di tanto in tanto se il tuo Ledger si addormenta. + +Dopo averlo fatto, puoi chiedere a HWI di accedere al Ledger con il comando "enumerate".: +``` +$ hwi enumerate +[{"type": "ledger", "model": "ledger_nano_s", "path": "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/XHC1@14000000/HS05@14100000/Nano S@14100000/Nano S@0/IOUSBHostHIDDevice@14100000,0", "fingerprint": "9a1d520b", "needs_pin_sent": false, "needs_passphrase_sent": false}] +``` +Se ricevi informazioni sul tuo dispositivo, sei a posto! Come puoi vedere, verifica il tuo tipo di portafoglio hardware, fornisce altre informazioni identificative e ti dice come comunicare con il dispositivo. L'impronta digitale (`9a1d520b`) è ciò a cui dovresti prestare particolare attenzione, perché tutte le interazioni con il tuo portafoglio hardware la richiederanno. + +Se invece hai ottenuto "[]", allora (1) non hai preparato il tuo dispositivo Ledger inserendo il PIN e scegliendo l'applicazione corretta, oppure (2) c'è qualcosa di sbagliato nella configurazione di Python, probabilmente una dipendenza mancante: dovresti considerare di disinstallarlo e provare da zero. + +## Importa indirizzi + +L'interazione con un portafoglio hardware di solito avviene in due parti: ricerca di fondi e spesa di fondi. + +Puoi controllare i fondi importando gli indirizzi dal tuo portafoglio hardware al tuo nodo completo, utilizzando HWI e `bitcoin-cli`. + +### Crea un portafoglio + +Per utilizzare il tuo portafoglio hardware con `bitcoin-cli`, ti consigliamo di creare un portafoglio con nome specifico in Bitcoin Core, utilizzando l'RPC `createwallet`, che è un comando di cui non abbiamo discusso in precedenza. +``` +$ bitcoin-cli --named createwallet wallet_name="ledger" disable_private_keys="true" descriptors="false" +{ + "name": "ledger", + "warning": "" +} +``` +In questo caso, stai creando un nuovo portafoglio `ledger` senza chiavi private (poiché queste saranno presenti sul dispositivo Ledger). + +> :book: ***Perché nominare i portafogli?*** Fino ad oggi, questo corso ha utilizzato il portafoglio predefinito (` "" `) in Bitcoin Core. Questo va bene per molti scopi, ma è inadeguato se hai una situazione più complessa, come quando guardi le chiavi da un portafoglio hardware. Qui, vogliamo essere in grado di distinguere dalle chiavi possedute localmente (che sono conservate nel portafoglio ` "" ` ) e dalle chiavi possedute in remoto (che sono conservate nel portafoglio "ledger"). + +Ora puoi vedere che il nuovo portafoglio è nell'elenco dei tuoi portafogli: +``` +$ bitcoin-cli listwallets +[ + "", + "ledger" +] +``` +Poiché hai creato un secondo portafoglio, alcuni comandi ora richiederanno un flag `-rpcwallet=`, per specificare quale stai utilizzando + +### Importa le chiavi + +Ora devi importare una watchlist di indirizzi dal portafoglio hardware. Questo viene fatto con il comando `getkeypool` di HWI: +``` +$ hwi -f 9a1d520b getkeypool 0 1000 +[{"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#qttxy592", "range": [0, 1000], "timestamp": "now", "internal": false, "keypool": true, "active": true, "watchonly": true}, {"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/1/*)#3lw8ep4j", "range": [0, 1000], "timestamp": "now", "internal": true, "keypool": true, "active": true, "watchonly": true}] +``` +Indirizziamo HWI con l'impronta digitale e chiediamo i primi 1000 indirizzi. Per impostazione predefinita viene utilizzato il tipo di indirizzo WPKH (nativo Segwit). In cambio riceviamo due descrittori per il key pool: uno per ricevere gli indirizzi e uno per cambiare gli indirizzi. + +> :book: ***Che cos'è un pool di chiavi?*** Un pool di chiavi è un gruppo di chiavi pregenerate. I moderni portafogli HD creano pool di chiavi continuando a determinare nuovi indirizzi gerarchici basati sul seed originale. L’idea dei pool di chiavi è stata originariamente implementata per facilitare i requisiti di backup dei portafogli. Ciò ha consentito a un utente di generare un pool di chiavi e quindi eseguire immediatamente il backup del portafoglio, anziché richiedere backup dopo la creazione di ogni nuovo indirizzo. Il concetto si è rivelato molto utile anche ai giorni nostri poiché consente di importare un intero set di indirizzi futuri da un dispositivo all'altro. + +I valori restituiti da `getkeypool` sono lo stesso tipo di descrittori di cui abbiamo appreso nel [Capitolo3.5: Comprendere il descrittore](03_5_Comprendere_il_Descriptor.md). All'epoca dicevamo che erano utilissimi per spostare indirizzi tra macchine diverse. Ecco l'esempio della vita reale: spostare gli indirizzi da un portafoglio hardware al nodo Bitcoin Core, in modo che la nostra macchina connessa alla rete sia in grado di sorvegliare le chiavi possedute dal portafoglio hardware offline. + +Proprio come hai imparato nel [Capitolo 3.5](03_5_Comprendere_il_Descriptor.md), puoi esaminare questi descrittori con l'RPC `getdescriptorinfo`: +``` +$ bitcoin-cli getdescriptorinfo "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#qttxy592" +{ + "descriptor": "wpkh([9a1d520b/84'/1'/0']tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#n65e7wjf", + "checksum": "qttxy592", + "isrange": true, + "issolvable": true, + "hasprivatekeys": false +} +``` +Come ci si aspetterebbe, _non_ hai le "chiavi private", perché i portafogli hardware le conservano. + +Con il descrittore in mano, puoi importare le chiavi nel tuo nuovo portafoglio `ledger` utilizzando l'RPC `importmulti` che hai incontrato anche nel [Capitolo 3.5](03_5_Comprendere_il_Descriptor.md). In questo caso, inserisci semplicemente l'intera risposta ricevuta da HWI in `'`. +``` +$ bitcoin-cli -rpcwallet=ledger importmulti '[{"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/0/*)#qttxy592", "range": [0, 1000], "timestamp": "now", "internal": false, "keypool": true, "active": true, "watchonly": true}, {"desc": "wpkh([9a1d520b/84h/1h/0h]tpubDD7KTtoGzK9GuWUQcr1uTJazsAkqoXhdrwGXWVix6nPpNZmSbagZWD4QSaMsyK8YohAirGDPrWdRiEpKzTFB7DrTrqfzHCn7yi5EsqeR93S/1/*)#3lw8ep4j", "range": [0, 1000], "timestamp": "now", "internal": true, "keypool": true, "active": true, "watchonly": true}]' +[ + { + "success": true + }, + { + "success": true + } +] +``` +(Si noti che HWI restituisce utilmente il percorso di derivazione con `h` per mostrare le derivazioni rafforzate anziché `'` e calcola il suo checksum di conseguenza, in modo da non dover fare citazioni massicce come abbiamo fatto nel Capitolo 3.5.) + +Ora _potresti_ elencare tutti gli indirizzi di watch-okly che hai ricevuto utilizzando il comando `getaddressesbylabel`. Tutti i 1000 indirizzi di ricezione sono proprio lì, nel portafoglio `ledger`! + +``` +$ bitcoin-cli -rpcwallet=ledger getaddressesbylabel "" | more +{ + "tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y": { + "purpose": "receive" + }, + "tb1qqzvrm6hujdt93qctuuev5qc4499tq9fdk0prwf": { + "purpose": "receive" + }, +... +} +``` +## Ricevi una transazione + +Ovviamente, ricevere una transazione è semplice. Utilizzi "getnewaddress" per richiedere uno di quegli indirizzi importati: +``` +$ bitcoin-cli -rpcwallet=ledger getnewaddress +tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y +``` +Quindi gli invii denaro. + +Il potere di HWI è che puoi guardare i pagamenti dal tuo nodo Bitcoin Core, invece di dover collegare il tuo portafoglio hardware e interrogarlo. +``` +$ bitcoin-cli -rpcwallet=ledger listunspent +[ + { + "txid": "c733533eb1c052242f9ed89cd8927aedb41852156e684634ee7c74028774e595", + "vout": 1, + "address": "tb1q948388a23pfsf52kz6skd5k4z4627jja2evztr", + "label": "", + "scriptPubKey": "00142d4f139faa885304d15616a166d2d51574af4a5d", + "amount": 0.01000000, + "confirmations": 12, + "spendable": false, + "solvable": true, + "desc": "wpkh([9a1d520b/84'/1'/0'/0/0]02a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab)#9za8hlvk", + "safe": true + }, + { + "txid": "5b3c4aeb811f9a119fd633b12a6927415cc61b8654628df58e9141cab804bab8", + "vout": 0, + "address": "tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y", + "label": "", + "scriptPubKey": "001400193c8bf25ef056f8d4571a1c3f65123e5fe788", + "amount": 0.01000000, + "confirmations": 1, + "spendable": false, + "solvable": true, + "desc": "wpkh([9a1d520b/84'/1'/0'/0/569]030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec5)#sx9haake", + "safe": true + } +] +``` +## Crea una transazione con PSBT + +Controllare e ricevere pagamenti è solo metà dell'opera. Potresti anche voler effettuare pagamenti utilizzando gli account detenuti dal tuo portafoglio hardware. Questo è il quarto esempio di vita reale per l'utilizzo di PSBT, secondo il processo delineato in [Capitolo 7.1: Creare una transazione Bitcoin parzialmente firmata](07_1_Creare_una_Transazione_Bitcoin_Parzialmente_Firmata.md). + +I comandi funzionano esattamente allo stesso modo. In questo caso, usa `walletcreatefundedpsbt` per formare il tuo PSBT perché questa è una situazione in cui non ti interessa quali UTXO vengono utilizzati: +``` +$ bitcoin-cli -named -rpcwallet=ledger walletcreatefundedpsbt inputs='''[]''' outputs='''[{"tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd":0.015}]''' +{ + "psbt": "cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giBgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxRiaHVILVAAAgAEAAIAAAACAAAAAADkCAAAAAQEfQEIPAAAAAAAWABQtTxOfqohTBNFWFqFm0tUVdK9KXSIGAqATz5xLX1aJ2SUwNqPkd8+YaJYm94FMlPCScm8Rt0GrGJodUgtUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgID2UK1nupSfXC81nmB65XZ+pYlJp/W6wNk5FLt5ZCSx6kYmh1SC1QAAIABAACAAAAAgAEAAAABAAAAAA==", + "fee": 0.00000209, + "changepos": 1 +} +``` + +Puoi dare un'occhiata al PSBT e verificare che sembri razionale: + +``` +$ psbt="cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giBgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxRiaHVILVAAAgAEAAIAAAACAAAAAADkCAAAAAQEfQEIPAAAAAAAWABQtTxOfqohTBNFWFqFm0tUVdK9KXSIGAqATz5xLX1aJ2SUwNqPkd8+YaJYm94FMlPCScm8Rt0GrGJodUgtUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgID2UK1nupSfXC81nmB65XZ+pYlJp/W6wNk5FLt5ZCSx6kYmh1SC1QAAIABAACAAAAAgAEAAAABAAAAAA==" + +$ bitcoin-cli decodepsbt $psbt +{ + "tx": { + "txid": "45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d", + "hash": "45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d", + "version": 2, + "size": 154, + "vsize": 154, + "weight": 616, + "locktime": 0, + "vin": [ + { + "txid": "5b3c4aeb811f9a119fd633b12a6927415cc61b8654628df58e9141cab804bab8", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + }, + { + "txid": "c733533eb1c052242f9ed89cd8927aedb41852156e684634ee7c74028774e595", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01500000, + "n": 0, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + }, + { + "value": 0.00499791, + "n": 1, + "scriptPubKey": { + "asm": "0 f4e8dde5db370898b57c84566e3f76098850817d", + "hex": "0014f4e8dde5db370898b57c84566e3f76098850817d", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q7n5dmewmxuyf3dtus3txu0mkpxy9pqtacuprak" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 00193c8bf25ef056f8d4571a1c3f65123e5fe788", + "hex": "001400193c8bf25ef056f8d4571a1c3f65123e5fe788", + "type": "witness_v0_keyhash", + "address": "tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y" + } + }, + "bip32_derivs": [ + { + "pubkey": "030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec5", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/0/569" + } + ] + }, + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 2d4f139faa885304d15616a166d2d51574af4a5d", + "hex": "00142d4f139faa885304d15616a166d2d51574af4a5d", + "type": "witness_v0_keyhash", + "address": "tb1q948388a23pfsf52kz6skd5k4z4627jja2evztr" + } + }, + "bip32_derivs": [ + { + "pubkey": "02a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/0/0" + } + ] + } + ], + "outputs": [ + { + }, + { + "bip32_derivs": [ + { + "pubkey": "03d942b59eea527d70bcd67981eb95d9fa9625269fd6eb0364e452ede59092c7a9", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/1/1" + } + ] + } + ], + "fee": 0.00000209 +} +``` +E come al solito, `analyzepsbt` mostrerà quanto lontano sei arrivato: +``` +$ bitcoin-cli analyzepsbt $psbt +{ + "inputs": [ + { + "has_utxo": true, + "is_final": false, + "next": "signer", + "missing": { + "signatures": [ + "00193c8bf25ef056f8d4571a1c3f65123e5fe788" + ] + } + }, + { + "has_utxo": true, + "is_final": false, + "next": "signer", + "missing": { + "signatures": [ + "2d4f139faa885304d15616a166d2d51574af4a5d" + ] + } + } + ], + "estimated_vsize": 208, + "estimated_feerate": 0.00001004, + "fee": 0.00000209, + "next": "signer" +} +``` +Poiché hai importato quel pool di chiavi, `bitcoin-cli` ha tutte le informazioni necessarie per compilare gli input, semplicemente non può firmare perché le chiavi private sono conservate nel portafoglio hardware. + +È qui che entra in gioco HWI, con il comando `signtx`. Basta inviare lungo il PSBT: +``` +$ hwi -f 9a1d520b signtx $psbt +``` +Aspettatevi di dover armeggiare con il vostro portafoglio hardware a questo punto. Probabilmente il dispositivo ti chiederà di confermare gli ingressi, le uscite e la tariffa. Al termine, dovrebbe restituire un nuovo PSBT. + +``` +{"psbt": "cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giAgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxUcwRAIgAxkQlk2fqEMxvP54WWyiFhlfSul9sd4GzKDhfGpmlewCIHYej3zXWWMgWI6rixxQw9yzGozDaFPqQNNIvcFPk+lfASIGAwFo2UguKwLXAn+0qJ7cVK2qGt9wkzT2R9ChsFM4KK7FGJodUgtUAACAAQAAgAAAAIAAAAAAOQIAAAABAR9AQg8AAAAAABYAFC1PE5+qiFME0VYWoWbS1RV0r0pdIgICoBPPnEtfVonZJTA2o+R3z5holib3gUyU8JJybxG3QatHMEQCIH5t6T2yufUP7glYZ8YH0/PhDFpotSmjgZUhvj6GbCFIAiBcgXzyYl7IjYuaF3pJ7AgW1rLYkjeCJJ2M9pVUrq5vFwEiBgKgE8+cS19WidklMDaj5HfPmGiWJveBTJTwknJvEbdBqxiaHVILVAAAgAEAAIAAAACAAAAAAAAAAAAAACICA9lCtZ7qUn1wvNZ5geuV2fqWJSaf1usDZORS7eWQksepGJodUgtUAACAAQAAgAAAAIABAAAAAQAAAAA="} +$ psbt_f="cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giAgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxUcwRAIgAxkQlk2fqEMxvP54WWyiFhlfSul9sd4GzKDhfGpmlewCIHYej3zXWWMgWI6rixxQw9yzGozDaFPqQNNIvcFPk+lfASIGAwFo2UguKwLXAn+0qJ7cVK2qGt9wkzT2R9ChsFM4KK7FGJodUgtUAACAAQAAgAAAAIAAAAAAOQIAAAABAR9AQg8AAAAAABYAFC1PE5+qiFME0VYWoWbS1RV0r0pdIgICoBPPnEtfVonZJTA2o+R3z5holib3gUyU8JJybxG3QatHMEQCIH5t6T2yufUP7glYZ8YH0/PhDFpotSmjgZUhvj6GbCFIAiBcgXzyYl7IjYuaF3pJ7AgW1rLYkjeCJJ2M9pVUrq5vFwEiBgKgE8+cS19WidklMDaj5HfPmGiWJveBTJTwknJvEbdBqxiaHVILVAAAgAEAAIAAAACAAAAAAAAAAAAAACICA9lCtZ7qUn1wvNZ5geuV2fqWJSaf1usDZORS7eWQksepGJodUgtUAACAAQAAgAAAAIABAAAAAQAAAAA=" +``` + +Quando lo analizzi, vedrai che è pronto per essere finalizzato: + +``` +$ bitcoin-cli analyzepsbt $psbt_f +{ + "inputs": [ + { + "has_utxo": true, + "is_final": false, + "next": "finalizer" + }, + { + "has_utxo": true, + "is_final": false, + "next": "finalizer" + } + ], + "estimated_vsize": 208, + "estimated_feerate": 0.00001004, + "fee": 0.00000209, + "next": "finalizer" +} +``` + +A questo punto sei di nuovo nel territorio standard: +``` +$ bitcoin-cli finalizepsbt $psbt_f +{ + "hex": "02000000000102b8ba04b8ca41918ef58d6254861bc65c4127692ab133d69f119a1f81eb4a3c5b0000000000feffffff95e5748702747cee3446686e155218b4ed7a92d89cd89e2f2452c0b13e5333c70100000000feffffff0260e3160000000000160014c772d6f95542e11ef11e8efc7c7a69830ad38a054fa0070000000000160014f4e8dde5db370898b57c84566e3f76098850817d024730440220031910964d9fa84331bcfe78596ca216195f4ae97db1de06cca0e17c6a6695ec0220761e8f7cd7596320588eab8b1c50c3dcb31a8cc36853ea40d348bdc14f93e95f0121030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec50247304402207e6de93db2b9f50fee095867c607d3f3e10c5a68b529a3819521be3e866c214802205c817cf2625ec88d8b9a177a49ec0816d6b2d8923782249d8cf69554aeae6f17012102a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab00000000", + "complete": true +} +$ hex=02000000000102b8ba04b8ca41918ef58d6254861bc65c4127692ab133d69f119a1f81eb4a3c5b0000000000feffffff95e5748702747cee3446686e155218b4ed7a92d89cd89e2f2452c0b13e5333c70100000000feffffff0260e3160000000000160014c772d6f95542e11ef11e8efc7c7a69830ad38a054fa0070000000000160014f4e8dde5db370898b57c84566e3f76098850817d024730440220031910964d9fa84331bcfe78596ca216195f4ae97db1de06cca0e17c6a6695ec0220761e8f7cd7596320588eab8b1c50c3dcb31a8cc36853ea40d348bdc14f93e95f0121030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec50247304402207e6de93db2b9f50fee095867c607d3f3e10c5a68b529a3819521be3e866c214802205c817cf2625ec88d8b9a177a49ec0816d6b2d8923782249d8cf69554aeae6f17012102a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab00000000 +$ bitcoin-cli sendrawtransaction $hex +45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d +``` +Hai inviato fondi con successo utilizzando le chiavi private conservate nel tuo portafoglio hardware! + +## Scopri altri comandi HWI + +Sono disponibili numerosi altri comandi da utilizzare con HWI. Al momento in cui scrivo, ci sono: +``` +numerate,getmasterxpub,signtx,getxpub,signmessage,getkeypool,getdescriptors,displayaddress,setup,wipe,restore,backup,promptpin,togglepassphrase,sendpin +``` + +## Riepilogo: Integrazione con hardware wallet + +I hardware wallet possono offrire una migliore protezione mantenendo le tue chiavi private offline, protette nell'hardware. Fortunatamente, c'è ancora un modo per interagire con loro utilizzando "bitcoin-cli". Basta installare HWI e ti consentirà quindi di (1) importare chiavi pubbliche e guardarle; e (2) firmare le transazioni utilizzando il tuo hardware wallet. + +> :fire: ***Qual è il potere di HWI?*** HWI ti consente di interagire con i portafogli hardware utilizzando tutti i comandi di `bitcoin-cli` che hai imparato fino ad oggi. Puoi effettuare transazioni grezze di qualsiasi tipo, quindi inviare PSBT ai portafogli hardware per la firma. Pertanto, hai tutta la potenza di Bitcoin Core, ma hai anche la sicurezza di un dispositivo hardware. + +## Qual è il prossimoargomento? + +Espandi maggiormente le transazioni Bitcoin con il [Capitolo 8: Ampliare Altre Transazioni Bitcoin](08_0_Ampliare_Altre_Transazioni_Bitcoin.md). diff --git a/it/08_0_Ampliare_Altre_Transazioni_Bitcoin.md b/it/08_0_Ampliare_Altre_Transazioni_Bitcoin.md new file mode 100644 index 000000000..32b24347a --- /dev/null +++ b/it/08_0_Ampliare_Altre_Transazioni_Bitcoin.md @@ -0,0 +1,21 @@ +# Capitolo otto: Ampliare le transazioni Bitcoin in altri modi + +La definizione di transazioni di base nel [Capitolo 6](06_0_Ampliare_le_Transazioni_Bitcoin_con_Multifirme.md) affermava che venivano inviati _"fondi"_ _"immediatamente"_, ma questi sono due elementi che possono essere modificati. Questa sezione finale sull'espansione delle transazioni Bitcoin parla di come inviare cose diverse dal contanti e come farlo in un momento diverso da quello attuale. + +## Obiettivi di questa sezione + +Dopo aver letto questo capitolo, uno sviluppatore sarà in grado di: + + * Creare transazioni con Locktimes + * Creare transazioni con Dati + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere i diversi tipi di Timelocks, blocchi temporali + * Pianificare la potenza di Locktime + * Pianificare la potenza di OP_RETURN + +## Sommario + + * [Capitolo 8.1: Inviare una Transazione con Blocco temporale](08_1_Inviare_una_Transazione_con_Blocco_temporale.md) + * [Capitolo 8.2: Inviare una Transazione con Dati](08_2_Inviare_una_Transazione_con_Dati.md) diff --git a/it/08_1_Inviare_una_Transazione_con_Blocco_temporale.md b/it/08_1_Inviare_una_Transazione_con_Blocco_temporale.md new file mode 100644 index 000000000..61a12303e --- /dev/null +++ b/it/08_1_Inviare_una_Transazione_con_Blocco_temporale.md @@ -0,0 +1,135 @@ +# 8.1: Invio di una transazione con un Locktime + +I capitoli precedenti hanno mostrato due modi diversi per inviare fondi da più macchine e a più destinatari. Ma ci sono altri due modi per modificare radicalmente le transazioni di base. Il primo di questi è variare il tempo scegliendo un tempo di attessa, _locktime_. Ciò ti dà la possibilità di inviare transazioni grezze in un momento futuro. + +## Comprendere come funziona Locktime + +Quando crei una transazione locktime, la fermi con un numero che rappresenta l'altezza del blocco ( (se è un numero piccolo) o un timestamp UNIX (se è un numero grande). Questo dice alla rete Bitcoin che la transazione non può essere inserita in un blocco finché non è arrivato il momento specificato o finché la blockchain non ha raggiunto l'altezza specificata. + +> :book: **_Che cos'è l'altezza del blocco?_** `block height` è il conteggio totale dei blocchi nella catena, risalendo al blocco numero 1 cioè il blocco genesi di Bitcoin. + +Quando una transazione locktime è in attesa di entrare in un blocco, può essere annullata. Ciò significa che è tutt’altro che finalizzato. In effetti, lo scopo principale di una transazione locktime è avere la possibilità di annullarla. + +> :book: **_Cos'è nLockTime?_** È la stessa cosa di locktime. Più specificamente, è ciò che viene chiamato locktime interno al codice sorgente di Bitcoin Core. + +> :book: **_Che cos'è Timelock?_** Locktime è solo un modo per trattenere le transazioni Bitcoin fino a un certo punto nel futuro; collettivamente questi metodi sono chiamati timelock. Locktime è il metodo di blocco temporale più semplice. Blocca un'intera transazione con un tempo assoluto ed è disponibile tramite `bitcoin-cli` (motivo per cui è l'unico blocco temporale trattato in questa sezione). Un metodo parallelo, che blocca una transazione con un tempo relativo, è definito nel [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) e trattato nel [Capitolo 11.3: Utilizzo di CSV negli script](11_3_Using_CSV_in_Scripts.md). + +> Bitcoin Script potenzia ulteriormente entrambi i tipi di blocchi temporali, consentendo il blocco di singoli output anziché di intere transazioni. I timelock assoluti (come Locktime) sono collegati al codice operativo dello script OP_CHECKLOCKTIMEVERIFY, che è definito in [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) e trattato in [ §11.2: Using CLTV in Scripts](11_2_Usare_CLTV_negli_Scripts.md), mentre i timelock relativi (come Timelock) sono collegati al codice operativo dello script `OP_CHECKSEQUENCEVERIFY`, che è definito nel [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) e trattato anche nel [Capitolo11.3](11_3_Usare_CSV_negli_Scripts.md). + +## Creare una transazione Locktime + +Per creare una transazione `locktime`, devi prima determinare su cosa imposterai il locktime. + +### Scopri il tuo orario di blocco tramite timestamp UNIX + +Molto spesso imposterai il locktime su un timestamp UNIX che rappresenta una data e un'ora specifiche. È possibile calcolare un timestamp UNIX in un sito Web come [UNIX Time Stamp](http://www.unixtimestamp.com/) o [Epoch Converter](https://www.epochconverter.com/). Tuttavia, sarebbe meglio [scrivere il proprio script](https://www.epochconverter.com/#code) sul computer locale, in modo da sapere che il timestamp UNIX ricevuto è accurato. Se non lo fai, almeno ricontrolla su due siti diversi. + +> :book: **_Perché dovrei utilizzare un timestamp UNIX?_** L'uso di un timestamp UNIX rende semplice collegare definitivamente una transazione a un'ora specifica, senza preoccuparsi se la velocità di creazione del blocco potrebbe cambiare ad un certo punto. Soprattutto se stai creando un locktime lontano nel futuro, è la cosa più sicura da fare. Ma, oltre a ciò, è semplicemente più intuitivo, poiché crea una correlazione diretta tra una data di calendario e l'ora in cui la transazione può essere estratta. + +> :warning: **ATTENZIONE:** Il locktime con i timestamp UNIX ha un po' di margine di manovra: il rilascio dei blocchi non è regolare e gli orari dei blocchi possono essere due ore avanti rispetto al tempo reale, quindi un locktime in realtà significa "entro pochi ore di questo tempo, più o meno". + +### Determina il tempo di chiusura in base all'altezza del blocco + +In alternativa, puoi impostare il tempo di blocco su un numero più piccolo che rappresenta l'altezza del blocco. Per calcolare l'altezza futura del blocco, devi prima sapere qual è l'altezza attuale del blocco. `bitcoin-cli getblockcount` ti dirà quale è l'altezza del blocco secondo la tua macchina locale. Potresti voler ricontrollare con un esploratore Bitcoin. + +Una volta determinata l'altezza attuale, puoi decidere fino a che punto nel futuro impostare il tempo di blocco. Ricorda che in media verrà creato un nuovo blocco ogni 10 minuti. Quindi, ad esempio, se volessi impostare il tempo di blocco su una settimana nel futuro, sceglieresti un'altezza del blocco pari a 6 x 24 x 7 = 1.008 blocchi dopo rispetto a quella attuale. + +> :book: **_Perché dovrei usare un Blockheight?_** A differenza dei timestamp, non c'è confusione per i blockheight. Se imposti un'altezza del blocco di 120.000 per il tuo locktime, non c'è assolutamente alcun modo per farlo entrare nel blocco 119.999. Ciò può rendere più semplice il controllo algoritmico della transazione bloccata. Lo svantaggio è che non puoi essere sicuro di quando sarà esattamente l'ora di blocco. + +> :warning: **AVVISO:** Se vuoi impostare un block-height locktime, devi impostare il tempo di blocco su un valore inferiore a 500 milioni. Se lo imposti su 500 milioni o più, il tuo numero verrà invece interpretato come un timestamp. Poiché il timestamp UNIX di 500 milioni era il 5 novembre 1985, ciò probabilmente significa che la tua transazione verrà bloccata alla prima occasione dei minatori. + +## Scrivere la transazione + +Una volta stabilito il tempo di blocco, tutto ciò che devi fare è scrivere una tipica transazione grezza, con una terza variabile per `locktime`: +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.001, "'$changeaddress'": 0.00095 }''' locktime=1774650) +``` +Tieni presente che questo utilizzo di `locktime` è inferiore a 500 milioni, il che significa che definisce l'altezza del blocco. In questo caso, sono solo pochi blocchi oltre l'altezza del blocco attuale al momento della stesura di questo articolo, pensato per esemplificare come funziona il locktime senza stare a lungo ad aspettare e vedere cosa succede. + +Ecco come appare la transazione creata: +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex +{ + "txid": "ba440b1dd87a7ccb6a200f087d2265992588284eed0ae455d0672aeb918cf71e", + "hash": "ba440b1dd87a7ccb6a200f087d2265992588284eed0ae455d0672aeb918cf71e", + "version": 2, + "size": 113, + "vsize": 113, + "weight": 452, + "locktime": 1774650, + "vin": [ + { + "txid": "0ad9fb6992dfe4ea90236b69852b3605c0175633b32996a486dcd0b2e739e385", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00100000, + "n": 0, + "scriptPubKey": { + "asm": "0 f333554cc0830d03a9c1f26758e2e7e0f155539f", + "hex": "0014f333554cc0830d03a9c1f26758e2e7e0f155539f", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q7ve42nxqsvxs82wp7fn43ch8urc425ul5um4un" + ] + } + }, + { + "value": 0.00095000, + "n": 1, + "scriptPubKey": { + "asm": "0 a37718a3510958112b6a766e0023ff251b6c2bfb", + "hex": "0014a37718a3510958112b6a766e0023ff251b6c2bfb", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q5dm33g63p9vpz2m2wehqqglly5dkc2lmtmr98d" + ] + } + } + ] +} +``` +Tieni presente che il numero di sequenza (`4294967294`) è inferiore a `0xffffffff`. Questa è una segnalazione necessaria per mostrare che la transazione include un locktime. Viene eseguito anche automaticamente da `bitcoin-cli`. Se il numero di sequenza è invece impostato su `"0xffffffff`, il tempo di blocco verrà ignorato. + +> :information_source: **NOTA — SEQUENCE:** Questo è il secondo utilizzo del valore `nSequence` in Bitcoin. Come con RBF, `nSequence` viene nuovamente utilizzato come opt-in, questa volta per l'utilizzo di locktime. 0xffffffff-1 (4294967294) è il valore preferito per segnalare locktime perché non consente intenzionalmente l'uso sia di RBF (che richiede `nSequence < 0xffffffff-1`) che di timelock relativo (che richiede `nSequence < 0xf0000000`), gli altri due usano del valore "nSequence". Se imposti "nSequence" su un valore inferiore a "0xf0000000", bloccherai anche la transazione, il che probabilmente non è quello che desideri. + +> :warning: **AVVISO:** Se stai creando una transazione grezza locktime con un mezzo diverso da `bitcoin-cli`, dovrai impostare manualmente la sequenza su un valore inferiore a `0xffffffff`. + +## Invia la tua transazione + +Ormai probabilmente hai già familiarità con il completamento finale delle transazioni: +``` +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +error code: -26 +error message: +non-final +``` +Oops! Cos'è quell'errore!? + +Dal 2013, generalmente non è possibile inserire la transazione bloccata nel mempool finché il suo blocco non è scaduto. Tuttavia, puoi comunque trattenere la transazione, inviandola occasionalmente alla rete Bitcoin finché non viene accettata nel mempool. In alternativa, potresti inviare la transazione firmata (`$signedtx`) al destinatario, in modo che possa inserirla nel mempool una volta scaduto il locktime. + +Una volta trascorso il tempo di blocco, chiunque può inviare la transazione firmata alla rete e il destinatario riceverà il denaro come previsto... a condizione che la transazione non sia stata annullata. + +## Annullare una transazione Locktime + +Annullare una transazione locktime è _molto_ semplice: invii una nuova transazione utilizzando almeno uno degli stessi UTXO. + +## Riepilogo: invio di una transazione con un locktime + +Locktime offre un modo per creare una transazione che _dovrebbe_ non essere inoltrabile alla rete e che _non_ sarà_ accettata in un blocco finché non sarà arrivato il momento appropriato. Nel frattempo è possibile annullarlo semplicemente riutilizzando un UTXO. + +> :fire: **_Qual è il potere di Locktime?_** Il potere di Locktime potrebbe non essere immediatamente evidente a causa della possibilità di annullarlo così facilmente. Tuttavia, è un'altra delle basi degli Smart Contracts: ha molta utilità in una varietà di applicazioni custodiali o contrattuali. Ad esempio, considera una situazione in cui una terza parte detiene i tuoi bitcoin. Per garantire la restituzione dei tuoi bitcoin nel caso in cui il custode scomparisse, potrebbe produrre una transazione con blocco temporale per restituirti le monete, quindi aggiornarla di tanto in tanto con una nuova, più avanti in futuro. Se mai non riuscissero ad aggiornarsi, le monete ti verranno restituite allo scadere del blocco temporale corrente. Allo stesso modo Locktime potrebbe essere applicato a una rete di pagamento, in cui la rete trattiene monete mentre vengono scambiate dai partecipanti alla rete. Infine, un testamento offre un esempio di contratto più complesso, in cui i pagamenti vengono inviati a un numero di persone. Questi pagamenti verrebbero basati su transazioni bloccate e verrebbero continuamente aggiornati finché il proprietario continua a mostrare segni di vita. (Il fattore unificante di tutte queste applicazioni è, ovviamente, la _fiducia_. Le semplici transazioni locktime funzionano solo se ci si può fidare del detentore delle monete per inviarle alle condizioni appropriate.) + +## Qual è il prossimo argomento? + +Continua con "Espansione delle transazioni Bitcoin" nel [Capitolo 8.2: Inviare una Transazione con Dati](08_2_Inviare_una_Transazione_con_Dati.md). diff --git a/it/08_2_Inviare_una_Transazione_con_Dati.md b/it/08_2_Inviare_una_Transazione_con_Dati.md new file mode 100644 index 000000000..a65e9ffe1 --- /dev/null +++ b/it/08_2_Inviare_una_Transazione_con_Dati.md @@ -0,0 +1,123 @@ +# 8.2: Inviare una transazione con dati + +L'ultimo modo per variare la modalità di invio di una transazione di base è utilizzare la transazione per inviare dati anziché fondi (o, in realtà, in aggiunta di fondi). Questo ti dà la possibilità di incorporare informazioni nella blockchain. Viene eseguito tramite uno speciale comando `OP_RETURN`. + +Il limite? Puoi memorizzare solo 80 byte alla volta! + +## Crea i tuoi dati + +La prima cosa che devi fare è creare gli 80 byte (o meno) di dati che registrerai nel tuo `OP_RETURN`. Potrebbe essere semplice come preparare un messaggio oppure potresti eseguire l'hashing dei dati esistenti. Ad esempio, "sha256sum" produce 256 bit di dati, ovvero 32 byte, ben al di sotto dei limiti: +``` +$ sha256sum contratto.jpg +b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75 contratto.jpg +$ op_return_data="b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75" +``` +> :book: _Che cos'è un OP_RETURN?_ Tutte le transazioni Bitcoin sono basate su script opcode che incontreremo nel prossimo capitolo. `OP_RETURN` è un semplice codice operativo che definisce un OUTPUT come non valido. La convenzione ha portato al suo utilizzo per incorporare dati nella blockchain. + +## Prepara dei soldi + +Il tuo scopo nel creare una transazione di dati non è inviare denaro a nessuno, ma inserire i dati nella blockchain. Tuttavia, devi_ inviare denaro per farlo. Devi solo utilizzare un indirizzo di resto come _unico_ destinatario. Quindi puoi identificare un UTXO e inviarlo al tuo indirizzo di modifica, meno una commissione di transazione, utilizzando anche la stessa transazione per creare un OP_RETURN. + +Ecco la configurazione standard: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "vout": 0, + "address": "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh", + "scriptPubKey": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "amount": 0.01463400, + "confirmations": 1392, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/12']02883bb5463e37d55252d8b3d5c2141b007b37c8a7db6211f75c955acc5ea325eb)#cjr03mru", + "safe": true + } +] + +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ changeaddress=$(bitcoin-cli getrawchangeaddress) +``` + +## Scrivi una transazione grezza + +Ora puoi scrivere una nuova transazione grezza con due output: uno è il tuo indirizzo di resto per recuperare (la maggior parte) dei tuoi soldi, l'altro è un idata address, che è il termine `bitcoin-cli` per un OP_RETURN. +``` +rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "data": "'$op_return_data'", "'$changeaddress'": 0.0146 }''') +``` + + +Ecco come appare effettivamente la transazione: +``` +{ + "txid": "a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8", + "hash": "a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8", + "version": 2, + "size": 125, + "vsize": 125, + "weight": 500, + "locktime": 0, + "vin": [ + { + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00000000, + "n": 0, + "scriptPubKey": { + "asm": "OP_RETURN b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75", + "hex": "6a20b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75", + "type": "nulldata" + } + }, + { + "value": 0.01460000, + "n": 1, + "scriptPubKey": { + "asm": "0 998a9b0ed076bbdec1d88da4f475b9dde75e3620", + "hex": "0014998a9b0ed076bbdec1d88da4f475b9dde75e3620", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qnx9fkrksw6aaaswc3kj0gademhn4ud3q7cz4fm" + ] + } + } + ] +} + +``` +Come puoi vedere, questo rimanda la maggior parte del denaro direttamente all'indirizzo modificato (`tb1qnx9fkrksw6aaaswc3kj0gademhn4ud3q7cz4fm`) meno una piccola commissione di transazione. Ancora più importante, il primo output mostra un OP_RETURN con i dati (`b9f81a8919e5aba39aeb86145c684010e6e559b580a85003ae25d78237a12e75`) subito dopo. + +## Invia la transazione grezza + +Firma la tua transazione grezza e inviala, e presto OP_RETURN sarà incorporato nella blockchain! + +## Controlla il tuo OP_RETURN + +Ancora una volta, ricorda che puoi guardare questa transazione usando un blockchain explorer: +[https://live.blockcypher.com/btc-testnet/tx/a600148ac3b05f0c774b8687a71c545077ea5dfb9677e5c6d708215053d892e8/](https://live.blockcypher.com/btc-testnet/tx/a600148ac3b05f0c7 74b8687a71c545077ea5dfb9677e5c6d708215053d892e8/) + +Potresti notare un avviso relativo ai dati che si trovano in un "protocollo sconosciuto". Se stessi progettando un uso regolare dei dati `OP_RETURN`, probabilmente lo contrassegneresti con un prefisso speciale, per contrassegnare quel protocollo. Quindi, i dati OP_RETURN effettivi potrebbero essere qualcosa come "CONTRACTS3b110a164aa18d3a5ab064ba93fdce62". In questo esempio non è stato utilizzato un prefisso per evitare di confondere lo spazio dati. + +## Riepilogo: invio di una transazione con dati + +Puoi utilizzare un codice operativo `OP_RETURN` per archiviare fino a 80 byte di dati sulla blockchain. Puoi farlo con la parola in codice `data` per un `vout`. Devi comunque inviare anche del denaro, ma devi semplicemente rispedirlo a un indirizzo diverso, meno una commissione di transazione. + +> :fire: _Qual è il potere di OP_RETURN?_ OP_RETURN apre possibilità completamente nuove per la blockchain, perché puoi incorporare dati che dimostrano che determinate cose sono accadute in determinati momenti. Varie organizzazioni hanno utilizzato OP_RETURN per provare l'esistenza, per il copyright, per monete colorate e [per altri scopi](https://en.bitcoin.it/wiki/OP_RETURN). Anche se 80 byte potrebbero non sembrare molti, possono essere abbastanza efficaci se si utilizzano OP_RETURN per archiviare gli hash dei dati effettivi. Quindi, puoi dimostrare l'esistenza dei tuoi dati digitali dimostrando che il loro hash corrisponde all'hash sulla blockchain. + +Tieni presente che c'è qualche controversia sull'utilizzo della blockchain Bitcoin in questo modo. + +## Qual è il prossimo argomento? + +Passa a "Bitcoin Scripting" nel [Capitolo 9: Introduzione script di Bitcoin](09_0_Introduzione_script_di_Bitcoin.md). diff --git a/it/09_0_Introduzione_script_di_Bitcoin.md b/it/09_0_Introduzione_script_di_Bitcoin.md new file mode 100644 index 000000000..8467ac2e6 --- /dev/null +++ b/it/09_0_Introduzione_script_di_Bitcoin.md @@ -0,0 +1,27 @@ +# Capitolo 9: Introduzione agli script Bitcoin + +Finora, abbiamo interagito con Bitcoin a un livello di astrazione relativamente elevato. Il programma `bitcoin-cli` offre accesso a una varietà di comandi RPC che supportano la creazione e il controllo di transazioni Bitcoin raw che includono fondi, dati, timelock e multisig. + +Tuttavia, Bitcoin offre molta più complessità di così. Include un semplice linguaggio di scripting che può essere utilizzato per creare condizioni di riscatto ancora più complesse. Se multisig e timelock hanno fornito la base degli Smart Contract, allora Bitcoin Script si fondamenta su quella base. È il passo successivo per potenziare Bitcoin. + +## Obiettivi di questo capitolo + +Dopo aver completato questo capitolo, uno sviluppatore sarà in grado di: + +* Progettare uno script Bitcoin +* Applicare uno script Bitcoin + +Gli obiettivi di supporto includono la capacità di: + +* Comprendere lo scopo degli script Bitcoin +* Comprendere lo script P2PKH +* Comprendere come funziona P2WPKH con lo scripting +* Comprendere le esigenze per il test degli script Bitcoin + +## Indice + +* [Capitolo 9.1: Le basi delle transazioni](09_1_Le_basi_delle_transazioni.md) +* [Capitolo 9.2: Eseguire uno Script di Bitcoin](09_2_Eseguire_uno_Script_di_Bitcoin.md) +* [Capitolo 9.3: Provare uno Script Bitcoin](09_3_Provare_uno_Script_Bitcoin.md) +* [Capitolo 9.4: Programmare una 2PKH](09_4_Programmare_una_P2PKH.md) +* [Capitolo 9.5: Programmare una P2WPKH](09_5_Programmare_una_P2WPKH.md) diff --git a/it/09_1_Le_basi_delle_transazioni.md b/it/09_1_Le_basi_delle_transazioni.md new file mode 100644 index 000000000..59efcb920 --- /dev/null +++ b/it/09_1_Le_basi_delle_transazioni.md @@ -0,0 +1,142 @@ +# 9.1: Comprendere le basi delle transazioni + +Le basi di Bitcoin sono la capacità di proteggere le transazioni, cosa che viene fatta con un semplice linguaggio di scripting. + +## Conoscere le parti del puzzle crittografico + +Come descritto nel [Capitolo 1](01_0_Introduzione.md), i fondi in ogni transazione Bitcoin sono bloccati con un puzzle crittografico. Per essere precisi, abbiamo detto che Bitcoin è composto da "una sequenza di transazioni atomiche". Abbiamo notato che: "Ogni transazione è autenticata da un mittente con la soluzione a un precedente puzzle crittografico che è stato memorizzato come uno script. La nuova transazione è bloccata per il destinatario con un nuovo puzzle crittografico che è anche memorizzato come uno script". Questi script, che bloccano e sbloccano le transazioni, sono scritti in Bitcoin Script. + +> :book: ***Cos'è Bitcoin Script?*** Bitcoin Script è un linguaggio simile a Forth basato su stack che evita volutamente i loop e quindi non è Turing-completo. È composto da singoli opcode. Ogni singola transazione in Bitcoin è bloccata con uno script Bitcoin; quando la transazione di blocco per un UTXO viene eseguita con gli input corretti, quell'UTXO può essere speso. + +Il fatto che le transazioni siano bloccate con script significa che possono essere bloccate in vari modi diversi, richiedendo una varietà di chiavi diverse. Infatti, abbiamo incontrato diversi meccanismi di blocco fino ad oggi, ognuno dei quali utilizzava diversi opcode: + +* OP_CHECKSIG, che controlla una chiave pubblica rispetto a una firma, è la base del classico indirizzo P2PKH, come verrà spiegato in dettaglio in [Capitolo 9.4: Programmare una P2PKH](09_4_Programmare_una_P2PKH.md). +* OP_CHECKMULTISIG controlla in modo simile i multisig, come verrà spiegato in dettaglio in [Capitolo 10.4: Programmare una Multifirma](10_4_Programmare_una_Multifirma.md). +* OP_CHECKLOCKTIMEVERIFY e OP_SEQUENCEEVERIFY costituiscono la base di Timelock più complessi, come verrà spiegato in dettaglio nel [Capitolo 11.2: Usare CLTV negli Scripts](11_2_Usare_CLTV_negli_Scripts.md). +* OP_RETURN è un segno di una transazione non spendibile, motivo per cui viene utilizzato per trasportare dati, come accennato in [Capitolo 8.2: Inviare una Transazione con Dati](08_2_Inviare_una_Transazione_con_Dati.md). + +## Script di accesso nelle tue transazioni + +Potresti non rendertene conto, ma hai già visto questi script di blocco e sblocco come parte delle transazioni raw con cui hai lavorato. Il modo migliore per esaminare questi script in modo più approfondito è quindi creare una transazione raw, quindi esaminarla. + +### Crea una transazione di prova + +Per esaminare gli script di sblocco e blocco, crea una rapida transazione raw prendendo un UTXO Legacy non speso e reinviandolo a un indirizzo di resto Legacy, meno una commissione di transazione: +``` +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') +$ recipient=$(bitcoin-cli -named getrawchangeaddress address_type=legacy) +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.0009 }''') +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +``` +In realtà non è necessario inviarlo: l'obiettivo è semplicemente produrre una transazione completa che puoi esaminare. + +> **NOTA:** Perché indirizzi legacy? Perché i loro script sono più significativi. Tuttavia, offriremo anche un esempio di un SegWit P2WPKH nativo nel [Capitolo 9.5](09_5_Programmare_una_P2WPKH.md). + +### Esamina la tua transazione di prova + +Ora puoi esaminare la tua transazione in modo approfondito utilizzando `decoderawtransaction` su `$signedtx`: +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$signedtx +{ + "txid": "34151dac704d94a269cd33f80be34c122152edc9bfbb9323852966bf0ce937ed", + "hash": "34151dac704d94a269cd33f80be34c122152edc9bfbb9323852966bf0ce937ed", + "version": 2, + "size": 191, + "vsize": 191, + "weight": 764, + "locktime": 0, + "vin": [ + { + "txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa", + "vout": 0, + "scriptSig": { + "asm": "304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b", + "hex": "47304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c01210315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91406b5c6ba5330cdf738a2ce91152bfd0e71f9ec3988ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mg8S7F1gY3ivV9M9GrWwe6ziWvK2MFquCf" + ] + } + } + ] +} + +``` +I due script si trovano in due parti diverse della transazione. + +Lo `scriptSig` si trova in `vin`. Questo è lo script di _sblocco_. È ciò che viene eseguito per accedere all'UTXO utilizzato per finanziare questa transazione. Ci sarà uno `scriptSig` per UTXO in una transazione. + +Lo `scriptPubKey` si trova in `vout`. Questo è lo script di _blocco_. È ciò che blocca il nuovo output dalla transazione. Ci sarà uno `scriptPubKey` per output in una transazione. + +> :book: ***Come interagiscono scriptSig e scriptPubKey?*** Lo `scriptSig` di una transazione sblocca l'UTXO precedente; l'output di questa nuova transazione verrà quindi bloccato con uno `scriptPubKey`, che a sua volta può essere sbloccato dallo `scriptSig` della transazione che riutilizza quell'UTXO. + +### Leggi gli script nella tua transazione + +Guarda i due script e vedrai che ognuno include due rappresentazioni diverse: `hex` è ciò che viene effettivamente memorizzato, ma il linguaggio assembly più leggibile (`asm`) può in un certo senso mostrarti cosa sta succedendo. + +Dai un'occhiata a `asm` dello script di sblocco e avrai una prima occhiata a come appare Bitcoin Scripting: +``` +04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +``` +Come capita, quel pasticcio di numeri è una firma a chiave privata seguita dalla chiave pubblica associata. O almeno si spera che sia così, perché è ciò che serve per sbloccare l'UTXO P2PKH che questa transazione sta utilizzando. + +Leggi lo script di blocco e vedrai che è molto più ovvio: +``` +OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG +``` +Questo è il metodo standard in Bitcoin Script per bloccare una transazione P2PKH. + +Il [Capitolo 9.4](09_4_Programmare_una_P2PKH.md) spiegherà come questi due script vanno insieme, ma prima dovrai sapere come vengono valutati gli script Bitcoin. + +## Esaminare una transazione diversa + +Prima di abbandonare questa base, esamineremo un diverso tipo di script di blocco. Ecco `scriptPubKey` dalla transazione multisig che hai creato in [Capitolo 6.1: Inviare una Transazione a un Indirizzo Multifirma](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md). +``` + "scriptPubKey": { + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + ] + } +``` + +Confrontalo con lo `scriptPubKey` della tua nuova transazione P2PKH: +``` + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91406b5c6ba5330cdf738a2ce91152bfd0e71f9ec3988ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mg8S7F1gY3ivV9M9GrWwe6ziWvK2MFquCf" + ] + } +``` + +Queste due transazioni sono _sicuramente_ bloccate in modi diversi. Bitcoin riconosce la prima come `scripthash` (P2SH) e la seconda come `pubkeyhash` (P2PKH), ma dovresti anche essere in grado di vedere la differenza nel diverso codice `asm`: `OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL` contro `OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG`. Questo è il potere dello scripting: può semplicemente produrre alcuni dei tipi di transazioni radicalmente diversi che hai imparato nei capitoli precedenti. + +## Riepilogo: comprendere le basi delle transazioni + +Ogni transazione Bitcoin include almeno uno script di sblocco (`scriptSig`), che risolve un precedente puzzle crittografico, e almeno uno script di blocco (`scriptPubKey`), che crea un nuovo puzzle crittografico. C'è uno `scriptSig` per input e uno `scriptPubKey` per output. Ognuno di questi script è scritto in Bitcoin Script, un linguaggio simile a Forth che potenzia ulteriormente Bitcoin. + +> :fire: ***Qual è il potere degli script?*** Gli script sbloccano tutta la potenza degli Smart Contract. Con gli opcode appropriati, puoi prendere decisioni molto precise su chi può riscattare i fondi, quando possono riscattare i fondi e come possono riscattare i fondi. Regole più complesse per la spesa aziendale, la spesa di partnership, la spesa proxy e altre metodologie possono anche essere codificate all'interno di uno Script. Potenzia persino servizi Bitcoin più complessi come Lightning e sidechain. + +## Cosa c'è dopo? + +Continua "Introduzione agli script Bitcoin" col [Capitolo 9.2:Eseguire uno Script di Bitcoin](09_2_Eseguire_uno_Script_di_Bitcoin.md). diff --git a/it/09_2_Eseguire_uno_Script_di_Bitcoin.md b/it/09_2_Eseguire_uno_Script_di_Bitcoin.md new file mode 100644 index 000000000..434481f75 --- /dev/null +++ b/it/09_2_Eseguire_uno_Script_di_Bitcoin.md @@ -0,0 +1,125 @@ +# 9.2: Esecuzione di uno script Bitcoin + +Gli script Bitcoin inizialmente potrebbero non sembrare così intuitivi, ma la loro esecuzione è abbastanza semplice, utilizzando la notazione Polacca inversa e uno stack. + +## Comprendere il linguaggio di scripting + +Uno script Bitcoin è composto da tre parti: ha una riga di input; ha uno stack per la conservazione; e ha comandi specifici per l'esecuzione. + +### Comprendere l'ordine + +Gli script Bitcoin vengono eseguiti da sinistra a destra. Sembra abbastanza facile, perché è lo stesso modo in cui leggi. Tuttavia, potrebbe in realtà essere l'elemento meno intuitivo di Bitcoin Script, perché significa che le funzioni non appaiono come ti aspetteresti. Invece, _gli operandi vanno prima dell'operatore._ + +Ad esempio, se dovessi sommare "1" e "2", il tuo script Bitcoin sarebbe `1 2 OP_ADD`, _non_ "1 + 2". Poiché sappiamo che l'operatore OP_ADD accetta due input, sappiamo che i due input prima di esso sono i suoi operandi. + +> :warning: **AVVISO:** Tecnicamente, tutto in Bitcoin Script è un codice operativo, quindi sarebbe più appropriato registrare l'esempio precedente come `OP_1 OP_2 OP_ADD`. Nei nostri esempi, non ci preoccupiamo di come verranno valutate le costanti, poiché questo è un argomento di traduzione, come spiegato nel [Capitolo 10.2: Costruire la struttura di P2SH](10_2_Construire_la_Struttura_di_P2SH.md). Alcuni autori preferiscono lasciare anche il prefisso "OP" su tutti gli operatori, ma noi abbiamo deciso di non farlo. + +### Comprendere lo stack + +In realtà non è del tutto corretto dire che un operatore si applica agli input che lo precedono. In realtà, un operatore si applica agli input principali nello stack di Bitcoin. + +> :book: ***Cos'è uno stack?*** Uno stack è una struttura dati LIFO (last-in-first-out). Ha due funzioni di accesso: push e pop. Push posiziona un nuovo oggetto in cima alla pila, spingendo verso il basso tutto ciò che si trova sotto di esso. Pop rimuove l'oggetto in cima alla pila. + +Ogni volta che Bitcoin Script incontra una costante, la inserisce nello stack. Quindi l'esempio sopra di "1 2 OP_ADD" sarebbe effettivamente simile a questo mentre veniva elaborato: +``` +Script: 1 2 OP_ADD +Stack: [ ] + +Script: 2 OP_ADD +Stack: [ 1 ] + +Script: OP_ADD +Stack: [ 1 2 ] +``` +_Nota che in questo esempio e nei seguenti esempi la parte superiore dello stack è a destra e la parte inferiore a sinistra._ + +### Comprendere i codici operativi + +Quando uno script Bitcoin incontra un operatore, lo valuta. Ogni operatore estrae zero o più elementi dallo stack come input, solitamente uno o due. Quindi li elabora in un modo specifico prima di rimettere zero o più elementi nello stack, solitamente uno o due. + +> :book: ***Cos'è un Opcode?*** Opcode sta per "codice operativo". È tipicamente associato al codice in linguaggio macchina ed è una funzione semplice (o "operatore"). + +OP_ADD estrae due elementi dallo stack (qui: 2 poi 1), li somma e rimette il risultato nello stack (qui: 3). +``` +Script: +Running: 1 2 OP_ADD +Stack: [ 3 ] +``` + +## Aumentiamo la complessità + +Gli script più complessi vengono creati eseguendo più comandi in ordine. Devono essere valutati attentamente da sinistra a destra, in modo da poter comprendere lo stato dello stack quando viene eseguito ogni nuovo comando. Cambierà costantemente, come risultato degli operatori precedenti: +``` +Script: 3 2 OP_ADD 4 OP_SUB +Stack: [ ] + +Script: 2 OP_ADD 4 OP_SUB +Stack: [ 3 ] + +Script: OP_ADD 4 OP_SUB +Stack: [ 3 2 ] + +Script: 4 OP_SUB +Running: 3 2 OP_ADD +Stack: [ 5 ] + +Script: OP_SUB +Stack: [ 5 4 ] + +Script: +Running: 5 4 OP_SUB +Stack: [ 1 ] +``` + +## Comprendere l'utilizzo dello script Bitcoin + +Questo è praticamente Bitcoin Scripting... a parte alcune complessità su come questo linguaggio di scripting interagisce con Bitcoin stesso. + +### Comprendere scriptSig e scriptPubKey + +Come abbiamo visto, ogni input per una transazione Bitcoin contiene uno "scriptSig" utilizzato per sbloccare lo "scriptPubKey" per l'UTXO associato. Sono _effettivamente_ concatenati insieme, il che significa che `scriptSig` e `scriptPubKey` vengono eseguiti insieme, in quest'ordine. + +Quindi, presumi che un UTXO sia stato bloccato con uno `scriptPubKey` che legga `OP_ADD 99 OP_EQUAL`, richiedendo come input due numeri che si sommano a novantanove, e presumi che `scriptSig` di `1 98` sia stato eseguito per sbloccare Esso. I due script verrebbero effettivamente eseguiti in ordine come "1 98 OP_ADD 99 OP_EQUAL". + +Valutare il risultato: +``` +Script: 1 98 OP_ADD 99 OP_EQUAL +Stack: [] + +Script: 98 OP_ADD 99 OP_EQUAL +Stack: [ 1 ] + +Script: OP_ADD 99 OP_EQUAL +Stack: [ 1 98 ] + +Script: 99 OP_EQUAL +Running: 1 98 OP_ADD +Stack: [ 99 ] + +Script: OP_EQUAL +Stack: [ 99 99 ] + +Script: +Running: 99 99 OP_EQUAL +Stack: [ True ] +``` +Questa astrazione non è del tutto accurata: per motivi di sicurezza, viene eseguito `scriptSig`, quindi il contenuto dello stack viene trasferito per l'esecuzione di `scriptPubKey`, ma è sufficientemente accurato per comprendere come si inserisce la chiave di `scriptSig` il blocco di `scriptPubKey`. + +> :warning: **AVVISO** Quanto sopra è un tipo di transazione non standard. In realtà non sarebbe accettato dai nodi che eseguono Bitcoin Core con le impostazioni standard. [Capitolo 10.1:Comprendere la Base di P2SH](10_1_Comprendere_la_Base_di_P2SH.md) spiega come effettivamente _potresti_ eseguire uno script Bitcoin come questo, utilizzando la potenza di P2SH. + +### Ottieni i risultati + +Bitcoin verificherà una transazione e consentirà di spendere l'UTXO se questi due criteri vengono soddisfatti durante l'esecuzione di `scriptSig` e `scriptPubKey`: + + 1. L'esecuzione non è stata contrassegnata come non valida in nessun momento, ad esempio con un `OP_VERIFY` non riuscito o con l'utilizzo di un codice operativo disabilitato. + 2. L'elemento in cima allo stack alla fine dell'esecuzione è `true` (diverso da zero). + +Nell'esempio sopra, la transazione avrebbe successo perché lo stack ha un `true` in cima. Ma sarebbe altrettanto lecito terminare con uno stack completo e il numero `42` in cima. + +## Riepilogo: Eseguire uno script Bitcoin + +Per eseguire uno script Bitcoin, si eseguie uno `scriptSig` seguito dallo `scriptPubKey` che lo sta sbloccando. Questi comandi vengono eseguiti in ordine, da sinistra a destra, con le costanti che vengono inserite in uno stack e gli operatori che estraggono elementi da quello stack, quindi reinseriscono i risultati su di esso. Se lo script non si ferma a metà e se l'elemento in cima allo stack alla fine è diverso da zero, l'UTXO è sbloccato. + +## Qual è il prossimo argomento? + +Continua con "Introduzione agli script Bitcoin" nel [Capitolo 9.3: Provare uno Script Bitcoin](09_3_Provare_uno_Script_Bitcoin.md). diff --git a/it/09_3_Provare_uno_Script_Bitcoin.md b/it/09_3_Provare_uno_Script_Bitcoin.md new file mode 100644 index 000000000..d2408abaf --- /dev/null +++ b/it/09_3_Provare_uno_Script_Bitcoin.md @@ -0,0 +1,213 @@ +# 9.3: Provare uno Script Bitcoin + +Bitcoin Scripting consente un notevole controllo aggiuntivo sulle transazioni Bitcoin, ma è anche alquanto pericoloso. Come descriveremo nel [Capitolo 10.1](10_1_Comprendere_la_Base_di_P2SH.md), gli script effettivi sono in qualche modo isolati dalla rete Bitcoin, il che significa che è possibile scrivere uno script e farlo accettare dalla rete anche se è impossibile riscattarlo quello script! Quindi, devi testare a fondo i tuoi script prima di investire i tuoi soldi in essi. + +Questo capitolo descrive quindi un metodo fondamentale per testare gli script Bitcoin, che utilizzeremo anche per esempi occasionali nel resto di questa sezione. + +## Installa btcdeb + +Bitcoin Script Debugger (`btcdeb`) di @kallewoof è uno dei metodi più affidabili che abbiamo trovato per eseguire il debug degli script Bitcoin. Richiede, tuttavia, la configurazione di C++ e alcuni altri accessori sul computer, quindi offriremo anche alcune altre opzioni verso la fine di questo capitolo. + +Per prima cosa devi clonare il repository GitHub `btcdeb`, che richiederà anche l'installazione di `git` se non lo hai ancora +. +``` +$ sudo apt-get install git +$ git clone https://github.com/bitcoin-core/btcdeb.git +``` +Tieni presente che quando esegui `git clone` copierà `btcdeb` nella tua directory corrente. Abbiamo scelto di farlo nella nostra directory '~standup'. +``` +$ ls +bitcoin-0.20.0-x86_64-linux-gnu.tar.gz btcdeb laanwj-releases.asc SHA256SUMS.asc +``` +Successivamente è necessario installare il C++ richiesto e gli altri pacchetti. +``` +$ sudo apt-get install autoconf libtool g++ pkg-config make +``` +Dovresti anche installare `readline`, poiché ciò rende il debugger molto più semplice da usare supportando la cronologia utilizzando le frecce su/giù, il movimento da sinistra a destra, il completamento automatico utilizzando la scheda e altre buone interfacce utente. +``` +$ sudo apt-get install libreadline-dev +``` +Ora sei pronto per compilare e installare `btcdeb`: +``` +$ cd btcdeb +$ ./autogen.sh +$ ./configure +$ make +$ sudo make install +``` +Dopo tutto ciò, dovresti avere una copia di `btcdeb`: +``` +$ which btcdeb +/usr/local/bin/btcdeb +``` + +## Usa btcdeb + +`btcdeb` funziona come un debugger standard. Richiede uno script (così come un numero qualsiasi di voci dello stack) come argomento di avvio. È quindi possibile 'correre' attraverso lo script. + +Se invece lo avvii senza argomenti, otterrai semplicemente un interprete in cui puoi eseguire i comandi `exec [opcode]` per eseguire direttamente le azioni. + +### Usa btcdeb per un esempio di addizione + +L'esempio seguente mostra l'uso di `btcdeb` per l'esempio di addizione della sezione precedente, "1 2 OP_ADD" +``` +$ btcdeb '[1 2 OP_ADD]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +warning: ambiguous input 1 is interpreted as a numeric value; use OP_1 to force into opcode +warning: ambiguous input 2 is interpreted as a numeric value; use OP_2 to force into opcode +miniscript failed to parse script; miniscript support disabled +valid script +3 op script loaded. type `help` for usage information +script | stack +--------+-------- +1 | +2 | +OP_ADD | +#0000 1 +``` +Mostra il nostro script iniziale, eseguito dall'alto verso il basso, e mostra anche cosa verrà eseguito successivamente nello script. + +Digitiamo `step` e avanza di un passo prendendo il primo elemento nello script e inserendolo nello stack: + +``` +btcdeb> step + <> PUSH stack 01 +script | stack +--------+-------- +2 | 01 +OP_ADD | +#0001 2 +``` +E ancora: +``` +btcdeb> step + <> PUSH stack 02 +script | stack +--------+-------- +OP_ADD | 02 + | 01 +#0002 OP_ADD +``` +Ora eseguiamo `OP_ADD` e c'è grande eccitazione perché il codice operativo estrae i primi due elementi dallo stack, li somma insieme, quindi inserisce la loro somma nello stack. +``` +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 03 +script | stack +--------+-------- + | 03 +``` +Ed è qui che finisce il nostro script, senza più nulla da eseguire e uno `03` in cima al nostro stack come risultato dello script. + +> **NOTA:** `btcdeb` ti consente di ripetere il comando precedente premendo invio. Lo faremo negli esempi successivi, quindi non sorprenderti se il prompt `btcdeb>` non contiene nulla come input. Si tratta semplicemente di ripetere il comando precedente (spesso `step`). + +### Usa btcdeb per un esempio di sottrazione + +La sezione precedente includeva anche un esempio di sottrazione leggermente più complesso di Scripting: `3 2 OP_ADD 4 OP_SUB`. Ecco come appare: + +``` +$ btcdeb '[3 2 OP_ADD 4 OP_SUB]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +warning: ambiguous input 3 is interpreted as a numeric value; use OP_3 to force into opcode +warning: ambiguous input 2 is interpreted as a numeric value; use OP_2 to force into opcode +warning: ambiguous input 4 is interpreted as a numeric value; use OP_4 to force into opcode +miniscript failed to parse script; miniscript support disabled +valid script +5 op script loaded. type `help` for usage information +script | stack +--------+-------- +3 | +2 | +OP_ADD | +4 | +OP_SUB | +#0000 3 +btcdeb> step + <> PUSH stack 03 +script | stack +--------+-------- +2 | 03 +OP_ADD | +4 | +OP_SUB | +#0001 2 +btcdeb> + <> PUSH stack 02 +script | stack +--------+-------- +OP_ADD | 02 +4 | 03 +OP_SUB | +#0002 OP_ADD +btcdeb> + <> POP stack + <> POP stack + <> PUSH stack 05 +script | stack +--------+-------- +4 | 05 +OP_SUB | +#0003 4 +btcdeb> + <> PUSH stack 04 +script | stack +--------+-------- +OP_SUB | 04 + | 05 +#0004 OP_SUB +btcdeb> + <> POP stack + <> POP stack + <> PUSH stack 01 +script | stack +--------+-------- + | 01 +``` +Torneremo a `btcdeb` di tanto in tanto e rimarrà uno strumento eccellente per testare i tuoi script. + +### Usa la potenza di btcdeb + +`btcdeb` ha anche alcune funzioni più potenti, come `print` e `stack`, che mostrano lo script e lo stack in qualsiasi momento. + +Ad esempio, nello script sopra, una volta che sei passato al comando "OP_ADD", puoi vedere quanto segue: +``` +btcdeb> print + #0000 3 + #0001 2 + -> #0002 OP_ADD + #0003 4 + #0004 OP_SUB +btcdeb> stack +<01> 02 (top) +<02> 03 +``` +L'uso di questi comandi può rendere più semplice vedere cosa sta succedendo e dove ti trovi. + +> :warning: **AVVISO:** `btcdeb` è molto più complesso da usare se stai cercando di verificare le firme. Vedi [Controllo della firma con btcdeb](https://github.com/bitcoin-core/btcdeb/blob/master/doc/btcdeb.md#signature-checking). Questo è vero per qualsiasi test di script, quindi non lo consigliamo se stai cercando di verificare un `OP_CHECKSIG` o un `OP_CHECKMULTISIG`. + +## Prova uno script online + +Esistono anche alcuni simulatori web che puoi utilizzare per testare gli script online. Possono essere superiori a uno strumento da riga di comando offrendo un output più grafico, ma scopriamo anche che tendono ad avere dei difetti. + +In passato abbiamo cercato di fornire linee guida dettagliate sull'utilizzo di siti come [Script Playground](http://www.crmarsh.com/script-playground/) o [Bitcoin Online Script Debugger](https://bitcoin-script-debugger.visvirial.com/), ma diventano obsoleti e/o scompaiono troppo rapidamente per poter stare al passo con loro. + +Supponiamo che questi debugger abbiano il vantaggio di mostrare le cose visivamente e di dirti esplicitamente se uno script riesce (si sblocca) o fallisce (rimane bloccato). Supponiamo che abbiano degli svantaggi con le firme, dove molti di loro restituiscono sempre "true" per i test di firma oppure hanno meccanismi molto macchinosi per incorporarli. + +## Prova uno script con Bitcoin + +Anche con un ottimo strumento come `btcdeb` o risorse transitorie come i vari tester di script online, non lavori con la realtà. Non puoi garantire che seguano le regole di consenso di Bitcoin, il che significa che non puoi garantire i loro risultati. Ad esempio, Script Playground afferma esplicitamente di ignorare un bug implicito nelle multifirme Bitcoin. Ciò significa che qualsiasi codice multisig testato con successo su Script Playground si romperà nel mondo reale. + +Quindi l'unico modo per testare _veramente_ gli script Bitcoin è provarli su Testnet. + +E come lo fai? Si dà il caso che questo sia l'argomento del [Capitolo 10](110_0_Inserire_Scripts_di_Bitcoin_in_Transazioni_P2SH.md), che esamina l'introduzione di questi script astratti nel mondo reale di Bitcoin incorporandoli nelle transazioni P2SH. (Ma anche in questo caso, probabilmente avrai bisogno di un'API per inviare la tua transazione P2SH sulla rete Bitcoin, quindi i test completi saranno ancora possibili in futuro.) + +_Quali_ siano gli altri metodi di test che hai utilizzato, testare uno script su Testnet dovrebbe essere il tuo test finale _prima_ di inserire lo script su Mainnet. Non fidarti che il tuo codice sia corretto; non limitarti a guardarlo. Non fidarti nemmeno dei simulatori o debugger che hai utilizzato. Farlo è un altro ottimo modo per perdere fondi su Bitcoin. + +## Riepilogo: Provare uno script Bitcoin + +Dovresti installare `btcdeb` come strumento da riga di comando per testare i tuoi script Bitcoin. Al momento della stesura di questo articolo, produce risultati accurati che possono passare attraverso l'intero processo di scripting. Puoi anche consultare alcuni siti online per una rappresentazione più visiva. Quando avrai finito, dovrai andare su testnet per assicurarti che le cose funzionino correttamente, prima di eseguire la distribuzione in modo più generale. + +## Qual è il prossimo argomento? + +Continua "Presentazione degli script Bitcoin" con il nostro primo esempio reale: [Capitolo 9.4:09_4_Programmare una P2PKH](09_4_Programmare_una_P2PKH.md). diff --git a/it/09_4_Programmare_una_P2PKH.md b/it/09_4_Programmare_una_P2PKH.md new file mode 100644 index 000000000..d7be02771 --- /dev/null +++ b/it/09_4_Programmare_una_P2PKH.md @@ -0,0 +1,388 @@ +# 9.4: Script di un P2PKH + +Gli indirizzi P2PKH stanno rapidamente perdendo popolarità a causa dell'avvento di SegWit, ma rimangono comunque un ottimo elemento fondamentale per comprendere Bitcoin, e soprattutto per comprendere gli script Bitcoin. (Daremo una rapida occhiata a come gli script P2WPKH nativi di Segwit funzionano in modo diverso nella sezione successiva.) + +## Comprendere lo script di sblocco + +Da tempo sosteniamo che quando i fondi vengono inviati a un indirizzo Bitcoin, sono bloccati nella chiave privata associata a quell'indirizzo. Questo viene gestito tramite "scriptPubKey" di una transazione P2PKH, progettata in modo tale da richiedere al destinatario di avere la chiave privata associata all'indirizzo Bitcoin P2PKH. Per la precisione, il destinatario deve fornire sia la chiave pubblica collegata alla chiave privata, sia una firma generata dalla chiave privata. + +Dai un'altra occhiata alla transazione che hai creato nel [Capitolo 9.1](09_1_Le_basi_delle_transazioni.md): +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$signedtx +{ + "txid": "34151dac704d94a269cd33f80be34c122152edc9bfbb9323852966bf0ce937ed", + "hash": "34151dac704d94a269cd33f80be34c122152edc9bfbb9323852966bf0ce937ed", + "version": 2, + "size": 191, + "vsize": 191, + "weight": 764, + "locktime": 0, + "vin": [ + { + "txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa", + "vout": 0, + "scriptSig": { + "asm": "304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b", + "hex": "47304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c01210315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91406b5c6ba5330cdf738a2ce91152bfd0e71f9ec3988ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mg8S7F1gY3ivV9M9GrWwe6ziWvK2MFquCf" + ] + } + } + ] +} +``` +Puoi vedere che il suo script di sblocco `scriptSig` ha due valori. Questo è una `` (e un `[ALL]`) e una ``: +``` +304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +``` +Questo è tutto, uno script di sblocco! (Per un P2PKH.) + +## Comprendere lo script di blocco + +Ricorda che ogni script di sblocco sblocca un UTXO precedente. Nell'esempio sopra, `vin` rivela che sta effettivamente sbloccando vout `0` di txid `bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa`. + +Puoi esaminare l'UTXO con `gettransaction`. +``` +$ bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa" +{ + "amount": 0.00095000, + "confirmations": 12, + "blockhash": "0000000075a4c1519da5e671b15064734c42784eab723530a6ace83ca1e66d3f", + "blockheight": 1780789, + "blockindex": 132, + "blocktime": 1594841768, + "txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa", + "walletconflicts": [ + ], + "time": 1594841108, + "timereceived": 1594841108, + "bip125-replaceable": "no", + "details": [ + { + "address": "mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9", + "category": "receive", + "amount": 0.00095000, + "label": "", + "vout": 0 + } + ], + "hex": "020000000001011efcc3bf9950ac2ea08c53b43a0f8cc21e4b5564e205f996f7cadb7d13bb79470000000017160014c4ea10874ae77d957e170bd43f2ee828a8e3bc71feffffff0218730100000000001976a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac713b10000000000017a914b780fc2e945bea71b9ee2d8d2901f00914a25fbd8702473044022025ee4fd38e6865125f7c315406c0b3a8139d482e3be333727d38868baa656d3d02204b35d9b5812cb85894541da611d5cec14c374ae7a7b8ba14bb44495747b571530121033cae26cb3fa063c95e2c55a94bd04ab9cf173104555efe448b1bfc3a68c8f873342c1b00" +} +``` +Ma come puoi vedere, non hai ottenuto "scriptPubKey" con "gettransaction". Devi fare un ulteriore passo per recuperarlo esaminando le informazioni grezze sulla transazione (che sono `hex`) con `decoderawtransaction`: +``` +$ hex=$(bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa" | jq -r '.hex') +$ bitcoin-cli decoderawtransaction $hex +{ + "txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa", + "hash": "6866490b16a92d68179e1cf04380fd08f16ec80bf66469af8d5e78ae624ff202", + "version": 2, + "size": 249, + "vsize": 168, + "weight": 669, + "locktime": 1780788, + "vin": [ + { + "txid": "4779bb137ddbcaf796f905e264554b1ec28c0f3ab4538ca02eac5099bfc3fc1e", + "vout": 0, + "scriptSig": { + "asm": "0014c4ea10874ae77d957e170bd43f2ee828a8e3bc71", + "hex": "160014c4ea10874ae77d957e170bd43f2ee828a8e3bc71" + }, + "txinwitness": [ + "3044022025ee4fd38e6865125f7c315406c0b3a8139d482e3be333727d38868baa656d3d02204b35d9b5812cb85894541da611d5cec14c374ae7a7b8ba14bb44495747b5715301", + "033cae26cb3fa063c95e2c55a94bd04ab9cf173104555efe448b1bfc3a68c8f873" + ], + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00095000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9" + ] + } + }, + { + "value": 0.01063793, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 b780fc2e945bea71b9ee2d8d2901f00914a25fbd OP_EQUAL", + "hex": "a914b780fc2e945bea71b9ee2d8d2901f00914a25fbd87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N9yWARt5E3TQsX2RjsauxSZaEZVhinAS4h" + ] + } + } + ] +} +``` +Ora puoi guardare `vout` `0` e vedere che era bloccato con `scriptPubKey` di `OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG`. Questa è la metodologia di blocco standard utilizzata per un vecchio indirizzo P2PKH con `` bloccato nel mezzo. + +Eseguirlo dimostrerà come funziona. + +## Esegui uno script P2PKH + +Quando sblocchi un P2PKH UTXO, concateni (effettivamente) gli script di sblocco e blocco. Per un indirizzo P2PKH, come nell'esempio utilizzato in questo capitolo, che produce: + +``` +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +``` +Detto questo, puoi esaminare come viene sbloccato un P2PKH UTXO. + +Innanzitutto, inserisci le costanti iniziali nello stack, quindi crea un duplicato di pubKey con `OP_DUP`: +``` +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] + +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] + +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] + +Script: OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: OP_DUP +Stack: [ ] +``` +Perché il duplicato? Perché bisogna controllare i due elementi di sblocco: la chiave pubblica e la firma. + +Successivamente, `OP_HASH160` estrae `` dallo stack, ne esegue l'hashing e reinserisce il risultato nello stack. +``` +Script: OP_EQUALVERIFY OP_CHECKSIG +Running: OP_HASH160 +Stack: [ ] +``` +Quindi, inserisci nello stack il valore `` che si trovava nello script di blocco: +``` +Script: OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] +``` +`OP_EQUALVERIFY` è effettivamente composto da due codici operativi: `OP_EQUAL`, che estrae due elementi dallo stack e inserisce `True` o `False` in base al confronto; e `OP_VERIFY` che visualizza il risultato e contrassegna immediatamente la transazione come non valida se è `False`. (Il Capitolo 12 parla più approfonditamente dell'uso di `OP_VERIFY` come condizionale.) + +Supponendo che i due `es` siano uguali, otterrai il seguente risultato: +``` +Script: OP_CHECKSIG +Running: OP_EQUALVERIFY +Stack: [ ] +``` +A questo punto hai dimostrato che il `` fornito in `scriptSig` ha l'hash dell'indirizzo Bitcoin in questione, quindi sai che il redeemer conosceva la chiave pubblica. Ma devono anche dimostrare di conoscere la chiave privata, cosa che viene fatta con `OP_CHECKSIG`, che conferma che la firma dello script di sblocco corrisponde a quella chiave pubblica. +``` +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` +Lo Script ora termina e, se ha avuto successo, la transazione può spendere nuovamente l'UTXO in questione. + +### Usa btcdeb per un esempio P2PKH + +Testare le effettive transazioni Bitcoin con "btcdeb" è un po' più complicato, perché è necessario conoscere la chiave pubblica e una firma per far funzionare tutto, e generare quest'ultima è piuttosto difficile. Tuttavia, un modo per testare le cose è lasciare che Bitcoin faccia il lavoro per te nel generare una transazione che _sbloccherebbe_ un UTXO. Questo è quello che hai fatto sopra: la generazione della transazione per spendere l'UTXO ha fatto sì che `bitcoin-cli` calcolasse `` e ``. Quindi esamini le informazioni grezze sulla transazione dell'UTXO per apprendere lo script di blocco incluso `` + +Puoi mettere insieme lo script di blocco, la firma e la pubkey utilizzando `btcdeb`, mostrando quanto sia semplice uno script P2PKH. +``` +$ btcdeb '[304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +unknown key ID 41d83eaffbf80f82dee4c152de59a38ffd0b6021: returning fake key +valid script +7 op script loaded. type `help` for usage information +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... | +0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | +OP_DUP | +OP_HASH160 | +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | +OP_EQUALVERIFY | +OP_CHECKSIG | + | + | +#0000 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c +``` +Spingi la `` e la `` nello stack: +``` +btcdeb> step + <> PUSH stack 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... +OP_DUP | +OP_HASH160 | +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | +OP_EQUALVERIFY | +OP_CHECKSIG | + | + | + | + | + | +#0001 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +btcdeb> step + <> PUSH stack 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +OP_DUP | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +OP_HASH160 | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | +OP_EQUALVERIFY | +OP_CHECKSIG | + | + | + | + | + | + | + | +``` +Il tuo `OP_DUP` e `OP_HASH` la ``: +``` +#0002 OP_DUP +btcdeb> step + <> PUSH stack 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +OP_HASH160 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +OP_EQUALVERIFY | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... +OP_CHECKSIG | + | + | + | + | + | + | + | + | + | +#0003 OP_HASH160 +btcdeb> step + <> POP stack + <> PUSH stack 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +41d83eaffbf80f82dee4c152de59a38ffd0b6021 | 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +OP_EQUALVERIFY | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b +OP_CHECKSIG | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... + | + | + | + | + | + | + | + | + | + | +``` +Spingi la `` dallo script di blocco nella pila e verifichi: +``` +#0004 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +btcdeb> step + <> PUSH stack 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +OP_EQUALVERIFY | 41d83eaffbf80f82dee4c152de59a38ffd0b6021 +OP_CHECKSIG | 41d83eaffbf80f82dee4c152de59a38ffd0b6021 + | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b + | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... + | + | + | + | + | + | + | + | + | + | +#0005 OP_EQUALVERIFY +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 + <> POP stack +script | stack +-------------------------------------------------------------------+------------------------------------------------------------------- +OP_CHECKSIG | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b + | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... + | + | and_v( + | sig(304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c... + | and_v( + | pk(0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3... + | c:pk_h(030500000000000000000000000000000000000000000000... + | ) + | + | ) + | + +``` +A questo punto, serve soltanto il `OP_CHECKSIG`: +``` +#0006 OP_CHECKSIG +btcdeb> step +error: Signature is found in scriptCode +``` +(Sfortunatamente questo controllo potrebbe funzionare o meno in qualsiasi momento a causa dei capricci del Bitcoin Core e del codice `btcdeb`.) + +Come si vede, un P2PKH è abbastanza semplice: la sua protezione avviene attraverso la forza della sua crittografia. + +### Come cercare manualmente la PubKey e la firma + +E se volessi generare le informazioni `` e `` necessarie per sbloccare tu stesso un UTXO, senza appoggiarti a "bitcoin-cli" per creare una transazione? + +Si scopre che è abbastanza semplice ottenere un ``. Devi solo usare `getaddressinfo` per esaminare l'indirizzo in cui si trova attualmente l'UTXO: +``` +$ bitcoin-cli getaddressinfo mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9 +{ + "address": "mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9", + "scriptPubKey": "76a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac", + "ismine": true, + "solvable": true, + "desc": "pkh([f004311c/0'/0'/2']0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b)#t3g5mjk9", + "iswatchonly": false, + "isscript": false, + "iswitness": false, + "pubkey": "0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b", + "iscompressed": true, + "ischange": false, + "timestamp": 1594835792, + "hdkeypath": "m/0'/0'/2'", + "hdseedid": "f058372260f71fea37f7ecab9e4c5dc25dc11eac", + "hdmasterfingerprint": "f004311c", + "labels": [ + "" + ] +} +``` +Per capire quella firma, tuttavia, è necessario comprendere veramente i dettagli di come vengono create le transazioni Bitcoin. Quindi lo lasciamo come uno studio avanzato per il lettore: creare una transazione `bitcoin-cli` per `risolvere` un UTXO è la soluzione migliore per il momento. + +## Riepilogo: Programmare Pay to Public Key Hash + +L'invio a un indirizzo P2PKH era relativamente semplice quando utilizzavi solo `bitcoin-cli`. L'esame dello script Bitcoin sottostante mette a nudo le funzioni crittografiche implicite nel finanziamento di quella transazione: come l'UTXO è stato sbloccato con una firma e una chiave pubblica. + +## Qual è il prossimo argomento? + +Continua l' "Introduzione agli script Bitcoin" con [Capitolo 9.5: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md). diff --git a/it/09_5_Programmare_una_P2WPKH.md b/it/09_5_Programmare_una_P2WPKH.md new file mode 100644 index 000000000..36797a9a1 --- /dev/null +++ b/it/09_5_Programmare_una_P2WPKH.md @@ -0,0 +1,120 @@ +# 9.5: Script di un P2WPKH + +> :information_source: **NOTA:** Questa sezione è stata aggiunta di recente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettor avvisato. + +I P2PKH vanno bene per spiegare il modo fondamentale in cui funzionano gli script Bitcoin, ma che dire degli script nativi SegWit P2WPKH, che stanno diventando sempre più la maggior parte delle transazioni Bitcoin? A quanto pare, gli indirizzi P2WPKH non utilizzano script Bitcoin come fanno gli indirizzi Bitcoin tradizionali, quindi questa sezione è in realtà una digressione dallo scripting di questo capitolo, ma importante, perché delinea l'_altro_ modo principale in cui i Bitcoin possono essere transati. + +## Visualizzare uno script P2WPKH + +È abbastanza facile vedere come appare uno script P2WPKH. La seguente transazione grezza è stata creata spendendo un UTXO P2WPKH e quindi inviando il denaro a un indirizzo di resto P2WPKH, proprio come abbiamo fatto con un indirizzo legacy nel [Capitolo 9.1](09_1_Le_basi_delle_transazioni.md). +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$signedtx +{ + "txid": "bdf8f12768a9870d41ac280f8bb4f8ecd9d2fa66fffc75606811f5751c17cb3a", + "hash": "ec09c84cae48694bec7fd3461b3c5b38a76829c56e9d876037bf2484d443174b", + "version": 2, + "size": 191, + "vsize": 110, + "weight": 437, + "locktime": 0, + "vin": [ + { + "txid": "3f5417bc7a3a4144d715f3f006d35ea2b405f06091cbb9ce492e04ccefe02b18", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "txinwitness": [ + "3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001", + "03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903" + ], + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "0 92a0db923b3a13eb576a40c4b35515aa30206cba", + "hex": "001492a0db923b3a13eb576a40c4b35515aa30206cba", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qj2sdhy3m8gf7k4m2grztx4g44gczqm96y6sszv" + ] + } + } + ] +} +``` +There are probably two surprising things here: (1) There's no `scriptSig` to unlock the previous transaction; and (2) the `scriptPubKey` to lock the new transaction is just `0 92a0db923b3a13eb576a40c4b35515aa30206cb`. + +Questo è molto semplice perché P2WPKH funziona diversamente! + +## Comprendere una transazione P2WPKH + +Una transazione P2WPKH contiene tutte le stesse informazioni di una transazione P2PKH classica, ma le colloca in posti strani, non all'interno di un tradizionale Bitcoin Script - e, questo è lo scopo esatto delle transazioni SegWit, per estrarre le informazioni `testimone`, cioè chiavi pubbliche e firme, fuori dalla transazione. + +Ma, se guardi attentamente, vedrai che il vuoto `scriptSig` è stato sostituito con due voci in una nuova sezione `txinwitness`. Se ne esamini le dimensioni e la formattazione, dovrebbero sembrarti familiari: sono una firma e una chiave pubblica. Allo stesso modo, se guardi "scriptPubKey", vedrai che è composto da uno "0" (in realtà: "OP_0", è il numero di versione di SegWit) e un altro numero lungo, che è l'hash della chiave pubblica. + +Ecco un confronto tra i nostri due esempi: + +| Type | PubKeyHash | PubKey | Signature | +|----------------|----------|-------------|---------| +| SegWit | 92a0db923b3a13eb576a40c4b35515aa30206cba | 03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903 | 3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001 | +| non-SegWit | 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c | + +Allora come funziona? Dipende dal vecchio codice che lo interpreta come una transazione valida e dal nuovo codice che sa controllare le nuove informazioni "testimone". + +### Leggere uno script SegWit su un nodo non aggiornato + +Se un nodo non è stato aggiornato per supportare SegWit, esegue il solito trucco di concatenare `scriptSig` e `scriptPubKey`. Questo produce: `0 92a0db923b3a13eb576a40c4b35515aa30206cba` (perché c'è solo uno `scriptPubKey`). L'esecuzione produrrà una pila con tutto ciò che contiene in ordine inverso: +``` +$ btcdeb '[0 92a0db923b3a13eb576a40c4b35515aa30206cba]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +miniscript failed to parse script; miniscript support disabled +valid script +2 op script loaded. type `help` for usage information +script | stack +-----------------------------------------+-------- +0 | +92a0db923b3a13eb576a40c4b35515aa30206cba | +#0000 0 +btcdeb> step + <> PUSH stack +script | stack +-----------------------------------------+-------- +92a0db923b3a13eb576a40c4b35515aa30206cba | 0x +#0001 92a0db923b3a13eb576a40c4b35515aa30206cba +btcdeb> step + <> PUSH stack 92a0db923b3a13eb576a40c4b35515aa30206cba +script | stack +-----------------------------------------+----------------------------------------- + | 92a0db923b3a13eb576a40c4b35515aa30206cba + | 0x +``` +Gli script Bitcoin sono considerati riusciti se c'è qualcosa nello stack ed è diverso da zero, quindi gli script SegWit riescono automaticamente sui vecchi nodi purché `scriptPubKey` venga creato correttamente con un hash pub-key diverso da zero. Questa è chiamata transazione "chiunque può spendere", perché i vecchi nodi le hanno verificate come corrette senza bisogno di firme. + +> :book: ***Perché i vecchi nodi non possono rubare gli UTXO SegWit?*** SegWit è stato abilitato sulla rete Bitcoin quando il 95% dei minatori ha segnalato di essere pronto per iniziare a utilizzarlo. Ciò significa che solo il 5% dei nodi a quel punto avrebbe potuto registrare come valide le transazioni SegWit “chiunque può spendere” senza passare attraverso il lavoro adeguato di controllo del `txinwitness`. Se incorporassero erroneamente un UTXO non valido che chiunque può spendere in un blocco, il restante 95% dei nodi si rifiuterebbe di convalidare quel blocco, e quindi rimarrebbe rapidamente orfano anziché essere aggiunto alla blockchain "principale". (Certamente, il 51% dei nodi potrebbe scegliere di smettere di interpretare correttamente le transazioni SegWit, ma il 51% dei nodi può fare qualsiasi cosa su una rete di consenso come una blockchain.) + +Poiché i vecchi nodi vedono sempre gli script SegWit come corretti, li verificheranno sempre, anche senza comprenderne il contenuto. + +### Leggere uno script SegWit su un nodo aggiornato + +Un nodo che capisce come funziona SegWit fa esattamente le stesse cose che farebbe con un vecchio script P2PKH, ma non usa uno script di per sé: sa solo che deve eseguire l'hashing della chiave pubblica nel `txinwitness`, controlla quello contro la chiave con hash dopo il numero di versione in "scriptPubKey" e quindi eseguire "OP_CHECKSIG" sulla firma e sulla chiave pubblica in "txinwitness". + +Quindi, è un altro modo di fare la stessa cosa, ma senza avere gli script integrati nelle transazioni. (Il processo è invece integrato nel software del nodo.) + +## Riepilogo: Programmare un transazione Pay to Witness Public Key Hash + +In larga misura _non_ scrivi un P2WPKH. Invece, Bitcoin Core crea la transazione in un modo diverso, posizionando le informazioni del testimone in un posto diverso rispetto al tradizionale `scriptSig`. Ciò significa che i P2WPKH sono una digressione dagli script Bitcoin di questa parte del libro, perché sono un'espansione di Bitcoin che si allontana dagli script tradizionali. + +Tuttavia, SegWit è stato anche un uso intelligente degli script Bitcoin. Sapendo che ci sarebbero stati nodi che non si sarebbero aggiornati e che avrebbero dovuto rimanere compatibili con le versioni precedenti, gli sviluppatori hanno creato il formato P2WPKH in modo da generare uno script sempre convalidato sui vecchi nodi (pur mantenendo lo script che fornisce informazioni ai nuovi nodi nel formato di un numero di versione e una chiave pubblica hashata). + +Quando programmi dalla riga di comando, fondamentalmente non devi preoccuparti di questo, a parte sapere che non troverai script tradizionali nelle transazioni SegWit grezze (che, ancora una volta, era il punto). + +## Che segue ? + +Continua "Programmando Bitcoin" col [Capitolo 10: Inserire Scripts di Bitcoin in Transazioni P2SH](10_0_Inserire_Scripts_di_Bitcoin_in_Transazioni_P2SH.md). diff --git a/it/10_0_Inserire_Scripts_di_Bitcoin_in_Transazioni_P2SH.md b/it/10_0_Inserire_Scripts_di_Bitcoin_in_Transazioni_P2SH.md new file mode 100644 index 000000000..8a93d3fe7 --- /dev/null +++ b/it/10_0_Inserire_Scripts_di_Bitcoin_in_Transazioni_P2SH.md @@ -0,0 +1,26 @@ +# Capitolo 10: Inserire script Bitcoin nelle transazioni P2SH + +Bitcoin Script scende su diversi livelli di astrazione, consentendoti di controllare minuziosamente le condizioni di riscatto dei fondi Bitcoin. Ma come puoi effettivamente incorporare questi script Bitcoin nelle transazioni che hai costruito fino ad oggi? La risposta è un nuovo tipo di transazione Bitcoin, la P2SH. + +## Obiettivi di questo capitolo + +Dopo aver letto questo capitolo, uno sviluppatore sarà in grado di: + + * Progettare una transazione P2SH + * Applicare uno script Bitcoin P2SH + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere lo script P2SH + * Comprendere lo script Multisig + * Comprendere le diverse variazioni Segwit degli script + * Comprendere come spendere i fondi inviati a un P2SH + +## Sommario + +* [Capitolo 10.1: Comprendere la Base di P2SH](10_1_Comprendere_la_Base_di_P2SH.md) +* [Capitolo 10.2: Construire la Struttura di P2SH](10_2_Construire_la_Struttura_di_P2SH.md) +* [Capitolo 10.3: Eseguire un Script Bitcoin con P2SH](10_3_Eseguire_un_Script_Bitcoin_con_P2SH.md) +* [Capitolo 10.4: Programmare una Multifirma](10_4_Programmare_una_Multifirma.md) +* [Capitolo 10.5: Programmare uno Script Segwit](10_5_Programmare_uno_Script_Segwit.md) +* [Capitolo 10.6: Spendere una Transazione P2SH](10_6_Spendere_una_Transazione_P2SH.md) diff --git a/it/10_1_Comprendere_la_Base_di_P2SH.md b/it/10_1_Comprendere_la_Base_di_P2SH.md new file mode 100644 index 000000000..d1290b2a6 --- /dev/null +++ b/it/10_1_Comprendere_la_Base_di_P2SH.md @@ -0,0 +1,99 @@ +# 10.1: Comprendere le Basi di P2SH + +Sai che gli Script di Bitcoin possono essere utilizzati per controllare il riscatto degli UTXO. Il prossimo passo è creare i tuoi Script... ma ciò richiede una tecnica molto specifica. + +## Conoscere gli Standard di Bitcoin + +Ecco la questione per l'uso degli Script di Bitcoin: per motivi di sicurezza, la maggior parte dei nodi Bitcoin accetterà solo sei tipi di transazioni Bitcoin "standard". + +* __Pay to Public Key (P2PK)__ — Una transazione più vecchia, deprecata (` OP_CHECKSIG`) che è stata sostituita dalla maggiore sicurezza di P2PKH. +* __Pay to Public Key Hash (P2PKH)__ — Una transazione standard (`OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG`) che paga l'hash di una chiave pubblica. +* __Pay to Witness Public Key hash (P2WPKH)__ — Il più recente tipo di transazione a chiave pubblica. È semplicemente (`OP_0 `) perché dipende dal consenso dei minatori per funzionare, come descritto nel [Capitolo 9.5](09_5_Programmare_una_P2WPKH.md). +* __Multisig__ — Una transazione per un gruppo di chiavi, come spiegato più dettagliatamente nel [Capitolo 10.4](10_4_Programmare_una_Multifirma.md). +* __Null Data__ — Una transazione non spendibile (`OP_RETURN Data`). +* __Pay to Script Hash (P2SH)__ — Una transazione che paga a uno script specifico, come spiegato più dettagliatamente qui. + +Quindi come si scrive uno Script Bitcoin più complesso? La risposta è in quell'ultimo tipo di transazione standard, il P2SH. Puoi inserire qualsiasi tipo di script lungo e complesso in una transazione P2SH, e finché segui le regole standard per incorporare il tuo script e per riscattare i fondi, otterrai tutti i benefici degli Script Bitcoin. + +> :warning: **AVVISO SULLA VERSIONE:** Gli script P2SH arbitrari sono diventati standard solo a partire da Bitcoin Core 0.10.0. Prima di allora, erano consentiti solo i P2SH Multisig. + +## Comprendere lo Script P2SH + +Hai già visto una transazione P2SH quando hai creato un multisig nel [Capitolo 6.1: Inviare una Transazione a un Indirizzo Multifirma](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md). Sebbene il multisig sia uno dei tipi di transazione standard, `bitcoin-cli` semplifica l'uso dei suoi multisig incorporandoli in transazioni P2SH, come descritto più dettagliatamente nel [Capitolo 10.4: Programmare una Multifirma](10_4_Programmare_una_Multifirma.md). + +Quindi, guardiamo ancora una volta lo `scriptPubKey` di quel multisig P2SH: +``` + "scriptPubKey": { + "asm": "OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL", + "hex": "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr" + ] + } +``` + Lo script di blocco è piuttosto semplice: `OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL`. Come al solito, c'è un grosso pezzo di dati nel mezzo. Questo è un hash di un altro script di blocco nascosto (`redeemScript`) che sarà rivelato solo quando i fondi saranno riscattati. In altre parole, lo script di blocco standard per un indirizzo P2SH è: `OP_HASH160 OP_EQUAL`. + +> :book: ***Cos'è un redeemScript?*** Ogni transazione P2SH porta con sé l'impronta di uno script di blocco nascosto sotto forma di un hash di 20 byte. Quando una transazione P2SH viene riscattata, il `redeemScript` completo (non hashato) è incluso come parte del `scriptSig`. Bitcoin verificherà che il `redeemScript` corrisponda all'hash; poi eseguirà effettivamente il `redeemScript` per vedere se i fondi possono essere spesi (o no). + +Uno degli elementi interessanti delle transazioni P2SH è che né il mittente né la Blockchain sanno effettivamente cosa sia il `redeemScript`! Un mittente invia semplicemente a un indirizzo P2SH standardizzato contrassegnato con un prefisso "2" e non si preoccupa di come il destinatario recupererà i fondi alla fine. + +> :link: **TESTNET vs MAINNET:** su testnet, il prefisso per gli indirizzi P2SH è `2`, mentre su mainnet è `3`. + +## Comprendere Come Costruire uno Script P2SH + +Poiché lo script di blocco visibile per una transazione P2SH è così semplice, creare una transazione di questo tipo è piuttosto semplice anche. In teoria. Tutto quello che devi fare è creare una transazione il cui script di blocco includa un hash di 20 byte del `redeemScript`. Questo hashing viene effettuato con il `OP_HASH160` standard di Bitcoin. + +> :book: ***Cos'è OP_HASH160?*** L'operazione hash standard per Bitcoin esegue un hash SHA-256, poi un hash RIPEMD-160. + +In generale, sono necessari quattro passaggi: + +1. Crea uno script di blocco arbitrario con Bitcoin Script. +2. Crea una versione serializzata di quello script di blocco. +3. Esegui un hash SHA-256 su quei byte serializzati. +4. Esegui un hash RIPEMD-160 sui risultati di quell'hash SHA-256. + +Ciascuno di questi passaggi ovviamente richiede del lavoro a sé, e alcuni di essi possono essere piuttosto intricati. La buona notizia è che non devi davvero preoccuparti di essi, perché sono sufficientemente complessi da far sì che di solito un'API si occupi di tutto per te. + +Quindi, per ora, ti forniremo solo una panoramica, in modo che tu possa comprendere la metodologia generale. In [Capitolo 10.2: Construire la Struttura di P2SH](10_2_Construire_la_Struttura_di_P2SH.md) forniremo uno sguardo più approfondito alla creazione di script, nel caso tu voglia mai capire i dettagli di questo processo. + +## Comprendere Come Inviare una Transazione Script P2SH + +Quindi, come invii effettivamente la tua transazione P2SH? Di nuovo, la teoria è molto semplice: + +1. Incorpora il tuo hash in uno script `OP_HASH160 OP_EQUAL`. +2. Traduci questo in codice esadecimale. +3. Usa quel codice esadecimale come tuo `scriptPubKey`. +4. Crea il resto della transazione. + +Purtroppo, questo è un altro caso in cui dovrai fare affidamento sulle API, in gran parte perché `bitcoin-cli` non fornisce alcun supporto per la creazione di transazioni P2SH. (Può riscattarle senza problemi.) + +## Comprendere Come Sbloccare una Transazione Script P2SH + +Il trucco per riscattare una transazione P2SH è che il destinatario deve aver salvato lo script di blocco serializzato segreto che è stato hashato per creare l'indirizzo P2SH. Questo è chiamato `redeemScript` perché è ciò che il destinatario deve avere per riscattare i suoi fondi. + +Uno `scriptSig` di sblocco per una transazione P2SH è formato come: `... dati ... `. I `dati` devono essere _solamente_ dati che vengono spinti nello stack, non operatori. ([BIP 16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki) li chiama firme, ma non è un requisito reale.) + +> :warning: **AVVERTENZA:** Sebbene le firme non siano un requisito, uno script P2SH in realtà non è molto sicuro se non richiede almeno una firma nei suoi input. I motivi di ciò sono descritti in [§13.1: Scrivere Script Enigmi](13_1_Writing_Puzzle_Scripts.md). + +Quando un UTXO viene riscattato, viene eseguito in due round di verifica: + +1. Innanzitutto, il `redeemScript` nel `scriptSig` viene hashato e confrontato con lo script hashato nel `scriptPubKey`. +2. Se corrispondono, inizia un secondo round di verifica. +3. In secondo luogo, il `redeemScript` viene eseguito utilizzando i dati precedenti che sono stati spinti nello stack. +4. Se anche quel secondo round di verifica ha successo, l'UTXO viene sbloccato. + +Mentre non puoi facilmente creare una transazione P2SH senza un'API, dovresti essere in grado di riscattare facilmente una transazione P2SH con `bitcoin-cli`. In effetti, lo hai già fatto in [Capiotolo 6.2:Spendere una Transazione con un Indirizzo Multifirma](06_2_Spendere_una_Transazione_con_un_Indirizzo_Multifirma.md). Il processo esatto è descritto nel [Capitolo 10.6: Spendere una Transazione P2SH](10_6_Spendere_una_Transazione_P2SH.md), dopo che avremo finito con tutte le complessità della creazione di transazioni P2SH. + +> :warning: **AVVISO:** Puoi creare una transazione perfettamente valida con un redeemScript hashato correttamente, ma se il redeemScript non viene eseguito, o non viene eseguito correttamente, i tuoi fondi sono persi per sempre. Ecco perché è così importante testare i tuoi Script, come discusso nel [Capitlo 9.3: Provare uno Script Bitcoin](09_3_Provare_uno_Script_Bitcoin.md). + +## Riepilogo: Comprendere le Basi di P2SH + +Gli Script Bitcoin arbitrari non sono standard in Bitcoin. Tuttavia, puoi incorporarli in transazioni standard utilizzando il tipo di indirizzo P2SH. Basta hashare il tuo script come parte dello script di blocco, poi rivelarlo ed eseguirlo come parte dello script di sblocco. Finché puoi anche soddisfare il `redeemScript`, l'UTXO può essere speso. + +> :fire: ***Qual è il potere di P2SH?*** Conosci già il potere dello Script Bitcoin, che ti consente di creare contratti intelligenti più complessi di ogni tipo. P2SH è ciò che sblocca effettivamente quel potere permettendoti di includere Script Bitcoin arbitrari nelle transazioni Bitcoin standard. + +## Cosa Succede Dopo? + +Continua a "Incorporare gli Script Bitcoin" col [Capitolo 10.2: Construire la Struttura di P2SH](10_2_Construire_la_Struttura_di_P2SH.md). diff --git a/it/10_2_Construire_la_Struttura_di_P2SH.md b/it/10_2_Construire_la_Struttura_di_P2SH.md new file mode 100644 index 000000000..856d35dbb --- /dev/null +++ b/it/10_2_Construire_la_Struttura_di_P2SH.md @@ -0,0 +1,194 @@ +# 10.2: Costruire la Struttura di P2SH + +Nella sezione precedente abbiamo presentato la teoria su come creare transazioni P2SH per contenere Script Bitcoin. La pratica effettiva è _molto più difficile_, ma per completezza, la esamineremo qui. Probabilmente non è qualcosa che faresti mai senza un'API, quindi se diventa troppo intimidatorio, sappi che torneremo a Script di alto livello tra un momento. + +## Creare uno Script di Blocco + +Qualsiasi transazione P2SH inizia con uno script di blocco. Questo è l'argomento dei capitoli 9 e 11-12. Puoi usare uno qualsiasi dei metodi di Bitcoin Script descritti in quei capitoli per creare qualsiasi tipo di script di blocco, purché il `redeemScript` serializzato risultante sia di 520 byte o meno. + +> :book: ***Perché gli script P2SH sono limitati a 520 byte?*** Come per molte cose in Bitcoin, la risposta è la retrocompatibilità: la nuova funzionalità deve essere costantemente costruita entro i vecchi vincoli del sistema. In questo caso, 520 byte è il massimo che può essere spinto nello stack in una volta. Poiché l'intero redeemScript viene spinto nello stack come parte del processo di riscatto, raggiunge quel limite. + +## Serializzare uno Script di Blocco nel Modo Difficile + +Dopo aver creato uno script di blocco, devi serializzarlo prima che possa essere inserito in Bitcoin. Questo è un processo in due parti. Prima devi trasformarlo in codice esadecimale, poi devi trasformare quel codice esadecimale in binario. + +### Creare il Codice Esadecimale + +Creare il codice esadecimale necessario per serializzare uno script è sia una semplice traduzione sia qualcosa di abbastanza complesso da andare oltre qualsiasi script shell che probabilmente scriverai. Questo passaggio è uno dei motivi principali per cui hai bisogno di un'API per creare transazioni P2SH. + +Crei il codice esadecimale passando attraverso il tuo script di blocco e trasformando ciascun elemento in un comando esadecimale di un byte, eventualmente seguito da dati aggiuntivi, secondo la guida alla [pagina del Bitcoin Wiki Script](https://en.bitcoin.it/wiki/Script): + +* Gli operatori sono tradotti nel byte corrispondente per quell'opcode +* Le costanti 1-16 sono tradotte negli opcode 0x51 a 0x61 (OP_1 a OP_16) +* La costante -1 è tradotta nell'opcode 0x4f (OP_1NEGATE) +* Altre costanti sono precedute dagli opcode 0x01 a 0x4e (OP_PUSHDATA, con il numero che specifica quanti byte spingere) + * Gli interi sono tradotti in esadecimale usando la notazione a segno e magnitudine a little-endian + +### Tradurre gli Interi + +Gli interi sono la parte più problematica della traduzione di uno script di blocco. + +Per prima cosa, dovresti verificare che il tuo numero rientri tra -2147483647 e 2147483647, l'intervallo degli interi a quattro byte quando il byte più significativo è usato per la firma. + +In secondo luogo, devi tradurre il valore decimale in esadecimale e riempirlo fino a ottenere un numero pari di cifre. Questo può essere fatto con il comando `printf`: + +``` +$ integer=1546288031 +$ hex=$(printf '%08x\n' $integer | sed 's/^\(00\)*//') +$ echo $hex +5c2a7b9f +``` +In terzo luogo, devi aggiungere un byte aggiuntivo di `00` se la cifra superiore è "8" o maggiore, in modo che il numero non sia interpretato come negativo. + +``` +$ hexfirst=$(echo $hex | cut -c1) +$ [[ 0x$hexfirst -gt 0x7 ]] && hex="00"$hex +``` +In quarto luogo, devi tradurre l'esadecimale da big-endian (byte meno significativo per ultimo) a little-endian (byte meno significativo per primo). Puoi fare questo con il comando `tac`: + +``` +$ lehex=$(echo $hex | tac -rs .. | echo "$(tr -d '\n')") +$ echo $lehex +9f7b2a5c +``` +Inoltre, devi sempre conoscere la dimensione di qualsiasi dato che metti nello stack, in modo da poterlo precedere con l'opcode corretto. Puoi semplicemente ricordare che ogni due caratteri esadecimali è un byte. Oppure, puoi usare `echo -n` pipato a `wc -c`, e dividere per due: + +``` +$ echo -n $lehex | wc -c | awk '{print $1/2}' +4 +``` +Con tutta questa trafila, sapresti che potresti tradurre l'intero 1546288031 in un opcode `04` (per spingere quattro byte nello stack) seguito da `9f7b2a5c` (la rappresentazione esadecimale a little-endian di 1546288031). + +Se invece avessi un numero negativo, dovresti (1) fare i tuoi calcoli sul valore assoluto del numero, poi (2) fare un or bit a 0x80 sul tuo risultato finale a little-endian. Ad esempio, `9f7b2a5c`, che è 1546288031, diventerebbe `9f7b2adc`, che è -1546288031: + +``` +$ neglehex=$(printf '%x\n' $((0x$lehex | 0x80))) +$ echo $neglehex +9f7b2adc +``` +### Trasformare l'Esadecimale in Binario + +Per completare la tua serializzazione, devi tradurre il codice esadecimale in binario. Da riga di comando, questo richiede solo una semplice invocazione di `xxd -r -p`. Tuttavia, probabilmente vorrai farlo come parte di una singola pipe che hasherà anche lo script... + +## Eseguire lo Script di Conversione degli Interi + +Uno script completo per cambiare un intero tra -2147483647 e 2147483647 in una rappresentazione a segno e magnitudine a little-endian in esadecimale può essere trovato nella [directory del codice sorgente](src/10_2_integer2lehex.sh). Puoi scaricarlo come `integer2lehex.sh`. + +> :warning: **AVVERTENZA:** Questo script non è stato controllato in modo robusto. Se hai intenzione di usarlo per creare veri script di blocco dovresti assicurarti di ricontrollare e testare i tuoi risultati. + +Assicurati che i permessi sullo script siano corretti: + +``` +$ chmod 755 integer2lehex.sh +``` +Puoi quindi eseguire lo script come segue: +``` +$ ./integer2lehex.sh 1546288031 +Integer: 1546288031 +LE Hex: 9f7b2a5c +Length: 4 bytes +Hexcode: 049f7b2a5c + +$ ./integer2lehex.sh -1546288031 +Integer: -1546288031 +LE Hex: 9f7b2adc +Length: 4 bytes +Hexcode: 049f7b2adc +``` + + +## Analizzare un Multisig P2SH + +Per capire meglio questo processo, esamineremo il multisig P2SH che abbiamo creato in [Capitolo 6.1: Inviare una Transazione a un IndirizzoMultifirma](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md). Dai un'occhiata al `redeemScript` che hai usato, che ora sai essere la versione esadecimale serializzata dello script di blocco: + +``` +522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae +``` +Puoi tradurlo di nuovo in Script manualmente usando la [pagina del Bitcoin Wiki Script](https://en.bitcoin.it/wiki/Script) come riferimento. Basta guardare un byte (due caratteri esadecimali) di dati alla volta, a meno che non ti venga detto di guardare di più da un comando OP_PUSHDATA (un opcode nell'intervallo da 0x01 a 0x4e). + +L'intero script si scomporrà come segue: + +``` +52 / 21 / 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 / 21 / 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 / 52 / ae +``` +Ecco cosa significano le singole parti: + +* 0x52 = OP_2 +* 0x21 = OP_PUSHDATA 33 bytes (hex: 0x21) +* 0x02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 = i prossimi 33 byte (public-key hash) +* 0x21 = OP_PUSHDATA 33 bytes (hex: 0x21) +* 0x02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 = i prossimi 33 byte (public-key hash) +* 0x52 = OP_2 +* 0xae = OP_CHECKMULTISIG + +In altre parole, quel `redeemScript` era una traduzione di `2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG`. Torneremo su questo script nel [Capitolo 10.4:Scripting a Multisig](10_4_Scripting_a_Multisig.md) quando dettaglieremo esattamente come funzionano i multisig all'interno del paradigma P2SH. + +Se desideri un aiuto meccanico con questo tipo di traduzione in futuro, puoi usare `bitcoin-cli decodescript`: + +``` +$ bitcoin-cli -named decodescript hexstring=522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae +{ + "asm": "2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG", + "reqSigs": 2, + "type": "multisig", + "addresses": [ + "mmC2x2FoYwBnVHMPRUAzPYg6WDA31F1ot2", + "mhwZFJUnWqTqy4Y7pXVum88qFtUnVG1keM" + ], + "p2sh": "2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr", + "segwit": { + "asm": "0 6fe9f451ccedb8e4090b822dcad973d0388a37b4c89fd1aed485110adecab2a9", + "hex": "00206fe9f451ccedb8e4090b822dcad973d0388a37b4c89fd1aed485110adecab2a9", + "reqSigs": 1, + "type": "witness_v0_scripthash", + "addresses": [ + "tb1qdl5lg5wvakuwgzgtsgku4ktn6qug5da5ez0artk5s5gs4hk2k25szvjky9" + ], + "p2sh-segwit": "2NByn92W1vH5oQC1daY69F5sU7PEStKKQBR" + } +} +``` +È particolarmente utile per controllare il tuo lavoro quando stai serializzando. + +## Serializzare uno Script di Blocco nel Modo Facile + +Quando hai installato `btcdeb` nel [Capitolo 9.3](09_3_Provare_uno_Script_Bitcoin.md) hai anche installato `btcc` che può essere usato per serializzare gli script Bitcoin: + +``` +$ btcc 2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG +warning: ambiguous input 2 is interpreted as a numeric value; use OP_2 to force into opcode +warning: ambiguous input 2 is interpreted as a numeric value; use OP_2 to force into opcode +522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae +``` +È molto più facile che capirlo a mano! + +Considera anche il [Transaction Script Compiler](https://github.com/Kefkius/txsc) di Python, che traduce avanti e indietro. + +## Hashare uno Script Serializzato + +Dopo aver creato uno script di blocco e serializzato, il terzo passaggio nella creazione di una transazione P2SH è hashare lo script di blocco. Come notato in precedenza, un hash OP_HASH160 di 20 byte è creato attraverso una combinazione di un hash SHA-256 e un hash RIPEMD-160. Hashare uno script serializzato richiede quindi due comandi: `openssl dgst -sha256 -binary` esegue l'hash SHA-256 e produce un binario da inviare tramite pipe, poi `openssl dgst -rmd160` prende quel flusso binario, esegue un hash RIPEMD-160 e infine produce un codice esadecimale leggibile. + +Ecco l'intera pipe, inclusa la precedente trasformazione dello script serializzato esadecimale in binario: + +``` +$ redeemScript="522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae" +$ echo -n $redeemScript | xxd -r -p | openssl dgst -sha256 -binary | openssl dgst -rmd160 +(stdin)= a5d106eb8ee51b23cf60d8bd98bc285695f233f3 +``` +## Creare una Transazione P2SH + +Creare il tuo hash di 20 byte ti dà solo l'hash al centro di uno script di blocco P2SH. Devi ancora metterlo insieme agli altri opcode che creano una transazione P2SH standard: `OP_HASH160 a5d106eb8ee51b23cf60d8bd98bc285695f233f3 OP_EQUAL`. + +A seconda della tua API, potresti essere in grado di inserire questo come un `scriptPubKey` in stile `asm` per la tua transazione, oppure potresti doverlo tradurre anche in codice `hex`. Se devi tradurre, usa gli stessi metodi descritti sopra per "Creare il Codice Esadecimale" (oppure usa `btcc`), risultando in `a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387`. + +Nota che il `scriptPubKey` esadecimale per una transazione Script P2SH inizierà _sempre_ con un `a914`, che è l'`OP_HASH160` seguito da un `OP_PUSHDATA` di 20 byte (hex: `0x14`); e terminerà _sempre_ con un `87`, che è un `OP_EQUAL`. Quindi tutto ciò che devi fare è mettere il tuo redeem script hashato tra quei numeri. + +## Riepilogo: Costruire la Struttura di P2SH + +Creare effettivamente lo script di blocco P2SH ti porta più a fondo nel cuore di Bitcoin di quanto tu abbia mai fatto prima. Sebbene sia utile sapere come funziona tutto questo a un livello molto basso, è molto probabile che avrai un'API che si occuperà di tutto il lavoro pesante per te. Il tuo compito sarà semplicemente creare il Bitcoin Script per fare il blocco... che è l'argomento principale dei capitoli 9 e 11-12. + +## Cosa c'è Dopo? + +Continua "Incorporare Bitcoin Scripts" con [Capitolo 10.3: Eseguire uno Script Bitcoin con P2SH](10_3_Eseguire_uno_Script_Bitcoin_con_P2SH.md). + + diff --git a/it/10_3_Eseguire_uno_Script_Bitcoin_con_P2SH.md b/it/10_3_Eseguire_uno_Script_Bitcoin_con_P2SH.md new file mode 100644 index 000000000..353bcd514 --- /dev/null +++ b/it/10_3_Eseguire_uno_Script_Bitcoin_con_P2SH.md @@ -0,0 +1,104 @@ +# 10.3: Eseguire uno Script Bitcoin con P2SH + +Ora che conosci la teoria e la pratica dietro gli indirizzi P2SH, sei pronto a trasformare uno Script Bitcoin non standard in una transazione effettiva. Riutilizzeremo lo script di blocco semplice da [Capitolo 9.2: Eseguire uno Script di Bitcoin](09_2_Eseguire_uno_Script_di_Bitcoin.md), `OP_ADD 99 OP_EQUAL`. + +## Creare una Transazione P2SH + +Per bloccare una transazione con questo Script, fai quanto segue: + +1. Serializzare `OP_ADD 99 OP_EQUAL`: + 1. OP_ADD = 0x93 — una semplice traduzione dell'opcode + 2. 99 = 0x01, 0x63 — questo opcode spinge un byte nello stack, 99 (hex: 0x63) + * Nessuna preoccupazione per la conversione endian poiché è solo un byte + 3. OP_EQUAL = 0x87 — una semplice traduzione dell'opcode + 4. `` = "93016387" + + + +``` +$ btcc OP_ADD 99 OP_EQUAL +93016387 +``` + + +2. Salva `` per riferimento futuro come `redeemScript`. + 1. `` = "93016387" +3. Esegui l'hash SHA-256 e RIPEMD-160 dello script serializzato. + 1. `` = "3f58b4f7b14847a9083694b9b3b52a4cea2569ed" +4. Produci uno script di blocco P2SH che includa il ``. + 1. `scriptPubKey` = "a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87" + +Puoi quindi creare una transazione usando questo `scriptPubKey`, probabilmente tramite un'API. + +## Sbloccare la Transazione P2SH + +Per sbloccare questa transazione è necessario che il destinatario produca un `scriptSig` che premetta due costanti per un totale di novantanove allo script serializzato: `1 98 `. + +### Eseguire il Primo Ciclo di Validazione + +Il processo di sblocco della transazione P2SH inizia con un primo ciclo di validazione, che verifica che il redeem script corrisponda al valore hashato nello script di blocco. + +Concatena `scriptSig` e `scriptPubKey` ed eseguili, come di consueto: + +``` +Script: 1 98 OP_HASH160 OP_EQUAL +Stack: [] + +Script: 98 OP_HASH160 OP_EQUAL +Stack: [ 1 ] + +Script: OP_HASH160 OP_EQUAL +Stack: [ 1 98 ] + +Script: OP_HASH160 OP_EQUAL +Stack: [ 1 98 ] + +Script: OP_EQUAL +Running: OP_HASH160 +Stack: [ 1 98 ] + +Script: OP_EQUAL +Stack: [ 1 98 ] + +Script: +Running: OP_EQUAL +Stack: [ 1 98 True ] +``` +Lo Script termina con un `True` in cima allo stack, quindi ha successo... anche se ci sono altre informazioni inutili sotto. + +Tuttavia, poiché questo era uno script P2SH, l'esecuzione non è finita. + +### Eseguire il Secondo Ciclo di Validazione + +Per il secondo ciclo di validazione, verifica che i valori nello script di sblocco soddisfino il `redeemScript`: deserializza il `redeemScript` ("93016387" = "OP_ADD 99 OP_EQUAL"), quindi eseguilo usando gli elementi nel `scriptSig` prima dello script serializzato: + +``` +Script: 1 98 OP_ADD 99 OP_EQUAL +Stack: [ ] + +Script: 98 OP_ADD 99 OP_EQUAL +Stack: [ 1 ] + +Script: OP_ADD 99 OP_EQUAL +Stack: [ 1 98 ] + +Script: 99 OP_EQUAL +Running: 1 98 OP_ADD +Stack: [ 99 ] + +Script: OP_EQUAL +Stack: [ 99 99 ] + +Script: +Running: 99 99 OP_EQUAL +Stack: [ True ] +``` +Con quella seconda validazione _anche_ vera, il UTXO può ora essere speso! + +## Riepilogo: Costruire uno Script Bitcoin con P2SH + +Una volta che conosci la tecnica per costruire P2SH, qualsiasi Script può essere incorporato in una transazione Bitcoin; e una volta che comprendi la tecnica di validazione dei P2SH, è facile eseguire gli script in due cicli. + +## Cosa c'è Dopo? + +Continua a "Incorporare Bitcoin Scripts" col [Capitolo 10.4 Programmare una Multifirma](10_4_Programmare_una_Multifirma.md). diff --git a/it/10_4_Programmare_una_Multifirma.md b/it/10_4_Programmare_una_Multifirma.md new file mode 100644 index 000000000..dd01eafc3 --- /dev/null +++ b/it/10_4_Programmare_una_Multifirma.md @@ -0,0 +1,153 @@ +# 10.4: Scripting di un Multisig + +Prima di concludere questa introduzione agli script P2SH, vale la pena esaminare un esempio più realistico. Fin dal [Capitolo 6.1](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md), abbiamo detto casualmente che l'interfaccia `bitcoin-cli` avvolge la sua transazione multisig in una transazione P2SH. In effetti, questa è la metodologia standard per creare multisig sulla Blockchain. Ecco come funziona, in dettaglio. + +## Comprendere il Codice Multisig + +Le transazioni multisig sono create in Bitcoin usando il codice `OP_CHECKMULTISIG`. `OP_CHECKMULTISIG` si aspetta una lunga stringa di argomenti che assomiglia a questa: `0 ... sigs ... ... addresses ... OP_CHECKMULTISIG`. Quando `OP_CHECKMULTISIG` viene eseguito, fa quanto segue: + +1. Estrae il primo valore dallo stack (``). +2. Estrae "n" valori dallo stack come indirizzi Bitcoin (chiavi pubbliche hashate). +3. Estrae il valore successivo dallo stack (``). +4. Estrae "m" valori dallo stack come potenziali firme. +5. Estrae uno `0` dallo stack a causa di un errore nella codifica originale. +6. Confronta le firme con gli indirizzi Bitcoin. +7. Spinge un `True` o `False` a seconda del risultato. + +Gli operandi di `OP_MULTISIG` sono tipicamente divisi, con lo `0` e le firme provenienti dallo script di sblocco e "m", "n" e gli indirizzi dettagliati dallo script di blocco. + +Il requisito di quello `0` come primo operando per `OP_CHECKMULTISIG` è una regola di consenso. Poiché la versione originale di `OP_CHECKMULTISIG` ha accidentalmente estratto un elemento in più dallo stack, Bitcoin deve seguire per sempre quello standard, altrimenti gli script di riscatto complessi di quel periodo rischiano di essere rotti, rendendo i vecchi fondi irrecuperabili. + +> :book: ***Cos'è una regola di consenso?*** Queste sono le regole che i nodi Bitcoin seguono per lavorare insieme. In gran parte sono definite dal codice di Bitcoin Core. Queste regole includono molti mandati ovvi, come il limite a quanti Bitcoin sono creati per ogni blocco e le regole su come le transazioni possono essere rispese. Tuttavia, includono anche correzioni per bug che sono apparsi nel corso degli anni, perché una volta che un bug è stato introdotto nel codice di Bitcoin, deve essere continuamente supportato, altrimenti i vecchi Bitcoin diventano non spendibili. + +## Creare un Multisig Raw + +Come discusso nel [Capitolo 10.1: Comprendere la Base di P2SH](10_1_Comprendere_la_Base_di_P2SH.md), i multisig sono uno dei tipi di transazione standard di Bitcoin. Una transazione può essere creata con uno script di blocco che usa il comando raw `OP_CHECKMULTISIG`, e sarà accettata in un blocco. Questa è la metodologia classica per usare i multisig in Bitcoin. + +Come esempio, rivisiteremo il multisig creato nel [Capitolo 6.1](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md) un'ultima volta e costruiremo un nuovo script di blocco per esso usando questa metodologia. Come forse ricorderai, quello era un multisig 2-di-2 costruito da `$address1` e `$address2`. + +Poiché lo script di blocco `OP_CHECKMULTISIG` richiede "m" (`2`), gli indirizzi e "n" (`2`), potresti scrivere il seguente `scriptPubKey`: +``` +2 $address1 $address2 2 OP_CHECKMULTISIG +``` +Se questo ti sembra familiare, è perché è il multisig che hai deserializzato nel [Capitolo 10.2: Construire la Struttura di P2SH](10_2_Construire_la_Struttura_di_P2SH.md). +``` +2 02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3 2 OP_CHECKMULTISIG +``` + + +> **AVVISO:** Per le firme `OP_CHECKMULTISIG` classiche, "n" deve essere ≤ 3 affinché la transazione sia standard. + +## Sbloccare un Multisig Raw + +Lo `scriptSig` per un indirizzo multisig standard deve quindi fornire gli operandi mancanti per `OP_CHECKMULTISIG`: uno `0` seguito da "m" firme. Ad esempio: +: +``` +0 $signature1 $signature2 +``` + + +### Eseguire uno Script Multisig Raw + +Per spendere un UTXO multisig, esegui lo `scriptSig` e lo `scriptPubKey` come segue: + +``` +Script: 0 $signature1 $signature2 2 $address1 $address2 2 OP_CHECKMULTISIG +Stack: [ ] +``` +Prima, metti tutte le costanti nello stack: +``` +Script: OP_CHECKMULTISIG +Stack: [ 0 $signature1 $signature2 2 $address1 $address2 2 ] +``` +Poi, l'`OP_CHECKMULTISIG` inizia a funzionare. Prima, viene estratto il "2": +``` +Running: OP_CHECKMULTISIG +Stack: [ 0 $signature1 $signature2 2 $address1 $address2 ] +``` +Poi, il "2" dice a `OP_CHECKMULTISIG` di estrarre due indirizzi: +``` +Running: OP_CHECKMULTISIG +Stack: [ 0 $signature1 $signature2 2 ] +``` +Poi, viene estratto il prossimo "2": +``` +Running: OP_CHECKMULTISIG +Stack: [ 0 $signature1 $signature2 ] +``` +Poi, il "2" dice a `OP_CHECKMULTISIG` di estrarre due firme: +``` +Running: OP_CHECKMULTISIG +Stack: [ 0 ] +``` +Poi, un altro elemento viene erroneamente estratto: +``` +Running: OP_CHECKMULTISIG +Stack: [ ] +``` +Poi, `OP_CHECKMULTISIG` completa la sua operazione confrontando le "m" firme con gli indirizzi "n": +``` +Script: +Stack: [ True ] +``` +## Comprendere i Limiti degli Script Multisig Raw + +Sfortunatamente, la tecnica di incorporare un multisig raw in una transazione ha alcuni svantaggi notevoli: + +1. Poiché non esiste un formato di indirizzo standard per i multisig, ogni mittente deve: inserire uno script multisig lungo e ingombrante; avere un software che lo consenta; e essere affidabile per non sbagliare. +2. Poiché i multisig possono essere molto più lunghi degli script di blocco tipici, la blockchain incorre in maggiori costi. Questo richiede commissioni di transazione più elevate da parte del mittente e crea più fastidi per ogni nodo. + +Questi erano generalmente problemi con qualsiasi tipo di script Bitcoin complesso, ma sono diventati rapidamente problemi molto reali quando applicati ai multisig, che erano alcuni dei primi script complessi ad essere ampiamente utilizzati sulla rete Bitcoin. Le transazioni P2SH sono state create per risolvere questi problemi, a partire dal 2012. + +> :book: ***Cos'è un multisig P2SH?*** I multisig P2SH sono la prima implementazione delle transazioni P2SH. Semplicemente confezionano una transazione multisig standard in una transazione P2SH standard. Questo consente la standardizzazione degli indirizzi; riduce lo spazio di archiviazione dei dati; e aumenta i conteggi di "m" e "n". + +## Creare un Multisig P2SH + +I multisig P2SH sono la metodologia moderna per creare multisig sulla Blockchain. Possono essere creati molto semplicemente, usando lo stesso processo visto nelle sezioni precedenti. + +### Creare il Blocco per il Multisig P2SH + +Per creare un multisig P2SH, segui i passaggi standard per creare uno script di blocco P2SH: + +1. Serializzare `2 $address1 $address2 2 OP_CHECKMULTISIG`. + 1. `` = "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae" +2. Salva `` per riferimento futuro come redeemScript. + 1. `` = "522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae" +3. Esegui l'hash SHA-256 e RIPEMD-160 dello script serializzato. + 1. `` = "a5d106eb8ee51b23cf60d8bd98bc285695f233f3" +4. Produci uno script di blocco Multisig P2SH che includa lo script hashato (`OP_HASH160 OP_EQUAL`). + 1. `scriptPubKey` = "a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387" + +Puoi quindi creare una transazione usando quel `scriptPubKey`. + +## Sbloccare il Multisig P2SH + +Per sbloccare questa transazione multisig è necessario che il destinatario produca uno scriptSig che includa le due firme e il `redeemScript`. + +### Eseguire il Primo Ciclo di Validazione P2SH + +Per sbloccare il multisig P2SH, conferma prima lo script: + +1. Produci uno script di sblocco di `0 $signature1 $signature2 `. +2. Concatenalo con lo script di blocco di `OP_HASH160 OP_EQUAL`. +3. Valida `0 $signature1 $signature2 OP_HASH160 OP_EQUAL`. +4. Ha successo se il `` corrisponde al ``. + +### Eseguire il Secondo Ciclo di Validazione P2SH + +Poi, esegui lo script multisig: + +1. Deserializza `` in `2 $address1 $address2 2 OP_CHECKMULTISIG`. +2. Concatenalo con gli operandi precedenti nello script di sblocco, `0 $signature1 $signature2`. +3. Valida `0 $signature1 $signature2 2 $address1 $address2 2 OP_CHECKMULTISIG`. +4. Ha successo se gli operandi soddisfano il `redeemScript` deserializzato. + +Ora sai come la transazione multisig nel [Capitolo 6.1](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md) è stata effettivamente creata, come è stata validata per la spesa e perché quel `redeemScript` era così importante. + +## Riepilogo: Creare Script Multisig + +I multisig sono un tipo di transazione standard, ma sono un po' ingombranti da usare, quindi sono regolarmente incorporati in transazioni P2SH, come nel caso del [Capitolo 6.1](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md) quando abbiamo creato i nostri primi multisig. Il risultato è più pulito, più piccolo e più standardizzato — ma più importante, è un ottimo esempio reale di come funzionano veramente gli script P2SH. + +## Cosa c'è Dopo? + +Continua "Incorporare Bitcoin Scripts" con [Capitolo 10.5: Programmare uno Script Segwit](10_5_Programmare_uno_Script_Segwit.md) diff --git a/it/10_5_Programmare_uno_Script_Segwit.md b/it/10_5_Programmare_uno_Script_Segwit.md new file mode 100644 index 000000000..83f6bb7c7 --- /dev/null +++ b/it/10_5_Programmare_uno_Script_Segwit.md @@ -0,0 +1,134 @@ +# 10.5: Programmare uno script Segwit + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Segwit ha introdotto una serie di nuove opzioni per i tipi di indirizzi (e quindi di script). [Capitolo 9.5: Programmare una P2WPKH](09_5_Programmare_una_P2WPKH.md) ha spiegato come il nuovo tipo di indirizzo Bech32 abbia variato gli script standard trovati nella maggior parte delle transazioni tradizionali. Questo capitolo esamina gli altri tre tipi di script introdotti dall'aggiornamento Segwit: il P2SH-Segwit (che era l'indirizzo di transizione "nested Segwit", quando Segwit è stato introdotto), il P2WSH (che è l'equivalente Segwit dell'indirizzo P2SH, proprio come P2WPKH è l'equivalente Segwit dell'indirizzo P2PKH) e l'indirizzo P2WSH annidato. + +Questa è un'altra situazione in cui non dovrai davvero preoccuparti di queste sfumature mentre lavori con `bitcoin-cli`, ma è utile sapere come funziona tutto. + +## Comprendere uno Script P2SH-Segwit + +L'indirizzo P2SH-Segwit è una razza morente. Era fondamentalmente una misura provvisoria mentre Bitcoin stava passando a Segwit, che permetteva a un utente di creare un indirizzo Segwit e poi fare in modo che qualcuno con uno scambio o un portafoglio non abilitato a Segwit finanziasse quell'indirizzo. + +Se mai dovessi usarne uno, c'è un'opzione per creare un indirizzo P2SH-Segwit usando `getnewaddress`: +``` +$ bitcoin-cli getnewaddress -addresstype p2sh-segwit +2NEzBvokxh4ME4ahdT18NuSSoYvvhS7EnMU +``` +L'indirizzo inizia con un `2` (o un `3`), rivelandosi come uno script + +> :book: ***Perché i vecchi nodi non possono inviare agli indirizzi Segwit nativi?*** [Capitolo 10.1](10_1_Comprendere_la_Base_di_P2SH.md) ha notato che c'erano un numero stabilito di transazioni Bitcoin "standard". Non puoi effettivamente bloccare una transazione con uno script che non sia uno di quei tipi standard. Segwit è ora riconosciuto come uno di quegli standard, ma un vecchio nodo non lo saprà, e quindi si rifiuterà di inviare su una tale transazione per protezione del mittente. Avvolgere un indirizzo Segwit all'interno di un hash di script risolve il problema. + +Quando guardi un UTXO inviato a quell'indirizzo, puoi vedere che il `desc` è diverso, rivelando un indirizzo WPKH avvolto in uno script: + +``` +$ bitcoin-cli listunspent + { + "txid": "ed752673bfd4338ccf0995983086da846ad652ae0f28280baf87f9fd44b3c45f", + "vout": 1, + "address": "2NEzBvokxh4ME4ahdT18NuSSoYvvhS7EnMU", + "redeemScript": "001443ab2a09a1a5f2feb6c799b5ab345069a96e1a0a", + "scriptPubKey": "a914ee7aceea0865a05a29a28d379cf438ac5b6cd9c687", + "amount": 0.00095000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "sh(wpkh([f004311c/0'/0'/3']03bb469e961e9a9cd4c23db8442d640d9b0b11702dc0126462ac9eb88b64a4dd48))#p29e839h", + "safe": true + } +``` +Più importante, c'è un `redeemScript`, che si decodifica in `OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a`. Questo dovrebbe sembrare familiare, perché è un `OP_0` seguito da un codice esadecimale a 20 byte di un hash di chiave pubblica. In altre parole, un P2SH-SegWit è solo uno `scriptPubKey` SegWit inserito in uno script. Questo è tutto. Corrisponde esattamente a come i multisig moderni sono un multisig inserito in un P2SH, come discusso nel [Capitolo 10.4: Programmare una Multisig](10_4_Programmare_una_Multifirma.md). + +Al contrario, quando spendiamo questa transazione, sembra esattamente come un P2SH: + +``` +$ bitcoin-cli getrawtransaction ed752673bfd4338ccf0995983086da846ad652ae0f28280baf87f9fd44b3c45f 1 +{ + "txid": "ed752673bfd4338ccf0995983086da846ad652ae0f28280baf87f9fd44b3c45f", + "hash": "aa4b1c2bde86ea446c9a9db2f77e27421316f26a8d88869f5b195f03b1ac4f23", + "version": 2, + "size": 247, + "vsize": 166, + "weight": 661, + "locktime": 1781316, + "vin": [ + { + "txid": "59178b02cfcbdee51742a4b2658df35b63b51115a53cf802bc6674fd94fa593a", + "vout": 1, + "scriptSig": { + "asm": "00149ef51fb1f5adb44e20eff758d34ae64fa781fa4f", + "hex": "1600149ef51fb1f5adb44e20eff758d34ae64fa781fa4f" + }, + "txinwitness": [ + "3044022069a23fcfc421b44c622d93b7639a2152f941dbfd031970b8cef69e6f8e97bd46022026cb801f38a1313cf32a8685749546a5825b1c332ee4409db82f9dc85d99086401", + "030aec1384ae0ef264718b8efc1ef4318c513403d849ea8466ef2e4acb3c5ccce6" + ], + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 8.49029534, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 b4b656f4c4b14ee0d098299d1d6eb42d2e22adcd OP_EQUAL", + "hex": "a914b4b656f4c4b14ee0d098299d1d6eb42d2e22adcd87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2N9ik3zihJ91VGNF55sZFe9GiCAXh2cVKKW" + ] + } + }, + { + "value": 0.00095000, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 ee7aceea0865a05a29a28d379cf438ac5b6cd9c6 OP_EQUAL", + "hex": "a914ee7aceea0865a05a29a28d379cf438ac5b6cd9c687", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2NEzBvokxh4ME4ahdT18NuSSoYvvhS7EnMU" + ] + } + } + ], + "hex": "020000000001013a59fa94fd7466bc02f83ca51511b5635bf38d65b2a44217e5decbcf028b175901000000171600149ef51fb1f5adb44e20eff758d34ae64fa781fa4ffeffffff029e299b320000000017a914b4b656f4c4b14ee0d098299d1d6eb42d2e22adcd87187301000000000017a914ee7aceea0865a05a29a28d379cf438ac5b6cd9c68702473044022069a23fcfc421b44c622d93b7639a2152f941dbfd031970b8cef69e6f8e97bd46022026cb801f38a1313cf32a8685749546a5825b1c332ee4409db82f9dc85d9908640121030aec1384ae0ef264718b8efc1ef4318c513403d849ea8466ef2e4acb3c5ccce6442e1b00", + "blockhash": "0000000069cbe44925fab2d472870608c7e1e241a1590fd78be10c63388ed6ee", + "confirmations": 282952, + "time": 1595360859, + "blocktime": 1595360859 +} +``` +Ogni `vout` è della forma `OP_HASH160 OP_EQUAL`. Questo è un normale P2SH come si vede nel [Capitolo 10.2](10_2_Construire_la_Struttura_di_P2SH.md), il che significa che è solo quando viene eseguito lo script di riscatto che avviene la magia. Proprio come con un P2WPKH, un vecchio nodo vedrà `OP_0 OP_PUSHDATA (20 bytes) 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a` nello script di riscatto e lo verificherà automaticamente, mentre un nuovo nodo vedrà quello, saprà che è un P2WPKH e quindi andrà a cercare nei `witnesses`. Vedi [Capitolo 9.5: Programmare una P2WPKH](09_5_Programmare_una_P2WPKH.md). + +> :book: ***Quali sono gli svantaggi delle transazioni Segwit annidate?*** Sono più grandi delle transazioni Segwit native, quindi ottieni alcuni vantaggi del Segwit, ma non tutti. + +## Comprendere uno Script P2WSH + +Al contrario, le transazioni P2WSH dovrebbero essere sempre più utilizzate, poiché sono la sostituzione Segwit nativa per P2SH, offrendo tutti gli stessi vantaggi di dimensione del blocco creati con le transazioni P2WPKH Segwit native. + +Questo è un esempio di indirizzo P2WSH: +[https://blockstream.info/testnet/address/tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7](https://blockstream.info/testnet/address/tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7) + +I dettagli mostrano che un UTXO inviato a questo indirizzo è bloccato con uno `scriptPubKey` come questo: + +``` +OP_0 OP_PUSHDATA (32 bytes) 1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262 +``` +Funziona proprio come un indirizzo P2WPKH, l'unica differenza è che invece di un hash di chiave pubblica a 20 byte, l'UTXO include un hash di script a 32 byte. Proprio come con un P2WPKH, i vecchi nodi lo verificano, mentre i nuovi nodi riconoscono che è un P2WSH e quindi verificano internamente lo script come descritto nelle sezioni precedenti, ma utilizzando i dati `witness`, che ora includono lo script di riscatto. + +C'è anche un'altra variante, uno script P2WSH incorporato in uno script P2SH, che funziona molto come il P2SH-Segwit descritto sopra, ma per gli script P2WSH annidati. (Uff!) + +## Riepilogo: Scripting di un Segwit Script + +Ci sono due tipi di script P2SH che riguardano Segwit. + +L'indirizzo P2SH-Segwit è un indirizzo Segwit annidato che incorpora il semplice `scriptPubkey` Segwit all'interno di uno Script, proprio come i multisig sono incorporati negli script oggigiorno: la chiave in stile Segwit viene srotolata e quindi analizzata normalmente su una macchina che comprende Segwit. Lo scopo è la compatibilità all'indietro con i vecchi nodi che altrimenti potrebbero non essere in grado di inviare a indirizzi Segwit nativi. + +L'indirizzo P2WSH è una variante Segwit di P2SH, proprio come P2WPKH è una variante Segwit di P2WSH. Funziona con la stessa logica ed è identificato dall'avere un hash a 32 byte invece di un hash a 20 byte. Lo scopo è estendere i vantaggi di Segwit ad altri tipi di script. + +## Cosa c'è Dopo? + +Continua "Incorporare Bitcoin Scripts" con [Capitolo 10.6: Spendere una Transazione P2SH](10_6_Spendere_una_Transazione_P2SH.md). diff --git a/it/10_6_Spendere_una_Transazione_P2SH.md b/it/10_6_Spendere_una_Transazione_P2SH.md new file mode 100644 index 000000000..7ebc54811 --- /dev/null +++ b/it/10_6_Spendere_una_Transazione_P2SH.md @@ -0,0 +1,43 @@ +# 10.6: Spendere una Transazione P2SH + +Prima di concludere questa panoramica sulle transazioni P2SH, toccheremo come spenderle. Questa sezione è principalmente una panoramica, facendo riferimento a una sezione precedente in cui abbiamo _già_ speso una transazione P2SH. + +## Usa il Redeem Script + +Come abbiamo visto in [Capitolo 6.2: Spendere una Transazione con un Indirizzo Multifirma](06_2_Spendere_una_Transazione_con_un_Indirizzo_Multifirma.md), spendere una transazione P2SH riguarda tutto l'avere quella versione serializzata dello script di blocco, il cosiddetto _redeemScript_. Quindi, il primo passo per poter spendere una transazione P2SH è assicurarsi di salvare il _redeemScript_ prima di distribuire l'indirizzo P2SH a tutti. + +### Raccogli le Tue Variabili + +Poiché gli indirizzi P2SH, diversi dagli indirizzi multisig speciali e dagli indirizzi Segwit annidati, non sono integrati in `bitcoin-cli`, non ci saranno scorciatoie per spendere P2SH come hai visto in [Capitolo 6.3: Inviare e Ricevere una Multifirma Automatizzata](06_3_Inviare_e_Ricevere_una_Multifirma_Automatizzata.md). Dovrai raccogliere tutte le variabili più complesse da solo! + +Questo significa che devi raccogliere: + + * L'`hex` dello `scriptPubKey` per la transazione che stai spendendo + * Il `redeemScript` serializzato + * Qualsiasi chiave privata, poiché firmerai manualmente + * Tutti i normali `txids`, `vouts` e `addresses` di cui avresti bisogno + +## Creare la Transazione + +Come abbiamo visto in §6.2, la creazione di una transazione è abbastanza standard: + +``` +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') +$ echo $rawtxhex +020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b10000000000ffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 +``` +Tuttavia, firmare richiede l'inserimento di informazioni extra per (1) `scriptPubKey`; (2) il `redeemScript`; e (3) qualsiasi chiave privata necessaria. + +Ecco l'esempio di farlo per quel multisig incorporato in P2SH nel Capitolo6.2: +``` +$ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR"]' +``` +Con qualsiasi altro tipo di P2SH includerai un diverso `redeemscript`, ma per il resto la pratica è esattamente la stessa. L'unica differenza è che dopo due capitoli di lavoro sugli Script ora capisci cos'è lo `scriptPubKey` e cos'è il `redeemScript`, quindi spero che quelli che erano elementi misteriosi quattro capitoli fa siano ora familiari. + +## Riepilogo: Spendere una Transazione P2SH + +Hai già speso una P2SH nel Capitolo 6, quando hai reinviato una transazione multisig nel modo difficile, che richiedeva di allineare le informazioni `scriptPubKey` e `redeemScript`. Ora sai che lo `scriptPubKey` è uno script di blocco P2SH standardizzato, mentre il `redeemScript` corrisponde a un hash in quello script di blocco e che devi essere in grado di eseguirlo con le variabili appropriate per ottenere un risultato `True`. Ma oltre a sapere di più, non c'è nulla di nuovo nello spendere una transazione P2SH, perché lo hai già fatto! + +## Cosa c'è Dopo? + +Avanza attraverso "Bitcoin Scripting" con [Capitolo 11: Potenziare Blocchi Temporali con Scripts di Bitcoin](11_0_Potenziare_Blocchi_Temporali_con_Scripts_di_Bitcoin.md). diff --git a/it/11_0_Potenziare_Blocchi_Temporali_con_Scripts_di_Bitcoin.md b/it/11_0_Potenziare_Blocchi_Temporali_con_Scripts_di_Bitcoin.md new file mode 100644 index 000000000..df05f386c --- /dev/null +++ b/it/11_0_Potenziare_Blocchi_Temporali_con_Scripts_di_Bitcoin.md @@ -0,0 +1,24 @@ +# Capitolo 11: Potenziare il Timelock con Bitcoin Scripts + +La funzione `nLockTime` vista nel [Capitolo 8.1](08_1_Inviare_una_Transazione_con_Blocco_temporale.md) era solo l'inizio dei Timelocks. Quando inizi a scrivere Bitcoin Scripts, diventano disponibili due opcode di timelocking. + +## Obiettivi di Questo Capitolo + +Dopo aver lavorato su questo capitolo, uno sviluppatore sarà in grado di: + + * Decidere quale Timelock Utilizzare + * Creare Script con CLTV + * Creare Script con CSV + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere le Differenze tra i Diversi Timelocks + * Generare Tempi Relativi + +## Indice + +* [Capitolo 11.1: Comprendere le Opzioni dei Blocchi Temporali](11_1_Comprendere_le_Opzioni_dei_Blocchi_Temporali.md) +* [Capitolo 11.2: Usare CLTV negli Scripts](11_2_Usare_CLTV_negli_Scripts.md) +* [Capitolo 11.3: Usare CSV negli Scripts](11_3_Usare_CSV_negli_Scripts.md) + + diff --git a/it/11_1_Comprendere_le_Opzioni_dei_Blocchi_Temporali.md b/it/11_1_Comprendere_le_Opzioni_dei_Blocchi_Temporali.md new file mode 100644 index 000000000..49f5c4af1 --- /dev/null +++ b/it/11_1_Comprendere_le_Opzioni_dei_Blocchi_Temporali.md @@ -0,0 +1,49 @@ +# 11.1: Comprendere le Opzioni di Timelock + +Nel [Capitolo 8.1: Inviare una Transazione con Blocco temporale](08_1_Inviare_una_Transazione_con_Blocco_temporale.md), `nLocktime` ha offerto una grande prima opzione per bloccare le transazioni in modo che non potessero essere spese fino a un certo punto nel futuro — basato sia sul tempo che sull'altezza del blocco. Ma, non è l'unico modo per mettere un timelock su una transazione. + +## Comprendere i Limiti di nLockTime + +`nLockTime` è un modo semplice e potente per bloccare una transazione, ma ha alcuni limiti: + +1. **Nessuna Divisione.** `nLocktime` blocca l'intera transazione. +2. **Nessun Networking.** La maggior parte dei nodi moderni non accetteranno un `nLockTime` nella mempool fino a quando non è quasi pronto per essere finalizzato. +3. **Nessuno Script.** L'uso originale e semplice di `nLockTime` non permetteva che fosse usato negli Script. +4. **Nessuna Protezione.** `nLockTime` permette ai fondi di essere spesi con una transazione diversa, non bloccata. + +L'ultimo punto è stato spesso il punto di rottura per `nLockTime`. Impediva che una transazione venisse spesa, ma non impediva che i fondi fossero usati in una transazione diversa. Quindi, aveva usi, ma tutti dipendevano dalla fiducia. + +## Comprendere le Possibilità degli Script Timelock + +Negli anni più recenti, Bitcoin Core si è espanso per permettere la manipolazione dei timelock a livello di opcode con _OP_CHECKLOCKTIMEVERIFY_ (CLTV) e _OP_CHECKSEQUENCEVERIFY_ (CSV). Entrambi funzionano con una nuova metodologia che potenzia ulteriormente Bitcoin. + +_Sono Opcode._ Poiché sono opcode, CLTV e CSV possono essere usati come parte di condizioni di riscatto più complesse. Molto spesso sono collegati con le condizioni descritte nel prossimo capitolo. + +_Bloccano gli Output._ Poiché sono opcode che sono inclusi nelle transazioni come parte di un `sigPubKey`, bloccano solo quell'output singolo. Ciò significa che le transazioni sono accettate sulla rete Bitcoin e che gli UTXO usati per finanziare quelle transazioni sono spesi. Non si può tornare indietro su una transazione bloccata con CLTV o CSV come si può fare con un semplice `nLockTime`. Spendere nuovamente l'UTXO risultante richiede quindi che le condizioni del timelock siano soddisfatte. + +Ecco un'avvertenza per l'uso dei timelock: _Sono blocchi unidirezionali._ I timelock sono progettati in modo da sbloccare i fondi in un certo momento. Non possono quindi ri-bloccare un fondo: una volta che un fondo bloccato nel tempo è disponibile per essere speso, rimane disponibile per essere speso. + +### Comprendere le Possibilità di CLTV + +_OP_CHECKLOCKTIMEVERIFY_ o CLTV è una corrispondenza per la caratteristica classica `nLockTime`, ma nel nuovo paradigma basato su opcode. Permette a un UTXO di diventare accessibile in un certo momento o a una certa altezza di blocco. + +CLTV è stato dettagliato per la prima volta in [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki). + +### Comprendere le Possibilità di CSV + +_OP_CHECKSEQUENCEVERIFY_ o CSV dipende da un nuovo tipo di "relative locktime", che è impostato nel campo _nSequence_ della transazione. Come di consueto, può essere impostato come tempo o come altezza del blocco. Se è impostato come tempo, "n", allora una transazione bloccata nel tempo relativa è spendibile "n x 512" secondi dopo che il suo UTXO è stato minato, e se è impostato come blocco, "n", allora una transazione bloccata nel tempo relativa è spendibile "n" blocchi dopo che il suo UTXO è stato minato. + +L'uso di `nSequence` per un timelock relativo è stato dettagliato per la prima volta in [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki), poi l'opcode CSV è stato aggiunto in [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki). + +## Riepilogo: Comprendere le Opzioni di Timelock + +Ora hai quattro opzioni per Timelock: + +* `nLockTime` per tenere una transazione fuori dalla blockchain fino a un momento specifico. +* `nSequence` per tenere una transazione fuori dalla blockchain fino a un tempo relativo. +* CLTV per rendere un UTXO non spendibile fino a un momento specifico. +* CSV per rendere un UTXO non spendibile fino a un tempo relativo. + +## Cosa Succede Dopo? + +Continua a "Potenziare Timelock" nel [Capitolo 11.2: Usare CLTV negli Scripts](11_2_Usare_CLTV_negli_Scripts.md). diff --git a/it/11_2_Usare_CLTV_negli_Scripts.md b/it/11_2_Usare_CLTV_negli_Scripts.md new file mode 100644 index 000000000..d06c0d6ee --- /dev/null +++ b/it/11_2_Usare_CLTV_negli_Scripts.md @@ -0,0 +1,168 @@ +# 11.2: Utilizzo di CLTV negli Script + +`OP_CHECKLOCKTIMEVERIFY` (o CLTV) è il complemento naturale di `nLockTime`. Porta l'idea di bloccare le transazioni per un tempo assoluto o altezza di blocco nel regno degli opcode, permettendo il blocco di singoli UTXO. + +> :warning: **AVVISO VERSIONE:** CLTV è diventato disponibile con Bitcoin Core 0.11.2, ma dovrebbe essere abbastanza ampiamente distribuito a questo punto. + +## Ricorda nLockTime + +Prima di approfondire CLTV, dovremmo prima ricordare come funziona `nLockTime`. + +Come dettagliato in [§8.1: Invio di una Transazione con un Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md), il locktime è abilitato impostando due variabili, `nLockTime` e `nSequence`. Il `nSequence` deve essere impostato a meno di 0xffffffff (di solito: 0xffffffff-1), poi il `nLockTime` è interpretato come segue: + +* Se il `nLockTime` è inferiore a 500 milioni, è interpretato come altezza di blocco. +* Se il `nLockTime` è 500 milioni o più, è interpretato come un timestamp UNIX. + +Una transazione con `nLockTime` impostato non può essere spesa (o anche inserita nella blockchain) fino a quando non viene raggiunta l'altezza del blocco o il tempo. Nel frattempo, la transazione può essere annullata spendendo nuovamente uno qualsiasi degli UTXO che compongono la transazione. + +## Comprendere l'Opcode CLTV + +`OP_CHECKLOCKTIMEVERIFY` funziona nello stesso paradigma delle altezze di blocco assolute o dei tempi UNIX assoluti, ma viene eseguito come parte di uno Script Bitcoin. Legge un argomento, che può essere un'altezza di blocco o un tempo UNIX assoluto. Attraverso una metodologia alquanto complicata, confronta quell'argomento con il tempo corrente. Se è troppo presto, lo script fallisce; se la condizione temporale è stata soddisfatta, lo script continua. + +Poiché CLTV è solo parte di uno script (e presumibilmente parte di una transazione P2SH), una transazione CLTV non è tenuta fuori dalla mempool come una transazione `nLockTime`; non appena viene verificata, entra nella blockchain e i fondi sono considerati spesi. Il trucco è che tutti gli output bloccati con il CLTV non sono disponibili per _spendere nuovamente_ fino a quando il CLTV non lo consente. + +### Comprendere un Tempo Assoluto CLTV + +Ecco come `OP_CHECKLOCKTIMEVERIFY` sarebbe usato per verificare contro il 24 maggio 2017: + +``` +1495652013 OP_CHECKLOCKTIMEVERIFY +``` +Ma di solito lo rappresenteremo in un'astrazione così: +``` + OP_CHECKLOCKTIMEVERIFY +``` +O cosi: +``` + OP_CHECKLOCKTIMEVERIFY +``` + + +### Comprendere un'Altezza di Blocco Assoluta CLTV + +Ecco come `OP_CHECKLOCKTIMEVERIFY` verificherebbe contro un'altezza di blocco raggiunta il 24 maggio 2017: + +``` +467951 OP_CHECKLOCKTIMEVERIFY +``` + +Ma di solito lo astrarremo così: + +``` + OP_CHECKLOCKTIMEVERIFY +``` + + +### Comprendere Come Funziona Davvero CLTV + +La spiegazione sopra è sufficiente per usare e comprendere CLTV. Tuttavia, [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) espone tutti i dettagli. + +Uno script di blocco permetterà di spendere nuovamente un UTXO bloccato con un CLTV solo se `OP_CHECKLOCKTIMEVERIFY` verifica tutte le seguenti condizioni: + +* Il campo `nSequence` deve essere impostato a meno di 0xffffffff, di solito 0xffffffff-1 per evitare conflitti con i timelock relativi. +* CLTV deve estrarre un operando dallo stack e deve essere 0 o maggiore. +* Sia l'operando dello stack che il valore di `nLockTime` devono essere sopra o sotto i 500 milioni, per rappresentare lo stesso tipo di timelock assoluto. +* Il valore di `nLockTime` deve essere maggiore o uguale all'operando dello stack. + +Quindi la prima cosa da notare qui è che `nLockTime` è ancora usato con CLTV. Per essere precisi, è richiesto nella transazione che cerca di _spendere nuovamente_ un UTXO bloccato con CLTV. Ciò significa che non fa parte dei requisiti dello script. È solo il timer usato per rilasciare i fondi, _come definito nello script_. + +Questo è gestito attraverso una comprensione intelligente di come funziona `nLockTime`: un valore per `nLockTime` deve sempre essere scelto che sia inferiore o uguale al tempo presente (o altezza del blocco), in modo che la transazione di spesa possa essere inserita nella blockchain. Tuttavia, a causa dei requisiti di CLTV, deve anche essere scelto un valore maggiore o uguale all'operando di CLTV. L'unione di questi due insiemi è `NULL` fino a quando il tempo presente non corrisponde all'operando di CLTV. Successivamente, può essere scelto qualsiasi valore tra l'operando di CLTV e il tempo presente. Di solito, lo imposteresti semplicemente al tempo presente (o al blocco). + +## Scrivere uno Script CLTV + +`OP_CHECKLOCKTIMEVERIFY` include un `OP_VERIFY`, il che significa che interromperà immediatamente lo script se la sua verifica non riesce. Ha un'altra peculiarità: a differenza della maggior parte dei comandi "verify", lascia ciò che sta testando sullo stack (nel caso in cui tu voglia fare altri controlli contro il tempo). Ciò significa che un `OP_CHECKLOCKTIMEVERIFY` è di solito seguito da un `OP_DROP` per pulire lo stack. + +Il seguente semplice script di blocco potrebbe essere usato per trasformare un output P2PKH in una transazione P2PKH bloccata nel tempo: + +``` + OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +``` + + +### Codificare uno Script CLTV + +Ovviamente, come per qualsiasi script Bitcoin complesso, questo script CLTV sarebbe effettivamente codificato in uno script P2SH, come spiegato in [§10.1: Comprendere le Basi di P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) e [§10.2: Costruire la Struttura di P2SH](10_2_Building_the_Structure_of_P2SH.md). + +Supponendo che `` fosse l'intero "1546288031" (hex little-endian: 0x9f7b2a5c) e `` fosse "371c20fb2e9899338ce5e99908e64fd30b789313", questo `redeemScript` sarebbe costruito come: + +``` +OP_PUSHDATA (4 bytes) 0x9f7b2a5c OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_PUSHDATA (20 bytes) 0x371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG +``` +Che si traduce in hex come: +``` +04 9f7b2a5c b1 75 76 a9 14 371c20fb2e9899338ce5e99908e64fd30b789313 88 ac +``` +Oppure, se preferisci: +``` +$ btcc 0x9f7b2a5c OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 0x371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG +049f7b2a5cb17576a914371c20fb2e9899338ce5e99908e64fd30b78931388ac +``` +L'RPC `decodescript` può verificare che abbiamo fatto tutto correttamente: +``` +{ + "asm": "1546288031 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG", + "type": "nonstandard", + "p2sh": "2MxANZMPo1b2jGaeKTv9rwcBEiXcXYCc3x9", + "segwit": { + "asm": "0 07e55bf1eaedf43ec52af57b77ad7330506c209a70d17fa2e1853304aa8e4e5b", + "hex": "002007e55bf1eaedf43ec52af57b77ad7330506c209a70d17fa2e1853304aa8e4e5b", + "reqSigs": 1, + "type": "witness_v0_scripthash", + "addresses": [ + "tb1qqlj4hu02ah6ra3f274ah0ttnxpgxcgy6wrghlghps5esf25wfedse4yw4w" + ], + "p2sh-segwit": "2N4HTwMjVdm38bdaQ5h3X3VktLY74D2qBoK" + } +} +``` + + +Non mostreremo continuamente come tutti gli Script Bitcoin vengono codificati in transazioni P2SH, ma offriremo invece queste abbreviazioni: quando descriviamo uno script, sarà un `redeemScript`, che sarebbe normalmente serializzato e hashato in uno script di blocco e serializzato nello script di sblocco; quando mostriamo una procedura di sblocco, sarà il secondo turno di convalida, dopo la conferma dell'hash dello script di blocco. + +## Spendere un UTXO CLTV + +Per spendere un UTXO bloccato con un CLTV, è necessario impostare `nLockTime` sulla nuova transazione. Di solito, vuoi solo impostarlo al tempo presente o al blocco presente, come appropriato. Finché il tempo CLTV o l'altezza del blocco è nel passato, e finché fornisci tutti gli altri dati richiesti dallo script di sblocco, sarai in grado di elaborare l'UTXO. + +Nel caso dell'esempio sopra, il seguente script di sblocco sarebbe sufficiente, a condizione che `nLockTime` fosse impostato a un momento successivo alla data ``, e a condizione che fosse effettivamente almeno ``: + +``` + +``` + + +### Eseguire uno Script CLTV + +Per eseguire lo Script, dovresti prima concatenare gli script di sblocco e blocco: + +``` +Script: OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] +``` +I tre costanti verrebbero spinti nello stack: +``` +Script: OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] +``` +Poi, `OP_CHECKLOCKTIMEVERIFY` viene eseguito. Trova qualcosa nello stack e verifica che `nSequence` non sia 0xffffffff. Infine, confronta `` con `nLockTime`. Se sono entrambi dello stesso tipo di rappresentazione e se `nLockTime ≥ `, allora viene elaborato con successo (altrimenti, termina lo script): +``` +Script: OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: OP_CHECKLOCKTIMEVERIFY +Stack: [ ] +``` +Poi, `OP_DROP` elimina quel `` rimasto: +``` +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: OP_DROP +Stack: [ ] +``` +FInfine, il resto dello script viene eseguito, che è un controllo normale di una firma e una chiave pubblica. + +## Riepilogo: Utilizzo di CLTV negli Script + +`OP_CHECKLOCKTIMEVERIFY` è un semplice opcode che guarda un singolo argomento, lo interpreta come un'altezza di blocco o un timestamp UNIX, e permette solo che il suo UTXO venga sbloccato se quell'altezza di blocco o timestamp UNIX è nel passato. Impostare `nLockTime` sulla transazione di spesa è ciò che permette a Bitcoin di fare questo calcolo. + +> :fire: ***Qual è il Potere di CLTV?*** Hai già visto che i semplici locktime erano una delle basi dei Contratti Intelligenti. CLTV fa il passo successivo. Ora puoi sia garantire che un UTXO non possa essere speso prima di un certo momento _sia_ garantire che non venga speso diversamente. Nella sua forma più semplice, questo potrebbe essere usato per creare un trust che qualcuno potrebbe accedere solo quando raggiunge i 18 anni o un fondo pensione che potrebbe essere accessibile solo quando compie 50 anni. Tuttavia, il suo vero potere si manifesta quando combinato con i condizionali, dove il CLTV si attiva solo in determinate situazioni. + +## Cosa Succede Dopo? + +Continua a "Potenziare Timelock" col [Capitolo 11.3: Usare CSV negli Scripts](11_3_Usare_CSV_negli_Scripts.md). diff --git a/it/11_3_Usare_CSV_negli_Scripts.md b/it/11_3_Usare_CSV_negli_Scripts.md new file mode 100644 index 000000000..f8459d9eb --- /dev/null +++ b/it/11_3_Usare_CSV_negli_Scripts.md @@ -0,0 +1,151 @@ +# 11.3: Utilizzo di CSV negli Script + +`nLockTime` e `OP_CHECKLOCKTIMEVERIFY` (o CLTV) sono solo una faccia dell'equazione del timelock. Dall'altra parte ci sono `nSequence` e `OP_CHECKSEQUENCEVERIFY`, che possono essere utilizzati per controllare i tempi relativi piuttosto che i tempi assoluti. + +> :warning: **AVVISO VERSIONE:** CSV è diventato disponibile con Bitcoin Core 0.12.1, nella primavera del 2016. + +## Comprendere nSequence + +Ogni input in una transazione ha un valore `nSequence` (o se preferisci `sequence`). È stato uno strumento primario per le espansioni di Bitcoin come discusso in precedenza nel [Capitolo 5.2 Rinviare le Transazioni con RBF](05_2_Rinviare_le_Transazioni_con_RBF.md) e nel [Capitolo 8.1 Inviare una Transazione con Blocco temporale](08_1_Inviare_una_Transazione_con_Blocco_temporale.md), dove è stato utilizzato per segnalare RBF e `nLockTime`, rispettivamente. Tuttavia, c'è un altro uso per `nSequence`, descritto da [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki): puoi usarlo per creare un timelock relativo su una transazione. + +Un timelock relativo è un blocco che viene posto su un input specifico di una transazione e che viene calcolato in relazione alla data di mining dell'UTXO utilizzato nell'input. Ad esempio, se un UTXO è stato minato al blocco #468260 e una transazione è stata creata dove l'input per quell'UTXO è stato dato un `nSequence` di 100, allora la nuova transazione non potrebbe essere minata fino almeno al blocco #468360. + +Facile! + +> :information_source: **NOTA — SEQUENCE:** Questo è il terzo utilizzo del valore `nSequence` in Bitcoin. Qualsiasi valore `nSequence` senza il 32° bit impostato (1<<31), quindi da 0x00000001 a 0x7ffffffff, sarà interpretato come un timelock relativo se `nVersion ≥ 2` (che è il valore predefinito a partire da Bitcoin Core 0.14.0). Dovresti fare attenzione per garantire che i timelock relativi non confliggano con gli altri due usi di `nSequence`, per segnalare `nTimeLock` e RBF. `nTimeLock` di solito imposta un valore di 0xffffffff-1, dove un timelock relativo è disattivato; e RBF di solito imposta un valore di "1", dove un timelock relativo è irrilevante, perché definisce un timelock di 1 blocco. + +> In generale, ricorda: con un valore `nVersion` di 2, un valore `nSequence` da 0x00000001 a 0x7fffffff consente timelock relativi, RBF e `nTimeLock`; un valore `nSequence` da 0x7fffffff a 0xffffffff-2 consente RBF e `nTimeLock`; un valore `nSequence` di 0xffffffff-1 consente solo `nTimeLock`; un valore `nSequence` di 0xffffffff non consente nessuno; e `nVersion` può essere impostato a 1 per disabilitare i timelock relativi per qualsiasi valore di `nSequence`. Uff! + +### Creare un Tempo Relativo a Blocchi CSV + +Il formato per utilizzare `nSequence` per rappresentare i timelock relativi è definito in [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) ed è leggermente più complesso del semplice inserimento di un numero, come hai fatto per `nTimeLock`. Invece, le specifiche BIP dividono il numero a quattro byte in tre parti: + +* I primi due byte vengono utilizzati per specificare un locktime relativo. +* Il 23° bit viene utilizzato per segnalare positivamente se il lock si riferisce a un tempo anziché a un'altezza di blocco. +* Il 32° bit viene utilizzato per segnalare positivamente se i timelock relativi sono disattivati. + +Detto ciò, la costruzione di un timelock relativo basato su blocchi è ancora abbastanza semplice, perché i due bit segnalati sono impostati a `0`, quindi imposti semplicemente `nSequence` a un valore tra 1 e 0xffff (65535). La nuova transazione può essere minata quel numero di blocchi dopo che l'UTXO associato è stato minato. + +### Creare un Tempo Relativo CSV + +Puoi invece impostare `nSequence` come un tempo relativo, dove il lock dura per 512 secondi moltiplicato per il valore di `nSequence`. + +Per fare ciò: + +1. Decidi quanto in avanti impostare il tuo timelock relativo. +2. Converti quel tempo in secondi. +3. Dividi per 512. +4. Arrotonda quel valore in su o in giù e impostalo come `nSequence`. +5. Imposta il 23° bit a true. + +Per impostare un tempo 6 mesi nel futuro, devi prima calcolare come segue: +``` +$ seconds=$((6*30*24*60*60)) +$ nvalue=$(($seconds/512)) +``` +Poi, trasformalo in hex: +``` +$ hexvalue=$(printf '%x\n' $nvalue) +``` +Infine, esegui un'operazione bitwise-or sul 23° bit nel valore hex che hai creato: +``` +$ relativevalue=$(printf '%x\n' $((0x$hexvalue | 0x400000))) +$ echo $relativevalue +4224679 +``` +Se converti nuovamente, vedrai che 4224679 = 10000000111011010100111. Il 23° bit è impostato a "1"; nel frattempo, i primi 2 byte, 0111011010100111, si convertono in 76A7 in hex o 30375 in decimale. Moltiplicalo per 512 e ottieni 15,55 milioni di secondi, che sono effettivamente 180 giorni. + +## Creare una Transazione con un Timelock Relativo + +Quindi vuoi creare una semplice transazione con un timelock relativo? Tutto ciò che devi fare è emettere una transazione dove il `nSequence` in un input è impostato come mostrato sopra: con il `nSequence` per quell'input impostato in modo che i primi due byte definiscano il timelock, il 23° bit definisca il tipo di timelock e il 32° bit sia impostato a falso. + +Emetti la transazione e vedrai che non può essere legalmente minata fino a quando non saranno passati abbastanza blocchi o abbastanza tempo oltre il momento in cui l'UTXO è stato minato. + +Tranne che praticamente nessuno lo fa. Le definizioni di [BIP 68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki) per `nSequence` sono state incorporate in Bitcoin Core allo stesso tempo di [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki), che descrive l'opcode CSV, l'equivalente di `nSequence` dell'opcode CLTV. Proprio come CLTV, CSV offre capacità aumentate. Quindi, quasi tutto l'uso dei timelock relativi è stato con l'opcode CSV, non con il valore grezzo `nSequence` da solo. + +| | Timelock Assoluto | Timelock Relativo | +|:--------------------:|-------------------|-------------------| +| **Blocco Transazione** | nTimeLock | nSequence | +| **Blocco Output** | OP_CHECKLOCKTIMEVERIFY| OP_CHECKSEQUENCEVERIFY | + +## Comprendere l'Opcode CSV + +`OP_SEQUENCEVERIFY` negli Script Bitcoin funziona praticamente come `OP_LOCKTIMEVERIFY`. + +Potresti richiedere che un UTXO sia mantenuto per cento blocchi dopo il suo mining: + +``` +100 OP_CHECKSEQUENCEVERIFY +``` +Oppure potresti fare un calcolo più complesso per richiedere che un UTXO sia mantenuto per sei mesi, nel qual caso finirai con un numero più complesso: +``` +4224679 OP_CHECKSEQUENCEVERIFY +``` +In questo caso useremo una scorciatoia: +``` +<+6Months> OP_CHECKSEQUENCEVERIFY +``` +> :warning: **AVVISO:** Ricorda che un timelock relativo è un intervallo di tempo dal mining dell'UTXO utilizzato come input. Non è un intervallo di tempo dopo che crei la transazione. Se utilizzi un UTXO che è già stato confermato cento volte e applichi un timelock relativo di 100 blocchi, sarà idoneo per il mining immediatamente. I timelock relativi hanno alcuni usi molto specifici, ma probabilmente non si applicano se il tuo unico obiettivo è determinare un tempo specifico nel futuro. + +### Comprendere Come Funziona Davvero CSV + +CSV ha molte delle stesse sottigliezze nell'uso di CLTV: + +* Il campo `nVersion` deve essere impostato a 2 o più. +* Il campo `nSequence` deve essere impostato a meno di 0x80000000. +* Quando CSV viene eseguito, ci deve essere un operando sullo stack che sia compreso tra 0 e 0xf0000000-1. +* Sia l'operando dello stack che `nSequence` devono avere lo stesso valore nel 23° bit. +* Il `nSequence` deve essere maggiore o uguale all'operando dello stack. + +Proprio come con CLTV, quando stai spendendo nuovamente un UTXO con un CSV nelle sue condizioni di blocco, devi impostare `nSequence` per abilitare la transazione. Di solito lo imposterai al valore esatto nello script di blocco. + +## Scrivere uno Script CSV + +Proprio come `OP_CHECKLOCKTIMEVERIFY`, `OP_CHECKSEQUENCEVERIFY` include un implicito `OP_VERIFY` e lascia i suoi argomenti sullo stack, richiedendo un `OP_DROP` quando hai finito. + +Uno script che bloccherebbe i fondi fino a sei mesi dopo il mining dell'input e che richiederebbe quindi una firma in stile P2PKH standard sarebbe il seguente: +``` +<+6Months> OP_CHECKSEQUENCEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +``` + +# +### Codificare uno Script CSV + +Quando codifichi uno script CSV, fai attenzione a come codifichi il valore intero per il timelock relativo. Dovrebbe essere passato come un intero a 3 byte, il che significa che stai ignorando il byte superiore, che potrebbe disattivare il timelock relativo. Poiché è un intero, assicurati di convertirlo in little-endian. + +Questo può essere fatto con lo script `integer2lehex.sh` dalla capitolo precedente. + +Per un tempo relativo di 100 blocchi: +``` +$ ./integer2lehex.sh 100 +Integer: 100 +LE Hex: 64 +Length: 1 bytes +Hexcode: 0164 +``` +Anche se dovrebbe essere completato a `000064`, richiedendo un codice di `03000064`. + +Per un tempo relativo di 6 mesi: + +``` +$ ./integer2lehex.sh 4224679 +Integer: 4224679 +LE Hex: a77640 +Length: 3 bytes +Hexcode: 03a77640 +``` + + +## Spendere un UTXO CSV + +Per spendere un UTXO bloccato con uno script CSV, devi impostare il `nSequence` di quell'input a un valore maggiore del requisito nello script, ma inferiore al tempo tra l'UTXO e il blocco presente. Sì, questo significa che devi conoscere il requisito esatto nello script di blocco... ma hai una copia del `redeemScript`, quindi se non conosci i requisiti, lo deserializzi e poi imposti il `nSequence` al numero mostrato lì. + +## Riepilogo: Utilizzo di CSV negli Script + +`nSequence` e CSV offrono un'alternativa a `nLockTime` e CLTV dove blocchi una transazione basata su un tempo relativo da quando l'input è stato minato, anziché basare il blocco su un tempo stabilito nel futuro. Funzionano quasi in modo identico, a parte il fatto che il valore `nSequence` è codificato in modo leggermente diverso dal valore `nLockTime`, con bit specifici che significano cose specifiche. + +> :fire: ***Qual è il potere di CSV?*** CSV non è solo un modo pigro per bloccare, quando non vuoi calcolare un tempo nel futuro. Invece, è un paradigma totalmente diverso, un blocco che useresti se fosse importante creare una durata minima specifica tra quando una transazione è minata e quando i suoi fondi possono essere spesi nuovamente. L'uso più ovvio è (ancora una volta) per un escrow, quando vuoi un tempo preciso tra l'input dei fondi e il loro output. Tuttavia, ha possibilità molto più potenti nelle transazioni off-chain, inclusi i canali di pagamento. Queste applicazioni sono per definizione basate su transazioni che non sono effettivamente inserite nella blockchain, il che significa che se sono successivamente inserite nella blockchain, un intervallo di tempo forzato può essere molto utile. [Contratti Hashed Timelock](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) sono stati una di queste implementazioni, potenziando la rete di pagamenti Lightning. Sono discussi nel[Capitolo 13.3: Potenziare Bitcoin con Scripts](13_3_Potenziare_Bitcoin_con_Scripts.md). + +## Cosa Succede Dopo? + +Avanza attraverso "Bitcoin Scripting" col [Capitolo 12: Ampliando Scripts di Bitcoin](12_0_Ampliando_Scripts_di_Bitcoin.md). diff --git a/it/12_0_Ampliando_Scripts_di_Bitcoin.md b/it/12_0_Ampliando_Scripts_di_Bitcoin.md new file mode 100644 index 000000000..cb305f65e --- /dev/null +++ b/it/12_0_Ampliando_Scripts_di_Bitcoin.md @@ -0,0 +1,20 @@ +# Capitolo 12: Espandere gli Script Bitcoin + +C'è ancora un po' da scoprire sugli Script Bitcoin. I condizionali ti danno pieno accesso al controllo del flusso, mentre una varietà di altri opcode può espandere le tue possibilità. + +## Obiettivi per Questo Capitolo + +Dopo aver lavorato su questo capitolo, uno sviluppatore sarà in grado di: + + * Decidere Come Usare i Condizionali negli Script + * Decidere Come Usare Altri Opcode degli Script + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere l'Intera Gamma di Possibilità degli Script + * Identificare Come Imparare di Più sugli Opcode + +## Indice dei Contenuti + +* [Capitolo 12.1 Usare Script Condizionati](12_1_Usare_Script_Condizionati.md) +* [Capitolo 12.2 Usare Altri Comandi di Scripting](12_2_Usare_Altri_Comandi_di_Scripting.md) diff --git a/it/12_1_Usare_Script_Condizionati.md b/it/12_1_Usare_Script_Condizionati.md new file mode 100644 index 000000000..941c80e46 --- /dev/null +++ b/it/12_1_Usare_Script_Condizionati.md @@ -0,0 +1,204 @@ +# 12.1: Utilizzo dei Condizionali negli Script + +C'è un ultimo aspetto degli Script Bitcoin che è cruciale per sbloccare il loro vero potere: i condizionali ti permettono di creare vari percorsi di esecuzione. + +## Comprendere Verify + +Hai già visto un condizionale negli script: `OP_VERIFY` (0x69). Estrae l'elemento in cima allo stack e verifica se è vero; in caso contrario _termina l'esecuzione dello script_. + +Verify è solitamente incorporato in altri opcode. Hai già visto `OP_EQUALVERIFY` (0xad), `OP_CHECKLOCKTIMEVERIFY` (0xb1) e `OP_CHECKSEQUENCEVERIFY` (0xb2). Ciascuno di questi opcode esegue la sua azione principale (equal, checklocktime o checksequence) e poi esegue un verify successivamente. Gli altri opcode verify che non hai visto sono: `OP_NUMEQUALVERIFY` (0x9d), `OP_CHECKSIGVERIFY` (0xad) e `OP_CHECKMULTISIGVERIFY` (0xaf). + +Quindi come è `OP_VERIFY` un condizionale? È il tipo più potente di condizionale. Usando `OP_VERIFY`, _se_ una condizione è vera, lo Script continua l'esecuzione, _altrimenti_ lo Script termina. Questo è il modo in cui controlli le condizioni che sono assolutamente necessarie affinché uno Script abbia successo. Ad esempio, lo script P2PKH (`OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG`) ha due condizioni richieste: (1) che la chiave pubblica fornita corrisponda all'hash della chiave pubblica; e (2) che la firma fornita corrisponda a quella chiave pubblica. Un `OP_EQUALVERIFY` è usato per il confronto dell'hash della chiave pubblica perché è una condizione assolutamente necessaria. Non vuoi che lo script continui se ciò fallisce. + +Potresti notare che non c'è `OP_VERIFY` alla fine di questo (o della maggior parte degli) script, nonostante la condizione finale sia richiesta. Questo perché Bitcoin effettua effettivamente un `OP_VERIFY` alla fine di ogni Script, per garantire che il risultato finale dello stack sia vero. Non vuoi fare un `OP_VERIFY` prima della fine dello script, perché devi lasciare qualcosa nello stack da verificare! + +## Comprendere If/Then + +L'altro principale condizionale in Bitcoin Script è il classico `OP_IF` (0x63) / `OP_ELSE` (0x67) / `OP_ENDIF` (0x68). Questo è il controllo di flusso tipico: se `OP_IF` rileva una dichiarazione vera, esegue il blocco sotto di esso; altrimenti, se c'è un `OP_ELSE`, esegue quello; e `OP_ENDIF` segna la fine del blocco finale. + +> :warning: **ATTENZIONE:** Questi condizionali sono tecnicamente anche opcode, ma come per i numeri piccoli, lasceremo il prefisso `OP_` per brevità e chiarezza. Quindi scriveremo `IF`, `ELSE` e `ENDIF` invece di `OP_IF`, `OP_ELSE` e `OP_ENDIF`. + +### Comprendere l'Ordine di If/Then + +Ci sono due grandi problemi nei condizionali. Rendono più difficile leggere e valutare gli script se non stai attento. + +Primo, il condizionale `IF` controlla la verità di ciò che è _prima di esso_ (cioè ciò che è nello stack), non ciò che è dopo di esso. + +Secondo, il condizionale `IF` tende a essere nello script di blocco e ciò che sta controllando tende a essere nello script di sblocco. + +Certo, potresti dire, è così che funziona Bitcoin Script. I condizionali usano la notazione polacca inversa e adottano il paradigma standard di sblocco/blocco, proprio come _tutto il resto_ nel Bitcoin Scripting. Tutto ciò è vero, ma va anche contro il modo standard in cui leggiamo i condizionali IF/ELSE in altri linguaggi di programmazione; quindi, è facile leggere inconsciamente i condizionali Bitcoin in modo errato. + +Considera il seguente codice: `IF OP_DUP OP_HASH160 ELSE OP_DUP OP_HASH160 ENDIF OP_EQUALVERIFY OP_CHECKSIG`. + +Guardando i condizionali in notazione prefissa potresti leggere questo come:: +``` +IF (OP_DUP) THEN + OP_HASH160 + OP_PUSHDATA +ELSE + OP_DUP + OP_HASH160 + OP_PUSHDATA +ENDIF + OP_EQUALVERIFY + OP_CHECKSIG +``` +Quindi, potresti pensare, se `OP_DUP` ha successo, allora eseguiamo il primo blocco, altrimenti il secondo. Ma ciò non ha senso! Perché `OP_DUP` non dovrebbe avere successo?! + +E, infatti, non ha senso, perché abbiamo letto accidentalmente l'affermazione usando la notazione sbagliata. La lettura corretta di questo è: + +``` +IF + OP_DUP + OP_HASH160 + OP_PUSHDATA +ELSE + OP_DUP + OP_HASH160 + OP_PUSHDATA +ENDIF + OP_EQUALVERIFY + OP_CHECKSIG +``` +L'affermazione che sarà valutata come `True` o `False` è posta nello stack _prima_ di eseguire l'`IF`, quindi il blocco di codice corretto viene eseguito in base a quel risultato. + +Questo esempio di codice è inteso come una multisignature 1-di-2 di basso livello. Il proprietario di `` metterebbe ` True` nel suo script di sblocco, mentre il proprietario di `` metterebbe ` False` nel suo script di sblocco. Quel `True` o `False` finale è ciò che viene controllato dall'istruzione `IF`/`ELSE`. Dice allo script quale hash della chiave pubblica controllare, quindi `OP_EQUALVERIFY` e `OP_CHECKSIG` alla fine fanno il lavoro reale. + +### Eseguire una Multisig If/Then + +Con una comprensione di base dei condizionali Bitcoin, siamo ora pronti a eseguire uno script. Creeremo una leggera variante della nostra multisignature 1-di-2 di basso livello dove i nostri utenti non devono ricordare se sono `True` o `False`. Invece, se necessario, lo script controlla entrambi gli hash delle chiavi pubbliche, richiedendo solo un successo: + +``` +OP_DUP OP_HASH160 OP_EQUAL +IF + OP_CHECKSIG +ELSE + OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +ENDIF +``` +Ricorda la notazione polacca inversa! Quell'istruzione `IF` si riferisce all'`OP_EQUAL` prima di essa, non all'`OP_CHECKSIG` dopo di essa! + +#### Eseguire il Ramo True + +Ecco come funziona effettivamente se sbloccato con ` `: + +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Per prima cosa, mettiamo le costanti nello stack: + +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Poi eseguiamo i primi comandi ovvi, `OP_DUP` e `OP_HASH160`, e mettiamo un'altra costante: + +``` +Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_DUP +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Successivamente, eseguiamo l'`OP_EQUAL`, che è ciò che alimenterà l'`IF`: +``` +Script: IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_EQUAL +Stack: [ True ] +``` +Ora l'`IF` viene eseguito e, poiché c'è un `True`, esegue solo il primo blocco, eliminando tutto il resto: +``` +Script: OP_CHECKSIG +Running: True IF +Stack: [ ] +``` +E l'`OP_CHECKSIG` risulterà `True`: +``` +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` +##### Eseguire il Ramo False + +Ecco come funziona effettivamente se sbloccato con ` `: + +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Per prima cosa, mettiamo le costanti nello stack: +``` +Script: OP_DUP OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Poi eseguiamo i primi comandi ovvi, `OP_DUP` e `OP_HASH160`, e mettiamo un'altra costante: +``` +Script: OP_HASH160 OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_DUP +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Stack: [ ] +``` +Successivamente, eseguiamo l'`OP_EQUAL`, che è ciò che alimenterà l'`IF`: +``` +Script: IF OP_CHECKSIG ELSE OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ENDIF +Running: OP_EQUAL +Stack: [ False ] +``` +Ops! Il risultato è stato `False` perché `` non è uguale a ``. Ora quando l'`IF` viene eseguito, si riduce solo all'istruzione `ELSE`: +``` +Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: False IF +Stack: [ ] +``` +Successivamente, rifacciamo tutto il processo, iniziando con un altro `OP_DUP`, ma alla fine testando contro l'altro `pubKeyHash`: +``` +Script: OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +Running: OP_DUP +Stack: [ ] + +Script: OP_EQUALVERIFY OP_CHECKSIG +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUALVERIFY OP_CHECKSIG +Stack: [ ] + +Script:OP_CHECKSIG +Running: OP_EQUALVERIFY +Stack: [ ] + +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` +TQuesto probabilmente non è altrettanto efficiente come una vera multisignature di Bitcoin, ma è un buon esempio di come i risultati inseriti nello stack dai test precedenti possono essere utilizzati per alimentare i condizionali futuri. In questo caso, è il fallimento della prima firma che dice al condizionale che dovrebbe controllare la seconda. + +## Comprendere Altri Condizionali + +Ci sono alcuni altri condizionali degni di nota. Il più importante è `OP_NOTIF` (0x64), che è l'opposto di `OP_IF`: esegue il blocco successivo se l'elemento in cima è `False`. Un `ELSE` può essere inserito con esso, che come al solito viene eseguito se il primo blocco non viene eseguito. Si termina ancora con `OP_ENDIF`. + +C'è anche un `OP_IFDUP` (0x73), che duplica l'elemento in cima allo stack solo se non è 0. + +Queste opzioni sono usate molto meno spesso della costruzione principale `IF`/`ELSE`/`ENDIF`. + +## Riepilogo: Utilizzo dei Condizionali negli Script + +I condizionali in Bitcoin Script ti permettono di fermare lo script (usando `OP_VERIFY`) o di scegliere diversi rami di esecuzione (usando `OP_IF`). Tuttavia, leggere `OP_IF` può essere un po' complicato. Ricorda che è l'elemento inserito nello stack _prima_ che l'`OP_IF` venga eseguito a controllarne l'esecuzione; quell'elemento sarà tipicamente parte dello script di sblocco (o altrimenti un risultato diretto degli elementi nello script di sblocco). + +> :fire: ***Qual è il potere dei condizionali?*** I Condizionali degli Script sono l'ultimo grande blocco costitutivo negli Script Bitcoin. Sono ciò che è necessario per trasformare semplici Script Bitcoin statici in Script Bitcoin complessi e dinamici che possono essere valutati in modo diverso in base a tempi diversi, circostanze diverse o input diversi degli utenti. In altre parole, sono la base finale dei contratti intelligenti. + +## Cosa Succede Dopo? + +Continua a "Espandere gli Script Bitcoin" col [Capitolo 12.2Usare Altri Comandi di Scripting](12_2_Usare_Altri_Comandi_di_Scripting.md). diff --git a/it/12_2_Usare_Altri_Comandi_di_Scripting.md b/it/12_2_Usare_Altri_Comandi_di_Scripting.md new file mode 100644 index 000000000..f37c69659 --- /dev/null +++ b/it/12_2_Usare_Altri_Comandi_di_Scripting.md @@ -0,0 +1,85 @@ +# 12.2: Utilizzo di Altri Comandi degli Script + +Probabilmente hai già a portata di mano la maggior parte degli opcode di Bitcoin Script che utilizzerai nella maggior parte degli script. Tuttavia, Bitcoin Script offre molte più opzioni, che potrebbero essere esattamente ciò di cui hai bisogno per creare lo strumento finanziario dei tuoi sogni. + +Dovresti consultare la [pagina Bitcoin Script](https://en.bitcoin.it/wiki/Script) per uno sguardo più approfondito a tutti questi e molti altri comandi. Questa sezione evidenzia solo gli opcode più notevoli. + +## Comprendere gli Opcode Aritmetici + +Gli opcode aritmetici manipolano o testano i numeri. + +Manipolare un numero: + +* OP_1ADD (0x8b) — Incrementa di uno +* OP_1SUB (0x8c) — Decrementa di uno +* OP_NEGATE (0x8f) — Inverte il segno del numero +* OP_ABS (0x90) — Rende il numero positivo +* OP_NOT (0x91) — Inverte 1 e 0, altrimenti 0 + +Vedi anche: `OP_0NOTEQUAL` (0x92) + +Manipolare due numeri matematicamente: + +* OP_ADD (0x93) — Somma due numeri +* OP_SUB (0x94) — Sottrae due numeri +* OP_MIN (0xa3) — Restituisce il minore di due numeri +* OP_MAX (0xa4) — Restituisce il maggiore di due numeri + +Manipolare due numeri logicamente: + +* OP_BOOLAND (0x9a) — 1 se entrambi i numeri non sono 0, altrimenti 0 +* OP_BOOLOR (0x9b) — 1 se uno dei due numeri non è 0, altrimenti 0 + +Testare due numeri: + +* OP_NUMEQUAL (0x9c) — 1 se entrambi i numeri sono uguali, altrimenti 0 +* OP_LESSTHAN (0x9f) — 1 se il primo numero è minore del secondo, altrimenti 0 +* OP_GREATERTHAN (0xa0) — 1 se il primo numero è maggiore del secondo, altrimenti 0 +* OP_LESSTHANOREQUAL (0xa1) — 1 se il primo numero è minore o uguale al secondo, altrimenti 0 +* OP_GREATERTHANOREQUAL (0xa2) — 1 se il primo numero è maggiore o uguale al secondo, altrimenti 0 + +Vedi anche: `OP_NUMEQUALVERIFY` (0x9d), `OP_NUMNOTEQUAL` (0x9e) + +Testare tre numeri: + +* OP_WITHIN (0xa5) — 1 se un numero è nell'intervallo di due altri numeri + +## Comprendere gli Opcode dello Stack + +Ci sono un numero sorprendente di opcode dello stack, ma a parte `OP_DROP`, `OP_DUP` e talvolta `OP_SWAP`, generalmente non sono necessari se sei attento all'ordinamento dello stack. Tuttavia, ecco alcuni dei più interessanti: + +* OP_DEPTH (0x74) — Inserisce la dimensione dello stack +* OP_DROP (0x75) — Rimuove l'elemento in cima allo stack +* OP_DUP (0x76) — Duplica l'elemento in cima allo stack +* OP_PICK (0x79) — Duplica l'elemento n dello stack come cima dello stack +* OP_ROLL (0x7a) — Sposta l'elemento n dello stack in cima allo stack +* OP_SWAP (0x7c) — Scambia i primi due elementi dello stack + +Vedi anche: `OP_TOALTSTACK` (0x6b), `OP_FROMALTSTACK` (0x6c), `OP_2DROP` (0x6d), `OP_2DUP` (0x6e), `OP_3DUP` (0x6f), `OP_2OVER` (0x70), `OP_2ROT` (0x71), `OP_2SWAP` (0x72), `OP_IFDUP` (0x73), `OP_NIP` (0x77), `OP_OVER` (0x78), `OP_ROT` (0x7b) e `OP_TUCK` (0x7d). + +## Comprendere gli Opcode Crittografici + +Infine, una varietà di opcode supporta l'hashing e il controllo delle firme: + +Hash: + +* OP_RIPEMD160 (0xa6) — RIPEMD-160 +* OP_SHA1 (0xa7) — SHA-1 +* OP_SHA256 (0xa8) - SHA-256 +* OP_HASH160 (0xa9) — SHA-256 + RIPEMD-160 +* OP_HASH256 (0xaa) — SHA-256 + SHA-256 + +Controllo delle Firme: + +* OP_CHECKSIG (0xac) — Controlla una firma +* OP_CHECKMULTISIG (0xae) — Controlla una multisig m-di-n + +Vedi anche: `OP_CODESEPARATOR` (0xab), `OP_CHECKSIGVERIFY` (0xad) e `OP_CHECKMULTISIGVERIFY` (0xaf). + +## Riepilogo: Utilizzo di Altri Comandi degli Script + +Bitcoin Script include una vasta gamma di opcode aritmetici, di stack e crittografici. La maggior parte di questi opcode aggiuntivi probabilmente non è comune come quelli discussi nelle sezioni precedenti, ma sono comunque disponibili se sono esattamente ciò di cui hai bisogno per scrivere il tuo Script! + +## Cosa Succede Dopo? + +Avanza attraverso "Bitcoin Scripting" col [Capitolo 13: Progettare Scripts di Bitcoin reali](13_0_Progettare_Scripts_di_Bitcoin_reali.md). diff --git a/it/13_0_Progettare_Scripts_di_Bitcoin_reali.md b/it/13_0_Progettare_Scripts_di_Bitcoin_reali.md new file mode 100644 index 000000000..d036b0075 --- /dev/null +++ b/it/13_0_Progettare_Scripts_di_Bitcoin_reali.md @@ -0,0 +1,20 @@ +# Capitolo 13: Progettare Veri Script Bitcoin + +I nostri Script Bitcoin fino ad oggi sono stati in gran parte esempi teorici, perché abbiamo ancora messo insieme i pezzi del puzzle. Ora, con il repertorio completo degli Script Bitcoin a portata di mano, siamo pronti a esplorare diversi Script Bitcoin del mondo reale e vedere come funzionano. + +## Obiettivi per Questo Capitolo + +Dopo aver lavorato su questo capitolo, uno sviluppatore sarà in grado di: + + * Valutare Script Bitcoin del Mondo Reale + * Creare Script Bitcoin del Mondo Reale + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere gli Script Bitcoin Esistenti + * Comprendere l'Importanza delle Firme + +## Indice dei Contenuti + * [Capitolo 13.1 Scrivere Scripts Puzzle](13_1_Scrivere_Scripts_Puzzle.md) + * [Capitolo 13.2 Scrivere Scripts Multifirma Complessi](13_2_Scrivere_Scripts_Multifirma_Complessi.md) + * [Capitolo 13.3 Potenziare Bitcoin con Scripts](13_3_Potenziare_Bitcoin_con_Scripts.md) diff --git a/it/13_1_Scrivere_Scripts_Enigmatici.md b/it/13_1_Scrivere_Scripts_Enigmatici.md new file mode 100644 index 000000000..19451c293 --- /dev/null +++ b/it/13_1_Scrivere_Scripts_Enigmatici.md @@ -0,0 +1,513 @@ +# 13.1: Scrivere Script Enigmatici + +Gli Script Bitcoin _non_ devono necessariamente dipendere dalla conoscenza di una chiave segreta. Possono invece essere enigmi di qualsiasi tipo. + +## Scrivere Script di Algebra Semplici + +Il nostro primo vero script, dal [Capitolo 9.2: Eseguire uno Script di Bitcoin](009_2_Eseguire_uno_Script_di_Bitcoin.md), era un enigma algebrico. Quello script Bitcoin, `OP_ADD 99 OP_EQUAL`, potrebbe essere descritto alternativamente come `x + y = 99`. + +Questo tipo di script non ha molta applicabilità nel mondo reale, poiché è troppo facile rivendicare i fondi. Tuttavia, un concorso di risoluzione di enigmi che distribuisce piccole quantità di Bitcoin potrebbe proporlo come un intrattenimento divertente. + +Più precisamente, creare enigmi algebrici ti dà una buona comprensione di come funzionano le funzioni aritmetiche negli script Bitcoin. + +### Scrivere uno Script Moltiplicatore + +Bitcoin Script ha un certo numero di opcode che sono stati disabilitati per mantenere la sicurezza del sistema. Uno di questi è `OP_MUL`, che avrebbe permesso la moltiplicazione... ma è invece disabilitato. + +Quindi, come scriveresti una funzione algebrica come `3x + 7 = 13`? + +La risposta più ovvia è `OP_DUP` il numero di input dallo script di blocco due volte. Poi puoi aggiungere `7` e continuare ad aggiungere fino a ottenere il totale. Lo script di blocco completo sarebbe così: `OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL`. + +Ecco come verrebbe eseguito se eseguito con lo script di sblocco corretto di `2`: + +``` +Script: 2 OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Stack: [ ] + +Script: OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Stack: [ 2 ] + +Script: OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Running: 2 OP_DUP +Stack: [ 2 2 ] + +Script: 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Running: 2 OP_DUP +Stack: [ 2 2 2 ] + +Script: OP_ADD OP_ADD OP_ADD 13 OP_EQUAL +Stack: [ 2 2 2 7 ] + +Script: OP_ADD OP_ADD 13 OP_EQUAL +Running: 2 7 OP_ADD +Stack: [ 2 2 9 ] + +Script: OP_ADD 13 OP_EQUAL +Running: 2 9 OP_ADD +Stack: [ 2 11 ] + +Script: 13 OP_EQUAL +Running: 2 11 OP_ADD +Stack: [ 13 ] + +Script: OP_EQUAL +Stack: [ 13 13 ] + +Script: +Running: 13 13 OP_EQUAL +Stack: [ True ] +``` +Oppure se preferisci `btcdeb`: +``` +$ btcdeb '[2 OP_DUP OP_DUP 7 OP_ADD OP_ADD OP_ADD 13 OP_EQUAL]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +valid script +9 op script loaded. type `help` for usage information +script | stack +---------+-------- +2 | +OP_DUP | +OP_DUP | +7 | +OP_ADD | +OP_ADD | +OP_ADD | +13 | +OP_EQUAL | + +#0000 2 +btcdeb> step + <> PUSH stack 02 +script | stack +---------+-------- +OP_DUP | 02 +OP_DUP | +7 | +OP_ADD | +OP_ADD | +OP_ADD | +13 | +OP_EQUAL | + +#0001 OP_DUP +btcdeb> step + <> PUSH stack 02 +script | stack +---------+-------- +OP_DUP | 02 +7 | 02 +OP_ADD | +OP_ADD | +OP_ADD | +13 | +OP_EQUAL | + +#0002 OP_DUP +btcdeb> step + <> PUSH stack 02 +script | stack +---------+-------- +7 | 02 +OP_ADD | 02 +OP_ADD | 02 +OP_ADD | +13 | +OP_EQUAL | + +#0003 7 +btcdeb> step + <> PUSH stack 07 +script | stack +---------+-------- +OP_ADD | 07 +OP_ADD | 02 +OP_ADD | 02 +13 | 02 +OP_EQUAL | + +#0004 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 09 +script | stack +---------+-------- +OP_ADD | 09 +OP_ADD | 02 +13 | 02 +OP_EQUAL | + +#0005 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 0b +script | stack +---------+-------- +OP_ADD | 0b +13 | 02 +OP_EQUAL | + +#0006 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 0d +script | stack +---------+-------- +13 | 0d +OP_EQUAL | +#0007 13 +btcdeb> step + <> PUSH stack 0d +script | stack +---------+-------- +OP_EQUAL | 0d + | 0d + +#0008 OP_EQUAL +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 +script | stack +---------+-------- + | 01 +``` +### Scrivere un Sistema di Equazioni + +E se volessi invece scrivere un sistema di equazioni, come `x + y = 3`, `y + z = 5` e `x + z = 4`? Un po' di algebra ti dice che le risposte sono `x = 1`, `y = 2` e `z = 3`. Ma come lo scripti? + +Ovviamente, dopo che il redentore ha inserito i tre numeri, avrai bisogno di due copie di ogni numero, poiché ogni numero entra in due equazioni diverse. `OP_3DUP` si occupa di questo e risulta in `x y z x y z` sullo stack. Eliminando due elementi alla volta otterrai `y z`, `z x` e `x y`. Voilà! Queste sono le tre equazioni, quindi devi solo sommarle e testarle nell'ordine giusto! Ecco lo script completo: `OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL`. + +Ecco come funziona con lo script di sblocco corretto di `1 2 3`: + +``` +Script: 1 2 3 OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Stack: [ ] + +Script: OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Stack: [ 1 2 3 ] + +Script: OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Running: 1 2 3 OP_3DUP +Stack: [ 1 2 3 1 2 3 ] + +Script: 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Running: 2 3 OP_ADD +Stack: [ 1 2 3 1 5 ] + +Script: OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Stack: [ 1 2 3 1 5 5 ] + +Script: OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Running: 5 5 OP_EQUALVERIFY +Stack: [ 1 2 3 1 ] — Does Not Exit + +Script: 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Running: 3 1 OP_ADD +Stack: [ 1 2 4 ] + +Script: OP_EQUALVERIFY OP_ADD 3 OP_EQUAL +Stack: [ 1 2 4 4 ] + +Script: OP_ADD 3 OP_EQUAL +Running: 4 4 OP_EQUALVERIFY +Stack: [ 1 2 ] — Does Not Exit + +Script: 3 OP_EQUAL +Running: 1 2 OP_ADD +Stack: [ 3 ] + +Script: OP_EQUAL +Stack: [ 3 3 ] + +Script: +Running: 3 3 OP_EQUAL +Stack: [ True ] +``` +Ecco in `btcdeb`: +``` +$ btcdeb '[1 2 3 OP_3DUP OP_ADD 5 OP_EQUALVERIFY OP_ADD 4 OP_EQUALVERIFY OP_ADD 3 OP_EQUAL]' +btcdeb 0.2.19 -- type `btcdeb -h` for start up options +valid script +13 op script loaded. type `help` for usage information +script | stack +---------------+-------- +1 | +2 | +3 | +OP_3DUP | +OP_ADD | +5 | +OP_EQUALVERIFY | +OP_ADD | +4 | +OP_EQUALVERIFY | +OP_ADD | +3 | +OP_EQUAL | + +#0000 1 +btcdeb> step + <> PUSH stack 01 +script | stack +---------------+-------- +2 | 01 +3 | +OP_3DUP | +OP_ADD | +5 | +OP_EQUALVERIFY | +OP_ADD | +4 | +OP_EQUALVERIFY | +OP_ADD | +3 | +OP_EQUAL | + +#0001 2 +btcdeb> step + <> PUSH stack 02 +script | stack +---------------+-------- +3 | 02 +OP_3DUP | 01 +OP_ADD | +5 | +OP_EQUALVERIFY | +OP_ADD | +4 | +OP_EQUALVERIFY | +OP_ADD | +3 | +OP_EQUAL | + +#0002 3 +btcdeb> step + <> PUSH stack 03 +script | stack +---------------+-------- +OP_3DUP | 03 +OP_ADD | 02 +5 | 01 +OP_EQUALVERIFY | +OP_ADD | +4 | +OP_EQUALVERIFY | +OP_ADD | +3 | +OP_EQUAL | + +#0003 OP_3DUP +btcdeb> step + <> PUSH stack 01 + <> PUSH stack 02 + <> PUSH stack 03 +script | stack +---------------+-------- +OP_ADD | 03 +5 | 02 +OP_EQUALVERIFY | 01 +OP_ADD | 03 +4 | 02 +OP_EQUALVERIFY | 01 +OP_ADD | +3 | +OP_EQUAL | + +#0004 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 05 +script | stack +---------------+-------- +5 | 05 +OP_EQUALVERIFY | 01 +OP_ADD | 03 +4 | 02 +OP_EQUALVERIFY | 01 +OP_ADD | +3 | +OP_EQUAL | + +#0005 5 +btcdeb> step + <> PUSH stack 05 +script | stack +---------------+-------- +OP_EQUALVERIFY | 05 +OP_ADD | 05 +4 | 01 +OP_EQUALVERIFY | 03 +OP_ADD | 02 +3 | 01 +OP_EQUAL | + +#0006 OP_EQUALVERIFY +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 + <> POP stack +script | stack +---------------+-------- +OP_ADD | 01 +4 | 03 +OP_EQUALVERIFY | 02 +OP_ADD | 01 +3 | +OP_EQUAL | + +#0007 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 04 +script | stack +---------------+-------- +4 | 04 +OP_EQUALVERIFY | 02 +OP_ADD | 01 +3 | +OP_EQUAL | + +#0008 4 +btcdeb> step + <> PUSH stack 04 +script | stack +---------------+-------- +OP_EQUALVERIFY | 04 +OP_ADD | 04 +3 | 02 +OP_EQUAL | 01 + +#0009 OP_EQUALVERIFY +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 + <> POP stack +script | stack +---------------+-------- +OP_ADD | 02 +3 | 01 +OP_EQUAL | + +#0010 OP_ADD +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 03 +script | stack +---------------+-------- +3 | 03 +OP_EQUAL | + +#0011 3 +btcdeb> step + <> PUSH stack 03 +script | stack +---------------+-------- +OP_EQUAL | 03 + | 03 + +#0012 OP_EQUAL +btcdeb> step + <> POP stack + <> POP stack + <> PUSH stack 01 +script | stack +---------------+-------- + | 01 +``` + +> :warning: **ATTENZIONE** `btcdeb` non è solo utile per fornire una visualizzazione di questi script, ma anche per controllare i risultati. Sicuramente, abbiamo sbagliato la prima volta, testando le equazioni nell'ordine sbagliato. È così facile commettere un errore finanziario fatale in uno script Bitcoin, ed è per questo che ogni script deve essere testato. + +## Scrivere Script Computazionali Semplici + +Anche se gli script enigmatici sono banali, possono effettivamente avere un'utilità nel mondo reale se vuoi fare crowdsourcing di un calcolo. Crei semplicemente uno script che richiede la risposta al calcolo e invii fondi all'indirizzo P2SH come ricompensa. Rimarrà lì fino a quando qualcuno non troverà la risposta. + +Ad esempio, Peter Todd ha [offerto ricompense](https://bitcointalk.org/index.php?topic=293382.0) per risolvere equazioni che dimostrano collisioni per algoritmi crittografici standard. Ecco il suo script per confermare una collisione SHA1: `OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL`. Richiede due input, che saranno i due numeri che collidono. + +Ecco come funziona con le risposte corrette. + +Per prima cosa, riempiamo il nostro stack: + +``` +Script: OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Stack: [ ] + +Script: OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Stack: [ ] + +Script: OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Running: OP_2DUP +Stack: [ ] +``` +Poi, ci assicuriamo che i due numeri non siano uguali, uscendo se lo sono: +``` +Script: OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Running: OP_EQUAL +Stack: [ False ] + +Script: OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Running: False OP_NOT +Stack: [ True ] + +Script: OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL +Running: True OP_VERIFY +Stack: [ ] — Does Not Exit +``` +Ora creiamo due SHA: +``` +Script: OP_SWAP OP_SHA1 OP_EQUAL +Running: OP_SHA1 +Stack: [ ] + +Script: OP_SHA1 OP_EQUAL +Running: OP_SWAP +Stack: [ ] + +Script: OP_EQUAL +Running: OP_SHA1 +Stack: [ ] +``` +Infine, vediamo se corrispondono. +``` +Script: +Running: OP_EQUAL +Stack: [ True ] +``` +Questo è un buon script perché mostra un uso attento della logica (con `OP_NOT` e `OP_VERIFY`) e un buon uso delle funzioni stack (con `OP_SWAP`). È tutto sommato un ottimo esempio di una funzione del mondo reale. Ed è davvero del mondo reale. Quando [SHA-1 è stato violato](https://shattered.io/), 2.48 BTC sono stati rapidamente liberati dall'indirizzo, con un valore totale di circa $3,000 all'epoca. + +`btcdeb` può essere eseguito per dimostrare la collisione (e lo script): + +``` +$ btcdeb '[255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017f46dc93a6b67e013b029aaa1db2560b45ca67d688c7f84b8c4c791fe02b3df614f86db1690901c56b45c1530afedfb76038e972722fe7ad728f0e4904e046c230570fe9d41398abe12ef5bc942be33542a4802d98b5d70f2a332ec37fac3514e74ddc0f2cc1a874cd0c78305a21566461309789606bd0bf3f98cda8044629a1 255044462d312e330a25e2e3cfd30a0a0a312030206f626a0a3c3c2f57696474682032203020522f4865696768742033203020522f547970652034203020522f537562747970652035203020522f46696c7465722036203020522f436f6c6f7253706163652037203020522f4c656e6774682038203020522f42697473506572436f6d706f6e656e7420383e3e0a73747265616d0affd8fffe00245348412d3120697320646561642121212121852fec092339759c39b1a1c63c4c97e1fffe017346dc9166b67e118f029ab621b2560ff9ca67cca8c7f85ba84c79030c2b3de218f86db3a90901d5df45c14f26fedfb3dc38e96ac22fe7bd728f0e45bce046d23c570feb141398bb552ef5a0a82be331fea48037b8b5d71f0e332edf93ac3500eb4ddc0decc1a864790c782c76215660dd309791d06bd0af3f98cda4bc4629b1 OP_2DUP OP_EQUAL OP_NOT OP_VERIFY OP_SHA1 OP_SWAP OP_SHA1 OP_EQUAL]' +``` + +Le altre [ricompense](https://bitcointalk.org/index.php?topic=293382.0) di Peter Todd rimangono non rivendicate al momento della scrittura. Sono tutte scritte nello stesso modo dell'esempio SHA-1 sopra. + +## Comprendere le Limitazioni degli Script Enigmatici + +Gli script enigmatici sono ottimi per esaminare ulteriormente la Scrittura Bitcoin, ma li vedrai nel mondo reale solo se contengono piccole quantità di fondi o se sono destinati a essere riscattati da utenti molto abili. C'è una ragione per questo: non sono sicuri. + +Ecco dove la sicurezza cade: + +Innanzitutto, chiunque può riscattarli senza sapere molto di un segreto. Devono avere lo `script di riscatto`, che offre una certa protezione, ma una volta che lo hanno, probabilmente è l'unico segreto necessario — a meno che il tuo enigma non sia _davvero_ difficile, come un enigma computazionale. + +In secondo luogo, il riscatto effettivo non è sicuro. Normalmente, una transazione Bitcoin è protetta dalla firma. Poiché la firma copre la transazione, nessuno sulla rete può riscrivere quella transazione per inviarla al proprio indirizzo senza invalidare la firma (e quindi la transazione). Questo non è vero con una transazione i cui input sono solo numeri. Chiunque potrebbe prendere la transazione e riscriverla per consentire loro di rubare i fondi. Se riescono a far entrare la loro transazione in un blocco prima della tua, vincono e tu non ottieni i soldi dell'enigma. Ci sono soluzioni per questo, ma coinvolgono il mining del blocco da soli o avere un pool di fiducia che lo mini, e nessuna di queste opzioni è razionale per un utente Bitcoin medio. + +Eppure, le ricompense crittografiche di Peter Todd dimostrano che gli script enigmatici hanno qualche applicazione nel mondo reale. + +## Riepilogo: Scrivere Script Enigmatici + +Gli script enigmatici sono una grande introduzione a script Bitcoin più realistici e complessi. Dimostrano la potenza delle funzioni matematiche e di stack in Bitcoin Script e come possono essere combinati con cura per creare domande che richiedono risposte molto specifiche. Tuttavia, il loro uso nel mondo reale è limitato dai problemi di sicurezza inerenti alle transazioni Bitcoin non firmate. + +> :fire: ***Qual è la potenza degli script enigmatici?*** Nonostante le loro limitazioni, gli script enigmatici sono stati usati nel mondo reale come premi per ricompense computazionali. Chiunque riesca a risolvere un enigma complesso, la cui soluzione presumibilmente ha un impatto nel mondo reale, può vincere la ricompensa. Se riescono a tenerla realmente è un'altra questione. + +## Cosa c'è dopo? + +Continua "Progettare Veri Script Bitcoin" con [Capitolo 13.2: Scrivere Scripts Multifirma Complessi](13_2_Scrivere_Scripts_Multifirma_Complessi.md). diff --git a/it/13_2_Scrivere_Scripts_Multifirma_Complessi.md b/it/13_2_Scrivere_Scripts_Multifirma_Complessi.md new file mode 100644 index 000000000..e568a040e --- /dev/null +++ b/it/13_2_Scrivere_Scripts_Multifirma_Complessi.md @@ -0,0 +1,164 @@ +# 13.2: Scrivere Script Multisig Complessi + +Finora, i multisig descritti in questi documenti sono stati completamente semplici, della forma m-di-n o n-di-n. Tuttavia, potresti desiderare multisig più complessi, dove i cosigner variano o dove diverse opzioni potrebbero diventare disponibili nel tempo. + +## Scrivere un Multisig Variabile + +Un multisig variabile richiede numeri diversi di persone per firmare a seconda di chi sta firmando. + +### Scrivere un Multisig con un Singolo Firmatario o Co-Firmatari + +Immagina una corporazione dove sia il presidente o due dei tre vice-presidenti potrebbero concordare l'uso dei fondi. + +Puoi scriverlo creando un'istruzione `IF`/`ELSE`/`ENDIF` che ha due blocchi, uno per il presidente e la sua firma uno-di-uno e uno per i vice-presidenti e le loro firme due-di-tre. Puoi quindi determinare quale blocco usare in base a quante firme ci sono nello script di sblocco. Usare `OP_DEPTH 1 OP_EQUAL` ti dirà se c'è un elemento nello stack, e da lì procedi. + +Lo script di blocco completo sarebbe `OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF` + +Se eseguito dal presidente, apparirebbe così: + +``` +Script: OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ ] + +Script: OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ ] + +Script: 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Running: OP_DEPTH +Stack: [ 1 ] + +Script: OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ 1 1 ] + +Script: IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Running: 1 1 OP_EQUAL +Stack: [ True ] +``` +Poiché il risultato è `True`, lo Script ora si riduce all'istruzione `IF`: +``` +Script: OP_CHECKSIGNATURE +Running: True IF +Stack: [ ] + +Script: OP_CHECKSIGNATURE +Stack: [ ] + +Script: +Running: OP_CHECKSIGNATURE +Stack: [ True ] +``` +Se eseguito da due vice-presidenti, apparirebbe così: +``` +Script: 0 OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ ] + +Script: OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ 0 ] + +Script: 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Running: 0 OP_DEPTH +Stack: [ 0 3 ] + +Script: OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Stack: [ 0 3 1 ] + +Script: IF OP_CHECKSIGNATURE ELSE 2 3 OP_CHECKMULTISIG ENDIF +Running: 3 1 OP_EQUAL +Stack: [ 0 False ] +``` +Poiché il risultato è `False`, lo Script ora si riduce all'istruzione `ELSE`: +``` +Script: 2 3 OP_CHECKMULTISIG +Running: False IF +Stack: [ 0 ] + +Script: OP_CHECKMULTISIG +Stack: [ 0 2 3 ] + +Script: +Running: 0 2 3 OP_CHECKMULTISIG +Stack: [ ] +``` +Potresti notare che la firma del Presidente utilizza solo un semplice `OP_CHECKSIGNATURE` piuttosto che il codice più complesso solitamente richiesto per un P2PKH. Possiamo permetterci di includere la chiave pubblica nello script di blocco, evitando la solita trafila, perché è hashata e non sarà rivelata (attraverso il `redeemScript`) fino a quando la transazione non sarà sbloccata. Questo consente anche a tutti i firmatari possibili di firmare utilizzando la stessa metodologia. + +L'unico possibile problema è se il Presidente è smemorato e firma accidentalmente una transazione con uno dei suoi Vice-Presidenti, perché ricorda che si tratta di un multisig 2-di-3. Un'opzione è decidere che è una condizione di errore accettabile, perché il Presidente sta usando il multisig in modo errato. Un'altra opzione è trasformare il multisig 2-di-3 in un multisig 2-di-4, nel caso in cui il Presidente non tolleri errori: `OP_DEPTH 1 OP_EQUAL IF OP_CHECKSIGNATURE ELSE 2 4 OP_CHECKMULTISIG ENDIF`. Questo permetterebbe al Presidente di firmare erroneamente con qualsiasi Vice-Presidente, ma non influirebbe se due Vice-Presidenti volessero (correttamente) firmare. + +### Scrivere un Multisig con un Firmatario Richiesto + +Un'altra possibilità multisig prevede un multisig m-di-n dove uno dei firmatari è richiesto. Questo può solitamente essere gestito scomponendo il multisig in più multisig m di n-1. Ad esempio, un multisig 2-di-3 dove uno dei firmatari è richiesto sarebbe in realtà due multisig 2-di-2, ciascuno includendo il firmatario richiesto. + +Ecco un modo semplice per scriverlo: + +``` +OP_3DUP +2 2 OP_CHECKMULTISIG +NOTIF + + 2 2 OP_CHECKMULTISIG + +ENDIF +``` +Lo script di sblocco sarebbe `0 ` o `0 `. + +Prima lo Script controllerebbe le firme contro ` `. Se fallisce, controllerebbe contro ` `. + +Il risultato dell'ultimo `OP_CHECKMULTISIG` che è stato eseguito sarà lasciato in cima allo stack (anche se ci sarà spazzatura sotto di esso se il primo è riuscito). + +## Scrivere un Multisig Escrow + +Abbiamo parlato molto di escrow. I multisig complessi combinati con i timelock offrono un modo automatizzato per crearli in modo robusto. + +Immagina l'acquirente di una casa Alice e il venditore della casa Bob che lavorano con un agente escrow. Il modo semplice per scrivere questo sarebbe come un multisig dove qualsiasi due delle tre parti potrebbero rilasciare il denaro: o il venditore e l'acquirente sono d'accordo o l'agente escrow prende il controllo e concorda con una delle parti: `2 3 OP_CHECKMULTISIG`. + +Tuttavia, questo indebolisce il potere dell'agente escrow e consente al venditore e all'acquirente di prendere accidentalmente una decisione sbagliata tra loro — che è una delle cose che un sistema escrow è progettato per evitare. Quindi potrebbe essere che ciò che vogliamo veramente è il sistema che abbiamo appena esposto, dove l'agente escrow è una parte richiesta nel multisig 2-di-3: `OP_3DUP 2 2 OP_CHECKMULTISIG NOTIF 2 2 OP_CHECKMULTISIG ENDIF`. + +Tuttavia, questo non passa il test del "camminare davanti a un autobus". Se l'agente escrow muore o fugge alle Bahamas durante l'escrow, l'acquirente e il venditore perderanno molti soldi. Qui entra in gioco un timelock. Puoi creare un test aggiuntivo che verrà eseguito solo se abbiamo superato il periodo di escrow. In questa situazione, permetti all'acquirente e al venditore di firmare insieme: + +``` +OP_3DUP +2 2 OP_CHECKMULTISIG +NOTIF + + OP_3DUP + 2 2 OP_CHECKMULTISIG + NOTIF + + <+30Days> OP_CHECKSEQUENCEVERIFY OP_DROP + 2 2 OP_CHECKMULTISIG + + ENDIF +ENDIF +``` +Prima, testi una firma per l'acquirente e l'agente escrow, poi una firma per il venditore e l'agente escrow. Se entrambe falliscono e sono passati 30 giorni, permetti anche una firma per l'acquirente e il venditore. + +### Scrivere un Multisig Escrow Centrato sull'Acquirente + +[BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Escrow_with_Timeout) offre un esempio diverso di questo tipo di escrow che non ha le protezioni extra per evitare di aggirare l'agente escrow, ma che dà ad Alice il controllo totale se l'escrow fallisce. + +``` +IF + + 2 3 OP_CHECKMULTISIG + +ELSE + + <+30Days> OP_CHECKSEQUENCEVERIFY OP_DROP + OP_CHECKSIGNATURE + +ENDIF +``` +Qui, qualsiasi due dei tre firmatari possono rilasciare il denaro in qualsiasi momento, ma dopo 30 giorni Alice può recuperare i suoi soldi da sola. + +Nota che questo Script richiede un `True` o `False` da passare per identificare quale ramo viene utilizzato. Questo è un modo più semplice e meno intensivo dal punto di vista computazionale per supportare i rami in un Bitcoin Script; è abbastanza comune. + +All'inizio, il seguente `sigScript` sarebbe consentito: `0 True`. Dopo 30 giorni, Alice potrebbe produrre un `sigScript` come questo: ` False`. + +## Riepilogo: Scrivere Script Multisig Complessi + +Le multisignature più complesse possono essere solitamente create combinando firme o multisignature con condizionali e test. I multisig risultanti possono essere variabili, richiedendo numeri diversi di firmatari in base a chi sono e quando stanno firmando. + +> :fire: ***Qual è la potenza degli script multisig complessi?*** Più di qualsiasi cosa vista finora, gli script multisig complessi sono veri e propri contratti intelligenti. Possono essere molto precisi su chi è autorizzato a firmare e quando. Possono supportare corporazioni multi-livello, partnership e escrow. Usare altre funzionalità potenti come i timelock può ulteriormente proteggere questi fondi, permettendo che siano rilasciati o addirittura restituiti in determinati momenti. + +## Cosa c'è dopo? + +Continua con "Progettare Script Bitcoin Reali" col [Capitolo 13.3: Potenziare Bitcoin con Scripts](13_3_Potenziare_Bitcoin_con_Scripts.md). diff --git a/it/13_3_Potenziare_Bitcoin_con_Scripts.md b/it/13_3_Potenziare_Bitcoin_con_Scripts.md new file mode 100644 index 000000000..0332e96fc --- /dev/null +++ b/it/13_3_Potenziare_Bitcoin_con_Scripts.md @@ -0,0 +1,301 @@ +# 13.3: Potenziare Bitcoin con gli Script + +Gli Script Bitcoin possono andare ben oltre i relativi semplici strumenti finanziari dettagliati fino ad oggi. Sono anche la base della maggior parte degli usi complessi della rete Bitcoin, come dimostrato da questi esempi reali di funzionalità off-chain, tratti dagli esempi della Lightning Network in [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki). + +## Blocco per la Lightning Network + +La [Lightning Network](https://rusty.ozlabs.org/?p=450) è un canale di pagamento che consente agli utenti di prelevare fondi off-chain e impegnarsi in numerose microtransazioni prima di finalizzare il canale di pagamento e riportare i fondi in Bitcoin. I vantaggi includono commissioni più basse e velocità di transazione più elevate. Viene discussa in maggior dettaglio, con esempi di come utilizzarla dalla riga di comando, a partire dal [Capitolo 19](19_0_Understanding_Your_Lightning_Setup.md). + +[BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki) contiene alcuni esempi di come queste transazioni off-chain potrebbero essere generate, utilizzando script di blocco Bitcoin. + +### Blocco con Transazioni di Impegno Revocabili + +Il trucco con Lightning è il fatto che è off-chain. Per utilizzare Lightning, i partecipanti bloccano congiuntamente i fondi sulla blockchain Bitcoin con una multisignature n-di-n. Quindi, si impegnano in una serie di transazioni tra loro. Ogni nuova "transazione di impegno" divide quei fondi congiunti in modo diverso; queste transazioni sono parzialmente firmate ma _non vengono messe sulla blockchain_. + +Se hai una massa di transazioni non pubblicate, ognuna delle quali _potrebbe_ essere inserita nella Blockchain, come fai a impedire a uno dei partecipanti di tornare a una vecchia transazione più vantaggiosa per loro? La risposta è _revoca_. Un esempio semplificato in BIP 112, che offre una delle tappe per Lightning, mostra come: dai al partecipante che sarebbe danneggiato dalla reversione a una transazione revocata la possibilità di reclamare i fondi lui stesso se l'altro partecipante cerca illegittimamente di usare la transazione revocata. + +Ad esempio, supponiamo che Alice e Bob aggiornino la transazione di impegno per dare più fondi a Bob (effettivamente: Alice ha inviato fondi a Bob tramite la rete Lightning). Firmano parzialmente nuove transazioni, ma offrono anche ciascuno il proprio `revokeCode` per le transazioni precedenti. Questo garantisce effettivamente che non pubblicheranno transazioni precedenti, perché farlo permetterebbe alla loro controparte di reclamare quei fondi precedenti. + +Allora, come appariva la vecchia transazione? Era una transazione di impegno che mostrava fondi destinati ad Alice, prima che li desse a Bob. Aveva uno script di blocco come segue: + +``` +OP_HASH160 + +OP_EQUAL + +IF + + + +ELSE + + <+24Hours> + OP_CHECKSEQUENCEVERIFY + OP_DROP + + +ENDIF +OP_CHECKSIG +``` +Il blocco `ELSE` è dove Alice otteneva i suoi fondi, dopo un ritardo di 24 ore. Tuttavia ora è stato superato; questo è il punto centrale di un canale di pagamento in stile Lightning, dopo tutto. In questa situazione, questa transazione non dovrebbe mai essere pubblicata. Bob non ha alcun incentivo a farlo perché ha una nuova transazione, che lo avvantaggia di più perché ha ricevuto alcuni dei fondi di Alice. Alice non ha neanche incentivo, perché perde i fondi se ci prova a causa di quel `revokeCode`. Quindi nessuno mette la transazione sulla blockchain e le transazioni off-chain continuano. + +Vale la pena esplorare come questo script funzionerebbe in una varietà di situazioni, la maggior parte delle quali coinvolge Alice che cerca di barare tornando a questa vecchia transazione, che descrive i fondi _prima_ che Alice ne inviasse alcuni a Bob. + +#### Eseguire lo Script di Blocco per Alice che Bara, con Codice di Revoca + +Alice potrebbe provare a usare il codice di revoca che ha dato a Bob per reclamare immediatamente i fondi. Scrive uno script di blocco di ` `: + +``` +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: OP_EQUAL +Stack: [ True ] +``` +L'`OP_EQUAL` alimenta l'istruzione `IF`. Poiché Alice usa il `revokeCode`, entra nel ramo che le permette di riscattare immediatamente i fondi, riducendo il resto dello script a `` (all'interno del condizionale) e `OP_CHECKSIG` (dopo). +``` +Script: OP_CHECKSIG +Running: True IF +Stack: [ ] +``` +Maledizione! Solo Bob può firmare immediatamente usando il `redeemCode`! +``` +Script: OP_CHECKSIG +Stack: [ ] + +Script: +Running: OP_CHECKSIG +Stack: [ False ] +``` +#### Eseguire lo Script di Blocco per Alice che Bara, senza Codice di Revoca + +Quindi cosa succede se Alice invece prova a usare la propria firma, senza il `revokeCode`? Usa uno script di sblocco di ` `. +``` +Script: 0 OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ 0 ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: 0 OP_HASH160 +Stack: [ <0Hash> ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ <0Hash> ] + +Script: IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: <0Hash> OP_EQUAL +Stack: [ False ] +``` +Ora ci riduciamo all'istruzione `ELSE` e a ciò che viene dopo il condizionale: +``` +Script: <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKSIG +Running: False IF +Stack: [ ] + +Script: OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKSIG +Stack: [ <+24Hours> ] +``` +E poi Alice viene nuovamente sventata perché non sono passate 24 ore! +``` +Script: OP_DROP OP_CHECKSIG +Running: <+24Hours> OP_CHECKSEQUENCEVERIFY +Stack: [ <+24Hours> ] — Script EXITS +``` +#### Eseguire lo Script di Blocco per Bob Vittima + +Ciò significa che Bob ha 24 ore per reclamare i suoi fondi se Alice tenta mai di barare, usando il `` e la sua firma come script di sblocco: + +``` +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_HASH160 OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: OP_HASH160 +Stack: [ ] + +Script: OP_EQUAL IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Stack: [ ] + +Script: IF ELSE <+24Hours> OP_CHECKSEQUENCEVERIFY OP_DROP ENDIF OP_CHECKSIG +Running: OP_EQUAL +Stack: [ True ] + +Script: OP_CHECKSIG +Running: True IF +Stack: [ ] + +Script: OP_CHECKSIG +Stack: [ ] + +Script: +Running: OP_CHECKSIG +Stack: [ True ] +``` +#### Eseguire lo Script di Blocco per Alice Virtuosa + +Tutte le transazioni di impegno di Alice sono bloccate con questo stesso script di blocco, siano state revocate o meno. Ciò significa che anche la più recente transazione di impegno, che è quella attualmente valida, è bloccata con essa. Alice non ha mai inviato una nuova transazione a Bob e quindi non gli ha mai inviato il precedente `revokeCode`. + +In questa situazione, potrebbe pubblicare virtuosamente la transazione, chiudendo il canale proto-Lightning. Mette la transazione sulla catena e aspetta 24 ore. Bob non può fare nulla al riguardo perché non ha il codice di revoca. Quindi, dopo l'attesa, Alice reclama i suoi fondi. (Bob fa la stessa cosa con la sua ultima transazione di impegno.) + +### Blocco con Contratti Hashed Time-Lock + +Le Transazioni di Impegno Revocabili erano solo una tappa per Lightning. La vera Lightning Network utilizza un meccanismo più complesso chiamato [contratto hashed timelock](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts), o HTLC. + +Lo scopo principale degli HTLC è creare una rete completa di partecipanti. Le transazioni non sono più solo tra una coppia di partecipanti che sono entrati insieme nella rete, ma ora possono essere tra persone precedentemente non associate. Quando i fondi vengono inviati, viene creata una serie di transazioni, ciascuna bloccata con un `secretHash`. Quando viene rivelato il corrispondente `secretCode`, l'intera serie di transazioni può essere spesa. Questo è ciò che consente alle singole transazioni di diventare effettivamente una rete. + +C'è anche un po' più di complessità negli script di blocco della Lightning Network. Ci sono blocchi separati per il mittente e il destinatario di ciascuna transazione che sono più divergenti rispetto alle diverse transazioni di impegno menzionate nella sezione precedente. Mostreremo entrambi, per dimostrare la potenza di questi script di blocco, ma non ci soffermeremo su come interagiscono tra loro. + +#### Blocco della Transazione del Destinatario + +Ancora una volta, iniziamo a guardare la transazione di impegno di Alice, che mostra i fondi che ha ricevuto: +``` +OP_HASH160 +OP_DUP + +OP_EQUAL + +IF + + <+24Hours> + OP_CHECKSEQUENCEVERIFY + OP_2DROP + + +ELSE + + + OP_EQUAL + + OP_NOTIF + + + OP_CHECKLOCKTIMEVERIFY + OP_DROP + + ENDIF + + + +ENDIF + +OP_CHECKSIG +``` +La chiave di questi nuovi HTLC è il `secretHash`, che abbiamo detto è ciò che consente a una transazione di estendersi alla rete. Quando la transazione è passata dal suo originatore al destinatario previsto, viene rivelato il `secretCode`, che consente a tutti i partecipanti di creare un `secretHash` e sbloccare l'intera rete di pagamenti. + +Dopo che il `secretCode` è stato rivelato, si apre il ramo `IF`: Alice può reclamare i fondi 24 ore dopo che la transazione è stata inserita nella rete Bitcoin. + +Tuttavia, c'è anche l'opportunità per Bob di reclamare i suoi fondi, che appare nel ramo `ELSE`. Può farlo se la transazione è stata revocata (ma Alice la mette comunque sulla blockchain), _o se_ si è verificato un timeout assoluto. + +#### Blocco della Transazione del Mittente + +Ecco il script di blocco alternativo della transazione di impegno utilizzato dal mittente: + +``` +OP_HASH160 +OP_DUP + +OP_EQUAL +OP_SWAP + +OP_EQUAL +OP_ADD + +IF + + + +ELSE + + + OP_CHECKLOCKTIMEVERIFY + <+24Hours> + OP_CHECKSEQUENCEVERIFY + OP_2DROP + + +ENDIF +OP_CHECKSIG +``` +La parte iniziale del loro Script è piuttosto ingegnosa e quindi vale la pena eseguirla: +``` +Initial Script: OP_HASH160 OP_DUP OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Stack: [ ] + +Initial Script: OP_HASH160 OP_DUP OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Stack: [ ] + +Initial Script: OP_DUP OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Running: OP_HASH160 +Stack: [ ] + +Initial Script: OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Running: OP_DUP +Stack: [ ] + +Initial Script: OP_EQUAL OP_SWAP OP_EQUAL OP_ADD +Stack: [ ] + +Initial Script: OP_SWAP OP_EQUAL OP_ADD +Running: OP_EQUAL +Stack: [ ] + +Initial Script: OP_EQUAL OP_ADD +Running: OP_SWAP +Stack: [ ] + +Initial Script: OP_EQUAL OP_ADD +Stack: [ ] + +Initial Script: OP_ADD +Running: OP_EQUAL +Stack: [ ] + +Initial Script: +Running: OP_ADD +Stack: [ ] +``` +Eseguire lo script rivela che i controlli iniziali, sopra il `IF`/`ELSE`/`ENDIF`, determinano se l'hash era _sia_ il `secretCode` _sia_ il `revokeCode`. Se sì, Alice può prendere i fondi nel primo blocco. Se no, Bob può prendere i fondi, ma solo dopo che Alice ha avuto la sua occasione e dopo che entrambi il timeout di 24 ore e il timeout assoluto sono passati. + +#### Comprendere gli HTLC + +Gli HTLC sono piuttosto complessi, e questa panoramica non cerca di spiegare tutte le loro complessità. La [panoramica](https://rusty.ozlabs.org/?p=462) di Rusty Russell spiega di più, e c'è ancora più dettaglio nel suo documento [Deployable Lightning](https://github.com/ElementsProject/lightning/blob/master/doc/deployable-lightning.pdf). Ma non preoccuparti se alcune delle complessità ti sfuggono ancora, in particolare le interrelazioni dei due script. + +Per i fini di questo tutorial, ci sono due lezioni importanti per gli HTLC: + + * Comprendere che una struttura molto complessa come un HTLC può essere creata con Bitcoin Script. + * Analizzare come eseguire ciascuno dei due script HTLC. + +Vale la pena eseguire ciascuno dei due script HTLC attraverso ciascuna delle sue permutazioni, un elemento dello stack alla volta. + +## Riepilogo: Potenziare Bitcoin con gli Script + +Stiamo chiudendo il nostro esame degli Script Bitcoin guardando a quanto possano essere veramente potenti. In 20 opcodes o meno, uno Script Bitcoin può costituire la base di un intero canale di pagamento off-chain. Allo stesso modo, le sidechain a due vie sono il prodotto di meno di venti opcodes, come brevemente notato anche in [BIP 112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki). + +Se hai mai visto funzionalità Bitcoin complesse o sistemi adiacenti a Bitcoin, probabilmente sono stati costruiti su Script Bitcoin. E ora hai tutti gli strumenti per fare lo stesso tu stesso. + +## Cosa c'è dopo? + +Prosegui con "Usare Tor" col [Capitolo 14: Usare Tor](14_0_Usare_Tor.md). + +Oppure, se preferisci, ci sono due percorsi alternativi: + +Se vuoi rimanere concentrato su Bitcoin, prosegui con "Programmazione con RPC" col [Capitolo 16.0: Parlare a Bitcoind con C](16_0_Parlare_a_Bitcoind_con_C.md). + +Oppure, se vuoi rimanere concentrato sulla riga di comando perché non sei un programmatore, puoi passare al [Capitolo 19.0: Comprendere la Configurazione Lightning](19_0_Comprendere_la_Configurazione_Lightning.md) per continuare la tua formazione sulla riga di comando con Lightning Network. + diff --git a/it/14_0_Usare_Tor.md b/it/14_0_Usare_Tor.md new file mode 100644 index 000000000..123bf437c --- /dev/null +++ b/it/14_0_Usare_Tor.md @@ -0,0 +1,22 @@ +# Capitolo 14: Utilizzare Tor + +Tor è uno dei programmi standard installati da [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). Aiuterà a mantenere il tuo server sicuro, il che è di fondamentale importanza quando si ha a che fare con la criptovaluta. Questo capitolo si discosta momentaneamente da Bitcoin per aiutarti a comprendere questa infrastruttura di sicurezza di base. + +## Obiettivi di Questo Capitolo + +Dopo aver lavorato su questo capitolo, uno sviluppatore sarà in grado di: + + * Utilizzare una Configurazione Tor + * Eseguire la Manutenzione di Tor + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere la Rete Tor + * Comprendere le Varie Porte di Bitcoin + +## Indice + +* [Capitolo 14.1: Verificare la Configurazione Tor](14_1_Verificare_la_Configurazione_Tor.md) +* [Capitolo 14.2: Cambiare Bitcoin Hidden Services](14_2_Cambiare_Bitcoin_Hidden_Services.md) +* [Capitolo 14.3: Aggiungere SSH Hidden Services](14_3_Aggiungere_SSH_Hidden_Services.md) + diff --git a/it/14_1_Verificare_la_Configurazione_Tor.md b/it/14_1_Verificare_la_Configurazione_Tor.md new file mode 100644 index 000000000..03d3aca5f --- /dev/null +++ b/it/14_1_Verificare_la_Configurazione_Tor.md @@ -0,0 +1,376 @@ +# 14.1: Verificare la Configurazione di Tor + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza preliminare che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Se hai effettuato un'installazione standard con [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup), dovresti avere Tor configurato come parte del tuo nodo Bitcoin: Tor è installato e ha creato servizi nascosti per le porte RPC di Bitcoin; mentre un indirizzo `onion` è stato creato anche per `bitcoind`. Questa sezione parla di cosa sia tutto questo e cosa fare con esso. + +> :book: ***Cos'è Tor?*** Tor è una rete di anonimato a bassa latenza e sovrapposizione basata sul routing a cipolla e sulla progettazione di costruzione del percorso per consentire la comunicazione anonima. È un software libero e open-source il cui nome deriva dall'acronimo del nome del progetto software originale: "The Onion Router". + +> :book: ***Perché Usare Tor per Bitcoin?*** La rete Bitcoin è una rete peer-to-peer che ascolta le transazioni e le propaga utilizzando un indirizzo IP pubblico. Quando ci si connette alla rete senza usare Tor, si condividerebbe il proprio indirizzo IP, il che potrebbe esporre la propria posizione, il tempo di attività e altri dettagli a terze parti — una pratica di privacy indesiderabile. Per proteggerti online dovresti usare strumenti come Tor per nascondere i dettagli della tua connessione. Tor ti consente di migliorare la tua privacy online poiché i tuoi dati sono crittograficamente codificati e passano attraverso diversi nodi, ciascuno dei quali decodifica un singolo strato (da qui la metafora della cipolla). + +## Comprendere Tor + +Quindi, come funziona Tor? + +Quando un utente vuole connettersi a un server Internet, Tor cerca di costruire un percorso formato da almeno tre nodi di relay Tor, chiamati Guard, Middle e Exit. Durante la costruzione di questo percorso, vengono negoziate chiavi di crittografia simmetriche; quando un messaggio si sposta lungo il percorso, ogni relay rimuove il proprio strato di crittografia. In questo modo, il messaggio arriva alla destinazione finale nella sua forma originale, e ogni parte conosce solo l'hop precedente e successivo e non può determinare l'origine o la destinazione. + +Ecco come appare una connessione senza Tor: +``` +20:58:03.804787 IP bitcoin.36300 > lb-140-82-114-25-iad.github.com.443: Flags [P.], seq 1:30, ack 25, win 501, options [nop,nop,TS val 3087919981 ecr 802303366], length 29 +``` +Al contrario, con Tor viene trasmessa molta meno informazione sulle macchine effettive: +``` +21:06:52.744602 IP bitcoin.58776 > 195-xxx-xxx-x.rev.pxxxxxm.eu.9999: Flags [P.], seq 264139:265189, ack 3519373, win 3410, options [nop,nop,TS val 209009853 ecr 3018177498], length 1050 +21:06:52.776968 IP 195-xxx-xxx-x.rev.pxxxxxm.eu.9999 > bitcoin.58776: Flags [.], ack 265189, win 501, options [nop,nop,TS val 3018177533 ecr 209009853], length 0 +``` +Conclusione: Tor crittografa i tuoi dati in modo tale da nascondere la tua origine, la tua destinazione e quali servizi stai utilizzando, mentre un protocollo di crittografia standard come TLS *protegge solo* il contenuto dei tuoi dati. + +### Comprendere l'Architettura della Rete Tor + +L'architettura di base della rete Tor è composta dai seguenti componenti: + +* **Tor Client (OP o Onion Proxy).** Un client Tor installa software locale che funge da onion proxy. Esso impacchetta i dati dell'applicazione in celle tutte della stessa dimensione (512 byte), che poi invia alla rete Tor. Una cella è l'unità base di trasmissione di Tor. +* **Onion Node (OR o Onion Router).** Un onion node trasmette celle provenienti dal client Tor e dai server online. Ci sono tre tipi di onion node: input (Guard), intermediate nodes (Middle) e output nodes (Exit). +* **Directory Server.** Un server di directory memorizza informazioni sugli onion routers e sugli onion servers (servizi nascosti), come le loro chiavi pubbliche. +* **Onion Server (hidden server).** Un onion server supporta applicazioni TCP come pagine web o IRC come servizi. + +### Comprendere le Limitazioni di Tor + +Tor non è uno strumento perfetto. Poiché le informazioni dalla rete Tor vengono decrittate ai nodi di uscita prima di essere inviate alle destinazioni finali, teoricamente un osservatore potrebbe raccogliere metadati sufficienti per compromettere l'anonimato e potenzialmente identificare gli utenti. + +Ci sono anche studi che suggeriscono che possibili exploit della protezione anti-DoS di Bitcoin potrebbero consentire a un attaccante di costringere altri utenti che usano Tor a connettersi esclusivamente tramite i suoi nodi di uscita Tor o ai suoi peer Bitcoin, isolando il client dal resto della rete Bitcoin ed esponendoli a censura, correlazione e altri attacchi. + +Allo stesso modo, gli utenti Bitcoin Tor potrebbero essere attaccati con fingerprint impostando un cookie di indirizzo sui loro nodi. Ciò consentirebbe anche la correlazione e quindi la deanonymization. + +Nel frattempo, anche su Tor, Bitcoin è solo un servizio pseudonimo a causa dei molti pericoli di correlazione derivanti dal ledger permanente stesso. Ciò significa che l'uso di Bitcoin su Tor è in realtà più probabile essere _deanonimizzato_ rispetto ad altri servizi (e potrebbe portare alla deanonymization di altre attività). + +Detto questo, Tor è generalmente considerato più sicuro dell'alternativa, che è la navigazione non anonima. + +## Verificare la Configurazione di Tor + +Quindi, come verifichi di aver abilitato Tor? Se hai installato con Bitcoin Standup, quanto segue verificherà che Tor sia in esecuzione sul tuo sistema: + +``` +$ sudo -u debian-tor tor --verify-config +``` + + +Se Tor è installato correttamente, dovresti ottenere un output simile a questo: +``` +Jun 26 21:52:09.230 [notice] Tor 0.4.3.5 running on Linux with Libevent 2.0.21-stable, OpenSSL 1.0.2n, Zlib 1.2.11, Liblzma 5.2.2, and Libzstd N/A. +Jun 26 21:52:09.230 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning +Jun 26 21:52:09.230 [notice] Read configuration file "/etc/tor/torrc". +Configuration was valid +``` +> :warning: **ATTENZIONE:** Questo significa solo che Tor è in esecuzione, non che sia utilizzato per tutte (o qualsiasi) connessioni. + +### Verificare la Configurazione di Tor per RPC + +Lo scopo più importante di Tor, come installato da Bitcoin Standup, è offrire servizi nascosti per le porte RPC che vengono utilizzate per inviare comandi in stile linea di comando a `bitcoind`. + +> :book: ***Cos'è un Servizio Nascosto di Tor?*** Un servizio nascosto (alias "onion service") è un servizio accessibile tramite Tor. La connessione effettuata a quel servizio _utilizzando la Rete Onion_ sarà anonima. + +Il file di configurazione di Tor si trova in `/etc/tor/torrc`. Se lo guardi, dovresti vedere i seguenti servizi per proteggere le tue porte RPC: + +``` +HiddenServiceDir /var/lib/tor/standup/ +HiddenServiceVersion 3 +HiddenServicePort 1309 127.0.0.1:18332 +HiddenServicePort 1309 127.0.0.1:18443 +HiddenServicePort 1309 127.0.0.1:8332 +``` +> :link: **TESTNET vs MAINNET:** L'RPC del Mainnet è eseguito sulla porta 8332, quello del testnet sulla porta 18332. + +> :information_source: **NOTA:** La `HiddenServiceDir` è dove sono conservati tutti i file per questo particolare servizio. Se hai bisogno di cercare il tuo indirizzo onion, le chiavi di accesso o aggiungere client autorizzati, questo è il posto dove farlo! + +Il modo semplice per testare il tuo Servizio Nascosto RPC è utilizzare l'[API QuickConnect](https://github.com/BlockchainCommons/Bitcoin-Standup/blob/master/Docs/Quick-Connect-API.md) integrata in Bitcoin Standup. Basta scaricare il codice QR trovato in `/qrcode.png` e scansionarlo utilizzando un wallet o un nodo che supporti QuickConnect, come [The Gordian Wallet](https://github.com/BlockchainCommons/FullyNoded-2). Quando scansionerai il QR, dovresti vedere il wallet sincronizzarsi con il tuo nodo; sta facendo ciò utilizzando i servizi nascosti RPC. + +Il modo difficile per testare il tuo Servizio Nascosto RPC è inviare un comando `bitcoin-cli` con `torify`, che ti consente di tradurre un comando UNIX normale in un comando protetto da Tor. È difficile perché devi raccogliere tre pezzi di informazioni. + +1. **La Porta del Servizio Nascosto.** Questo proviene da `/etc/tor/torrc/`. Per impostazione predefinita, è la porta 1309. +2. **Il Tuo Indirizzo Tor.** Questo si trova nel file `hostname` nella directory `HiddenServiceDir` definita in `/etc/tor/torrc`. Per impostazione predefinita, il file è quindi `/var/lib/tor/standup/hostname`. È protetto, quindi dovrai usare `sudo` per accedervi: + +``` +$ sudo more /var/lib/tor/standup/hostname +mgcym6je63k44b3i5uachhsndayzx7xi4ldmwrm7in7yvc766rykz6yd.onion +``` +3. **La Tua Password RPC.** Questa si trova in `~/.bitcoin/bitcoin.conf` + +Quando hai tutte queste informazioni, puoi emettere un comando `bitcoin-cli` utilizzando `torify` e specificando il `-rpcconnect` come il tuo indirizzo onion, il `-rpcport` come la tua porta del servizio nascosto e il `-rpcpassword` come la tua password: +``` +$ torify bitcoin-cli -rpcconnect=mgcym6je63k44b3i5uachhsndayzx7xi4ldmwrm7in7yvc766rykz6yd.onion -rpcport=1309 -rpcuser=StandUp -rpcpassword=685316cc239c24ba71fd0969fa55634f getblockcount +``` + + +### Verificare la Configurazione di Tor per Bitcoind + +Bitcoin Standup garantisce anche che il tuo `bitcoind` sia configurato per comunicare opzionalmente su un indirizzo onion. + +Puoi verificare la configurazione iniziale di Tor per `bitcoind` cercando "tor" nel `debug.log` nella tua directory dei dati: + +``` +$ grep "tor:" ~/.bitcoin/testnet3/debug.log +2021-06-09T14:07:04Z tor: ADD_ONION successful +2021-06-09T14:07:04Z tor: Got service ID vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd, advertising service vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion:18333 +2021-06-09T14:07:04Z tor: Cached service private key to /home/standup/.bitcoin/testnet3/onion_v3_private_key +``` +> :information_source: **NOTA:** Bitcoin Core non supporta più gli indirizzi v2. Il supporto per Tor v2 è stato rimosso in [#22050](https://github.com/bitcoin/bitcoin/pull/22050) + +> **TESTNET vs MAINNET:** Il `bitcoind` del Mainnet risponde sulla porta 8333, quello del testnet sulla porta 18333. + +Puoi verificare che sia stato creato un servizio nascosto Tor per Bitcoin con la chiamata RPC `getnetworkinfo`: + +``` +$ bitcoin-cli getnetworkinfo +... + "localaddresses": [ + { + "address": "173.255.245.83", + "port": 18333, + "score": 1 + }, + { + "address": "2600:3c01::f03c:92ff:fe86:f26", + "port": 18333, + "score": 1 + }, + { + "address": "vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion", + "port": 18333, + "score": 4 + } + ], +... +``` +Questo mostra tre indirizzi per accedere al tuo server Bitcoin, un indirizzo IPv4 (`173.255.245.83`), un indirizzo IPv6 (`2600:3c01::f03c:92ff:fe86:f26`) e un indirizzo Tor (`vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion`). + +> :warning: **ATTENZIONE:** Ovviamente: non rivelare mai il tuo indirizzo Tor in modo associato al tuo nome o altri dati personali! + +Puoi vedere informazioni simili con `getnetworkinfo`. + +``` + bitcoin-cli getnetworkinfo +{ + "version": 200000, + "subversion": "/Satoshi:0.20.0/", + "protocolversion": 70015, + "localservices": "0000000000000408", + "localservicesnames": [ + "WITNESS", + "NETWORK_LIMITED" + ], + "localrelay": true, + "timeoffset": 0, + "networkactive": true, + "connections": 10, + "networks": [ + { + "name": "ipv4", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "ipv6", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "onion", + "limited": false, + "reachable": true, + "proxy": "127.0.0.1:9050", + "proxy_randomize_credentials": true + } + ], + "relayfee": 0.00001000, + "incrementalfee": 0.00001000, + "localaddresses": [ + { + "address": "173.255.245.83", + "port": 18333, + "score": 1 + }, + { + "address": "2600:3c01::f03c:92ff:fe86:f26", + "port": 18333, + "score": 1 + }, + { + "address": "vazr3k6bgnfafmdpcmbegoe5ju5kqyz4tk7hhntgaqscam2qupdtk2yd.onion", + "port": 18333, + "score": 4 + } + ], + "warnings": "" +} +``` +Questo servizio nascosto consentirà connessioni anonime al tuo `bitcoind` sulla rete Bitcoin. + +> :warning: **ATTENZIONE:** Eseguire Tor e avere un servizio nascosto Tor non obbliga né te né i tuoi peer a usare Tor. + +### Verificare la Configurazione di Tor per i Peer + +Utilizzando il comando RPC `getpeerinfo`, puoi vedere quali nodi sono connessi al tuo nodo e verificare se sono connessi con Tor. + +. + +``` +$ bitcoin-cli getpeerinfo +``` +Alcuni potrebbero essere connessi tramite Tor: + +``` +... +{ + "id": 9, + "addr": "nkv.......xxx.onion:8333", + "addrbind": "127.0.0.1:51716", + "services": "000000000000040d", + "servicesnames": [ + "NETWORK", + "BLOOM", + "WITNESS", + "NETWORK_LIMITED" + ], + "relaytxes": true, + "lastsend": 1593981053, + "lastrecv": 1593981057, + "bytessent": 1748, + "bytesrecv": 41376, + "conntime": 1593980917, + "timeoffset": -38, + "pingwait": 81.649295, + "version": 70015, + "subver": "/Satoshi:0.20.0/", + "inbound": false, + "addnode": false, + "startingheight": 637875, + "banscore": 0, + "synced_headers": -1, + "synced_blocks": -1, + "inflight": [ + ], + "whitelisted": false, + "permissions": [ + ], + "minfeefilter": 0.00000000, + "bytessent_per_msg": { + "addr": 55, + "feefilter": 32, + "getaddr": 24, + "getheaders": 1053, + "inv": 280, + "ping": 32, + "pong": 32, + "sendcmpct": 66, + "sendheaders": 24, + "verack": 24, + "version": 126 + }, + "bytesrecv_per_msg": { + "addr": 30082, + "feefilter": 32, + "getdata": 280, + "getheaders": 1053, + "headers": 106, + "inv": 9519, + "ping": 32, + "pong": 32, + "sendcmpct": 66, + "sendheaders": 24, + "verack": 24, + "version": 126 + } + } +... +``` +Alcuni potrebbero non esserlo, come questa connessione IPv6: +``` +... + { + "id": 17, + "addr": "[2001:638:a000:4140::ffff:191]:18333", + "addrlocal": "[2600:3c01::f03c:92ff:fe86:f26]:36344", + "addrbind": "[2600:3c01::f03c:92ff:fe86:f26]:36344", + "services": "0000000000000409", + "servicesnames": [ + "NETWORK", + "WITNESS", + "NETWORK_LIMITED" + ], + "relaytxes": true, + "lastsend": 1595447081, + "lastrecv": 1595447067, + "bytessent": 12250453, + "bytesrecv": 2298711417, + "conntime": 1594836414, + "timeoffset": -1, + "pingtime": 0.165518, + "minping": 0.156638, + "version": 70015, + "subver": "/Satoshi:0.20.0/", + "inbound": false, + "addnode": false, + "startingheight": 1780784, + "banscore": 0, + "synced_headers": 1781391, + "synced_blocks": 1781391, + "inflight": [ + ], + "whitelisted": false, + "permissions": [ + ], + "minfeefilter": 0.00001000, + "bytessent_per_msg": { + "addr": 4760, + "feefilter": 32, + "getaddr": 24, + "getdata": 8151183, + "getheaders": 1085, + "headers": 62858, + "inv": 3559475, + "ping": 162816, + "pong": 162816, + "sendcmpct": 132, + "sendheaders": 24, + "tx": 145098, + "verack": 24, + "version": 126 + }, + "bytesrecv_per_msg": { + "addr": 33877, + "block": 2291124374, + "feefilter": 32, + "getdata": 9430, + "getheaders": 1085, + "headers": 60950, + "inv": 2019175, + "ping": 162816, + "pong": 162816, + "sendcmpct": 66, + "sendheaders": 24, + "tx": 5136622, + "verack": 24, + "version": 126 + } + } +... +``` +Avere un indirizzo Tor per il tuo `bitcoind` è probabilmente un po' meno utile che avere un indirizzo Tor per le tue connessioni RPC. Questo in parte perché non è consigliato cercare di inviare tutte le tue connessioni Bitcoin tramite Tor, e in parte perché proteggere i tuoi comandi RPC è davvero ciò che è importante: è molto più probabile che tu stia facendo ciò da remoto, da un wallet software come The Gordian Wallet, mentre il tuo server stesso è più probabilmente seduto nel tuo ufficio, seminterrato o bunker. + +Tuttavia, ci sono modi per far usare Tor di più a `bitcoind`, come discusso nella prossima sezione. + +## Riepilogo: Verificare la Configurazione di Tor + +Tor è un pacchetto software installato come parte di Bitcoin Standup che ti consente di scambiare comunicazioni in modo anonimo. Proteggerà sia le tue porte RPC (8332 o 18332) che le tue porte `bitcoind` (8333 o 18333) — ma devi collegarti attivamente all'indirizzo onion per usarle! Tor è una pietra miliare della privacy e della sicurezza per il tuo setup Bitcoin, e puoi verificare che sia disponibile e collegato a Bitcoin con pochi semplici comandi. + +> :fire: ***Qual è il potere di Tor?*** Molti attacchi agli utenti Bitcoin dipendono dal sapere chi è la vittima e che stanno transando Bitcoin. Tor può proteggerti da ciò nascondendo sia dove ti trovi che cosa stai facendo. È particolarmente importante se vuoi connetterti al tuo nodo da remoto tramite un wallet software, e può essere cruciale se lo fai in qualche paese dove potresti non sentirti che il tuo utilizzo di Bitcoin sia apprezzato o protetto. Se devi portare i tuoi servizi Bitcoin in viaggio, assicurati che il tuo wallet supporti pienamente Tor e scambi tutti i comandi RPC con il tuo server utilizzando quel protocollo. + +## Cosa c'è Dopo? + +Continua "Comprendere Tor" con [Capitolo 14.2: Cambiare Bitcoin Hidden Services](14_2_Cambiare_Bitcoin_Hidden_Services.md). + diff --git a/it/14_2_Cambiare_Bitcoin_Hidden_Services.md b/it/14_2_Cambiare_Bitcoin_Hidden_Services.md new file mode 100644 index 000000000..ffcadf393 --- /dev/null +++ b/it/14_2_Cambiare_Bitcoin_Hidden_Services.md @@ -0,0 +1,80 @@ +# Capitolo 14.2: Cambiare_Bitcoin_Hidden_Services + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Hai un servizio Tor funzionante, ma nel tempo potresti volerlo resettare o modificarlo in altro modo. + +## Mettere in Sicurezza i tuoi Servizi Nascosti + +Tor ti consente di limitare quali client possono comunicare con i tuoi servizi nascosti. Se non hai già autorizzato il tuo client durante la configurazione del server, alla prima opportunità dovresti fare quanto segue: + +1. Richiedi la tua Chiave Pubblica di Autenticazione Tor V3 dal tuo client. (In [GordianWallet](https://github.com/BlockchainCommons/GordianWallet-iOS), è disponibile nel menu delle impostazioni.) +2. Vai alla sottodirectory appropriata per il servizio nascosto di Bitcoin, che se hai utilizzato Bitcoin Standup è `/var/lib/tor/standup/`. +3. Vai alla sottodirectory `authorized_clients`. +4. Aggiungi un file chiamato `[qualsiasi_nome].auth`. `[qualsiasi_nome]` può essere davvero qualsiasi cosa. +5. Inserisci la chiave pubblica (e nient'altro) nel file. + +Una volta aggiunto un file `.auth` alla sottodirectory `authorized_client`, solo i client autorizzati potranno comunicare con quel servizio nascosto. Puoi aggiungere circa 330 diverse chiavi pubbliche per abilitare client diversi. + +## Resettare l'Indirizzo Onion di `bitcoind` + +Se mai desideri resettare il tuo indirizzo onion per `bitcoind`, rimuovi semplicemente la `onion_private_key` nella tua directory dei dati, come `~/.bitcoin/testnet`: + +``` +$ cd ~/.bitcoin/testnet +$ rm onion_private_key +``` +Quando riavvii, verrà generato un nuovo indirizzo onion: +``` +2020-07-22T23:52:27Z tor: Got service ID pyrtqyiqbwb3rhe7, advertising service pyrtqyiqbwb3rhe7.onion:18333 +2020-07-22T23:52:27Z tor: Cached service private key to /home/standup/.bitcoin/testnet3/onion_private_key +``` + +## Resettare l'Indirizzo Onion dell'RPC + +Se desideri resettare il tuo indirizzo onion per l'accesso RPC, cancella allo stesso modo la `HiddenServiceDirectory` appropriata e riavvia Tor: + +``` +$ sudo rm -rf /var/lib/tor/standup/ +$ sudo /etc/init.d/tor restart +``` + + +> :warning: **ATTENZIONE:** Resettare il tuo indirizzo onion dell'RPC disconnetterà eventuali portafogli mobili o altri servizi che hai connesso utilizzando l'API Quicklink. Fai questo con estrema cautela. + +## Forzare `bitcoind` a Usare Tor + +Infine, puoi forzare `bitcoind` a usare onion aggiungendo quanto segue al tuo `bitcoin.conf`: + +``` +proxy=127.0.0.1:9050 +listen=1 +bind=127.0.0.1 +onlynet=onion +``` +Dovrai quindi aggiungere nodi seed basati su onion o altri nodi alla tua configurazione, ancora una volta modificando il `bitcoin.conf`: +``` +seednode=address.onion +seednode=address.onion +seednode=address.onion +seednode=address.onion +addnode=address.onion +addnode=address.onion +addnode=address.onion +addnode=address.onion +``` +Consulta [Bitcoin Onion Nodes](https://github.com/emmanuelrosa/bitcoin-onion-nodes) per un elenco e un esempio su come aggiungerli. + +Successivamente, riavvia `tor` e `bitcoind`. + +Ora dovresti comunicare esclusivamente su Tor. Ma, a meno che tu non ti trovi in uno stato ostile, questo livello di anonimato probabilmente non è necessario. Inoltre, non è particolarmente raccomandato: potresti ridurre notevolmente il numero dei tuoi peer potenziali, invitando problemi di censura o addirittura di correlazione. Potresti anche sperimentare ritardi. E, questa configurazione potrebbe darti un falso senso di anonimato che in realtà non esiste sulla rete Bitcoin. + +> :warning: **ATTENZIONE:** Questa configurazione non è testata! Usala a tuo rischio e pericolo! + +## Riepilogo: Cambiare Bitcoin Hidden Services + +Probabilmente non avrai bisogno di modificare i tuoi servizi Onion una volta verificati, ma in caso di necessità, ecco come resettare un indirizzo Tor che è stato compromesso o come passare all'uso esclusivo di Tor per il tuo `bitcoind`. + +## Cosa Viene Dopo? + +Continua a "Comprendere Tor" col [Capitolo 14.3: Aggiungere SSH Hidden Services](14_3_Aggiungere_SSH_Hidden_Services.md). diff --git a/it/14_3_Aggiungere_SSH_Hidden_Services.md b/it/14_3_Aggiungere_SSH_Hidden_Services.md new file mode 100644 index 000000000..2c461cdaf --- /dev/null +++ b/it/14_3_Aggiungere_SSH_Hidden_Services.md @@ -0,0 +1,63 @@ +# Capitolo 14.3: Aggiunta di Servizi Nascosti SSH + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Fino ad oggi, hai usato Tor con i tuoi servizi Bitcoin, ma puoi anche usarlo per proteggere altri servizi sulla tua macchina, migliorandone la sicurezza e la privacy. Questa sezione dimostra come fare introducendo un servizio nascosto `ssh` per accedere in remoto utilizzando Tor. + +## Creare Servizi Nascosti SSH + +I nuovi servizi vengono creati aggiungendoli al file `/etc/tor/torrc`: +: +``` +$ su +# cat >> /etc/tor/torrc << EOF +HiddenServiceDir /var/lib/tor/hidden-service-ssh/ +HiddenServicePort 22 127.0.0.1:22 +EOF +# exit +``` +Ecco cosa significa: + +* HiddenServiceDir: Indica che hai una directory di servizi nascosti con la configurazione necessaria in questo percorso. +* HiddenServicePort: Indica la porta tor da utilizzare; nel caso di SSH, questa è solitamente 22. + +Dopo aver aggiunto le righe appropriate al tuo file `torrc`, dovrai riavviare Tor: + +``` +$ sudo /etc/init.d/tor restart +``` + + +Dopo il riavvio, la tua `HiddenServiceDir` dovrebbe avere nuovi file come segue: + +``` +$ sudo ls -l /var/lib/tor/hidden-service-ssh +total 16 +drwx--S--- 2 debian-tor debian-tor 4096 Jul 22 14:55 authorized_clients +-rw------- 1 debian-tor debian-tor 63 Jul 22 14:56 hostname +-rw------- 1 debian-tor debian-tor 64 Jul 22 14:55 hs_ed25519_public_key +-rw------- 1 debian-tor debian-tor 96 Jul 22 14:55 hs_ed25519_secret_key +``` +Il file `hostname` in questa directory contiene il tuo nuovo ID onion: +``` +$ sudo cat /var/lib/tor/hidden-service-ssh/hostname +qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion +``` +Puoi connetterti al servizio nascosto `ssh` utilizzando `torify` e quell'indirizzo: +``` +$ torify ssh standup@qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion +The authenticity of host 'qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion (127.42.42.0)' can't be established. +ECDSA key fingerprint is SHA256:LQiWMtM8qD4Nv7eYT1XwBPDq8fztQafEJ5nfpNdDtCU. +Are you sure you want to continue connecting (yes/no)? yes +Warning: Permanently added 'qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion' (ECDSA) to the list of known hosts. +standup@qwkemc3vusd73glx22t3sglf7izs75hqodxsgjqgqlujemv73j73qpid.onion's password: +``` +## Sommario: Aggiunta di Servizi Nascosti SSH + +Ora che hai installato Tor e sai come usarlo, puoi aggiungere altri servizi a Tor. Basta aggiungere righe al tuo `torrc` (sul tuo server), quindi connettersi con `torify` (sul tuo client). + +> :fire: ***Qual è il potere di Altri Servizi Nascosti?*** Ogni volta che accedi a un servizio sul tuo server da remoto, lasci tracce sulla rete. Anche se i dati sono crittografati da qualcosa come SSH (o TLS), gli osservatori sulla rete possono vedere da dove ti connetti, dove ti connetti e quale servizio stai usando. Questo importa? Questa è la domanda che devi farti. Ma se la risposta è "Sì", puoi proteggere la connessione con un servizio nascosto. + +## Cosa succede dopo? + +Per un tipo diverso di privacy, passa a "Usare i2p" con [Capitolo 15: Usare i2p](15_0_Usare_i2p.md). diff --git a/it/15_0_Usare_i2p.md b/it/15_0_Usare_i2p.md new file mode 100644 index 000000000..429cf0a10 --- /dev/null +++ b/it/15_0_Usare_i2p.md @@ -0,0 +1,24 @@ +# Capitolo 15: Usare i2P + +Ci sono alternative a Tor. Una è il Progetto Internet Invisibile (i2P), uno strato di rete privata completamente crittografato. Utilizza un [database di rete](https://geti2p.net/en/docs/how/network-database) distribuito e tunnel unidirezionali crittografati tra i peer. La differenza più grande tra Tor e I2P è che Tor è fondamentalmente una rete proxy che offre servizi internet in forma privata, mentre I2P è fondamentalmente una rete segregata che offre servizi I2P solo alla rete I2P, creando una "rete nella rete". Tuttavia, potresti volerlo solo come alternativa, in modo da non dipendere esclusivamente da Tor. + +I2P non è attualmente installato da [Bitcoin Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts), poiché il supporto I2P è stato recentemente aggiunto in Bitcoin Core. Tuttavia, questo capitolo spiega come installarlo manualmente. + +## Obiettivi di Questo Capitolo + +Dopo aver lavorato su questo capitolo, un sviluppatore sarà in grado di: + + * Eseguire Bitcoin Core come servizio I2P (Invisible Internet Project) + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere la Rete I2P + * Imparare la differenza tra Tor e I2P + +## Indice + +* [Capitolo 15.1: Servizi i2P (Invisible Internet Project)](15_1_Servizi_i2p.md) + + + + diff --git a/it/15_1_Servizi_i2p.md b/it/15_1_Servizi_i2p.md new file mode 100644 index 000000000..acdc0cdac --- /dev/null +++ b/it/15_1_Servizi_i2p.md @@ -0,0 +1,137 @@ +# 15.1: Bitcoin Core come servizio I2P (Invisible Internet Project) + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Piuttosto che utilizzare il servizio basato su proxy di Tor per garantire la privacy delle tue comunicazioni Bitcoin, potresti invece desiderare di usare I2P, che è progettato per agire come una rete privata all'interno di internet, piuttosto che offrire semplicemente un accesso privato ai servizi internet. + +## Comprendere le Differenze + +Tor e I2P offrono entrambi accesso privato ai servizi online, ma con routing e database diversi e con architetture differenti per i relay. Poiché i servizi nascosti (come l'accesso a Bitcoin) sono fondamentali nel design di I2P, questi sono stati meglio ottimizzati: + +| | Tor | I2P | +| :--- | :---: | ---: | +| Routing | [Onion](https://www.onion-router.net/) | [Garlic](https://geti2p.net/en/docs/how/garlic-routing) | +| Network Database | Trusted [Directory Servers](https://blog.torproject.org/possible-upcoming-attempts-disable-tor-network) | [Distributed network database](https://geti2p.net/en/docs/how/network-database) | +| Relay | **Two-way** encrypted connections between each Relay | **One-way** connections between every server in its tunnels | +| Hidden services | Slow | Fast | + +Un confronto più dettagliato può essere trovato su [geti2p.net](https://geti2p.net/en/comparison/tor). + +### Comprendere i Compromessi per Limitare le Connessioni in Uscita + +Ci sono [compromessi](https://bitcoin.stackexchange.com/questions/107060/tor-and-i2p-tradeoffs-in-bitcoin-core) se si sceglie di supportare solo I2P, solo Tor, o entrambi. Queste configurazioni, che limitano le connessioni in uscita sulla rete clearnet, sono fatte in Bitcoin Core utilizzando l'argomento `onlynet` nel tuo `bitcoin.conf`. + +* `onlynet=onion`, che limita le connessioni in uscita a Tor, può esporre un nodo ad attacchi Sybil e può creare partizionamento della rete, a causa delle connessioni limitate tra Tornet e la clearnet. +* `onlynet=onion` e `onlynet=i2p` in congiunzione, che esegue il servizio Onion con il servizio I2P, è sperimentale per ora. + +## Installare I2P + +Per installare I2P, dovresti assicurarti che le tue porte siano correttamente configurate e poi puoi continuare con il processo di configurazione. + +### Preparare le Porte + +Per usare I2P, dovrai aprire le seguenti porte, che sono richieste da I2P: + +1. **Outbound (Internet facing):** viene selezionata una porta casuale tra 9000 e 31000. È meglio se tutte queste porte sono aperte per le connessioni in uscita, cosa che non influisce sulla tua sicurezza. +- Puoi controllare lo stato del firewall usando `sudo ufw status verbose`, che non dovrebbe negare le connessioni in uscita per impostazione predefinita. +2. Inbound (Internet facing): opzionale. Una varietà di porte in entrata sono elencate nei [documenti di I2P](https://geti2p.net/en/faq#ports). +- Per la massima privacy, è preferibile disabilitare l'accettazione delle connessioni in entrata. + +### Eseguire I2P + +Il seguente comando eseguirà i servizi I2P di Bitcoin Core: + +1. Installa `i2pd` su Ubuntu: + + + + ``` + sudo add-apt-repository ppa:purplei2p/i2pd + sudo apt-get update + sudo apt-get install i2pd + ``` + + +Per l'installazione su altri sistemi operativi, vedi [questi documenti](https://i2pd.readthedocs.io/en/latest/user-guide/install/). + +2. [Esegui](https://i2pd.readthedocs.io/en/latest/user-guide/run/) il servizio I2P: + + + ``` + $ sudo systemctl start i2pd.service + ``` + + +3. Controlla che I2P stia funzionando. Dovresti vederlo sulla porta 7656: + + + ``` + $ ss -nlt + + State Recv-Q Send-Q Local Address:Port Peer Address:Port Process + + LISTEN 0 4096 127.0.0.1:7656 0.0.0.0:* + ``` + + +4. Aggiungi le seguenti righe in `bitcoin.conf`: + + + ``` + i2psam=127.0.0.1:7656 + debug=i2p + ``` +L'opzione di log, `debug=i2p`, viene utilizzata per registrare informazioni aggiuntive nel log di debug sulla tua configurazione e connessioni I2P. La posizione predefinita di questo file di debug su Linux è: `~/.bitcoin/debug.log`. + +5. Riavvia `bitcoind` + + + + ``` + $ bitcoind + ``` + + +6. Controlla `debug.log` per vedere se I2P è stato configurato correttamente, o se sono comparsi errori nei log. + ``` + 2021-06-15T20:36:16Z i2paccept thread start + 2021-06-15T20:36:16Z I2P: Creating SAM session with 127.0.0.1:7656 + + 2021-06-15T20:36:56Z I2P: SAM session created: session id=3e0f35228b, my address=bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333 + 2021-06-15T20:36:56Z AddLocal(bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333,4) + ``` + + +L'indirizzo I2P è menzionato nei log, terminando con _b32.i2p_. Per esempio `bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p:18333`. + +7. Conferma che `i2p_private_key` è stato creato nella directory dei dati di Bitcoin Core. La prima volta che Bitcoin Core si connette al router I2P, il suo indirizzo I2P (e la corrispondente chiave privata) sarà automaticamente generato e salvato in un file chiamato *i2p_private_key*: + + ``` + ~/.bitcoin/testnet3$ ls + + anchors.dat chainstate i2p_private_key settings.json + banlist.dat debug.log mempool.dat wallets + blocks fee_estimates.dat peers.dat + ``` + + +8. Controlla che `bitcoin-cli -netinfo` o `bitcoin-cli getnetworkinfo` restituisca l'indirizzo I2P: + + + ``` + Local addresses + bmwyyuzyqdc5dcx27s4baltbu6zw7rbqfl2nmclt45i7ng3ul4pa.b32.i2p port 18333 score 4 + ``` + + +Ora il tuo server Bitcoin è accessibile attraverso la rete I2P al tuo nuovo indirizzo locale. + +## Sommario: Bitcoin Core come servizio I2P (Invisible Internet Project) + +È sempre bene avere alternative per la privacy e non dipendere esclusivamente da Tor per eseguire Bitcoin Core come servizio nascosto. Poiché I2P è stato recentemente aggiunto in Bitcoin Core, non molte persone lo utilizzano. Sperimenta con esso e segnala bug se trovi problemi. + +> :information_source: **NOTA:** Per l'implementazione ufficiale di i2prouter in Java, visita la [pagina di download di I2P](https://geti2p.net/en/download) e segui le istruzioni per il tuo sistema operativo. Una volta installato, apri una finestra di terminale e digita `i2prouter start`. Poi visita `127.0.0.1:7657` nel tuo browser per abilitare SAM. Per farlo, seleziona: "Configura Homepage", poi "Clienti", e infine seleziona il "Pulsante Play" accanto a SAM application Bridge. Sul lato sinistro della pagina, dovrebbe esserci una luce verde accanto a "Clienti Condivisi". + +Passa a "Programmare con RPC" con [Capitolo 16: Parlare a Bitcoind con C](16_0_Parlare_a_Bitcoind_con_C.md). + +Oppure, se non sei un programmatore, puoi saltare a [Capitolo 19: Comprendere la Configurazione Lightning](19_0_Comprendere_la_Configurazione_Lightning.md) per continuare la tua formazione sulla linea di comando con il Lightning Network. diff --git a/it/16_0_Parlare_a_Bitcoind_con_C.md b/it/16_0_Parlare_a_Bitcoind_con_C.md new file mode 100644 index 000000000..d13909163 --- /dev/null +++ b/it/16_0_Parlare_a_Bitcoind_con_C.md @@ -0,0 +1,30 @@ +16_0_Parlare_a_Bitcoind_con_C.md +# Capitolo 16: Parlare con Bitcoind in C + +Durante il lavoro con gli Script Bitcoin, abbiamo raggiunto i limiti di ciò che è possibile fare con `bitcoin-cli`: attualmente non può essere utilizzato per generare transazioni contenenti script inusuali. Gli script di shell non sono nemmeno ideali per alcune cose, come la creazione di programmi ascoltatori che controllano costantemente. Fortunatamente, ci sono altri modi per accedere alla rete Bitcoin: le API di programmazione. + +Questa sezione si concentra su tre diverse librerie che possono essere utilizzate come base per una programmazione sofisticata in C: una libreria RPC e una libreria JSON insieme ti permettono di ricreare molte delle operazioni che hai fatto con gli script di shell, ma ora utilizzando C; mentre una libreria ZMQ ti collega alle notifiche, qualcosa a cui non sei stato in grado di accedere precedentemente. (Il prossimo capitolo coprirà una libreria ancora più sofisticata chiamata Libwally, per completare questa introduzione alla programmazione di Bitcoin con C.) + +## Obiettivi per Questo Capitolo + +Dopo aver lavorato su questo capitolo, uno sviluppatore sarà in grado di: + + * Creare Programmi in C che utilizzano RPC per Parlare con Bitcoind + * Creare Programmi in C che utilizzano ZMQ per Parlare con Bitcoind + +Obiettivi di supporto includono la capacità di: + + * Comprendere come utilizzare una libreria RPC + * Comprendere come utilizzare una libreria JSON + * Comprendere le capacità di ZMQ + * Comprendere come utilizzare una libreria ZMQ + +## Indice + + +## Table of Contents + + * [Capitolo 16.1: Accedere a Bitcoind con Librerie RPC](16_1_Accedere_a_Bitcoind_con_Librerie_RPC.md) + * [Capitolo 16.2: Programare Bitcoind in C con Librerie RPC](16_2_Programare_Bitcoind_in_C_con_Librerie_RPC.md) + * [Capitolo 16.3: Ricevere Notifiche di Bitcoind in C tramite Librerie ZMQ](16_3_Ricevere_Notifiche_di_Bitcoind_in_C_tramite_Librerie_ZMQ.md) + diff --git a/it/16_1_Accedere_a_Bitcoind_con_Librerie_RPC.md b/it/16_1_Accedere_a_Bitcoind_con_Librerie_RPC.md new file mode 100644 index 000000000..753483cfb --- /dev/null +++ b/it/16_1_Accedere_a_Bitcoind_con_Librerie_RPC.md @@ -0,0 +1,305 @@ +# 16.1: Accesso a Bitcoind in C con Librerie RPC + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Hai già visto un modo alternativo per accedere alle porte RPC di Bitcoind: `curl`, che è stato trattato in un [Interludio del Capitolo 4](04_4__Interlude_Using_Curl.md). Interagire con `bitcoind` tramite una libreria RPC in C non è diverso da questo, hai solo bisogno di alcune buone librerie per aiutarti. Questa sezione introduce un pacchetto chiamato `libbitcoinrpc`, che ti permette di accedere alla porta JSON-RPC di `bitcoind`. Utilizza la libreria `curl` per accedere ai dati e la libreria `jansson` per codificare e decodificare il JSON. + +## Configurare libbitcoinrpc + +> :warning: **AVVERTENZA** Sembra che `libbitcoinrpc` sia stato completamente abbandonato. Abbiamo registrato l'aggiornamento a una nuova libreria C come un [problema](https://github.com/BlockchainCommons/Community/issues/140). Nel frattempo, la libreria `libbitcoinrpc` attualmente non compila senza interventi. Di conseguenza, le sezioni 16.1 e 16.2 sono principalmente visualizzabili come pseudo-codice che mostra il processo di integrazione di Bitcoin-Core con C. + +Per utilizzare `libbitcoinrpc`, devi installare una configurazione di base di C e i pacchetti dipendenti `libcurl`, `libjansson` e `libuuid`. I seguenti comandi lo faranno sul tuo server Bitcoin Standup (o su qualsiasi altro server Ubuntu). +. +``` +$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev +Suggested packages: + libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev +The following NEW packages will be installed: + libcurl4-openssl-dev libjansson-dev uuid-dev +0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. +Need to get 358 kB of archives. +After this operation, 1.696 kB of additional disk space will be used. +Do you want to continue? [Y/n] y +``` + +Puoi quindi scaricare [libbitcoinrpc da Github](https://github.com/BlockchainCommons/libbitcoinrpc/blob/master/README.md). Clonalo o prendi un file zip, come preferisci. + +``` +$ sudo apt-get install git +$ git clone https://github.com/BlockchainCommons/libbitcoinrpc.git +``` + +> :warning: **AVVERTENZA** Una modifica nella RPC "signrawtransaction" ha causato il crash con segmentazione (segfault) con `libbitcoinrpc` per Bitcoin 0.17 o superiore. È stato presentato un [PR](https://github.com/gitmarek/libbitcoinrpc/pull/1) per risolvere il problema, ma se non è ancora stato unito, puoi semplicemente apportare la modifica nel codice sorgente a `src/bitcoinrpc_method.c` prima di compilare. + +### Compilare libbitcoinrpc + +Prima di poter compilare e installare il pacchetto, probabilmente dovrai regolare il tuo `$PATH`, in modo da poter accedere a `/sbin/ldconfig`: + +``` +$ PATH="/sbin:$PATH" +``` +Per un sistema Ubuntu, vorrai anche regolare il `INSTALL_LIBPATH` nel `Makefile` di `libbitcoinrpc` per installarlo in `/usr/lib` invece di `/usr/local/lib`: +``` +$ emacs ~/libbitcoinrpc/Makefile +... +INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib +``` +(Se preferisci non sporcare il tuo `/usr/lib`, l'alternativa è modificare il tuo `etc/ld.so.conf` o i suoi file dipendenti in modo appropriato... ma per una configurazione di test su una macchina di test, questo va probabilmente bene.) + +Allo stesso modo, vorrai anche regolare il `INSTALL_HEADERPATH` nel `Makefile` di `libbitcoinrpc` per installarlo in `/usr/include` invece di `/usr/local/include`: +``` +... +INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include +``` + + +Poi puoi compilare: +``` +$ cd libbitcoinrpc +~/libbitcoinrpc$ make + +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ +src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ +-o .lib/libbitcoinrpc.so.0.2 \ +-Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl +ldconfig -v -n .lib +.lib: + libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) +ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so +``` +Se funziona, puoi installare il pacchetto: +``` +$ sudo make install +Installing to +install .lib/libbitcoinrpc.so.0.2 /usr/local/lib +ldconfig -n /usr/local/lib +ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so +install -m 644 src/bitcoinrpc.h /usr/local/include +Installing docs to /usr/share/doc/bitcoinrpc +mkdir -p /usr/share/doc/bitcoinrpc +install -m 644 doc/*.md /usr/share/doc/bitcoinrpc +install -m 644 CREDITS /usr/share/doc/bitcoinrpc +install -m 644 LICENSE /usr/share/doc/bitcoinrpc +install -m 644 Changelog.md /usr/share/doc/bitcoinrpc +Installing man pages +install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 +``` + + +## Preparare il Codice + +`libbitcoinrpc` ha metodi ben strutturati e semplici per connettersi al tuo `bitcoind`, eseguire chiamate RPC e decodificare la risposta. + +Per utilizzare `libbitcoinrpc`, assicurati che i tuoi file di codice includano le intestazioni appropriate: + +``` +#include +#include +``` +Avrai anche bisogno di collegare le librerie appropriate ogni volta che compili: +``` +$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode +``` + + +## Costruire la Connessione + +Costruire la connessione al tuo server `bitcoind` richiede pochi semplici passaggi. + +Innanzitutto, inizializza la libreria: + +``` +bitcoinrpc_global_init(); +``` +Poi connettiti al tuo `bitcoind` con `bitcoinrpc_cl_init_params`. I quattro argomenti per `bitcoinrpc_cl_init_params` sono nome utente, password, indirizzo IP e porta. Dovresti già conoscere tutte queste informazioni dal tuo lavoro con [Curl](04_4__Interlude_Using_Curl.md). Come ricorderai, l'indirizzo IP 127.0.0.1 e la porta 18332 dovrebbero essere corretti per la configurazione standard del testnet descritta in questi documenti, mentre puoi estrarre l'utente e la password da `~/.bitcoin/bitcoin.conf`. +``` +$ cat bitcoin.conf +server=1 +dbcache=1536 +par=1 +maxuploadtarget=137 +maxconnections=16 +rpcuser=StandUp +rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba +rpcallowip=127.0.0.1 +debug=tor +prune=550 +testnet=1 +[test] +rpcbind=127.0.0.1 +rpcport=18332 +[main] +rpcbind=127.0.0.1 +rpcport=8332 +[regtest] +rpcbind=127.0.0.1 +rpcport=18443 +``` +Che poi inserisci in `bitcoinrpc_cl_init_params`: +``` +bitcoinrpc_cl_t *rpc_client; +rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); +``` + + +> **MAINNET VS TESTNET:** La porta sarebbe 8332 per una configurazione mainnet. + +Se `rpc_client` viene inizializzato correttamente, sarai in grado di inviare comandi RPC. + +Successivamente, quando avrai finito con la tua connessione `bitcoind`, dovresti chiuderla: +``` +bitcoinrpc_global_cleanup(); +``` + + +### Testare il Codice di Test + +Il codice di test può essere trovato in [16_1_testbitcoin.c nella directory src](src/16_1_testbitcoin.c). Scaricalo sulla tua macchina testnet, quindi inserisci la password RPC corretta (e cambia l'utente RPC se non hai creato il tuo server con StandUp). + +Puoi compilare ed eseguire questo come segue: + +``` +$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin +$ ./testbitcoin +Successfully connected to server! +``` + + +> :warning: **AVVERTENZA:** Se dimentichi di inserire la tua password RPC in questo o in qualsiasi altro esempio di codice che dipende da RPC, riceverai un misterioso `ERROR CODE 5`. + +## Effettuare una Chiamata RPC + +Per utilizzare un metodo RPC utilizzando `libbitcoinrpc`, devi inizializzare una variabile di tipo `bitcoinrpc_method_t`. Lo fai con il valore appropriato per il metodo che vuoi utilizzare, tutti elencati nel [Reference di bitcoinrpc](https://github.com/BlockchainCommons/libbitcoinrpc/blob/master/doc/reference.md). + +``` +bitcoinrpc_method_t *getmininginfo = NULL; +getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); +``` +Di solito imposteresti i parametri successivamente, ma `getmininginfo` non richiede parametri, quindi puoi saltare questo passaggio per ora. + +Devi anche creare altri due oggetti, un "oggetto di risposta" e un "oggetto di errore". Possono essere inizializzati come segue: + +``` +bitcoinrpc_resp_t *btcresponse = NULL; +btcresponse = bitcoinrpc_resp_init(); + +bitcoinrpc_err_t btcerror; +``` +Usi la variabile `rpc_client` di cui hai già appreso nel test precedente, e aggiungi il tuo metodo `getmininginfo` e i due altri oggetti: +``` +bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); +``` +### Output della Tua Risposta + +Vorrai sapere cosa ha restituito la chiamata RPC. Per farlo, recupera l'output della tua chiamata come oggetto JSON con `bitcoinrpc_resp_get` e salvalo in un oggetto `jansson` standard, di tipo `json_t`: + +``` +json_t *jsonresponse = NULL; +jsonresponse = bitcoinrpc_resp_get(btcresponse); +``` +Se vuoi _outputtare_ i risultati JSON completi della chiamata RPC, puoi farlo con una semplice invocazione di `json_dumps`, anche dalla libreria `jansson`: +``` +printf ("%s\n", json_dumps(j, JSON_INDENT(2))); +``` + +Tuttavia, poiché ora stai scrivendo programmi completi, probabilmente vorrai fare lavori più sottili, come estrarre valori JSON individuali per un uso specifico. Il [Reference di jansson](https://jansson.readthedocs.io/en/2.10/apiref.html) dettaglia come farlo. + +Proprio come quando utilizzavi [Curl](04_2_Intermezzo_Usare_JQ.md), scoprirai che le RPC restituiscono un oggetto JSON contenente un `id`, un `error`, e soprattutto un oggetto JSON del `result`. + +La funzione `json_object_get` ti permetterà di recuperare un valore (come il `result`) da un oggetto JSON per chiave: + +``` +json_t *jsonresult = NULL; +jsonresult = json_object_get(jsonresponse,"result"); +printf ("%s\n", json_dumps (jsonresult, JSON_INDENT(2))); +``` +Tuttavia, probabilmente vorrai approfondire ulteriormente, per ottenere una variabile specifica. Una volta recuperato il valore appropriato, dovrai convertirlo in un oggetto C standard utilizzando la funzione `json_*_value` appropriata. Ad esempio, accedere a un intero utilizza `json_integer_value`: +``` +json_t *jsonblocks = NULL; +jsonblocks = json_object_get(jsonresult,"blocks"); + +int blocks; +blocks = json_integer_value(jsonblocks); +printf("Block Count: %d\n",blocks); +``` + + +> :warning: **AVVERTENZA:** È estremamente facile far crashare il tuo codice C con segmentazione quando lavori con oggetti `jansson` se ti confondi con il tipo di oggetto che stai recuperando. Fai un uso attento di `bitcoin-cli help` per sapere cosa aspettarti, e se sperimenti un errore di segmentazione, prima guarda le tue funzioni di recupero JSON. + +### Testare il Codice Info + +Recupera il codice di test dalla [directory src](src/16_1_getmininginfo.c). + +``` +$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo +$ ./getmininginfo +Full Response: { + "result": { + "blocks": 1804406, + "difficulty": 4194304, + "networkhashps": 54842097951591.781, + "pooledtx": 127, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" + }, + "error": null, + "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" +} + +Just the Result: { + "blocks": 1804406, + "difficulty": 4194304, + "networkhashps": 54842097951591.781, + "pooledtx": 127, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" +} + +Block Count: 1804406 +``` +## Effettuare una Chiamata RPC con Argomenti + +Ma cosa succede se la tua chiamata RPC _ha_ argomenti? + +### Creare un Array JSON + +Per inviare parametri alla tua chiamata RPC utilizzando `libbitcoinrpc` devi avvolgerli in un array JSON. Poiché un array è semplicemente un elenco ordinato di valori, tutto ciò che devi fare è codificare i parametri come elementi ordinati nell'array. + +Crea l'array JSON utilizzando la funzione `json_array` di `jansson`: + +``` +json_t *params = NULL; +params = json_array(); +``` +Invertirai quindi la procedura che hai seguito per accedere ai valori JSON: convertirai gli oggetti di tipo C in oggetti di tipo JSON utilizzando le funzioni `json_*`. Successivamente, li aggiungerai all'array: +``` +json_array_append_new(params,json_string(tx_rawhex)); +``` +Nota che ci sono due varianti del comando append: `json_array_append_new`, che aggiunge una variabile appena creata, e `json_array_append`, che aggiunge una variabile esistente. + +Questa semplice metodologia `json_array_append_new` servirà per la maggior parte dei comandi RPC con parametri, ma alcuni comandi RPC richiedono input più complessi. In questi casi, potrebbe essere necessario creare oggetti JSON o array JSON sussidiari, che aggiungerai quindi all'array dei parametri come al solito. La sezione successiva contiene un esempio di come farlo utilizzando `createrawtransaction`, che contiene un array JSON di oggetti JSON per gli input, un oggetto JSON per gli output e il parametro `locktime`. + +### Assegnare i Parametri + +Quando hai creato il tuo array JSON dei parametri, lo assegni semplicemente dopo aver inizializzato il tuo metodo RPC, come segue: + +``` +bitcoinrpc_method_set_params(rpc_method, params) +``` +Questa sezione non include un esempio completo di questa metodologia più complessa, ma la vedremo in azione più volte nel nostro primo programma completo basato su RPC in C, nella prossima sezione. + +## Riepilogo: Accesso a Bitcoind con C + +Collegandoti alle librerie RPC `bitcoinrpc` e JSON `jansson`, puoi facilmente accedere a `bitcoind` tramite chiamate RPC da una libreria C. Per farlo, crei una connessione RPC, quindi effettui chiamate RPC individuali, alcune con parametri. `jansson` ti permette poi di decodificare le risposte JSON. La prossima sezione dimostrerà come questo possa essere utilizzato per un programma pragmatico e reale. + +* :fire: ***Qual è il potere di C?*** C ti permette di fare il passo successivo oltre il scripting shell, permettendo la creazione di programmi più completi e robusti. + +## Cosa Succede Dopo? + +Scopri di più su "Parlare con Bitcoind in C" nel [Capitolo 16.2: Programare Bitcoind in C con Librerie RPC](16_2_Programare_Bitcoind_in_C_con_Librerie_RPC.md). diff --git a/it/16_2_Programare_Bitcoind_in_C_con_Librerie_RPC.md b/it/16_2_Programare_Bitcoind_in_C_con_Librerie_RPC.md new file mode 100644 index 000000000..14a5a5615 --- /dev/null +++ b/it/16_2_Programare_Bitcoind_in_C_con_Librerie_RPC.md @@ -0,0 +1,375 @@ +# 16.2: Programmare Bitcoind in C con Librerie RPC + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Il [Capitolo 16.1](16_1_Accedere_a_Bitcoind_con_Librerie_RPC.md) ha delineato la metodologia per creare programmi in C utilizzando librerie RPC e JSON. Ora mostreremo il potenziale di queste librerie C delineando una versione semplificata di un vero programma Bitcoin. + +## Pianifica il Tuo Codice + +Questa sezione creerà una prima versione semplificata di `sendtoaddress`, che permetterà a un utente di inviare denaro a un indirizzo purché abbia un UTXO abbastanza grande. Ecco cosa dobbiamo fare: + + 1. Richiedere un indirizzo e un importo + 2. Impostare una commissione arbitraria + 3. Preparare il Tuo RPC + 4. Trovare un UTXO abbastanza grande per l'importo + la commissione + 5. Creare un indirizzo di resto + 6. Creare una transazione grezza che invia dall'UTXO all'indirizzo e all'indirizzo di resto + 7. Firmare la transazione + 8. Inviare la transazione + +### Pianifica il Tuo Futuro + +Dato che questo è il tuo primo programma funzionale in C, cercheremo di mantenerlo semplice (KISS). Se stessimo producendo un vero programma di produzione, vorremmo almeno fare quanto segue: + + 1. Testare e/o sanitizzare gli input + 2. Calcolare automaticamente una commissione + 3. Pensare logicamente a quale UTXO valido utilizzare + 4. Combinare più UTXO se necessario + 5. Controllare più errori nei comandi `libbitcoinrpc` o `jansson` + 6. Controllare errori nelle risposte RPC + +Se vuoi continuare a espandere questo esempio, affrontare le carenze di questo programma esemplare sarebbe un ottimo punto di partenza. + +## Scrivi il Tuo Software di Transazione + +Ora sei pronto a intraprendere questo piano passo dopo passo. + +### Passo 1: Richiedere un Indirizzo e un Importo + +Inserire le informazioni è abbastanza facile tramite gli argomenti della riga di comando: +: +``` +if (argc != 3) { + + printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); + exit(-1); + +} + +char *tx_recipient = argv[1]; +float tx_amount = atof(argv[2]); + +printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); +``` + + +> :warning: **AVVERTENZA:** Un vero programma avrebbe bisogno di una sanificazione molto migliore di queste variabili. + +### Passo 2: Impostare una Commissione Arbitraria + +Questo esempio imposta una commissione arbitraria di 0,0005 BTC per assicurarsi che le transazioni di test vadano a buon fine rapidamente: + +``` +float tx_fee = 0.0005; +float tx_total = tx_amount + tx_fee; +``` + + +> :warning: **AVVERTENZA:** Un vero programma calcolerebbe una commissione che minimizza il costo garantendo al contempo che la velocità sia sufficiente per il mittente. + +### Passo 3: Preparare il Tuo RPC + +Ovviamente, dovrai preparare di nuovo tutte le tue variabili, come discusso in [§16.1: Accesso a Bitcoind con C](16_1_Accessing_Bitcoind_with_C.md). Devi anche inizializzare la tua libreria, connettere il tuo client RPC e preparare il tuo oggetto di risposta: + +``` +bitcoinrpc_global_init(); +rpc_client = bitcoinrpc_cl_init_params ("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); +btcresponse = bitcoinrpc_resp_init(); +``` + + +### Passo 4: Trovare un UTXO + +Per trovare un UTXO devi chiamare l'RPC `listunspent`: +: +``` +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +``` +Tuttavia, il vero lavoro consiste nel decodificare la risposta. La sezione precedente ha notato che la libreria `jansson` era "un po' ingombrante" e questo è il motivo: devi creare (e cancellare) un gran numero di oggetti `json_t` per scavare fino a ciò che desideri. + +Innanzitutto, devi recuperare il campo `result` dal JSON: + +``` +json_t *lu_response = NULL; +json_t *lu_result = NULL; + +lu_response = bitcoinrpc_resp_get (btcresponse); +lu_result = json_object_get(lu_response,"result"); +``` + + +> :warning: **AVVERTENZA:** Ottieni un risultato solo se non c'è stato un errore. Ecco un altro punto per un controllo degli errori migliore per il codice di produzione. + +Poi, entri in un ciclo, esaminando ogni transazione non spesa, che appare come un elemento nel tuo array di risultati JSON: + +``` +int i; + +const char *tx_id = 0; +int tx_vout = 0; +double tx_value = 0.0; + +for (i = 0 ; i < json_array_size(lu_result) ; i++) { + + json_t *lu_data = NULL; + lu_data = json_array_get(lu_result, i); + + json_t *lu_value = NULL; + lu_value = json_object_get(lu_data,"amount"); + tx_value = json_real_value(lu_value); +``` +L'UTXO è abbastanza grande da pagare la tua transazione? Se sì, prendilo! + +> :warning: **AVVERTENZA:** Un programma del mondo reale penserebbe più attentamente a quale UTXO prendere, in base alle dimensioni e ad altri fattori. Probabilmente non prenderebbe solo la prima cosa che vede che funziona. + + +``` + if (tx_value > tx_total) { + + json_t *lu_txid = NULL; + lu_txid = json_object_get(lu_data,"txid"); + tx_id = strdup(json_string_value(lu_txid)); + + json_t *lu_vout = NULL; + lu_vout = json_object_get(lu_data,"vout"); + tx_vout = json_integer_value(lu_vout); + + json_decref(lu_value); + json_decref(lu_txid); + json_decref(lu_vout); + json_decref(lu_data); + break; + + } +``` +Dovresti anche cancellare i tuoi elementi JSON principali: +``` +} + +json_decref(lu_result); +json_decref(lu_response); +``` + + +> :warning: **AVVERTENZA:** Un programma del mondo reale si assicurerebbe anche che gli UTXO siano `spendibili`. + +Se non hai trovato UTXO abbastanza grandi, dovrai riferire questo triste fatto all'utente... e forse suggerire che dovrebbe usare un programma migliore che unirà correttamente gli UTXO. + +``` +if (!tx_id) { + + printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); + exit(-1); +} +``` + + +> **AVVERTENZA:** Un vero programma utilizzerebbe subroutine per questo tipo di ricerca, in modo da poter chiamare varie RPC da una libreria di funzioni C con fiducia. Stiamo solo ammassando tutto in `main` come parte della nostra filosofia KISS di esempi semplici. + +### Passo 5: Creare un Indirizzo di Resto + +Ripeti la metodologia standard di ricerca RPC per ottenere un indirizzo di resto: + +``` +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); + +if (!rpc_method) { + + printf("ERROR: Unable to initialize listunspent method!\n"); + exit(-1); + +} + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); + +if (btcerror.code != BITCOINRPCE_OK) { + +printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); + + exit(-1); + +} + +lu_response = bitcoinrpc_resp_get (btcresponse); +lu_result = json_object_get(lu_response,"result"); +char *changeaddress = strdup(json_string_value(lu_result)); +``` +L'unica differenza sta in quale particolare informazione viene estratta dall'oggetto JSON. + +> :warning: **AVVERTENZA:** Ecco un punto in cui una subroutine sarebbe molto utile: per astrarre l'intera inizializzazione del metodo RPC e la chiamata. + +### Passo 6: Creare una Transazione Grezza + +Creare la transazione grezza effettiva è l'altra parte complicata della programmazione del tuo sostituto `sendtoaddress`. Questo perché richiede la creazione di un oggetto JSON complesso come parametro. + +Per creare correttamente questi parametri, dovrai rivedere cosa si aspetta l'RPC `createrawtransaction`. Fortunatamente, questo è facile da determinare utilizzando la funzionalità `bitcoin-cli help`: + +``` +$ bitcoin-cli help createrawtransaction +createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) +``` +Per riassumere, i tuoi input saranno un array JSON contenente un oggetto JSON per ciascun UTXO. Poi tutti gli output saranno in un unico oggetto JSON. È più facile creare questi elementi JSON dall'interno verso l'esterno, utilizzando i comandi `jansson`. + +#### Passo 6.1: Creare i Parametri di Input + +Per creare l'oggetto input per il tuo UTXO, usa `json_object`, quindi riempilo con coppie chiave-valore utilizzando `json_object_set_new` (per riferimenti di nuova creazione) o `json_object_set` (per riferimenti esistenti): + +``` +json_t *inputtxid = NULL; +inputtxid = json_object(); + +json_object_set_new(inputtxid,"txid",json_string(tx_id)); +json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); +``` +Noterai che devi di nuovo tradurre ciascun tipo di variabile C in un tipo di variabile JSON utilizzando la funzione appropriata, come `json_string` o `json_integer`. + +Per creare l'array di input generale per tutti i tuoi UTXO, usa `json_array`, quindi riempilo con oggetti utilizzando `json_array_append`: + +``` +json_t *inputparams = NULL; +inputparams = json_array(); +json_array_append(inputparams,inputtxid); +``` + + +#### Passo 6.2: Creare i Parametri di Output + +Per creare l'array di output per la tua transazione, segui lo stesso formato, creando un oggetto JSON con `json_object`, quindi riempiendolo con `json_object_set`: + +``` +json_t *outputparams = NULL; +outputparams = json_object(); + +char tx_amount_string[32]; +sprintf(tx_amount_string,"%.8f",tx_amount); +char tx_change_string[32]; +sprintf(tx_change_string,"%.8f",tx_value - tx_total); + +json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); +json_object_set(outputparams, changeaddress, json_string(tx_change_string)); +``` + + +> :warning: **AVVISO:** Potresti aspettarti di inserire i tuoi valori Bitcoin come numeri, utilizzando `json_real`. Sfortunatamente, questo espone uno dei principali problemi con l'integrazione della libreria `jansson` e Bitcoin. Bitcoin è valido solo fino a otto cifre significative dopo il punto decimale. Ricorderai che .00000001 BTC è un satoshi, e questa è la divisione più piccola possibile di un Bitcoin. I doppi in C offrono più cifre significative di così, anche se spesso sono imprecisi oltre otto decimali. Se provi a convertire direttamente il tuo valore doppio in C (o un valore float, per quella materia) in un valore Bitcoin, l'imprecisione creerà spesso un valore Bitcoin con più di otto cifre significative. Prima di Bitcoin Core 0.12 questo sembra funzionare, e potresti usare `json_real`. Ma a partire da Bitcoin Core 0.12, se provi a dare a `createrawtransaction` un valore Bitcoin con troppe cifre significative, riceverai invece un errore e la transazione non sarà creata. Di conseguenza, se il valore Bitcoin è _mai_ diventato un doppio o un float, devi riformattarlo a otto cifre significative dopo la cifra prima di inserirlo come stringa. Questo è ovviamente un trucco, quindi dovresti assicurarti che continui a funzionare nelle future versioni di Bitcoin Core. + +#### Passo 6.3: Creare l'Array dei Parametri + +Per finire di creare i tuoi parametri, basta racchiuderli tutti in un array JSON: + +``` +json_t *params = NULL; +params = json_array(); +json_array_append(params,inputparams); +json_array_append(params,outputparams); +``` +#### Passo 6.4: Effettuare la Chiamata RPC + +Usa il metodo normale per creare la tua chiamata RPC: + +``` +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); +``` +Tuttavia, ora devi fornire i tuoi parametri. Questo viene fatto semplicemente con `bitcoinrpc_method_set_params`: +``` +if (bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf (stderr, "Error: Could not set params for createrawtransaction"); + +} +``` +Successivamente, esegui l'RPC e ottieni i risultati come al solito: +``` +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); + +char *tx_rawhex = strdup(json_string_value(lu_result)); +``` +### Passo 7: Firmare la Transazione + +È molto più facile assegnare un semplice parametro a una funzione. Basta creare un array JSON, quindi assegnare il parametro all'array: + +``` +params = json_array(); +json_array_append_new(params,json_string(tx_rawhex)); +``` +Firma la transazione seguendo la solita tiritera per creare una chiamata RPC: +``` +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); +if (bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf (stderr, "Error: Could not set params for signrawtransaction"); + +} + +json_decref(params); + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +lu_response = bitcoinrpc_resp_get(btcresponse); +``` +Ancora una volta, usare `jansson` per accedere all'output può essere un po' complicato. Qui devi ricordare che `hex` è parte di un oggetto JSON, non un risultato autonomo, come era il caso quando hai creato la transazione grezza. Naturalmente, puoi sempre accedere a queste informazioni dall'aiuto della riga di comando: `bitcoin-cli help signrawtransaction`: + +``` +lu_result = json_object_get(lu_response,"result"); +json_t *lu_signature = json_object_get(lu_result,"hex"); +char *tx_signrawhex = strdup(json_string_value(lu_signature)); +json_decref(lu_signature); +``` + + +> :warning: **AVVERTENZA:** Un programma del mondo reale ovviamente testerebbe attentamente la risposta di ogni comando RPC per assicurarsi che non ci siano errori. Questo è particolarmente vero per `signrawtransaction`, perché potresti finire con una transazione parzialmente firmata. Peggio ancora, se non controlli gli errori nell'oggetto JSON, vedrai solo l'`hex` e non ti renderai conto che è non firmato o parzialmente firmato. + +### Passo 8: Inviare la Transazione + +Ora puoi inviare la tua transazione, usando tutte le tecniche precedenti: + +``` +params = json_array(); +json_array_append_new(params,json_string(tx_signrawhex)); + +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); + +if (bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf (stderr, "Error: Could not set params for sendrawtransaction"); + +} + +json_decref(params); + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); + +char *tx_newid = strdup(json_string_value(lu_result)); + +printf("Txid: %s\n",tx_newid); +``` +L'intero codice, con un _po' di_ controllo degli errori in più, appare nell'Appendice. + +## Testare il Tuo Codice + +Il codice completo può essere trovato nella [directory src](src/16_2_sendtoaddress.c). + +Compila questo come al solito: + +``` +$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress +``` +Puoi quindi usarlo per inviare fondi a un indirizzo: + +``` +./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 +Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 +``` +Puoi vedere le informazioni su questa transazione che abbiamo inviato [qui](https://live.blockcypher.com/btc-testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). + +## Riepilogo: Programmare Bitcoind con C + +Con l'accesso a una libreria C, puoi creare programmi molto più completi di quanto fosse ragionevole fare con script di shell. Ma può richiedere molto lavoro! Anche con 316 linee di codice, `sendtoaddress.c` non copre quasi tutte le complessità necessarie per transare bitcoin in modo sicuro e intelligente. + +## Cosa Succede Dopo? + +Scopri di più su "Parlare con Bitcoind in C" nel [Capitolo 16.3: Ricevere Notifiche di Bitcoind in C tramite Librerie ZMQ](16_3_Ricevere_Notifiche_di_Bitcoind_in_C_tramite_Librerie_ZMQ.md). diff --git a/it/16_3_Ricevere_Notifiche_di_Bitcoind_in_C_tramite_Librerie_ZMQ.md b/it/16_3_Ricevere_Notifiche_di_Bitcoind_in_C_tramite_Librerie_ZMQ.md new file mode 100644 index 000000000..bb13dea9e --- /dev/null +++ b/it/16_3_Ricevere_Notifiche_di_Bitcoind_in_C_tramite_Librerie_ZMQ.md @@ -0,0 +1,166 @@ +# 16.3 Ricevere Notifiche in C con Librerie ZMQ + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Nel [Capitolo 16.1](16_1_Accedere_a_Bitcoind_con_Librerie_RPC.md) e nel [Capitolo 16.2](16_2_Programare_Bitcoind_in_C_con_Librerie_RPC.md) hanno introdotto le librerie RPC e JSON per C, e in tal modo hanno mostrato uno dei vantaggi di accedere ai comandi RPC di Bitcoin attraverso un linguaggio di programmazione: la possibilità di creare ragionevolmente programmi molto più complessi. Questo capitolo introduce una terza libreria, per [ZMQ](http://zeromq.org/), e in tal modo rivela un altro vantaggio: la possibilità di monitorare le notifiche. Lo utilizzeremo per codificare un ascoltatore di blockchain. + +> :book: ***Che cos'è ZMQ?*** ZeroMQ (ZMQ) è una libreria di messaggistica asincrona ad alte prestazioni che fornisce una coda di messaggi. ZeroMQ supporta modelli di messaggistica comuni (pub/sub, request/reply, client/server e altri) su una varietà di trasporti (TCP, in-process, inter-process, multicast, WebSocket e altro), rendendo la messaggistica inter-processo semplice come la messaggistica inter-thread. Puoi trovare ulteriori dettagli sulle notifiche ZMQ e altri tipi di messaggi in [questo repository](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). + +## Configura ZMQ + +Prima di poter creare un ascoltatore di blockchain, dovrai configurare `bitcoind` per consentire le notifiche ZMQ e poi dovrai installare una libreria ZMQ per sfruttare queste notifiche. + +### Configurare `bitcoind` per ZMQ + +Bitcoin Core è pronto per ZMQ, ma devi specificare gli endpoint ZMQ. I socket di pubblicazione di ZeroMQ premettono a ogni elemento di dati un prefisso di argomento arbitrario che consente ai client abbonati di richiedere solo quegli elementi con un prefisso corrispondente. Attualmente ci sono quattro argomenti supportati da `bitcoind`: +: +``` +$ bitcoind --help | grep zmq | grep address + -zmqpubhashblock=
+ -zmqpubhashtx=
+ -zmqpubrawblock=
+ -zmqpubrawtx=
+``` +Puoi eseguire `bitcoind` con argomenti da riga di comando per gli endpoint ZMQ, come mostrato sopra, ma puoi anche rendere accessibile un endpoint aggiungendo le righe appropriate al tuo file `~/.bitcoin/bitcoin.conf` e riavviando il tuo demone. + + +``` +zmqpubrawblock=tcp://127.0.0.1:28332 +zmqpubrawtx=tcp://127.0.0.1:28333 +``` +Puoi quindi testare se i tuoi endpoint stanno funzionando utilizzando l'RPC `getzmqnotifications`: + + +``` +$ bitcoin-cli getzmqnotifications +[ + { + "type": "pubrawblock", + "address": "tcp://127.0.0.1:28332", + "hwm": 1000 + }, + { + "type": "pubrawtx", + "address": "tcp://127.0.0.1:28333", + "hwm": 1000 + } +] +``` +Il tuo `bitcoind` ora emetterà notifiche ZMQ. + +### Installare ZMQ + +Per sfruttare queste notifiche, hai bisogno di una libreria ZMQ da utilizzare con C; in questa sezione useremo quindi una nuova libreria ZMQ invece della libreria `libbitcoinrpc`, ma quando sperimenterai in futuro, potrai ovviamente combinarle. + +Fortunatamente, le librerie ZMQ sono disponibili tramite pacchetti standard Debian: + +``` +$ sudo apt-get install libzmq3-dev +$ sudo apt-get install libczmq-dev +``` +Ora sei pronto per programmare! + +## Scrivi il Tuo Programma di Notifica + +Il seguente programma C è un semplice client che si abbona a un punto di connessione ZMQ servito da `bitcoind` e legge i messaggi in arrivo. + +Il programma richiede due parametri: il primo parametro è il "server", che è il punto di connessione TCP esposto da `bitcoind`; e il secondo è l'argomento, che attualmente è `zmqpubhashblock`, `zmqpubhashtx`, `zmqpubrawblock` o `zmqpubrawtx`. L'argomento deve essere supportato tramite il `bitcoin.conf` e l'indirizzo IP e la porta del server devono corrispondere a quanto definito lì. + + +``` c +#include +int main(int argc, char ** argv) { + + char *zmqserver; + char *topic; + + if (argc < 3) { + printf("\nUSAGE:\nchainlistener \n\n"); + return 0; + } else { + zmqserver = argv[1]; + topic = argv[2]; + } +``` + +Aprirai un socket ZMQ al server definito per l'argomento definito: +``` c + zsock_t *socket = zsock_new_sub(zmqserver, topic); + assert(socket); +``` +Dopodiché, aspetti: +``` + while(1) { + zmsg_t *msg; + int rc = zsock_recv(socket, "m", &msg); + assert(rc == 0); + + char *header = zmsg_popstr(msg); + zframe_t *zdata = zmsg_pop(msg); + unsigned int *no = (unsigned int*)zmsg_popstr(msg); + + char *data = zframe_strhex(zdata); + int len = zframe_size(zdata); + printf("Size: %d\n", len); + printf("Data: %s", data); + printf("\nNo: %d\n", *no); + + free(header); + free(data); + free(no); + free(zdata); + zmsg_destroy(&msg); + sleep(1); + } +``` +Durante l'attesa, guardi i messaggi sul socket ZMQ. Ogni volta che ricevi un messaggio, lo estrai dallo stack e riporti il suo numero, la sua lunghezza e, soprattutto, i dati. + +Questo è tutto! + +Ovviamente, quando hai finito, dovresti pulire: +``` + zsock_destroy(&socket); + return 0; +} +``` +### Testare il Codice di Notifica + +Il codice sorgente è nella [directory src](src/16_3_chainlistener.c) come al solito. Dovresti compilarlo: + +``` +$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq +``` +Afterward, you can run it with the topics and addresses that you defined in your `bitcoin.conf`: +``` +$ ./chainlistener tcp://127.0.0.1:28333 rawtx +Size: 250 +Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 +No: 67 +Size: 249 +Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 +No: 68 +Size: 250 +Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 +No: 69 +Size: 250 +Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 +No: 70 +....... +``` +Dopodiché, puoi eseguirlo con gli argomenti e gli indirizzi che hai definito nel tuo `bitcoin.conf`: + +-------------------------- + +### Riepilogo: Ricevere Notifiche di Bitcoind con C + +Utilizzando il framework ZMQ, puoi facilmente ricevere notifiche collegandoti a un punto di connessione esposto da `bitcoind` attraverso il suo file di configurazione. + +> :fire: ***Qual è il Potere delle Notifiche?*** Con le notifiche, non dipendi più completamente dagli utenti per emettere comandi. Invece, puoi creare programmi che monitorano la blockchain di Bitcoin e prendono le azioni appropriate quando si verificano determinate cose. Questo potrebbe a sua volta essere integrato con i comandi RPC che hai programmato nelle sezioni precedenti. Questo è anche un grande passo avanti rispetto a ciò che potresti fare con gli script di shell: certamente, puoi creare script di shell ascoltatori con loop infiniti, ma i linguaggi di programmazione tendono a essere uno strumento migliore per quel compito. + +## Cosa Succede Dopo? + +Scopri di più su "Programmazione con RPC" in [Capitolo 17: Programmare Bitcoin con Libwally](17_0_Programmare_Bitcoin_con_Libwally.md). + + + + diff --git a/it/17_0_Programmare_Bitcoin_con_Libwally.md b/it/17_0_Programmare_Bitcoin_con_Libwally.md new file mode 100644 index 000000000..9a323dd0b --- /dev/null +++ b/it/17_0_Programmare_Bitcoin_con_Libwally.md @@ -0,0 +1,30 @@ +# Capitolo 17: Programmazione con Libwally + +Il capitolo precedente ha presentato tre librerie C, per RPC, JSON e ZMQ, tutte destinate a interagire direttamente con `bitcoind`, proprio come hai fatto dall'inizio. Ma a volte potresti voler programmare senza accesso diretto a un `bitcoind`. Questo potrebbe essere dovuto a un client offline, o semplicemente perché vuoi mantenere alcune funzionalità interne al tuo programma C. Potresti anche voler approfondire le funzionalità del portafoglio, come la creazione di parole mnemoniche o la derivazione di indirizzi. È qui che entra in gioco Libwally: è una libreria per portafogli per C, C++, Java, NodeJS o Python, con wrapper disponibili anche per altri linguaggi, come Swift. + +Questo capitolo tocca le funzionalità possibili all'interno di Libwally, la maggior parte delle quali completa il lavoro che hai svolto tramite l'accesso RPC a `bitcoind`, ma alcune delle quali lo replicano. Mostra anche come integrare quel lavoro con i client RPC con cui sei più familiare. Tuttavia, nota che questa è solo la minima introduzione a Libwally. Diverse delle sue serie di funzioni più importanti sono evidenziate, ma non facciamo mai più che bagnare i piedi. Se trovi le sue funzioni utili o intriganti, allora dovrai approfondire molto più di quanto questo corso possa coprire. + +## Obiettivi di questo Capitolo + +Dopo aver lavorato attraverso questo capitolo, uno sviluppatore sarà in grado di: + + * Utilizzare le Funzioni del Portafoglio con Libwally + * Eseguire Manipolazioni di PSBT e Transazioni con Libwally + * Implementare Progetti che Mescolano Lavoro con Libwally e RPC + +Obiettivi di supporto includono la capacità di: + + * Comprendere le Parole Mnemoniche BIP39 + * Comprendere di Più sui Portafogli Gerarchici BIP32 + * Riassumere la Profondità Funzionale di Libwally + +## Sommario + + + * [Capitolo 17.1 Configurare Libwally](17_1_Configurare_Libwally.md) + * [Capitolo 17.2 Usare BIP39 in Libwally](17_2_Usare_BIP39_in_Libwally.md) + * [Capitolo 17.3 Usare BIP32 in Libwally](17_3_Usare_BIP32_in_Libwally.md) + * [Capitolo 17.4 Usare PSBTs in Libwally](17_4_Usare_PSBTs_in_Libwally.md) + * [Capitolo 17.5 Usare Scripts in Libwally](17_5_Usare_Scripts_in_Libwally.md) + * [Capitolo 17.6 Usare Altre Funzioni in Libwally](17_6_Usare_Altre_Funzioni_in_Libwally.md) + * [Capitolo 17.7 Integrare Libwally e Bitcoin-CLI](17_7_Integrare_Libwally_e_Bitcoin-CLI.md) diff --git a/it/17_1_Configurare_Libwally.md b/it/17_1_Configurare_Libwally.md new file mode 100644 index 000000000..e528df57b --- /dev/null +++ b/it/17_1_Configurare_Libwally.md @@ -0,0 +1,207 @@ +# 17.1: Configurare Libwally + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe ancora essere in attesa di revisione. Lettore avvisato. + +Questa prima sezione spiegherà come scaricare la libreria C Libwally e farla funzionare. + +> :book: ***Cos'è Libwally?*** Libwally è una libreria di primitive utili per la creazione di portafogli che è cross-platform e cross-language, così che le stesse funzioni possano essere utilizzate ovunque. Ci sono [documenti online](https://wally.readthedocs.io/en/latest/). Libwally è resa disponibile come parte del [Elements Project](https://github.com/ElementsProject) di Blockstream. + +## Installare Libwally + +Come al solito, avrai bisogno di alcuni pacchetti sul tuo sistema: + +``` +$ sudo apt-get install git +$ sudo apt-get install dh-autoreconf +``` +Puoi quindi scaricare Libwally dal suo repository Git: +``` +$ git clone https://github.com/ElementsProject/libwally-core +``` +Successivamente, puoi iniziare il processo di configurazione: +``` +$ ./tools/autogen.sh +``` +Come con `libbitcoinrpc`, potresti voler installarlo in `/usr/include` e `/usr/lib` per facilità di utilizzo. Basta modificare la linea appropriata nel programma `configure`: +``` +< ac_default_prefix=/usr +--- +> ac_default_prefix=/usr/local +``` +Successivamente, puoi completare la preparazione: +``` +$ ./configure +$ make +``` +Puoi quindi verificare che i test funzionino: +``` +$ make check +Making check in src +make[1]: Entering directory '/home/standup/libwally-core/src' +Making check in secp256k1 +make[2]: Entering directory '/home/standup/libwally-core/src/secp256k1' +make check-TESTS +make[3]: Entering directory '/home/standup/libwally-core/src/secp256k1' +make[4]: Entering directory '/home/standup/libwally-core/src/secp256k1' +============================================================================ +Testsuite summary for libsecp256k1 0.1 +============================================================================ +# TOTAL: 0 +# PASS: 0 +# SKIP: 0 +# XFAIL: 0 +# FAIL: 0 +# XPASS: 0 +# ERROR: 0 +============================================================================ +make[4]: Leaving directory '/home/standup/libwally-core/src/secp256k1' +make[3]: Leaving directory '/home/standup/libwally-core/src/secp256k1' +make[2]: Leaving directory '/home/standup/libwally-core/src/secp256k1' +make[2]: Entering directory '/home/standup/libwally-core/src' +make check-TESTS check-local +make[3]: Entering directory '/home/standup/libwally-core/src' +make[4]: Entering directory '/home/standup/libwally-core/src' +PASS: test_bech32 +PASS: test_psbt +PASS: test_psbt_limits +PASS: test_tx +============================================================================ +Testsuite summary for libwallycore 0.7.8 +============================================================================ +# TOTAL: 4 +# PASS: 4 +# SKIP: 0 +# XFAIL: 0 +# FAIL: 0 +# XPASS: 0 +# ERROR: 0 +============================================================================ +make[4]: Leaving directory '/home/standup/libwally-core/src' +make[3]: Nothing to be done for 'check-local'. +make[3]: Leaving directory '/home/standup/libwally-core/src' +make[2]: Leaving directory '/home/standup/libwally-core/src' +make[1]: Leaving directory '/home/standup/libwally-core/src' +make[1]: Entering directory '/home/standup/libwally-core' +make[1]: Nothing to be done for 'check-am'. +make[1]: Leaving directory '/home/standup/libwally-core' +``` +Infine, puoi installare: +``` +$ sudo make install +``` + + +## Prepararsi per Libwally + +Quindi, come si usa Libwally in un programma? Come al solito, dovrai includere i file appropriati e collegare le librerie appropriate per il tuo codice. + +### Includere i File + +Ci sono un numero considerevole di file di inclusione possibili: + + +``` +$ ls /usr/include/wally* +/usr/include/wally_address.h /usr/include/wally_bip39.h /usr/include/wally_elements.h /usr/include/wally_script.h +/usr/include/wally_bip32.h /usr/include/wally_core.h /usr/include/wally.hpp /usr/include/wally_symmetric.h +/usr/include/wally_bip38.h /usr/include/wally_crypto.h /usr/include/wally_psbt.h /usr/include/wally_transaction.h +``` +Fortunatamente, i nomi dei file corrispondono in gran parte alle sezioni nei [documenti](https://wally.readthedocs.io/en/latest/), quindi dovresti essere in grado di includere i file corretti in base a ciò che stai facendo, dopo aver incluso l'onnipresente `wally_core.h`. + +### Collegare le Librerie + +Dovrai anche collegare le librerie appropriate: + +``` +$ ls /usr/lib/libsecp* /usr/lib/libwally* +/usr/lib/libsecp256k1.a /usr/lib/libwallycore.la /usr/lib/libwallycore.so.0 +/usr/lib/libsecp256k1.la /usr/lib/libwallycore.so /usr/lib/libwallycore.so.0.0.0 +``` +Principalmente, utilizzerai `libwallycore`. + +## Configurare un Programma Libwally + +Rispetto ad alcune delle librerie precedenti, Libwally è ridicolmente facile da inizializzare: + +``` +lw_response = wally_init(0); +``` +E poi, quando hai finito, c'è una comoda funzione per ripulire tutta la memoria allocata: +``` +wally_cleanup(0); +``` +In entrambi i casi, l'argomento è per i flag, ma è attualmente impostato su `0`. + +## Testare un Programma di Test Libwally + +La directory src contiene [testwally.c](src/17_1_testwally.c), che mostra semplicemente come funzionano le funzioni di inizializzazione e pulizia. + +Puoi compilarlo come segue: + +``` +$ cc testwally.c -lwallycore -o testwally +``` +Dopo puoi eseguirlo: +``` +$ ./testwally +Startup: 0 +``` +Il valore "Startup" è il ritorno di `wally_init`. Il valore `0` può inizialmente sembrare scoraggiante, ma è quello che vuoi vedere: +``` +include/wally_core.h:#define WALLY_OK 0 /** Success */ +``` + +## Install Libsodium + + +## Installare Libsodium + +Dovresti anche installare Libsodium per avere accesso a un generatore di numeri casuali di alta qualità per scopi di test. + +> :warning: **ATTENZIONE:** La generazione di numeri casuali può essere uno dei maggiori punti di vulnerabilità in qualsiasi software Bitcoin. Se lo fai male, esponi i tuoi utenti ad attacchi perché finiscono con chiavi Bitcoin non sicure, e questo non è un [problema teorico](https://github.com/BlockchainCommons/SmartCustodyBook/blob/master/manuscript/03-adversaries.md#adversary-systemic-key-compromise). BlockchainInfo una volta generò erroneamente lo 0,0002% delle loro chiavi, il che portò alla perdita temporanea di 250 Bitcoin. In breve: assicurati di essere completamente a tuo agio con la generazione dei numeri casuali. Potrebbe essere Libsodium, o potrebbe essere un metodo TRNG ancora più robusto. + +Puoi scaricare un [tarball Libsodium](https://download.libsodium.org/libsodium/releases/) e poi seguire le istruzioni su [installazione di Libsodium](https://doc.libsodium.org/installation) per installarlo. + +Prima, decomprimi: + +``` +$ tar xzfv /tmp/libsodium-1.0.18-stable.tar.gz +``` +Poi, aggiusta il file `configure` esattamente come hai fatto con le altre librerie finora: +``` +< ac_default_prefix=/usr +--- +> ac_default_prefix=/usr/local +``` +Infine, `make`, `check` e `install`: +``` +$ make +$ make check +... +============================================================================ +Testsuite summary for libsodium 1.0.18 +============================================================================ +# TOTAL: 77 +# PASS: 77 +# SKIP: 0 +# XFAIL: 0 +# FAIL: 0 +# XPASS: 0 +# ERROR: 0 +============================================================================ +... +$ sudo make install +``` +Questo corso userà `libsodium` solo per un piccolo (ma cruciale!) bit di generazione di entropia, ma tienilo d'occhio nella sezione successiva. + +## Riepilogo: Configurare Libwally + +Installando gli include e le librerie Libwally (e Libsodium), ottieni accesso a un numero di funzioni crittografiche e di portafoglio, che possono completare le tue librerie RPC e ZMQ (o il tuo `bitcoin-cli` da riga di comando). + +Quindi, cosa puoi fare esattamente ora? È di questo che tratta il resto di questo capitolo. + +## Cosa c'è dopo? + +Scopri di più su "Programmare Bitcoin con Libwally" nel [Capitolo 17.2: Usare BIP39 in Libwally](17_2_Usare_BIP39_in_Libwally.md). + + diff --git a/it/17_2_Usare_BIP39_in_Libwally.md b/it/17_2_Usare_BIP39_in_Libwally.md new file mode 100644 index 000000000..c2357380e --- /dev/null +++ b/it/17_2_Usare_BIP39_in_Libwally.md @@ -0,0 +1,110 @@ +# 17.2: Utilizzare BIP39 in Libwally + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe ancora essere in attesa di revisione. Lettore avvisato. + +Uno dei maggiori poteri di Libwally è che può mettere a nudo il lavoro sottostante di generazione di semi, chiavi private e, in ultima analisi, indirizzi. Per cominciare, supporta [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki), che è il BIP che definisce i codici mnemonici per Bitcoin — qualcosa che finora non è supportato da Bitcoin Core. + +> :book: ***Cos'è un Codice Mnemonico?*** Gli indirizzi Bitcoin (e le relative chiavi private e semi sottostanti) sono lunghe liste incomprensibili di caratteri e numeri, che non solo sono impossibili da ricordare, ma anche facili da digitare erroneamente. I codici mnemonici sono una soluzione a questo problema che consente agli utenti di registrare 12 (o 24) parole nella loro lingua — qualcosa di molto meno soggetto a errori. Questi codici possono quindi essere utilizzati per ripristinare completamente un seme BIP32 che è la base di un portafoglio HD. + +> :book: ***Cos'è un Seme?*** Abbiamo toccato brevemente l'argomento seme nel [Capitolo 3.5: Comprendere il Descriptor](03_5_Comprendere_il_Descriptor.md). È il numero casuale che viene utilizzato per generare un'intera sequenza di chiavi private (e quindi indirizzi) in un portafoglio HD. Torneremo sui semi nella sezione successiva, che riguarda i portafogli HD e Libwally. Per ora, sappi solo che un codice mnemonico BIP39 corrisponde al seme per un portafoglio deterministico gerarchico BIP32. + +## Creare Codici Mnemonici + +Tutte le chiavi Bitcoin iniziano con l'entropia. Questo primo utilizzo di Libwally e dei suoi mnemonici BIP39 mostra quindi come generare entropia e ottenere un codice mnemonico da essa. + +> :book: ***Cos'è l'Entropia?*** L'entropia è un modo sofisticato di dire casualità, ma è una casualità attentamente misurata che viene utilizzata come base di un generatore di numeri veramente casuali (TRG). È misurata in "bit", con più bit di entropia che risultano in maggiore casualità (e quindi maggiore protezione per ciò che viene generato). Per Bitcoin, l'entropia è la base del tuo seme, che in un portafoglio HD genera tutti i tuoi indirizzi. + +Inizierai sempre il lavoro con Libwally inizializzando la libreria e testando i risultati, come dimostrato per la prima volta nel [Capitolo 17.1](17_1_Configurare_Libwally.md): + +``` + int lw_response; + + lw_response = wally_init(0); + + if (lw_response) { + + printf("Error: Wally_init failed: %d\n",lw_response); + exit(-1); + + } +``` +Ora sei pronto per entropizzare. + +### Creare Entropia + +Usando `libsodium`, puoi creare entropia con il comando `randombytes_buf`: + +``` + unsigned char entropy[16]; + randombytes_buf(entropy, 16); +``` +Questo esempio, che sarà l'unico modo in cui utilizzeremo la libreria `libsodium`, crea 16 byte di entropia. In generale, per creare un codice mnemonico sicuro, dovresti usare tra 128 e 256 bit di entropia, ovvero 16-32 byte. + +>:warning: **ATTENZIONE:** Ancora una volta, assicurati di essere molto a tuo agio con il tuo metodo di generazione dell'entropia prima di usarlo in un programma reale. + +### Tradurre in un Mnemonico + +16 byte di entropia sono sufficienti per creare un codice mnemonico a 12 caratteri, che viene fatto con la funzione `bip39_mnemonic_from_bytes` di Libwally:: +``` + char *mnem = NULL; + lw_response = bip39_mnemonic_from_bytes(NULL,entropy,16,&mnem); +``` +Nota che devi passare la dimensione del byte, quindi se dovessi aumentare la dimensione della tua entropia, per generare una frase mnemonica più lunga, dovresti anche aumentare il valore in questa funzione. + +> **NOTA:** Esistono elenchi di parole mnemoniche per diverse lingue! Il valore predefinito è utilizzare l'elenco in lingua inglese, che è la variabile `NULL` in questi comandi mnemonici di Libwally, ma puoi richiedere alternativamente una lingua diversa! + +Ecco fatto! Hai creato una frase mnemonica! + +>:book: ***Come viene creata la Frase Mnemonica?*** Puoi impararlo in [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki), ma se preferisci, Greg Walker ha un [ottimo esempio](https://learnmeabitcoin.com/technical/mnemonic): in pratica, aggiungi un checksum, poi converti ogni serie di 11 bit in una parola dall'elenco delle parole. Puoi farlo con i comandi `bip39_get_wordlist` e `bip39_get_word` se non ti fidi del comando `bip39_mnemonic_from_bytes`. + +### Tradurre in un Seme + +Ci sono alcune funzioni, come `bip32_key_from_seed` (che incontreremo nella sezione successiva) che richiedono di avere il seme piuttosto che il Mnemonico. Le due cose sono funzionalmente identiche: se hai il seme, puoi generare il mnemonico e viceversa. + +Se hai bisogno di generare il seme dal tuo mnemonico, devi solo usare il comando `bip39_mnemonic_to_seed`: + +``` + unsigned char seed[BIP39_SEED_LEN_512]; + size_t seed_len; + + lw_response = bip39_mnemonic_to_seed(mnem,NULL,seed,BIP39_SEED_LEN_512,&seed_len); +``` +Nota che tutti i semi BIP39 sono attualmente 512 byte; tuttavia, devi impostare correttamente la dimensione della tua variabile e passare tale dimensione a `bip39_mnemonic_to_seed`. + +### Stampare il Tuo Seme + +Se vuoi vedere come appare il tuo seme in esadecimale, puoi usare la funzione `wally_hex_from_bytes` per trasformare il tuo seme in un codice esadecimale leggibile (ma non ottimale per le persone): +``` + char *seed_hex; + wally_hex_from_bytes(seed,sizeof(seed),&seed_hex); + printf("Seed: %s\n",seed_hex); +``` +Se hai fatto tutto correttamente, dovresti ottenere un seme di 64 byte. (Questa è la variabile `BIP39_SEED_LEN_512` che hai usato, che definisce una lunghezza predefinita del seme di 512 bit o 64 byte.) + +> :warning: **ATTENZIONE:** Dovresti assolutamente verificare che la lunghezza del tuo seme sia di 64 byte in qualche modo, perché è facile sbagliare, ad esempio utilizzando il tipo di variabile sbagliato quando esegui `bip39_mnemonic_to_seed`. + +## Testare il Codice Mnemonico + +Il codice completo per generare entropia, generare un mnemonico BIP39, convalidare il mnemonico e generare un seme può essere trovato nella [directory src](src/17_2_genmnemonic.c). Scaricalo e compila: + +``` +$ cc genmnemonic.c -lwallycore -lsodium -o genmnemonic +``` +Poi puoi eseguire il test: +``` +Mnemonic: parent wasp flight sweet miracle inject lemon matter label column canyon trend +Mnemonic validated! +Seed: 47b04cfb5d8fd43d371497f8555a27a25ca0a04aafeb6859dd4cbf37f6664b0600c4685c1efac29c082b1df29081f7a46f94a26f618fc6fd38d8bc7b6cd344c7 +``` + +## Riepilogo: Utilizzare BIP39 in Libwally + +BIP39 ti consente di generare un insieme di 12-24 parole mnemoniche da un seme (e la libreria Libwally ti consente anche di convalidarlo!). + +> :fire: ***Qual è la potenza di BIP39?*** I semi e le chiavi private di Bitcoin sono soggetti a tutti i tipi di perdite. Se sbagli una sola cifra, i tuoi soldi sono persi per sempre. Le parole mnemoniche sono un modo molto più user-friendly di rappresentare gli stessi dati, ma poiché sono parole nella lingua scelta dall'utente, sono meno soggette a errori. Il potere di BIP39 è quindi migliorare l'accessibilità, l'usabilità e la sicurezza di Bitcoin. + +> :fire: ***Qual è la potenza di BIP39 in Libwally?*** Bitcoind attualmente non supporta le parole mnemoniche, quindi usare Libwally può permetterti di generare parole mnemoniche in combinazione con gli indirizzi detenuti da `bitcoind` (anche se come vedremo nel §17.7, richiede un po' di lavoro al momento per importare le tue chiavi in Bitcoin Core). + +## Cosa c'è dopo? + +Scopri di più su "Programmare Bitcoin con Libwally" nel [Capitolo 17.3: Usare BIP32 in Libwally](17_3_Usare_BIP32_in_Libwally.md). diff --git a/it/17_3_Usare_BIP32_in_Libwally.md b/it/17_3_Usare_BIP32_in_Libwally.md new file mode 100644 index 000000000..1746bc4a9 --- /dev/null +++ b/it/17_3_Usare_BIP32_in_Libwally.md @@ -0,0 +1,152 @@ +# 17.3: Utilizzo di BIP32 in Libwally + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Nel [Capitolo 17.2](17_2_Usare_BIP39_in_Libwally.md), sei stato in grado di utilizzare l'entropia per generare un seed e il suo relativo mnemonico. Come ricorderai dal [Capitolo 3.5: Comprendere il Descriptor](03_5_Comprendere_il_Descriptor.md), un seed è la base di un Wallet Gerarchico Deterministico (HD), dove quel singolo seed può essere utilizzato per generare molti indirizzi. Quindi, come si passa dal seed agli indirizzi effettivi? È qui che entra in gioco [BIP32](https://en.bitcoin.it/wiki/BIP_0032). + +## Creare una Radice HD + +Per creare un indirizzo HD è necessario iniziare con un seed e poi scendere lungo la gerarchia fino al punto in cui si creano gli indirizzi. + +Questo inizia abbastanza facilmente, basta generare un seed, cosa che hai già fatto nella sezione precedente: + +``` + unsigned char entropy[16]; + randombytes_buf(entropy, 16); + + char *mnem = NULL; + lw_response = bip39_mnemonic_from_bytes(NULL,entropy,16,&mnem); + + unsigned char seed[BIP39_SEED_LEN_512]; + size_t seed_len; + lw_response = bip39_mnemonic_to_seed(mnem,NULL,seed,BIP39_SEED_LEN_512,&seed_len); +``` +### Generare una Chiave Radice + +Con un seed a portata di mano, puoi quindi generare una chiave master estesa con la funzione `bip32_key_from_seed_alloc` (o alternativamente `bip32_key_from_seed`, che non fa l'allocazione): + +``` + struct ext_key *key_root; + lw_response = bip32_key_from_seed_alloc(seed,sizeof(seed),BIP32_VER_TEST_PRIVATE,0,&key_root); +``` +Come puoi vedere, dovrai specificare quale versione della chiave restituire, in questo caso `BIP32_VER_TEST_PRIVATE`, una chiave privata per testnet. + +> :link: **TESTNET vs MAINNET:** Su mainnet, invece, dovresti chiedere `BIP32_VER_MAIN_PRIVATE`. + +### Generare xpub & xprv + +Ogni volta che hai una chiave a portata di mano, puoi trasformarla in chiavi xpub o xprv per la distribuzione con il comando `bip32_key_to_base58`. Basta indicare se desideri una chiave `PRIVATE` (xprv) o `PUBLIC` (xpub): + +``` + char *xprv; + lw_response = bip32_key_to_base58(key_root, BIP32_FLAG_KEY_PRIVATE, &xprv); + + char *xpub; + lw_response = bip32_key_to_base58(key_root, BIP32_FLAG_KEY_PUBLIC, &xpub); +``` + +## Comprendere la Gerarchia + +Prima di procedere, devi capire come funziona la gerarchia di un wallet HD. Come discusso in [§3.5](03_5_Understanding_the_Descriptor.md), un percorso di derivazione descrive l'albero che segui per arrivare a una chiave gerarchica, quindi `[0/1/0]` è il 0° figlio del 1° figlio del 0° figlio di una chiave radice. A volte parte di quella derivazione è contrassegnata con `'` o `h` per mostrare derivazioni hardened, che aumentano la sicurezza: `[0'/1'/0']`. + +Tuttavia, per i wallet HD, ciascuno di questi livelli della gerarchia è utilizzato in un modo molto specifico. Questo è stato originariamente definito in [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) ed è stato successivamente aggiornato per Segwit in [BIP84]. + +Nel complesso, un percorso di derivazione BIP32 è definito per avere cinque livelli: + +1. **Scopo.** Questo è solitamente impostato su `44'` o `84'`, a seconda del BIP che viene seguito. +2. **Moneta.** Per i bitcoin su Mainnet, questo è `0'`, per testnet è `1'`. +3. **Account.** Un wallet può contenere più account distinti, a partire da `0'`. +4. **Cambio.** Gli indirizzi esterni (per la distribuzione) sono impostati su `0`, mentre gli indirizzi interni (per il cambio) sono impostati su `1`. +5. **Indice.** Il n° indirizzo per la gerarchia, a partire da `0`. + +Quindi su testnet, il primo indirizzo per un indirizzo esterno per il primo account per le monete di testnet utilizzando gli standard BIP84 è `[m/84'/1'/0'/0/0]`. Questo è l'indirizzo che creerai tra poco. + +> :link: **TESTNET vs MAINNET:** Per mainnet, sarebbe `[m/84'/0'/0'/0/0]` + +### Comprendere la Gerarchia in Bitcoin Core + +Utilizzeremo la gerarchia sopra per tutte le chiavi HD in Libwally, ma nota che questo standard non è utilizzato dal `bitcoin-cli` di Bitcoin Core, che invece utilizza `[m/0'/0'/0']` per il 0° indirizzo esterno e `[m/0'/1'/0']` per il 0° indirizzo di cambio. + +## Generare un Indirizzo + +Per generare un indirizzo, devi quindi scendere attraverso l'intera gerarchia. + +### Generare una Chiave Account + +Un modo per farlo è utilizzare la funzione `bip32_key_from_parent_path_alloc` per scendere diversi livelli di una gerarchia. Incapsuli i livelli in un array: +``` + uint32_t path_account[] = {BIP32_INITIAL_HARDENED_CHILD+84, BIP32_INITIAL_HARDENED_CHILD+1, BIP32_INITIAL_HARDENED_CHILD}; +``` +Qui guarderemo al primo figlio hardened (cioè l'account) o al secondo figlio hardened (cioè le monete di testnet) del 84° figlio hardened (cioè lo standard BIP84): `[m/84'/1'/0']`. + +Puoi quindi utilizzare quel percorso per generare una nuova chiave dalla tua vecchia chiave: + +``` + struct ext_key *key_account; + lw_response = bip32_key_from_parent_path_alloc(key_root,path_account,sizeof(path_account),BIP32_FLAG_KEY_PRIVATE,&key_account); +``` +Ogni volta che hai una nuova chiave, puoi usarla per generare nuove chiavi xprv e xpub, se lo desideri: +``` + lw_response = bip32_key_to_base58(key_account, BIP32_FLAG_KEY_PRIVATE, &a_xprv); + lw_response = bip32_key_to_base58(key_account, BIP32_FLAG_KEY_PUBLIC, &a_xpub); +``` + + +### Generare una Chiave di Indirizzo + +In alternativa, puoi utilizzare la funzione `bip32_key_from_parent_alloc`, che scende solo di un livello della gerarchia alla volta. Il seguente esempio scende al 0° figlio della chiave account (che è l'indirizzo esterno) e poi al 0° figlio di quello. Questo sarebbe utile perché poi potresti continuare a generare il 1° indirizzo, il 2° indirizzo e così via da quella chiave esterna: + +``` + struct ext_key *key_external; + lw_response = bip32_key_from_parent_alloc(key_account,0,BIP32_FLAG_KEY_PRIVATE,&key_external); + + struct ext_key *key_address; + lw_response = bip32_key_from_parent_alloc(key_external,0,BIP32_FLAG_KEY_PRIVATE,&key_address); +``` +> :warning: **AVVISO:** A un certo punto in questa gerarchia, potresti decidere di generare `BIP32_FLAG_KEY_PUBLIC` invece di `BIP32_FLAG_KEY_PRIVATE`. Ovviamente questa decisione sarà basata sulla tua sicurezza e le tue necessità, ma ricorda che hai bisogno solo di una chiave pubblica per generare l'indirizzo effettivo. + +### Generare un Indirizzo + +Finalmente, sei pronto per generare un indirizzo dalla tua chiave finale. Tutto quello che devi fare è eseguire `wally_bip32_to_addr_segwit` usando la tua chiave finale e una descrizione del tipo di indirizzo che è. +. +``` + char *segwit; + lw_response = wally_bip32_key_to_addr_segwit(key_address,"tb",0,&segwit); + + printf("[m/84'/1'/0'/0/0]: %s\n",segwit); +``` + + +> :link: **TESTNET vs MAINNET:** L'argomento `tb` definisce un indirizzo di testnet. Per mainnet invece usa `bc`. + +Esiste anche una funzione `wally_bip32_key_to_address`, che può essere utilizzata per generare un indirizzo legacy o un indirizzo Segwit annidato. + +## Testare il Codice HD + +Il codice per questi esempi HD può, come al solito, essere trovato nella [directory src](src/17_3_genhd.c). + +Puoi compilarlo e testarlo: + +``` +$ cc genhd.c -lwallycore -lsodium -o genhd +$ ./genhd +Mnemonic: behind mirror pond finish borrow wood park foam guess mail regular reflect +Root xprv key: tprv8ZgxMBicQKsPdLFXmZ6VegTxcmeieNpRUq8J2ahXxSaK2aF7CGqAc14ZADLjdHJdCr8oR2Zng9YH1x1A7EBaajQLVGNtxc4YpFejdE3wyj8 +Root xpub key: tpubD6NzVbkrYhZ4WoHKfCm64685BoAeoi1L48j5K6jqNiNhs4VspfeknVgRLLiQJ3RkXiA9VxguUjmEwobtmrXNbhXsPHfm9W5HJR9DKRGaGJ2 +Account xprv key: tprv8yZN7h6SPvJXrhAk56z6cwHQE6qZBRreB9fqqZJ1Xd1nLci3Rw8HTmqNkpFNgf3eZx8hYzhFWafUhHSt3HgF13aHvCE6kveS7gZAyfQwMDi +Account xpub key: tpubDWFQG78gYHzCkACXxkeh2LwWo8MVLm3YkTGd85LJwtpBB6xp4KwseGTEvxjeZNhnCNPdfZqRcgcZZAka4tD3xGS2J53WKHPMRhG357VKsqT +[m/84'/1'/0'/0/0]: tb1q0knqq26ek59pfl7nukzqr28m2zl5wn2f0ldvwu +``` + + +## Riepilogo: Utilizzo di BIP32 in Libwally + +Un wallet HD ti consente di generare un numero enorme di chiavi da un singolo seed. Ora sai come sono organizzate quelle chiavi sotto BIP44, BIP84 e Bitcoin Core e come derivarle, partendo da un seed o da parole mnemoniche. + +> :fire: ***Qual è il potere di BIP32?*** Le chiavi sono l'elemento più difficile (e più pericoloso) della maggior parte delle operazioni crittografiche. Se le perdi, perdi ciò che la chiave proteggeva. BIP32 garantisce che devi conoscere solo una chiave, il seed, piuttosto che un enorme numero di chiavi diverse per indirizzi diversi. + +> :fire: ***Qual è il potere di BIP32 in Libwally?*** Bitcoind già crea indirizzi basati su HD per te, il che significa che di solito non devi preoccuparti di derivare indirizzi in questo modo. Tuttavia, l'utilizzo delle funzioni BIP32 di Libwally può essere molto utile se hai una macchina offline dove devi derivare indirizzi, possibilmente basati su un seed passato da `bitcoind` al tuo dispositivo offline (o viceversa). + +## Cosa c'è dopo? + +Scopri di più su "Programming Bitcoin with Libwally" nel [Capitolo 17.4: Usare PSBTs in Libwally](17_4_Usare_PSBTs_in_Libwally.md). diff --git a/it/17_4_Usare_PSBTs_in_Libwally.md b/it/17_4_Usare_PSBTs_in_Libwally.md new file mode 100644 index 000000000..89fb30c92 --- /dev/null +++ b/it/17_4_Usare_PSBTs_in_Libwally.md @@ -0,0 +1,383 @@ +# 17.4: Utilizzo di PSBTs in Libwally + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Hai imparato tutto sulle Transazioni Bitcoin Parzialmente Firmate (PSBT) in [§7.1](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) e [§7.2](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md), e come hai visto in [§7.3: Integrating with Hardware Wallets](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/07_3_Integrating_with_Hardware_Wallets.md), uno dei loro principali vantaggi è la possibilità di integrarsi con nodi offline, come i Portafogli Hardware. HWI ti permetteva di inviare comandi a un Portafoglio Hardware, ma cosa utilizza il portafoglio stesso per gestire le PSBT? Come si scopre, può utilizzare qualcosa come Libwally, come dimostra questa sezione. + +Fondamentalmente, Libwally ha tutta la funzionalità delle PSBT, quindi se c'è qualcosa che potresti fare con `bitcoind`, potresti farlo anche usando Libwally, anche se il tuo dispositivo è offline. Quello che segue è la più semplice introduzione a un argomento molto complesso. + +## Convertire una PSBT + +Convertire una PSBT nella struttura interna di Libwally è incredibilmente facile, basta eseguire `wally_psbt_from_base64` con una PSBT in base64 — che sono gli output prodotti da `bitcoin-cli`, come: + +`cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giBgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxRiaHVILVAAAgAEAAIAAAACAAAAAADkCAAAAAQEfQEIPAAAAAAAWABQtTxOfqohTBNFWFqFm0tUVdK9KXSIGAqATz5xLX1aJ2SUwNqPkd8+YaJYm94FMlPCScm8Rt0GrGJodUgtUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgID2UK1nupSfXC81nmB65XZ+pYlJp/W6wNk5FLt5ZCSx6kYmh1SC1QAAIABAACAAAAAgAEAAAABAAAAAA==` + +Tuttavia, è un po' più difficile gestire il risultato, perché Libwally lo converte in una struttura `wally_psbt` molto complessa. + +Ecco come è definita in `/usr/include/wally_psbt.h`: + +``` +struct wally_psbt { + unsigned char magic[5]; + struct wally_tx *tx; + struct wally_psbt_input *inputs; + size_t num_inputs; + size_t inputs_allocation_len; + struct wally_psbt_output *outputs; + size_t num_outputs; + size_t outputs_allocation_len; + struct wally_unknowns_map *unknowns; + uint32_t version; +}; + +struct wally_psbt_input { + struct wally_tx *non_witness_utxo; + struct wally_tx_output *witness_utxo; + unsigned char *redeem_script; + size_t redeem_script_len; + unsigned char *witness_script; + size_t witness_script_len; + unsigned char *final_script_sig; + size_t final_script_sig_len; + struct wally_tx_witness_stack *final_witness; + struct wally_keypath_map *keypaths; + struct wally_partial_sigs_map *partial_sigs; + struct wally_unknowns_map *unknowns; + uint32_t sighash_type; +}; + +struct wally_psbt_output { + unsigned char *redeem_script; + size_t redeem_script_len; + unsigned char *witness_script; + size_t witness_script_len; + struct wally_keypath_map *keypaths; + struct wally_unknowns_map *unknowns; +}; +``` +Questi a loro volta utilizzano alcune strutture di transazione definite in `/usr/include/wally_transaction.h`: +``` +struct wally_tx { + uint32_t version; + uint32_t locktime; + struct wally_tx_input *inputs; + size_t num_inputs; + size_t inputs_allocation_len; + struct wally_tx_output *outputs; + size_t num_outputs; + size_t outputs_allocation_len; +}; + +struct wally_tx_output { + uint64_t satoshi; + unsigned char *script; + size_t script_len; + uint8_t features; +}; +``` +C'è molto! Anche se gran parte di questo dovrebbe essere familiare dai capitoli precedenti, è un po' travolgente vederlo tutto disposto in strutture C. + +## Leggere una PSBT Convertita + +Ovviamente, puoi leggere qualsiasi cosa da una struttura PSBT richiamando i singoli elementi dalle varie sotto-strutture. Quanto segue è una breve panoramica che mostra come recuperare alcuni degli elementi. + +Ecco un esempio di recupero dei valori e `scriptPubKeys` degli input: + +``` + int inputs = psbt->num_inputs; + printf("TOTAL INPUTS: %i\n",inputs); + + for (int i = 0 ; i < inputs ; i++) { + printf("\nINPUT #%i: %i satoshis\n",i, psbt->inputs[i].witness_utxo->satoshi); + + char *script_hex; + wally_hex_from_bytes(psbt->inputs[i].witness_utxo->script,psbt->inputs[i].witness_utxo->script_len,&script_hex); + printf("scriptPubKey: %s\n",script_hex); + wally_free_string(script_hex); + } +``` +Questo schema di programmazione sarà utilizzato su molte parti della PSBT. Guardi la dimensione dell'array degli input, poi lo attraversi, recuperando ciò che vuoi vedere (in questo caso, satoshi e script). + +Ecco un esempio simile per gli output: + +``` + int outputs = psbt->num_outputs; + printf("\nTOTAL OUTPUTS: %i\n",outputs); + for (int i = 0 ; i < outputs ; i++) { + char *pubkey_hex; + wally_hex_from_bytes(psbt->tx->outputs[i].script,psbt->tx->outputs[i].script_len,&pubkey_hex); + printf("\nINPUT #%i\n",i); + printf("scriptPubKey: %s\n",pubkey_hex); + wally_free_string(pubkey_hex); + } +``` +Ovviamente, c'è molto altro che potresti guardare nelle PSBT. Infatti, guardare è il punto principale di una PSBT: puoi verificare input e output da un computer offline. + +> :warning: **AVVISO:** Queste funzioni di lettura sono _molto_ rudimentali e non funzioneranno correttamente in situazioni estremamente normali come un input o output che è ancora vuoto o che include un `non_witness_utxo`. Si verificheranno errori se non viene fornita una PSBT precisamente come previsto. Un lettore reale dovrebbe essere considerevolmente più robusto, per coprire tutte le possibili situazioni, ma questo è lasciato come esercizio per il lettore. + +### Testare il Tuo Lettore PSBT + +Ancora una volta, il codice per questo (estremamente rudimentale e specifico) lettore PSBT è nella [directory src](src/17_4_examinepsbt.c). + +Puoi compilarlo come al solito: + +``` +$ cc examinepsbt.c -lwallycore -o examinepsbt +``` +La seguente PSBT dal [Capitolo: 7.3](07_3_Integrazione_con_Hardware_Wallets.md) può essere utilizzata per i test, poiché corrisponde ai criteri molto ristretti richiesti da questa implementazione limitata: +``` +psbt=cHNidP8BAJoCAAAAAri6BLjKQZGO9Y1iVIYbxlxBJ2kqsTPWnxGaH4HrSjxbAAAAAAD+////leV0hwJ0fO40RmhuFVIYtO16ktic2J4vJFLAsT5TM8cBAAAAAP7///8CYOMWAAAAAAAWABTHctb5VULhHvEejvx8emmDCtOKBU+gBwAAAAAAFgAU9Ojd5ds3CJi1fIRWbj92CYhQgX0AAAAAAAEBH0BCDwAAAAAAFgAUABk8i/Je8Fb41FcaHD9lEj5f54giBgMBaNlILisC1wJ/tKie3FStqhrfcJM09kfQobBTOCiuxRiaHVILVAAAgAEAAIAAAACAAAAAADkCAAAAAQEfQEIPAAAAAAAWABQtTxOfqohTBNFWFqFm0tUVdK9KXSIGAqATz5xLX1aJ2SUwNqPkd8+YaJYm94FMlPCScm8Rt0GrGJodUgtUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgID2UK1nupSfXC81nmB65XZ+pYlJp/W6wNk5FLt5ZCSx6kYmh1SC1QAAIABAACAAAAAgAEAAAABAAAAAA== +``` +Esegui `examinepsbt` con quella PSBT, e dovresti vedere gli script sugli input e gli output: +``` +$ ./examinepsbt $psbt +TOTAL INPUTS: 2 + +INPUT #0: 1000000 satoshis +scriptPubKey: 001400193c8bf25ef056f8d4571a1c3f65123e5fe788 + +INPUT #1: 1000000 satoshis +scriptPubKey: 00142d4f139faa885304d15616a166d2d51574af4a5d + +TOTAL OUTPUTS: 2 + +INPUT #0 +scriptPubKey: 0014c772d6f95542e11ef11e8efc7c7a69830ad38a05 + +INPUT #1 +scriptPubKey: 0014f4e8dde5db370898b57c84566e3f76098850817d +``` +E ovviamente, puoi verificare questo con il comando RPC `decodepsbt` per `bitcoin-cli`: +``` +$ bitcoin-cli decodepsbt $psbt +{ + "tx": { + "txid": "45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d", + "hash": "45f996d4ff8c9e9ab162f611c5b6ad752479ede9780f9903bdc80cd96619676d", + "version": 2, + "size": 154, + "vsize": 154, + "weight": 616, + "locktime": 0, + "vin": [ + { + "txid": "5b3c4aeb811f9a119fd633b12a6927415cc61b8654628df58e9141cab804bab8", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + }, + { + "txid": "c733533eb1c052242f9ed89cd8927aedb41852156e684634ee7c74028774e595", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01500000, + "n": 0, + "scriptPubKey": { + "asm": "0 c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "hex": "0014c772d6f95542e11ef11e8efc7c7a69830ad38a05", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qcaedd724gts3aug73m78c7nfsv9d8zs9q6h2kd" + ] + } + }, + { + "value": 0.00499791, + "n": 1, + "scriptPubKey": { + "asm": "0 f4e8dde5db370898b57c84566e3f76098850817d", + "hex": "0014f4e8dde5db370898b57c84566e3f76098850817d", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q7n5dmewmxuyf3dtus3txu0mkpxy9pqtacuprak" + ] + } + } + ] + }, + "unknown": { + }, + "inputs": [ + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 00193c8bf25ef056f8d4571a1c3f65123e5fe788", + "hex": "001400193c8bf25ef056f8d4571a1c3f65123e5fe788", + "type": "witness_v0_keyhash", + "address": "tb1qqqvnezljtmc9d7x52udpc0m9zgl9leugd2ur7y" + } + }, + "bip32_derivs": [ + { + "pubkey": "030168d9482e2b02d7027fb4a89edc54adaa1adf709334f647d0a1b0533828aec5", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/0/569" + } + ] + }, + { + "witness_utxo": { + "amount": 0.01000000, + "scriptPubKey": { + "asm": "0 2d4f139faa885304d15616a166d2d51574af4a5d", + "hex": "00142d4f139faa885304d15616a166d2d51574af4a5d", + "type": "witness_v0_keyhash", + "address": "tb1q948388a23pfsf52kz6skd5k4z4627jja2evztr" + } + }, + "bip32_derivs": [ + { + "pubkey": "02a013cf9c4b5f5689d9253036a3e477cf98689626f7814c94f092726f11b741ab", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/0/0" + } + ] + } + ], + "outputs": [ + { + }, + { + "bip32_derivs": [ + { + "pubkey": "03d942b59eea527d70bcd67981eb95d9fa9625269fd6eb0364e452ede59092c7a9", + "master_fingerprint": "9a1d520b", + "path": "m/84'/1'/0'/1/1" + } + ] + } + ], + "fee": 0.00000209 +} +``` +Puoi vedere chiaramente i satoshi di input e `scriptPubKey` elencati negli `input` e i nuovi `scriptPubKey` nei `vout` del `tx`. + +Quindi, è tutto lì per il tuo recupero! + +## Creare una PSBT + +Come notato all'inizio di questa sezione, tutte le funzioni necessarie per creare e processare PSBT sono disponibili in Libwally. In realtà, eseguire il processo di creazione è così complesso che va oltre lo scopo di questa sezione, ma ecco una rapida panoramica delle funzioni necessarie. Nota che i [documenti](https://wally.readthedocs.io/en/latest/psbt/) sono obsoleti per PSBT, quindi dovrai consultare `/usr/include/wally_psbt.h` per informazioni complete. + +Come discusso nel [Capitolo 7.1](07_1_Creare_una_Transazione_Bitcoin_Parzialmente_Firmata.md), ci sono diversi ruoli coinvolti nella creazione delle PSBT + +### Assumere il Ruolo del Creatore + +Il ruolo del creatore è incaricato di creare una PSBT con almeno un input. + +Una PSBT è creata con un semplice utilizzo di `wally_psbt_init_alloc`, dicendo quante input e output aggiungerai alla fine: +: +``` + struct wally_psbt *psbt; + lw_response = wally_psbt_init_alloc(0,1,1,0,&psbt); +``` + +Ma ciò che hai non è ancora una PSBT legale, a causa della mancanza di input. Puoi crearli creando una transazione e impostandola come transazione globale nella PSBT, che aggiorna tutti gli input e output: + +``` + struct wally_tx *gtx; + lw_response = wally_tx_init_alloc(0,0,1,1,>x); + lw_response = wally_psbt_set_global_tx(psbt,gtx); +``` +### Testare la Creazione della Tua PSBT + +A questo punto, dovresti avere una PSBT vuota, ma funzionante, che puoi vedere compilando ed eseguendo [il programma](src/17_4_createemptypsbt.c). + +``` +$ cc createemptypsbt.c -lwallycore -o createemptypsbt +$ ./createemptypsbt +cHNidP8BAAoAAAAAAAAAAAAAAA== +``` +Puoi persino utilizzare `bitcoin-cli` per testare il risultato: +``` +$ psbt=$(./createpsbt) +$ bitcoin-cli decodepsbt $psbt +{ + "tx": { + "txid": "f702453dd03b0f055e5437d76128141803984fb10acb85fc3b2184fae2f3fa78", + "hash": "f702453dd03b0f055e5437d76128141803984fb10acb85fc3b2184fae2f3fa78", + "version": 0, + "size": 10, + "vsize": 10, + "weight": 40, + "locktime": 0, + "vin": [ + ], + "vout": [ + ] + }, + "unknown": { + }, + "inputs": [ + ], + "outputs": [ + ], + "fee": 0.00000000 +} +``` +## Assumere gli Altri Ruoli + +Come con la lettura delle PSBT, stiamo introducendo il concetto di creazione delle PSBT, e poi lasciando il resto come esercizio per il lettore. + +Quanto segue è un elenco approssimativo di funzioni per ogni ruolo; saranno necessarie ulteriori funzioni per creare alcuni degli elementi che vengono aggiunti alle PSBT. + +**Creatore:** + +* wally_psbt_init_alloc +* wally_psbt_set_global_tx + +**Aggiornante:** + +* wally_psbt_input_set_non_witness_utxo +* wally_psbt_input_set_witness_utxo +* wally_psbt_input_set_redeem_script +* wally_psbt_input_set_witness_script +* wally_psbt_input_set_keypaths +* wally_psbt_input_set_unknowns +* wally_psbt_output_set_redeem_script +* wally_psbt_output_set_witness_script +* wally_psbt_output_set_keypaths +* wally_psbt_output_set_unknowns + +**Firmante:** + +* wally_psbt_input_set_partial_sigs +* wally_psbt_input_set_sighash_type +* wally_psbt_sign + +**Combinatore:** + +* wally_psbt_combine + +**Finalizzatore:** +* wally_psbt_finalize +* wally_psbt_input_set_final_script_sig +* wally_psbt_input_set_final_witness + +**Estrattore:** + +* wally_psbt_extract + +## Riepilogo: Utilizzo di PSBT in Libwally + +Questa sezione potrebbe essere un intero capitolo, poiché lavorare con le PSBT a un livello basso è un lavoro molto intenso che richiede una manipolazione degli input e degli output molto più intensiva rispetto a quanto avvenuto nel [Capitolo 7](07_0_Ampliare_le_Transazioni_Bitcoin_con_PSBTs.md). Invece, questa sezione mostra le basi: come estrarre informazioni da una PSBT e come iniziare a crearne una. + +> :fire: ***Qual è il potere delle PSBT in Libwally?*** Ovviamente, puoi già fare tutto questo in `bitcoin-cli`, ed è più semplice perché Bitcoin Core gestisce molte delle operazioni di routine. Il vantaggio di usare Libwally è che può essere eseguito offline, quindi potrebbe essere Libwally a trovarsi dall'altra parte di un dispositivo hardware con cui il tuo `bitcoin-cli` sta comunicando tramite HWI. Questo è, infatti, uno dei principali punti delle PSBT: poter manipolare transazioni parzialmente firmate senza bisogno di un nodo completo. Libwally lo rende possibile. + +## Cosa c'è dopo? + +Scopri di più su "Programming Bitcoin with Libwally" nel [Capitolo 17.5: Usare Scripts in Libwally](17_5_Usare_Scripts_in_Libwally.md). + diff --git a/it/17_5_Usare_Scripts_in_Libwally.md b/it/17_5_Usare_Scripts_in_Libwally.md new file mode 100644 index 000000000..372341533 --- /dev/null +++ b/it/17_5_Usare_Scripts_in_Libwally.md @@ -0,0 +1,193 @@ +# 17.5: Utilizzare gli Script in Libwally + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza preliminare che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Molto tempo fa, nella Parte 3, mentre introducevamo gli Script, abbiamo detto che era probabile che tu creassi effettivamente transazioni utilizzando script con un'API, e l'avevamo segnato come un argomento per il futuro. Ebbene, il futuro è arrivato. + +## Crea lo Script + +Creare lo script è la _cosa più facile_ da fare in Libwally. Prendi il seguente esempio, un semplice [Puzzle Script](/13_1_Writing_Puzzle_Scripts.md) al quale siamo tornati di tanto in tanto: + +``` +OP_ADD 99 OP_EQUAL +``` +Utilizzando `btcc`, possiamo serializzarlo. +``` +$ btcc OP_ADD 99 OP_EQUAL +warning: ambiguous input 99 is interpreted as a numeric value; use 0x99 to force into hexadecimal interpretation +93016387 +``` +In precedenza avevamo costruito lo script standard P2SH a mano, ma Libwally può effettivamente farlo per te. + +Innanzitutto, Libwally deve convertire l'hex in byte, poiché i byte sono la maggior parte di quello con cui lavora: +``` + int script_length = strlen(script)/2; + unsigned char bscript[script_length]; + + lw_response = wally_hex_to_bytes(script,bscript,script_length,&written); +``` +Poi, esegui `wally_scriptpubkey_p2sh_from_bytes` con i tuoi byte, dicendo a Libwally di fare anche `HASH160` per te: +``` + unsigned char p2sh[WALLY_SCRIPTPUBKEY_P2SH_LEN]; + + lw_response = wally_scriptpubkey_p2sh_from_bytes(bscript,sizeof(bscript),WALLY_SCRIPT_HASH160,p2sh,WALLY_SCRIPTPUBKEY_P2SH_LEN,&written); +``` +Se guardi i risultati di `p2sh`, vedrai che era: +``` +a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87 +``` + +[Potresti ricordare](10_2_Construire_la_Struttura_di_P2SH.md) che si divide cosi: + +``` +a9 / 14 / 3f58b4f7b14847a9083694b9b3b52a4cea2569ed / 87 +``` +Questo è il nostro vecchio amico `OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL`. + +Fondamentalmente, Libwally ha preso il tuo script di rimborso serializzato, l'ha hashato per te con SHA-256 e RIPEMD-160, e poi ha applicato il framing standard per trasformarlo in un vero P2SH; Hai fatto un lavoro simile nel [Capitolo 10.2](10_2_Construire_la_Struttura_di_P2SH.md), ma con un eccesso di comandi shell. + +Infatti, puoi ricontrollare il tuo lavoro utilizzando gli stessi comandi di §10.2: + +``` +$ redeemScript="93016387" +$ echo -n $redeemScript | xxd -r -p | openssl dgst -sha256 -binary | openssl dgst -rmd160 +(stdin)= 3f58b4f7b14847a9083694b9b3b52a4cea2569ed +``` + + +## Crea una Transazione + +Per utilizzare quel `pubScriptKey` che hai appena creato, devi creare una transazione e incorporare il `pubScriptKey` al suo interno (e questo è il grande cambiamento rispetto a `bitcoin-cli`: puoi effettivamente creare manualmente una transazione con uno script P2SH). + +Il processo di creazione di una transazione in Libwally è molto intenso, proprio come il processo per creare un PSBT, quindi lo delineeremo solo, prendendo una scorciatoia principale, e poi lasceremo un metodo senza scorciatoie per ulteriori indagini. + +Creare una transazione stessa è abbastanza semplice: devi solo dire a `wally_tx_init_alloc` il tuo numero di versione, il tuo locktime e il numero di input e output: + +``` + struct wally_tx *tx; + lw_response = wally_tx_init_alloc(2,0,1,1,&tx); +``` + + +Compilare quegli input e output è dove le cose diventano complicate! + +### Crea un Output della Transazione + +Per creare un output, dici a `wally_tx_output_init_alloc` quanti satoshi stai spendendo e gli fornisci lo script di blocco: +``` + struct wally_tx_output *tx_output; + lw_response = wally_tx_output_init_alloc(95000,p2sh,sizeof(p2sh),&tx_output); +``` +Quella parte in realtà non è stata affatto difficile, e ti ha permesso finalmente di incorporare un P2SH in un `vout`. + +Un comando in più lo aggiunge alla tua transazione: + +``` + lw_response = wally_tx_add_output(tx,tx_output); +``` + + +### Crea un Input della Transazione + +Creare l'input è molto più difficile perché devi accumulare informazioni nelle routine di creazione, non tutte delle quali sono intuitivamente accessibili quando usi Libwally. Quindi, piuttosto che entrare così a fondo nei dettagli, ecco dove prendiamo la nostra scorciatoia. Scriviamo il nostro codice in modo che venga passato il codice hex di una transazione già creata, e poi riutilizziamo semplicemente l'input. + +La conversione dal codice hex è fatta con `wally_tx_from_hex`: + +``` + struct wally_tx *utxo; + lw_response = wally_tx_from_hex(utxo_hex,0,&utxo); +``` +Poi puoi saccheggiare gli input dal tuo codice hex per creare un input con Libwally: +``` + struct wally_tx_input *tx_input; + lw_response = wally_tx_input_init_alloc(utxo->inputs[0].txhash,sizeof(utxo->inputs[0].txhash),utxo->inputs[0].index,0,utxo->inputs[0].script,utxo->inputs[0].script_len,utxo->inputs[0].witness,&tx_input); + assert(lw_response == WALLY_OK); +``` +Come ti aspetti, poi aggiungi quell'input alla tua transazione: +``` + lw_response = wally_tx_add_input(tx,tx_input); +``` + + +> **NOTA** Ovviamente, vorrai essere in grado di creare i tuoi input se stai usando Libwally per applicazioni reali, ma questo è inteso come un primo passo. E, può essere effettivamente utile per integrarsi con `bitcoin-cli`, come vedremo Nel prossimo [Capitolo 17.7](17_7_Integrare_Libwally_e_Bitcoin-CLI.md). + +### Stampa una Transazione + +Teoricamente potresti firmare e inviare questa transazione dal tuo programma C costruito su Libwally, ma in linea con l'idea che stiamo solo utilizzando un semplice programma C per sostituire un P2SH, stamperemo il nuovo hex. Questo è fatto con l'aiuto di `wally_tx_to_hex`: + +``` + char *tx_hex; + lw_response = wally_tx_to_hex(tx,0, &tx_hex); + + printf("%s\n",tx_hex); +``` +Mostreremo come utilizzarlo in §16.7. + +## Testa il Tuo Script di Sostituzione + +Puoi prendere il codice di test dalla [directory src](src/17_5_replacewithscript.c) e compilarlo: + +``` +$ cc replacewithscript.c -lwallycore -o replacewithscript +``` +Successivamente, prepara una transazione hex e uno script hex serializzato: +``` +hex=020000000001019527cebb072524a7961b1ba1e58fc18dd7c6fc58cd6c1c45d7e1d8fc690b006e0000000017160014cc6e8522f0287b87b7d0a83629049c2f2b0e972dfeffffff026f8460000000000017a914ba421212a629a840492acb2324b497ab95da7d1e87306f0100000000001976a914a2a68c5f9b8e25fdd1213c38d952ab2be2e271be88ac02463043021f757054fa61cfb75b64b17230b041b6d73f25ff9c018457cf95c9490d173fb4022075970f786f24502290e8a5ed0f0a85a9a6776d3730287935fb23aa817791c01701210293fef93f52e6ce8be581db62229baf116714fcb24419042ffccc762acc958294e6921b00 + +script=93016387 +``` +Poi puoi eseguire il programma di sostituzione: +``` +$ ./replacewithscript $hex $script +02000000019527cebb072524a7961b1ba1e58fc18dd7c6fc58cd6c1c45d7e1d8fc690b006e0000000017160014cc6e8522f0287b87b7d0a83629049c2f2b0e972d0000000001187301000000000017a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed8700000000 +``` +Puoi poi vedere i risultati con `bitcoin-cli`: +``` +$ bitcoin-cli decoderawtransaction $newhex +{ + "txid": "f4e7dbab45e759a7ac6e2fb0f10720cd29d047efad89fe1b569f5f4ba61fd8e6", + "hash": "f4e7dbab45e759a7ac6e2fb0f10720cd29d047efad89fe1b569f5f4ba61fd8e6", + "version": 2, + "size": 106, + "vsize": 106, + "weight": 424, + "locktime": 0, + "vin": [ + { + "txid": "6e000b69fcd8e1d7451c6ccd58fcc6d78dc18fe5a11b1b96a7242507bbce2795", + "vout": 0, + "scriptSig": { + "asm": "0014cc6e8522f0287b87b7d0a83629049c2f2b0e972d", + "hex": "160014cc6e8522f0287b87b7d0a83629049c2f2b0e972d" + }, + "sequence": 0 + } + ], + "vout": [ + { + "value": 0.00095000, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL", + "hex": "a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2My2ApqGcoNXYceZC4d7fipBu4GodkbefHD" + ] + } + } + ] +} +``` +Il `vin` dovrebbe semplicemente corrispondere all'input che hai sostituito, ma è il `vout` che è entusiasmante: hai creato una transazione con uno `scripthash`! + +## Sommario: Utilizzare gli Script in Libwally + +Creare transazioni in Libwally è un altro argomento che potrebbe occupare un intero capitolo, ma la cosa fantastica è che una volta fatto questo salto, puoi introdurre uno `scriptPubKey` P2SH, e quella parte da sola è abbastanza semplice. Anche se la metodologia dettagliata in questo capitolo richiede di avere già in mano un hex di transazione (probabilmente creato con `bitcoin-cli`) se esplori ulteriormente Libwally, puoi fare tutto da solo. + +> :fire: ***Qual è il Potere degli Script in Libwally?*** Semplicemente, puoi fare qualcosa che non potevi fare prima: creare una transazione bloccata con un arbitrario P2SH. + +## Cosa c'è dopo? + +Scopri di più su "Programmazione Bitcoin con Libwally" nel [Capitolo 17.6: Usare Altre Funzioni in Libwally](17_6_Usare_Altre_Funzioni_in_Libwally.md). diff --git a/it/17_6_Usare_Altre_Funzioni_in_Libwally.md b/it/17_6_Usare_Altre_Funzioni_in_Libwally.md new file mode 100644 index 000000000..6f31a7542 --- /dev/null +++ b/it/17_6_Usare_Altre_Funzioni_in_Libwally.md @@ -0,0 +1,125 @@ +# 17.6: Usare Altre Funzioni in Libwally + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza preliminare che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Libwally è una libreria estesa che offre una notevole quantità di funzionalità relative ai wallet, molte delle quali non sono disponibili tramite `bitcoin-cli`. Di seguito è fornita una panoramica di alcune funzionalità non trattate precedentemente in questo capitolo. + +## Utilizzare Funzioni Criptografiche + +Un certo numero di funzioni crittografiche possono essere accessibili direttamente da Libwally: + + * `wally_aes` — Utilizzare la crittografia o decrittografia AES + * `wally_aes_cbc` — Utilizzare la crittografia o decrittografia AES in modalità CBC + * `wally_hash160` — Utilizzare l'hash RIPEMD-160(SHA-256) + * `wally_scrypt` — Utilizzare la derivazione della chiave Scrypt + * `wally_sha256` — Utilizzare l'hash SHA256 + * `wally_sha256_midstate` — Utilizzare SHA256 per fare hash solo del primo blocco di dati + * `wally_sha256d` — Effettuare un doppio hash SHA256 + * `wally_sha512` — Utilizzare l'hash SHA512 + +Ci sono anche funzioni HMAC per gli hash SHA, utilizzate per generare codici di autenticazione dei messaggi basati sugli hash. Sono usate in [BIP32](https://en.bitcoin.it/wiki/BIP_0032), tra le altre cose. + + * `wally_hmac_sha256` + * `wally_hmac_sha512` + +Funzioni aggiuntive coprono la derivazione della chiave PBKDF2 e la matematica delle curve ellittiche. + +## Utilizzare Funzioni per gli Indirizzi + +Libwally contiene un certo numero di funzioni che possono essere utilizzate per importare, esportare e tradurre gli indirizzi Bitcoin. + +Alcune convertono tra indirizzi e bytes `scriptPubKey`: + + * `wally_addr_segwit_from_bytes` — Convertire un programma witness (in bytes) in un indirizzo Segwit + * `wally_addr_segwit_to_bytes` — Convertire un indirizzo Segwit in un `scriptPubKey` (in bytes) + * `wally_address_to_scriptpubkey` — Convertire un indirizzo legacy in un `scriptPubKey` (in bytes) + * `wally_scriptpubkey_to_address` — Convertire un `scriptPubKey` (in bytes) in un indirizzo legacy + +Alcuni riguardano il formato di importazione del wallet (WIF): + + * `wally_wif_from_bytes` — Convertire una chiave privata (in bytes) in un WIF + * `wally_wif_is_uncompressed` — Determina se un WIF è non compresso + * `wally_wif_to_address` — Derivare un indirizzo P2PKH da un WIF + * `wally_wif_to_bytes` — Convertire un WIF in una chiave privata (in bytes) + * `wally_wif_to_public_key` — Derivare una chiave pubblica (in bytes) da un WIF + +## Utilizzare Funzioni BIP32 + +Ci sono ulteriori funzioni HD-wallet BIP32, oltre a quelle trattate nel [Capitolo 17.3: Usare BIP32 in Libwally](17_3_Usare_BIP32_in_Libwally.md). + + * `bip32_key_get_fingerprint` — Generare un'impronta BIP32 per una chiave estesa + * `bip32_key_serialize` — Trasformare una chiave estesa in bytes serializzati + * `bip32_key_strip_private_key` — Convertire una chiave privata estesa in una chiave pubblica estesa + * `bip32_key_unserialize` — Trasformare bytes serializzati in una chiave estesa + +Ci sono anche numerose altre a seconda che tu voglia allocare memoria o far fare a Libwally l'_alloc_ per te. + +## Utilizzare Funzioni BIP38 + +[BIP38](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki) consente la creazione di chiavi private protette da password. Non lo insegniamo perché consideriamo pericoloso inserire questo tipo di fattore umano nella gestione delle chiavi. Vedi [#SmartCustody](https://www.smartcustody.com/index.html). + +Le principali funzioni sono: + + * `bip38_from_private_key` — Codificare una chiave privata utilizzando BIP38 + * `bip38_to_private_key` — Decodificare una chiave privata utilizzando BIP38 + +## Utilizzare Funzioni BIP39 + +Alcune funzioni mnemoniche BIP39 sono state appena accennate nel [Capitolo 17.2: Usare BIP39 in Libwally](17_2_Usare_BIP39_in_Libwally.md): + + * `bip39_get_languages` — Vedere un elenco delle lingue supportate + * `bit39_get_word` — Recuperare una parola specifica dall'elenco delle parole di una lingua + * `bip39_get_wordlist` — Vedere un elenco di parole per una lingua + +## Utilizzare Funzioni PSBT + +L'elenco della maggior parte delle funzioni PSBT può essere trovato nel [Capitolo 17.4: Usare PSBTs in Libwally](17_4_Using_PSBTs_in_Libwally.md). + +## Utilizzare Funzioni per gli Script + +[Capitolo 17.5: Usare Scripts in Libwally](17_5_Usare_Scripts_in_Libwally.md) ha appena accennato alle funzioni degli Script di Libwally. + +C'è un'altra funzione che ti permette di determinare il tipo di script trovato in una transazione: + + * `wally_scriptpubkey_get_type` — Determinare il tipo di script di una transazione. + +Poi ci sono una serie di funzioni che creano `scriptPubKey` da bytes, `scriptSig` da firme e Witnesses da bytes o firme. + + * `wally_script_push_from_bytes` + * `wally_scriptpubkey_csv_2of2_then_1_from_bytes` + * `wally_scriptpubkey_csv_2of3_then_2_from_bytes` + * `wally_scriptpubkey_multisig_from_bytes` + * `wally_scriptpubkey_op_return_from_bytes` + * `wally_scriptpubkey_p2pkh_from_bytes` + * `wally_scriptpubkey_p2sh_from_bytes` + * `wally_scriptsig_multisig_from_bytes` + * `wally_scriptsig_p2pkh_from_der` + * `wally_scriptsig_p2pkh_from_sig` + * `wally_witness_multisig_from_bytes` + * `wally_witness_p2wpkh_from_der` + * `wally_witness_p2wpkh_from_sig` + * `wally_witness_program_from_bytes` + +## Utilizzare Funzioni per le Transazioni + +Abbiamo appena accennato alle funzioni che possono essere utilizzate per creare e convertire transazioni nel [Capitolo 17.5: Usare Scripts in Libwally](17_5_Usare_Scripts_in_Libwally.md). + +Ci sono numerose funzioni informative, alcune delle più interessanti sono: + + * `wally_tx_get_length` + * `wally_tx_get_total_output_satoshi` + * `wally_tx_get_weight` + +Ci sono anche funzioni che influenzano un `wally_tx`, un `wally_tx_input`, un `wally_tx_output`, o uno `stack di testimoni` e che creano firme. + +## Utilizzare Funzioni Elements + +Libwally può essere compilato per essere utilizzato con Elements di Blockstream, che include l'accesso alle sue funzioni per gli asset. + +## Riepilogo: Utilizzare Altre Funzioni in Libwally + +C'è molto di più che puoi fare con Libwally, più di quanto possa essere trattato in questo capitolo o persino elencato in questa sezione. In particolare, puoi eseguire funzioni crittografiche, codificare chiavi private, costruire transazioni complete e utilizzare Elements. La [documentazione di Libwally](https://wally.readthedocs.io/en/latest/) è il posto giusto per ulteriori informazioni, anche se al momento della scrittura sono sia limitate che obsolete. I file di intestazione di Libwally sono una riserva se la documentazione è incompleta o errata. + +## Cosa c'è dopo? + +Continua a imparare su "Programmazione Bitcoin con Libwally" nel [Capitolo 17.7: Integrare Libwally e Bitcoin-CLI](17_7_Integrare_Libwally_e_Bitcoin-CLI.md) diff --git a/it/17_7_Integrare_Libwally_e_Bitcoin-CLI.md b/it/17_7_Integrare_Libwally_e_Bitcoin-CLI.md new file mode 100644 index 000000000..98f189d7a --- /dev/null +++ b/it/17_7_Integrare_Libwally_e_Bitcoin-CLI.md @@ -0,0 +1,340 @@ +# 17.7: Integrazione di Libwally e Bitcoin-CLI + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza preliminare che potrebbe essere ancora in fase di revisione. Avvertenza per il lettore. + +Libwally è limitato. Si occupa della manipolazione di semi, chiavi, indirizzi e altri elementi dei portafogli, con alcune funzioni aggiuntive relative alle transazioni e ai PSBT che potrebbero essere utili per servizi non collegati ai nodi completi su Internet. Tuttavia, alla fine avrai bisogno di servizi di nodi completi per sfruttare appieno Libwally. + +Questa sezione finale offrirà alcuni esempi di utilizzo dei programmi Libwally per completare un ambiente `bitcoin-cli`. Anche se questi esempi implicano che questi servizi siano tutti sulla stessa macchina, potrebbero diventare ancora più potenti se il servizio `bitcoin-cli` è direttamente connesso a Internet e il servizio Libwally no. + +## Condividere una Transazione + +[Capitolo 17.5: Usare Scripts in Libwally](17_5_Usare_Scripts_in_Libwally.md) ha dettagliato come Libwally potrebbe essere utilizzato per riscrivere una transazione esistente, per fare qualcosa che `bitcoin-cli` non può: produrre una transazione che contiene uno P2SH unico. Ovviamente, questo è un elemento fondamentale; se decidi di approfondire Libwally, creerai transazioni complete da solo. Ma, anche questa metodologia abbreviata ha il suo utilizzo: mostra come le transazioni possono essere passate avanti e indietro tra `bitcoin-cli` e Libwally, dimostrando un primo esempio di utilizzo complementare. + +Per dimostrare completamente questa metodologia, creerai una transazione con `bitcoin-cli`, utilizzando questo UTXO: + +``` + { + "txid": "c0a110a7a84399b98052c6545018873b13ee3128fa74f7a697779174a36ea33a", + "vout": 1, + "address": "mvLyH7Rs45c16FG2dfV7uuTKV6pL92kWxo", + "label": "", + "scriptPubKey": "76a914a2a68c5f9b8e25fdd1213c38d952ab2be2e271be88ac", + "amount": 0.00094000, + "confirmations": 17375, + "spendable": true, + "solvable": true, + "desc": "pkh([ce0c7e14/0'/0'/5']0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65)#qldtsl65", + "safe": true + } +``` +Ormai sai come impostare una transazione con `bitcoin-cli`: +``` +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ recipient=tb1qycsmq3jas5wkhf8xrfn8k7438cm5pc8h9ae2k0 +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.0009 }''') +``` +Anche se hai inserito un destinatario e un importo nell'output, non è rilevante, perché riscriverai quei dati. Un codice più sofisticato potrebbe leggere le informazioni `vout` esistenti prima della riscrittura, ma noi manteniamo tutto molto vicino al nostro [codice originale](src/17_5_replacewithscript.c). + +Ecco la sola modifica necessaria, per permetterti di specificare il satoshi `vout`, senza doverlo codificare a mano, come nel caso originale: + +``` +... + int satoshis = atoi(argv[3]); +... + lw_response = wally_tx_output_init_alloc(satoshis,p2sh,sizeof(p2sh),&tx_output); +... +``` +Poi esegui le operazioni come prima: +``` +$ newtxhex=$(./replacewithscript $rawtxhex $script 9000) +``` +Ecco come appariva la transazione originale: +``` +$ bitcoin-cli decoderawtransaction $rawtxhex +{ + "txid": "438d50edd7abeaf656c5abe856a00a20af5ff08939df8fdb9f8bfbfb96234fcb", + "hash": "438d50edd7abeaf656c5abe856a00a20af5ff08939df8fdb9f8bfbfb96234fcb", + "version": 2, + "size": 82, + "vsize": 82, + "weight": 328, + "locktime": 0, + "vin": [ + { + "txid": "c0a110a7a84399b98052c6545018873b13ee3128fa74f7a697779174a36ea33a", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "0 2621b0465d851d6ba4e61a667b7ab13e3740e0f7", + "hex": "00142621b0465d851d6ba4e61a667b7ab13e3740e0f7", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qycsmq3jas5wkhf8xrfn8k7438cm5pc8h9ae2k0" + ] + } + } + ] +} +``` +Ecco la transazione riscritta da Libwally per utilizzare uno P2SH: +``` +standup@btctest:~/c$ bitcoin-cli decoderawtransaction $newtxhex +{ + "txid": "badb57622ab5fe029fc1a71ace9f7b76c695f933bceb0d38a155c2e5c984f4e9", + "hash": "badb57622ab5fe029fc1a71ace9f7b76c695f933bceb0d38a155c2e5c984f4e9", + "version": 2, + "size": 83, + "vsize": 83, + "weight": 332, + "locktime": 0, + "vin": [ + { + "txid": "c0a110a7a84399b98052c6545018873b13ee3128fa74f7a697779174a36ea33a", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 0 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL", + "hex": "a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2My2ApqGcoNXYceZC4d7fipBu4GodkbefHD" + ] + } + } + ] +} +``` +Successivamente puoi firmarla come al solito con `bitcoin-cli`: +``` +$ signedtx=$(bitcoin-cli signrawtransactionwithwallet $newtxhex | jq -r '.hex') +``` +E come puoi vedere, il risultato è una transazione legittima pronta per essere inviata alla rete Bitcoin: +``` +$ bitcoin-cli decoderawtransaction $signedtx +{ + "txid": "3061ca8c01d029c0086adbf8b7d4280280c8aee151500bab7c4f783bbc8e75e6", + "hash": "3061ca8c01d029c0086adbf8b7d4280280c8aee151500bab7c4f783bbc8e75e6", + "version": 2, + "size": 189, + "vsize": 189, + "weight": 756, + "locktime": 0, + "vin": [ + { + "txid": "c0a110a7a84399b98052c6545018873b13ee3128fa74f7a697779174a36ea33a", + "vout": 1, + "scriptSig": { + "asm": "3044022026c81b6ff4a15135d10c7f4b1ae6e44ac4fdb25c4a3c03161b17b8ab8d04850502200b448d070f418de1ca07e76943d23d447bc95c7c5e0322bcc153cadb5d9befe0[ALL] 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65", + "hex": "473044022026c81b6ff4a15135d10c7f4b1ae6e44ac4fdb25c4a3c03161b17b8ab8d04850502200b448d070f418de1ca07e76943d23d447bc95c7c5e0322bcc153cadb5d9befe001210368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65" + }, + "sequence": 0 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 3f58b4f7b14847a9083694b9b3b52a4cea2569ed OP_EQUAL", + "hex": "a9143f58b4f7b14847a9083694b9b3b52a4cea2569ed87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "2My2ApqGcoNXYceZC4d7fipBu4GodkbefHD" + ] + } + } + ] +} +``` +Voila! Questa è la potenza de Libwally con `bitcoin-cli`. + +Ovviamente, puoi anche passare un PSBT utilizzando le funzioni descritte nel [Capitolo17.4](17_4_Usare_PSBTs_in_Libwally.md) e questa è una metodologia più aggiornata per l'uso moderno di Bitcoin, ma in entrambi gli esempi, il concetto di passare le transazioni tra `bitcoin-cli` e il codice di Libwally e viceversa dovrebbe essere simile. + +## Import & Export BIP39 Seeds + +Purtroppo, non tutte le interazioni tra Libwally e `bitcoin-cli` sono così fluide. Ad esempio, sarebbe utile poter esportare un seme HD da `bitcoin-cli` per generare la frase mnemonica con Libwally, o generare un seme da una frase mnemonica utilizzando Libwally, e poi importarlo in `bitcoin-cli`. Sfortunatamente, nessuna di queste operazioni è possibile al momento. Una frase mnemonica viene tradotta in un seme utilizzando HMAC-SHA512, il che significa che il risultato è di 512 bit. Tuttavia, `bitcoin-cli` esporta semi HD (utilizzando `dumpwallet`) e importa semi HD (utilizzando `sethdseed`) con una lunghezza di 256 bit. Finché non verrà modificato, non ci sarà incontro tra i due. + +> :book: ***Qual è la differenza tra Entropia e un Seme?*** Libwally afferma di creare le sue frasi mnemoniche a partire dall'entropia. Questo è essenzialmente la stessa cosa di un seme: entrambi sono numeri grandi e casuali. Quindi, se `bitcoin-cli` fosse compatibile con i semi di frase mnemonica a 512 bit, potresti usare uno di essi per generare le frasi mnemoniche e ottenere i risultati che ti aspetti. + +> :book: ***Qual è la differenza tra Entropia e Entropia Grezza?*** Non tutta l'entropia è uguale. Quando inserisci l'entropia in un comando che crea un seme mnemonico, deve avere una lunghezza e un formato specifici. Trasformare l'entropia grezza in entropia richiede la regolazione dell'entropia grezza fino a ottenere la lunghezza e il formato giusti, e a quel punto puoi riutilizzare quell'entropia (non grezza) per ricreare sempre le stesse mnemoniche (il che è il motivo per cui l'entropia è effettivamente la stessa cosa di un seme a quel punto, ma l'entropia grezza no). + +## Importare Chiavi Private + +Fortunatamente, puoi fare quasi la stessa cosa importando una chiave privata generata in Libwally. Dai un'occhiata a [genhd-for-import.c](src/17_7_genhd_for_import.c), una versione semplificata del programma `genhd` del [Capitolo 17.3](17_3_Usare_BIP32_in_Libwally.md) che utilizza anche la libreria `jansson` nel [Capitolo 16.1](116_1_Accedere_a_Bitcoind_con_Librerie_RPC.md) per un'uscita regolarizzata. + +Il codice aggiornato contiene anche una modifica importante: richiede un'impronta (fingerprint) da Libwally in modo da poter creare correttamente un percorso di derivazione: + +``` + char account_fingerprint[BIP32_KEY_FINGERPRINT_LEN]; + lw_response = bip32_key_get_fingerprint(key_account,account_fingerprint,BIP32_KEY_FINGERPRINT_LEN); + + char *fp_hex; + lw_response = wally_hex_from_bytes(account_fingerprint,BIP32_KEY_FINGERPRINT_LEN,&fp_hex); +``` + + +> :warning: **ATTENZIONE:** Ricorda che l'impronta nel percorso di derivazione è arbitraria. Poiché Libwally ne fornisce una, la stiamo usando, ma se non ne avessi una, potresti aggiungere un codice esadecimale arbitrario di 4 byte come impronta al tuo percorso di derivazione. + +Assicurati di compilare il nuovo codice con la libreria `jansson`, dopo averla installata (se necessario) come indicato nel [Capitolo 16.1](116_1_Accedere_a_Bitcoind_con_Librerie_RPC.md). + +``` +$ cc genhd-for-import.c -lwallycore -lsodium -ljansson -o genhd-for-import +``` +Quando esegui il nuovo programma, otterrai un elenco ben formattato di tutto: +``` +$ ./genhd-for-import +{ + "mnemonic": "physical renew say quit enjoy eager topic remind riot concert refuse chair", + "account-xprv": "tprv8yxn8iFNgsLktEPkWKQpMqb7bcx5ViFQEbJMtqrGi8LEgvy8es6YeJvyJKrbYEPKMw8JbU3RFhNRQ4F2pataAtTNokS1JXBZVg62xfd5HCn", + "address": "tb1q9lhru6k0ymwrtr5w98w35n3lz22upml23h753n", + "derivation": "[d1280779/84h/1h/0h]" +} +``` +Hai la `mnemonic` da cui puoi recuperare, un `account-xprv` che puoi importare, una `derivation` da usare per l'importazione e un `address` di esempio, che puoi usare per testare l'importazione. + +Ora puoi ricorrere alle lezioni apprese nel [Capitolo 3.5](03_5_Comprendere_il_Descriptor.md) su come trasformare quel xprv in un descrittore e importarlo. + +Prima, devi determinare il checksum: + +``` +$ xprv=tprv8yxn8iFNgsLktEPkWKQpMqb7bcx5ViFQEbJMtqrGi8LEgvy8es6YeJvyJKrbYEPKMw8JbU3RFhNRQ4F2pataAtTNokS1JXBZVg62xfd5HCn +$ dp=[d1280779/84h/1h/0h] +$ bitcoin-cli getdescriptorinfo "wpkh($dp$xprv/0/*)" +{ + "descriptor": "wpkh([d1280779/84'/1'/0']tpubDWepH8HcqF2RmhRYPy5QmFFEAeU1f3SJotu9BMta8Q8dXRDuHFv8poYqUUtEiWftBjtKn1aNhi9Qg2P4NdzF66dShYvB92z78WJbYeHTLTz/0/*)#f8rmqc0z", + "checksum": "46c00dk5", + "isrange": true, + "issolvable": true, + "hasprivatekeys": true +} +``` + + +Ci sono tre cose da notare qui: + +1. Usiamo `wpkh` come funzione nel nostro percorso di derivazione. Questo perché vogliamo generare indirizzi Segwit moderni, non indirizzi legacy. Questo corrisponde al nostro utilizzo nella funzione `wally_bip32_key_to_addr_segwit` di Libwally. La cosa più importante, tuttavia, è avere le stesse aspettative con Libwally e `bitcoin-cli` (e il tuo descrittore) su che tipo di indirizzo stai generando, in modo che tutto corrisponda! +2. Utilizziamo il percorso `/0/*` perché volevamo gli indirizzi esterni per questo account. Se invece volessimo gli indirizzi di cambio, useremmo `/1/*`. +3. Non useremo la riga `descriptor` restituita, poiché è per un indirizzo `xpub`. Invece, applicheremo il `checksum` restituito al `xprv` che già possediamo. + +``` +$ cs=$(bitcoin-cli getdescriptorinfo "wpkh($dp$xprv/0/*)" | jq -r ' .checksum') +``` +Poi lo inserisci in `importmulti` per importare questa chiave in `bitcoin-cli`: +``` +$ bitcoin-cli importmulti '''[{ "desc": "wpkh('$dp''$xprv'/0/*)#'$cs'", "timestamp": "now", "range": 10, "watchonly": false, "label": "LibwallyImports", "keypool": false, "rescan": false }]''' +[ + { + "success": true + } +] + +``` +Qui hai importato/generato i primi dieci indirizzi per la chiave privata. + +Esaminando la nuova etichetta `LibwallyImported`, li mostra: + +``` +$ bitcoin-cli getaddressesbylabel "LibwallyImports" +{ + "tb1qzeqrrt77xhvazq5g8sc9th0lzjwstknan8gzq7": { + "purpose": "receive" + }, + "tb1q9lhru6k0ymwrtr5w98w35n3lz22upml23h753n": { + "purpose": "receive" + }, + "tb1q8fsgxt0z9r9hfl5mst5ylxka2yljjxlxlvaf8j": { + "purpose": "receive" + }, + "tb1qg6dayhdk4qc6guutxvdweh6pctc9dpguu6awqc": { + "purpose": "receive" + }, + "tb1qdphaj0exvemxhgfpyh4p99wn84e2533u7p96l6": { + "purpose": "receive" + }, + "tb1qwv9mdqkpx6trtmvgw3l95npq8gk9pgllucvata": { + "purpose": "receive" + }, + "tb1qwh92pkrv6sps62udnmez65vfxe9n5ceuya56xz": { + "purpose": "receive" + }, + "tb1q4e98ln8xlym64qjzy3k8zyfyt5q60dgcn39d90": { + "purpose": "receive" + }, + "tb1qhzje887fyl65j4mulqv9ysmntwn95zpgmgvtqd": { + "purpose": "receive" + }, + "tb1q62xf9ec8zcfkh2qy5qnq4qcxrx8l0jm27dd8ru": { + "purpose": "receive" + }, + "tb1qlw85usfk446ssxejm9dmxsfn40kzsqce77aq20": { + "purpose": "receive" + } +} + +``` +Il secondo sulla tua lista corrisponde effettivamente al tuo esempio (`tb1q9lhru6k0ymwrtr5w98w35n3lz22upml23h753n`). L'importazione di questa chiave privata e la derivazione di dieci indirizzi è stata effettuata con successo. + +Se guardi di nuovo il [Capitolo 7.3](07_3_Integrazione_con_Hardware_Wallets.md), vedrai che questo è lo stesso metodo che abbiamo usato per importare indirizzi da un Hardware Wallet (anche se in questo caso abbiamo importato anche la chiave privata come prova di concetto). La principale differenza è che in precedenza le informazioni erano create da una black box (letteralmente: era un dispositivo Ledger), e questa volta hai creato le informazioni tu stesso utilizzando Libwally, dimostrando come puoi fare questo tipo di lavoro su dispositivi airgapped o altri dispositivi più remoti, per poi portarli su `bitcoin-cli`. + +## Importare Indirizzi + +Ovviamente, se puoi importare chiavi private, puoi importare anche indirizzi — il che di solito significa importare indirizzi in sola visualizzazione _senza_ le chiavi private. + +Un modo per farlo è utilizzare la metodologia `importmulti` sopra, ma utilizzare l'indirizzo xpub fornito (`wpkh([d1280779/84'/1'/0']tpubDWepH8HcqF2RmhRYPy5QmFFEAeU1f3SJotu9BMta8Q8dXRDuHFv8poYqUUtEiWftBjtKn1aNhi9Qg2P4NdzF66dShYvB92z78WJbYeHTLTz/0/*)#f8rmqc0z`) piuttosto che l'xprv originale. Questo è il modo migliore per importare una sequenza intera di indirizzi in sola visualizzazione. + +In alternativa, puoi importare indirizzi individuali. Ad esempio, considera l'indirizzo di esempio restituito attualmente dal programma `genhd-for-import`: + +``` +$ ./genhd-for-import +{ + "mnemonic": "finish lady crucial walk illegal ride hamster strategy desert file twin nature", + "account-xprv": "tprv8xRujYeVN7CwBHxLoTHRdmzwdW7dKUzDfruSo56GqqfRW9QXtnxnaRG8ke7j65uNjxmCVfcagz5uuaMi2vVJ8jpiGZvLwahmNB8F3SHUSyv", + "address": "tb1qtvcchgyklp6cyleth85c7pfr4j72z2vyuwuj3d", + "derivation": "[6214ecff/84h/1h/0h]" +} +``` +Puoi importare quello come indirizzo in sola visualizzazione con `importaddress`: +``` +$ bitcoin-cli -named importaddress address=tb1qtvcchgyklp6cyleth85c7pfr4j72z2vyuwuj3d label=LibwallyWO rescan=false +$ bitcoin-cli getaddressesbylabel "LibwallyWO" +{ + "tb1qtvcchgyklp6cyleth85c7pfr4j72z2vyuwuj3d": { + "purpose": "receive" + } +} +} +``` + +## Riepilogo: Integrazione di Libwally e Bitcoin-CLI + +Con una conoscenza fondamentale di Libwally, puoi ora completare tutto il lavoro delle lezioni precedenti. Trasferire indirizzi, chiavi, transazioni e PSBT è solo alcuni dei modi in cui potresti utilizzare questi due potenti metodi di programmazione Bitcoin insieme. C'è anche molta più profondità se vuoi approfondire la vasta libreria di funzioni di Libwally. + +> :fire: ***Qual è il Potere dell'Integrazione tra Libwally e Bitcoin-CLI?*** Uno dei maggiori vantaggi di Libwally è che ha molte funzioni che possono essere utilizzate offline. In confronto, Bitcoin Core è un programma connesso alla rete. Questo può aiutarti ad aumentare la sicurezza passando chiavi, indirizzi, transazioni o PSBT a una fonte offline (che eseguirà programmi Libwally). Inoltre, Libwally può fare cose che Bitcoin Core attualmente non può, come generare un seme da una frase mnemonica BIP39 (e anche se attualmente non puoi importare il seme in Bitcoin Core, puoi ancora importare la chiave principale per l'account, come mostrato qui). + +## Cosa c'è dopo? + +Scopri altri tipi di programmazione nel [Capitolo 18: Parlare a Bitcoind in Altri Linguaggi](18_0_Parlare_a_Bitcoind_in_Altri_Linguaggi.md). diff --git a/it/18_0_Parlare_a_Bitcoind_in_Altri_Linguaggi.md b/it/18_0_Parlare_a_Bitcoind_in_Altri_Linguaggi.md new file mode 100644 index 000000000..bb1c713f7 --- /dev/null +++ b/it/18_0_Parlare_a_Bitcoind_in_Altri_Linguaggi.md @@ -0,0 +1,27 @@ +# Capitolo 18: Parlare con Bitcoind con Altri Linguaggi + +Ora dovresti avere una solida base per lavorare con Bitcoin in C, non solo utilizzando le librerie RPC, JSON e ZMQ per interagire direttamente con `bitcoind`, ma anche sfruttando le librerie Libwally per complementare quel lavoro. E C è un ottimo linguaggio per prototipare e astrarre — ma probabilmente non è il linguaggio in cui programmi. Questo capitolo quindi offre un rapido tour di sei altri linguaggi di programmazione, dimostrando le funzionalità base di Bitcoin in ciascuno e permettendoti di espandere le lezioni della riga di comando e di C al linguaggio di programmazione di tua scelta. + +Ogni sezione contiene informazioni approssimativamente uguali, focalizzate su: creare una connessione RPC; esaminare il portafoglio; creare un nuovo indirizzo e creare una transazione. Tuttavia, c'è una certa varietà tra i linguaggi, mostrando diversi aspetti dei comandi RPC di Bitcoin in esempi differenti. In particolare, alcuni linguaggi usano la metodologia semplice di `sendtoaddress` mentre altri usano la metodologia complessa di creare una transazione raw da zero. + +## Obiettivi di Questo Capitolo + +Dopo aver lavorato attraverso questo capitolo, uno sviluppatore sarà in grado di: + + * Preparare Ambienti di Sviluppo Bitcoin per una Varietà di Linguaggi + * Utilizzare Funzioni del Portafoglio in una Varietà di Linguaggi + * Utilizzare Funzioni delle Transazioni in una Varietà di Linguaggi + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere Maggiori Aspetti di Bitcoin RPC attraverso Interazioni con una Varietà di Linguaggi + +## Indice + + * [Capitolo 18.1 Accedere a Bitcoind con Go](18_1_Accedere_a_Bitcoind_con_Go.md) + * [Capitolo 18.2 Accedere a Bitcoind con Java](18_2_Accedere_a_Bitcoind_con_Java.md) + * [Capitolo 18.3 Accedere a Bitcoind con NodeJS](18_3_Accedere_a_Bitcoind_con_NodeJS.md) + * [Capitolo 18.4 Accedere a Bitcoind con Python](18_4_Accedere_a_Bitcoind_con_Python.md) + * [Capitolo 18.5 Accedere a Bitcoind con Rust](18_5_Accedere_a_Bitcoind_con_Rust.md) + * [Capitolo 18.6 Accedere a Bitcoind con Swift](18_6_Accedere_a_Bitcoind_con_Swift.md) + diff --git a/it/18_1_Accedere_a_Bitcoind_con_Go.md b/it/18_1_Accedere_a_Bitcoind_con_Go.md new file mode 100644 index 000000000..768e7e243 --- /dev/null +++ b/it/18_1_Accedere_a_Bitcoind_con_Go.md @@ -0,0 +1,458 @@ +# 18.1: Accedere a Bitcoind con Go + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza preliminare che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Questa sezione spiega come interagire con `bitcoind` utilizzando il linguaggio di programmazione Go e il [btcd rpcclient](https://github.com/btcsuite/btcd/tree/master/rpcclient). Si noti che presenta alcune peculiarità e limitazioni. + +## Configura Go + +Per preparare l'uso di Go sulla tua macchina UNIX, prima installa `curl` se non lo hai già fatto: + + + +``` +$ sudo apt install curl +``` + + +Poi, visita la [pagina di download di Go](https://golang.org/dl/), ottieni il link per l'ultima versione disponibile e scaricalo usando `curl`. Per una configurazione Debian, dovrai usare la versione `linux-amd64`: + + +``` +$ curl -O https://dl.google.com/go/go1.15.1.linux-amd64.tar.gz +``` + +Una volta terminato il download, confronta l'hash del file scaricato con l'hash sulla [pagina di download di Go](https://golang.org/dl/): + +``` +$ sha256sum go1.15.1.linux-amd64.tar.gz +70ac0dbf60a8ee9236f337ed0daa7a4c3b98f6186d4497826f68e97c0c0413f6 go1.15.1.linux-amd64.tar.gz +``` + +Gli hash dovrebbero corrispondere. Se sì, estrai il tarball e installa Go sul tuo sistema: + +``` +$ tar xfv go1.15.1.linux-amd64.tar.gz +$ sudo chown -R root:root ./go +$ sudo mv go /usr/local +``` + +Ora devi creare un percorso Go per specificare il tuo ambiente. Apri il file `~/.profile` con un editor a tua scelta e aggiungi quanto segue alla fine: + +``` +export GOPATH=$HOME/work +export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin +``` + +Poi, aggiorna il tuo profilo: + +``` +$ source ~/.profile +``` + +Infine, crea la directory per il tuo spazio di lavoro Go: + +``` +$ mkdir $HOME/work +``` + +### Configura `btcd` `rpcclient` + +Utilizzerai il `rpcclient` fornito con `btcd`, un'implementazione di Bitcoin scritta in Go. Anche se `rpcclient` è stato originariamente progettato per lavorare con il nodo completo `btcd` di Bitcoin, funziona anche con Bitcoin Core. Ha alcune peculiarità che esploreremo. + +Puoi usare ```go get``` per scaricarlo: + + +``` +$ go get github.com/btcsuite/btcd/rpcclient +``` + +Per testare che funzioni, naviga nella directory con gli esempi di Bitcoin Core: + +``` +$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/bitcoincorehttp +``` + +Modifica il file ```main.go``` e inserisci i dettagli associati alla tua configurazione di Bitcoin Core, che puoi trovare in `~/.bitcoin/bitcoin.conf`: + +``` + Host: "localhost:18332", + User: "StandUp", + Pass: "6305f1b2dbb3bc5a16cd0f4aac7e1eba", +``` + +> **MAINNET VS TESTNET:** La porta sarà 8332 per una configurazione mainnet. + +Ora puoi eseguire un test: + +``` +$ go run main.go +``` + +Dovresti vedere il conteggio dei blocchi stampato: + +``` +2020/09/01 11:41:24 Block count: 1830861 +``` + +### Crea un Progetto `rpcclient` + +Tipicamente creerai progetti nella tua directory `~/work/src/myproject/bitcoin`: + +``` +$ mkdir -p ~/work/src/myproject/bitcoin +$ cd ~/work/src/myproject/bitcoin +``` + +Ogni progetto dovrebbe avere i seguenti `import`: + +``` +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" +) +``` + +Questa dichiarazione di ```import``` ti consente di importare le librerie pertinenti. Per ogni esempio qui, dovrai importare ```"log", "fmt"``` e ```"github.com/btcsuite/btcd/rpcclient"```. Potrebbe essere necessario importare librerie aggiuntive per alcuni esempi. + * ```log``` è usato per stampare messaggi di errore. Dopo ogni chiamata al nodo Bitcoin, un'istruzione `if` controllerà se ci sono errori. Se ci sono errori, ```log``` verrà usato per stamparli. + * ```fmt``` è usato per stampare l'output. + * ```rpcclient``` è ovviamente la libreria `rpcclient`. + +## Costruisci la Tua Connessione + +Ogni funzione `bitcoind` in Go inizia con la creazione della connessione RPC, usando la funzione `ConnConfig`: + +``` + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "StandUp", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() +``` +TI parametri ```connCfg``` ti permettono di scegliere la porta RPC di Bitcoin, il nome utente, la password e se sei su testnet o mainnet. + +> **NOTA:** Ancora una volta, assicurati di sostituire `User` e `Pass` con quelli trovati nel tuo `~/.bitcoin/bitcoind.conf`. + +La funzione ```rpcclient.New(connCfg, nil)``` configura ```client``` per connettersi al tuo nodo Bitcoin. + +La linea ```defer client.Shutdown()``` serve per disconnettersi dal nodo Bitcoin una volta terminata l'esecuzione della funzione ```main()```. Dopo la linea ```defer client.Shutdown()``` è dove vanno le cose interessanti — e sarà piuttosto facile da usare. Questo perché `rpcclient` trasforma utilmente i comandi `bitcoin-cli` in funzioni usando PascalCase. Ad esempio, ```bitcoin-cli getblockcount``` sarà ```client.GetBlockCount``` in Go. + +### Effettua una Chiamata RPC + +Ora tutto ciò che è richiesto è fare una chiamata informativa come `GetBlockCount` o `GetBlockHash` usando il tuo `client`: + +``` + blockCount, err := client.GetBlockCount() + if err != nil { + log.Fatal(err) + } + blockHash, err := client.GetBlockHash(blockCount) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%d\n", blockCount) + fmt.Printf("%s\n", blockHash.String()) +``` + +### Effettua una Chiamata RPC con Argomenti + +Le funzioni `rpcclient` possono accettare anche input; per esempio ```client.GetBlockHash(blockCount)``` prende il conteggio dei blocchi come input. Il ```client.GetBlockHash(blockCount)``` di cui sopra apparirebbe così come comando ```bitcoin-cli```: + +``` +$ bitcoin-cli getblockhash 1830868 +00000000000002d53b6b9bba4d4e7dc44a79cebd1024d1bcfb9b3cc07d6cad9c +``` +Tuttavia, una particolarità con gli hash in `rpcclient` è che di solito vengono stampati in una codifica diversa se li stampi normalmente con ```blockHash```. Per stamparli come stringa, devi usare ```blockHash.String()```. + +### Esegui il Tuo Codice + +Puoi scaricare il codice completo dalla [directory src](src/18_1_blockinfo.go). + +Puoi poi eseguire: + +``` +$ go run blockinfo.go +1830868 +00000000000002d53b6b9bba4d4e7dc44a79cebd1024d1bcfb9b3cc07d6cad9c +``` + +Il numero dell'ultimo blocco insieme al suo hash dovrebbe essere stampato. + +## Cerca Fondi + +A causa delle limitazioni del `btcd` `rpcclient`, non puoi utilizzare la funzione ```getwalletinfo```. Tuttavia, puoi utilizzare il RPC `getbalance`: + + + +``` + wallet, err := client.GetBalance("*") + if err != nil { + log.Fatal(err) + } + + fmt.Println(wallet) +``` +```client.GetBalance("*")``` richiede l'input ```"*"```, a causa di una peculiarità di `btcd`. L'asterisco indica che vuoi ottenere il saldo di tutti i tuoi portafogli. + +Se esegui [il codice src](src/18_1_getbalance.go), dovresti ottenere un output simile a questo: + +``` +$ go run getbalance.go +0.000689 BTC +``` + +## Recupera Dati + +Dopo aver configurato il tuo client e recuperato informazioni generali, puoi usare `client.GetBlock` per accedere ai dati del blocco e `client.GetRawTransaction` per accedere ai dati delle transazioni. + +### Ottieni i Dati del Blocco + +Per ottenere i dati del blocco, dovrai usare: + + +## Crea un Indirizzo + +Puoi generare indirizzi in Go, ma non puoi specificare il tipo di indirizzo: + +Questo richiede l'uso di una funzione speciale `chaincfg`, per specificare per quale rete vengono creati gli indirizzi. Questa specifica è necessaria solo durante la generazione degli indirizzi, motivo per cui è utilizzata solo in questo esempio. Puoi includerla anche in altri esempi, ma non è necessario. + +Assicurati di importare `"github.com/btcsuite/btcd/chaincfg"`: + +``` +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/chaincfg" +) +``` +Quindi chiama `connCfG` con il parametro `chaincfg.TestNet3Params.Name`: + +``` + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + Params: chaincfg.TestNet3Params.Name, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() +``` +> **MAINNET VS TESTNET:** `Params: chaincfg.TestNet3Params.Name,` dovrebbe essere `Params: chaincfg.MainNetParams.Name,` su mainnet. + +Puoi quindi creare il tuo indirizzo: + +``` + address, err := client.GetNewAddress("") + if err != nil { + log.Fatal(err) + } + fmt.Println(address) +``` +Una peculiarità di `client.GetNewAddress("")` è che è necessario includere una stringa vuota affinché funzioni. + +Eseguendo [la fonte](17_1_getaddress.go) produce i seguenti risultati: + +``` +$ go run getaddress.go +tb1qutkcj34pw0aq7n9wgp3ktmz780szlycwddfmza +``` + +### Decodifica un Indirizzo + +Creare un indirizzo ha richiesto uno sforzo extra, nel specificare la catena appropriata. Utilizzare un indirizzo richiederà anche che tu lo decodifichi prima dell'uso. + +Significa che dovrai importare entrambe le librerie `"github.com/btcsuite/btcutil"` e `"github.com/btcsuite/btcd/chaincfg"`: + * `btcutil` permette di decodificare un indirizzo Bitcoin in un modo che `rpcclient` può comprendere. Questo è necessario quando si lavora con gli indirizzi in `rpcclient`. + * `chaincfg` è (di nuovo) utilizzato per configurare la tua catena come la catena Testnet. Questo è necessario per la decodifica degli indirizzi poiché gli indirizzi utilizzati su Mainnet e Testnet sono diversi. + + +``` +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcd/chaincfg" +) +``` + +La variabile `defaultNet` è ora utilizzata per specificare se il tuo nodo Bitcoin è su testnet o su mainnet. Queste informazioni (e l'oggetto `btcutil`) sono quindi utilizzate per decodificare l'indirizzo. + +> **MAINNET VS TESTNET:** `&chaincfg.TestNet3Params` dovrebbe essere `&chaincfg.MainNetParams` su mainnet. + +``` + defaultNet := &chaincfg.TestNet3Params + addr, err := btcutil.DecodeAddress("mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha", defaultNet) + if err != nil { + log.Fatal(err) + } +``` + + +> **NOTA:** Cambia l'indirizzo (`mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha`) con uno effettivamente del tuo portafoglio; puoi usare `bitcoin-cli listunspent` per trovare alcuni indirizzi con fondi per questo test. Se vuoi essere davvero sofisticato, modifica il codice Go per prendere un argomento, poi scrivi uno script che esegue `listunspent`, salva le informazioni in una variabile, e esegue il codice Go su quella. + +Solo dopo utilizzi il RPC `getreceivedbyaddress`, sul tuo indirizzo decodificato: + +``` + wallet, err := client.GetReceivedByAddress(addr) + if err != nil { + log.Fatal(err) + } + + fmt.Println(wallet) +``` +Quando esegui [il codice](src/18_1_getamountreceived.go), dovresti ottenere un output simile a: + +``` +$ go run getamountreceived.go +0.0085 BTC +``` + + +## Invia una Transazione + +Ora hai tutti i pezzi del puzzle per inviare una transazione. Ecco cosa dovrai fare: + +1. Importa le librerie corrette, incluse `chaincfg` per specificare una rete e `btcutil` per decodificare un indirizzo. +2. Scegli un indirizzo a cui inviare. +3. Decodifica quell'indirizzo. +4. Esegui `sendtoaddress` per inviare fondi in modo semplice. + + +``` +package main +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcd/chaincfg" +) +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "StandUp", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + defaultNet := &chaincfg.TestNet3Params + addr, err := btcutil.DecodeAddress("n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", defaultNet) + if err != nil { + log.Fatal(err) + } + sent, err := client.SendToAddress(addr, btcutil.Amount(1e4)) + if err != nil { + log.Fatal(err) + } + fmt.Println(sent) +} +``` + +Quando esegui [il codice](src/18_1_sendtransaction.go), l'ID della transazione viene visualizzato: + +``` +$ go run sendtransaction.go +9aa4cd6559e0d69059eae142c35bfe78b71a8084e1fcc2c74e2a9675e9e7489d +``` + +### Cerca una Transazione + +Per cercare una transazione, come quella che hai appena inviato, dovrai fare alcune conversioni, questa volta dell'ID della transazione. `"github.com/btcsuite/btcd/chaincfg/chainhash"` è importato per permettere che gli hash siano memorizzati nel codice Go. `chainhash.NewHashFromStr("hash")` converte un hash in una stringa in un formato che funziona con rpcclient. + + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/chaincfg/chainhash" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "StandUp", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + chash, err := chainhash.NewHashFromStr("1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df") + if err != nil { + log.Fatal(err) + } + transactions, err := client.GetTransaction(chash) + if err != nil { + log.Fatal(err) + } + + fmt.Println(transactions) +} +``` +> **NOTA:** Ancora una volta, vorrai cambiare l'ID della transazione con uno effettivamente riconosciuto dal tuo sistema. + +Quando esegui [il codice](17_1_lookuptransaction.go), stampa i dettagli associati a una transazione, come l'importo e quante volte è stata confermata: + + + +``` +$ go run lookuptransaction.go +{ + "amount": 0.00100000, + "confirmations": 4817, + "blockhash": "000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a", + "blockindex": 117, + "blocktime": 1591857418, + "txid": "1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df", + "walletconflicts": [ + ], + "time": 1591857343, + "timereceived": 1591857343, + "bip125-replaceable": "no", + "details": [ + { + "address": "mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha", + "category": "receive", + "amount": 0.00100000, + "label": "", + "vout": 0 + } + ], + "hex": "02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00" +} +``` +## Riassunto: Accesso a Bitcoind con Go + +Anche se il `btcd` `rpcclient` presenta alcuni limiti, puoi comunque eseguire i principali comandi RPC in Go. La documentazione per `rpcclient` è disponibile su [Godoc](https://godoc.org/github.com/btcsuite/btcd/rpcclient). Se la documentazione non offre ciò che cerchi, consulta anche il [repository btcd](https://github.com/btcsuite/btcd). È generalmente ben documentato e facile da leggere. Basandoti su questi esempi dovresti essere in grado di incorporare Bitcoin in un progetto Go e fare cose come inviare e ricevere monete. + +## Prossimi passi? + +Scopri di più su "Parlare con Bitcoin in Altre Lingue" nel [Capitolo 18.2: Accedere a Bitcoind con Java](18_2_Accedere_a_Bitcoind_con_Java.md). diff --git a/it/18_2_Accedere_a_Bitcoind_con_Java.md b/it/18_2_Accedere_a_Bitcoind_con_Java.md new file mode 100644 index 000000000..61164d8d6 --- /dev/null +++ b/it/18_2_Accedere_a_Bitcoind_con_Java.md @@ -0,0 +1,377 @@ +# 18.2: Accesso a Bitcoind con Java + +> :information_source: **NOTA:** Questa sezione è stata aggiunta di recente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Questa sezione spiega come interagire con `bitcoind` utilizzando il linguaggio di programmazione Java e il [JavaBitcoindRpcClient](https://github.com/Polve/JavaBitcoindRpcClient). + +## Configurare Java + +Puoi installare Java sul tuo server, utilizzando il comando `apt-get`. Installerai anche [Apache Maven](http://maven.apache.org/) per gestire le dipendenze. + +``` +$ sudo apt-get install openjdk-11-jre-headless maven +``` + +Puoi verificare la tua installazione di Java: + +``` +$ java -version +openjdk version "11.0.8" 2020-07-14 +OpenJDK Runtime Environment (build 11.0.8+10-post-Debian-1deb10u1) +OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Debian-1deb10u1, mixed mode, sharing) +``` + +### Creare un Progetto Maven + +Per programmare con Bitcoin utilizzando Java, creerai un progetto Maven: + +``` +$ mvn archetype:generate -DgroupId=com.blockchaincommons.lbtc -DartifactId=java-project -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false +``` + +Questo scaricherà alcune dipendenze + +``` +Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom +Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/2.5/maven-clean-plugin-2.5.pom (4 KB at 4.2 KB/sec) +Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom +Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom (13 KB at 385.9 KB/sec) +Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/21/maven-parent-21.pom +Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/21/maven-parent-21.pom (26 KB at 559.6 KB/sec) +Downloading: https://repo.maven.apache.org/maven2/org/apache/apache/10/apache-10.pom +.............. +``` + +Creerà anche un file di configurazione `pom.xml`: + +``` +$ cd java-project +$ ls -lagh +total 16K +drwxr-xr-x 3 sudo 4.0K Sep 1 13:58 . +drwxr-xr-x 15 sudo 4.0K Sep 1 13:58 .. +-rw-r--r-- 1 sudo 663 Sep 1 13:58 pom.xml +drwxr-xr-x 4 sudo 4.0K Sep 1 13:58 src +``` + +Per includere `JavaBitcoindRpcClient`, devi aggiungere la sua dipendenza a `` nel file `pom.xml` + +``` + + wf.bitcoin + bitcoin-rpc-client + 1.2.1 + +``` + +Devi anche aggiungere le proprietà del compilatore per indicare quale versione di JDK compilerà il codice sorgente. + +``` +$ cd cancellami sono una riga extra + + + UTF-8 + 11 + 11 + +``` + +Ogni volta che aggiungi codice sorgente alle tue classi, potrai testarlo con: + +``` +$ mvn compile +``` + +Puoi anche eseguire con `exec:java` + +``` +$ mvn exec:java -Dexec.mainClass=com.blockchaincommons.lbtc.App +``` + +### Creare Progetti Alternativi + +Se utilizzi [Gradle]((https://gradle.org/releases/), puoi invece eseguire: + + +``` +compile 'wf.bitcoin:JavaBitcoindRpcClient:1.2.1' +``` + +Se vuoi un progetto di esempio e alcune istruzioni su come eseguirlo sul server che hai appena creato, puoi fare riferimento al [Progetto di Esempio Bitcoind Java](https://github.com/brunocvcunha/bitcoind-java-client-sample/). Puoi anche sfogliare tutto il codice sorgente per bitcoin-rpc-client (https://github.com/Polve/bitcoin-rpc-client). + +## Costruire la Tua Connessione + +Per utilizzare `JavaBitcoindRpcClient`, devi creare un'istanza di `BitcoindRpcClient`. Questo si fa creando un URL con argomenti di username, password, indirizzo IP e porta. Come ricorderai, l'indirizzo IP `127.0.0.1` e la porta `18332` dovrebbero essere corretti per la configurazione standard di testnet descritta in questo corso, mentre puoi estrarre l'utente e la password da `~/.bitcoin/bitcoin.conf`. + +``` + BitcoindRpcClient rpcClient = new BitcoinJSONRPCClient("http://StandUp:6305f1b2dbb3bc5a16cd0f4aac7e1eba@localhost:18332"); +``` + +Nota che dovrai anche importare le informazioni appropriate: + +``` +import wf.bitcoin.javabitcoindrpcclient.BitcoinJSONRPCClient; +import wf.bitcoin.javabitcoindrpcclient.BitcoindRpcClient; +``` + +> **MAINNET VS TESTNET:** La porta sarebbe 8332 per una configurazione mainnet. + +Se `rpcClient` viene inizializzato con successo, potrai inviare comandi RPC. + +In seguito, quando avrai finito con la tua connessione `bitcoind`, dovresti chiuderla: + +``` +rpcClient.stop(); +``` + +### Effettuare una Chiamata RPC + +Scoprirai che `BitcoindRpcClient` fornisce la maggior parte delle funzionalità accessibili tramite `bitcoin-cli` o altri metodi RPC, utilizzando gli stessi nomi dei metodi, ma in camelCase. + +Ad esempio, per eseguire il comando `getmininginfo` per ottenere le informazioni sul blocco e la difficoltà della rete, dovresti utilizzare il metodo `getMiningInfo()`: + +``` +MiningInfo info = rpcClient.getMiningInfo(); +System.out.println("Mining Information"); +System.out.println("------------------"); +System.out.println("Chain......: " + info.chain()); +System.out.println("Blocks.....: " + info.blocks()); +System.out.println("Difficulty.: " + info.difficulty()); +System.out.println("Hash Power.: " + info.networkHashps()); +``` + +L'output per questa linea dovrebbe essere simile a questo: + +``` +Mining Information +------------------ +Chain......: test +Blocks.....: 1830905 +Difficulty.: 4194304 +Hash Power.: 40367401348837.41 +``` + +### Make an RPC Call with Arguments + +You can look up addresses on your wallet by passing the address as an argument to `getAddressInfo`: + +``` + String addr1 = "mvLyH7Rs45c16FG2dfV7uuTKV6pL92kWxo"; + AddressInfo addr1Info = rpcClient.getAddressInfo(addr1); + System.out.println("Address: " + addr1Info.address()); + System.out.println("MasterFingerPrint: " + addr1Info.hdMasterFingerprint()); + System.out.println("HdKeyPath: " + addr1Info.hdKeyPath()); + System.out.println("PubKey: " + addr1Info.pubKey()); +``` + +L'output sarà qualcosa del genere: + +``` +Address: mvLyH7Rs45c16FG2dfV7uuTKV6pL92kWxo +MasterFingerPrint: ce0c7e14 +HdKeyPath: m/0'/0'/5' +PubKey: 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65 +``` + +### Eseguire il Codice + +Il codice per questi esempi può essere trovato nella [directory src](src/18_2_App-getinfo.java) e dovrebbe essere installato nella struttura di directory standard creata qui come +`~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. Può quindi essere compilato ed eseguito. + + +``` +$ mvn compile +$ mvn exec:java -Dexec.mainClass=com.blockchaincommons.lbtc.App +Chain......: test +Blocks.....: 1831079 +Difficulty.: 4194304 +Hash Power.: 38112849943221.16 +Address: mvLyH7Rs45c16FG2dfV7uuTKV6pL92kWxo +MasterFingerPrint: ce0c7e14 +HdKeyPath: m/0'/0'/5' +PubKey: 0368d0fffa651783524f8b934d24d03b32bf8ff2c0808943a556b3d74b2e5c7d65 +``` + +(Vedrai anche molte altre informazioni sulla compilazione, naturalmente.) + +## Cercare Fondi + +Recuperare il saldo per un intero account è altrettanto semplice: + + +``` + System.out.println("Balance: " + rpcClient.getBalance()); +``` + +## Creare un Indirizzo + +Puoi creare un nuovo indirizzo sul tuo wallet, assegnargli una specifica etichetta e persino esportare la sua chiave privata. + +``` + String address = rpcClient.getNewAddress("Learning-Bitcoin-from-the-Command-Line"); + System.out.println("New Address: " + address); + + String privKey = rpcClient.dumpPrivKey(address); + System.out.println("Priv Key: " + privKey); +``` + +Output: + +``` +New Address: mpsFtZ8qTJPRGZy1gaaUw37fHeUSPLkzzs +Priv Key: cTy2AnmAALsHokYzJzTdsUBSqBtypmWfmSNYgG6qQH43euUZgqic +``` + +## Inviare una Transazione + +La libreria JavaBitcoindRpcClient ha alcuni buoni strumenti che rendono facile creare una transazione da zero. + +### Creare una Transazione + +Puoi creare una transazione grezza utilizzando il metodo `createRawTransaction`, passando come argomenti due oggetti ArrayList contenenti gli input e gli output da utilizzare. + +Prima imposti i tuoi nuovi indirizzi, qui un indirizzo esistente sul tuo sistema e un nuovo indirizzo sul tuo sistema. + +``` + String addr1 = "tb1qdqkc3430rexxlgnma6p7clly33s6jjgay5q8np"; + System.out.println("Used address addr1: " + addr1); + + String addr2 = rpcClient.getNewAddress(); + System.out.println("Created address addr2: " + addr2); +``` + +Poi puoi utilizzare l'RPC `listUnspent` per trovare i UTXO per l'indirizzo esistente. + + +``` + List utxos = rpcClient.listUnspent(0, Integer.MAX_VALUE, addr1); + System.out.println("Found " + utxos.size() + " UTXOs (unspent transaction outputs) belonging to addr1"); +``` + +Ecco un output di tutte le informazioni: + +``` +System.out.println("Created address addr1: " + addr1); +String addr2 = rpcClient.getNewAddress(); +System.out.println("Created address addr2: " + addr2); +List generatedBlocksHashes = rpcClient.generateToAddress(110, addr1); +System.out.println("Generated " + generatedBlocksHashes.size() + " blocks for addr1"); +List utxos = rpcClient.listUnspent(0, Integer.MAX_VALUE, addr1); +System.out.println("Found " + utxos.size() + " UTXOs (unspent transaction outputs) belonging to addr1"); +``` +Le transazioni sono costruite con `BitcoinRawTxBuilder`: + +``` + BitcoinRawTxBuilder txb = new BitcoinRawTxBuilder(rpcClient); +``` + +Per prima cosa riempi gli input con i UTXO che stai spendendo: + +``` + TxInput in = utxos.get(0); + txb.in(in); +``` + +> :warning: **ATTENZIONE:** Ovviamente in un vero programma selezioneresti intelligentemente un UTXO; qui, prendiamo solo il primo, una tattica che utilizzeremo in tutto questo capitolo. + +In secondo luogo, riempi gli output ciascuno con un importo e un indirizzo: + +``` + BigDecimal estimatedFee = BigDecimal.valueOf(0.00000200); + BigDecimal txToAddr2Amount = utxos.get(0).amount().subtract(estimatedFee); + txb.out(addr2, txToAddr2Amount); + System.out.println("unsignedRawTx in amount: " + utxos.get(0).amount()); + System.out.println("unsignedRawTx out amount: " + txToAddr2Amount); +``` + +Ora sei pronto a creare effettivamente la transazione: + +``` + String unsignedRawTxHex = txb.create(); + System.out.println("Created unsignedRawTx from addr1 to addr2: " + unsignedRawTxHex); +``` + +### Firmare una Transazione + +Ora puoi firmare la transazione con il metodo `signRawTransactionWithKey`. Questo metodo riceve come parametri una stringa di transazione grezza non firmata, la chiave privata dell'indirizzo mittente e l'oggetto TxInput. + + +``` + SignedRawTransaction srTx = rpcClient.signRawTransactionWithKey( + unsignedRawTxHex, + Arrays.asList(rpcClient.dumpPrivKey(addr1)), // + Arrays.asList(in), + null); + System.out.println("signedRawTx hex: " + srTx.hex()); + System.out.println("signedRawTx complete: " + srTx.complete()); +``` + +### Inviare una Transazione + +Infine, inviare richiede il comando `sendRawTransaction`: + +``` +String sentRawTransactionID = rpcClient.sendRawTransaction(srTx.hex()); +System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID); +``` + +### Eseguire il Codice + +Ora puoi eseguire [il codice della transazione](src/18_2_App-sendtx.java) come `~/java-project/src/main/java/com/blockchaincommons/lbtc/App.java`. + + +``` +$ mvn compile +$ mvn exec:java -Dexec.mainClass=com.blockchaincommons.lbtc.App +Used address addr1: tb1qdqkc3430rexxlgnma6p7clly33s6jjgay5q8np +Created address addr2: tb1q04q2wzlhfqlrnz95ynfj7gp4t3yynrj0542smv +Found 1 UTXOs (unspent transaction outputs) belonging to addr1 +unsignedRawTx in amount: 0.00850000 +unsignedRawTx out amount: 0.00849800 +Created unsignedRawTx from addr1 to addr2: 0200000001d2a90fc3b43e8eb4ae9452af43c9448112d359cac701f7f537aa8b6f39193bb90100000000ffffffff0188f70c00000000001600147d40a70bf7483e3988b424d32f20355c48498e4f00000000 +signedRawTx hex: 02000000000101d2a90fc3b43e8eb4ae9452af43c9448112d359cac701f7f537aa8b6f39193bb90100000000ffffffff0188f70c00000000001600147d40a70bf7483e3988b424d32f20355c48498e4f024730440220495fb64d8cf9dee9daa8535b8867709ac8d3763d693fd8c9111ce610645c76c90220286f39a626a940c3d9f8614524d67dd6594d9ee93818927df4698c1c8b8f622d01210333877967ac52c0d0ec96aca446ceb3f51863de906e702584cc4da2780d360aae00000000 +signedRawTx complete: true +Sent signedRawTx (txID): 82032c07e0ed91780c3369a1943ea8abf49c9e11855ffedd935374ecbc789c45 +``` + +## Ascoltare Transazioni o Blocchi + +Come con [C e le sue librerie ZMQ](16_3_Ricevere_Notifiche_di_Bitcoind_in_C_tramite_Librerie_ZMQ.md), ci sono modi semplici per utilizzare Java per ascoltare la blockchain e per eseguire codice specifico quando accade qualcosa, come una transazione che coinvolge un indirizzo nel tuo wallet, o anche la generazione di un nuovo blocco nella rete. + +Per fare ciò, utilizza la classe `BitcoinAcceptor` di `JavaBitcoindRpcClient`, che ti permette di collegare listener nella rete. + + +``` + String blockHash = rpcClient.getBestBlockHash(); + BitcoinAcceptor acceptor = new BitcoinAcceptor(rpcClient, blockHash, 6, new BitcoinPaymentListener() { + @Override + public void transaction(Transaction tx) { + System.out.println("Transaction: " + tx); + } + @Override + public void block(String block) { + System.out.println("Block: " + block); + } + }); + acceptor.run(); +``` + + +Consulta la [directory src](src/18_2_App-listen.java) per il codice completo. Ogni volta che viene inviata una transazione o generato un nuovo blocco, dovresti vedere un output sulla tua console: + + +``` +Transaction: {account=Tests, address=mhopuJzgmTwhGfpNLCJ9CRknugY691oXp1, category=receive, amount=5.0E-4, label=Tests, vout=1, confirmations=0, trusted=false, txid=361e8fcff243b74ebf396e595a007636654f67c3c7b55fd2860a3d37772155eb, walletconflicts=[], time=1513132887, timereceived=1513132887, bip125-replaceable=unknown} +Block: 000000004564adfee3738314549f7ca35d96c4da0afc6b232183917086b6d971 +``` + + +### Sommario Accesso a Bitcoind con Java + +Utilizzando la libreria javabitcoinrpc, puoi facilmente accedere a bitcoind tramite chiamate RPC da Java. Avrai anche accesso a funzionalità aggiuntive interessanti, come il servizio di ascolto `bitcoinAcceptor`. + +## Cosa c'è Dopo? + +Scopri di più su "Parlare con Bitcoin in Altri Linguaggi" nel [Capitolo 18.3: Accedere a Bitcoind con NodeJS](18_3_Accedere_a_Bitcoind_con_NodeJS.md). + + diff --git a/it/18_3_Accedere_a_Bitcoind_con_NodeJS.md b/it/18_3_Accedere_a_Bitcoind_con_NodeJS.md new file mode 100644 index 000000000..13115bc5e --- /dev/null +++ b/it/18_3_Accedere_a_Bitcoind_con_NodeJS.md @@ -0,0 +1,281 @@ +# 18.3: Accedere a Bitcoind con NodeJS + +> :information_source: **NOTA:** Questa sezione è stata aggiunta di recente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Questa sezione spiega come interagire con `bitcoind` utilizzando il linguaggio di programmazione NodeJS e il [pacchetto BCRPC](https://github.com/dgarage/bcrpc). + +## Set Up Node.js + +BCRPC è costruito su node.js. Pertanto, dovrai prima installare i pacchetti `node.js` e `npm` (il gestore di pacchetti node) per il tuo sistema. + +Se stai usando una macchina Ubuntu, puoi eseguire i seguenti comandi per ottenere una nuova versione di `node.js` (invece della versione molto datata nel sistema di pacchetti di Ubuntu). + +``` +$ curl -sL https://deb.nodesource.com/setup_14.x | sudo bash - +$ sudo apt-get install -y nodejs +$ sudo npm install mocha -g +``` + +### Configurare BCRPC + +Ora puoi clonare il pacchetto BCRPC da GitHub e installare le sue dipendenze. + +``` +$ git clone https://github.com/dgarage/bcrpc.git +$ cd bcrpc +$ npm install +``` + +Per testare il pacchetto BCRPC, devi prima impostare le variabili ambientali per il tuo rpcuser e rpcpassword. Come al solito, questi provengono da `~/.bitcoin/bitcoin.conf`. Devi anche impostare la porta RPC a 18332, che dovrebbe essere corretta per la configurazione standard del testnet descritta in questi documenti. + +``` +$ export BITCOIND_USER=StandUp +$ export BITCOIND_PASS=d8340efbcd34e312044c8431c59c792c +$ export BITCOIND_PORT=18332 +``` + +> :warning: **WARNING:** Ovviamente, non metteresti mai la tua password in una variabile ambientale in un ambiente di produzione. + +> :link: **MAINNET VS TESTNET:** La porta sarebbe 8332 per una configurazione mainnet. + +Ora puoi verificare che tutto funzioni correttamente: + +``` +$ npm test +> bcrpc@0.2.2 test /home/user1/bcrpc +> mocha tests.js + BitcoinD + ✓ is running + bcrpc + ✓ can get info + 2 passing (36ms) +``` + +Congratulazioni, ora hai un wrapper RPC pronto per Bitcoin per Node.js che funziona con la tua configurazione di Bitcoin. + +### Creare un Progetto BCRPC + +Ora puoi creare un nuovo progetto Node.js e installare BCRPC tramite npm. + +``` +$ cd ~ +$ mkdir myproject +$ cd myproject +$ npm init + [continue with default options] +$ npm install bcrpc +``` + +## Costruire la Tua Connessione + +Nella tua directory ```myproject```, crea un file `.js` dove verrà eseguito il tuo codice JavaScript. + +Puoi iniziare una connessione RPC creando un `RpcAgent`: + +``` +const RpcAgent = require('bcrpc'); +agent = new RpcAgent({port: 18332, user: 'StandUp', pass: 'd8340efbcd34e312044c8431c59c792c'}); +``` + +Ovviamente, il tuo `user` e `pass` dovrebbero corrispondere nuovamente a quelli presenti nel tuo `~/.bitcoin/bitcoin.conf`, e usi `port 18332` se sei su testnet. + +### Effettuare una Chiamata RPC + +Utilizzando BCRPC, puoi utilizzare gli stessi comandi RPC che useresti di solito tramite `bitcoin-cli` con il tuo `RpcAgent`, tranne che devono essere in camelCase. Ad esempio, `getblockhash` diventerebbe `getBlockHash`. + +Per stampare il numero del blocco più recente, basta chiamare `getBlockCount` tramite il tuo `RpcAgent`: + +``` +agent.getBlockCount(function (err, blockCount) { + if (err) + throw Error(JSON.stringify(err)); + console.log(blockCount.result); +}); +``` + +### Effettuare una Chiamata RPC con Argomenti + +Le funzioni BCRPC possono accettare argomenti. Ad esempio, `getBlockHash` prende `blockCount.result` come input. + +``` + agent.getBlockHash(blockCount.result, function (err, hash) { + if (err) + throw Error(JSON.stringify(err)); + console.log(hash.result); + }) +``` + +Il risultato delle funzioni BCRPC è un oggetto JSON contenente informazioni su eventuali errori e l'id della richiesta. Quando accedi al tuo risultato, aggiungi `.result` alla fine per specificare che sei interessato al risultato effettivo, non alle informazioni sugli errori. + +### Eseguire il Codice + +Puoi trovare il codice `getinfo` nella [directory src](src/18_3_getinfo.js). + +``` +$ node getinfo.js +1831094 +00000000000002bf8b522a830180ad3a93b8eed33121f54b3842d8838580a53c +``` + +Questo è l'aspetto che avrebbe l'output dell'esempio sopra se sostituissi `console.log(blockCount.result);` e `console.log(hash.result);` con +`console.log(blockCount);` e `console.log(hash);`, rispettivamente: + +``` +{ result: 1774686, error: null, id: null } +{ + result: '00000000000000d980c495a2b7addf09bb0a9c78b5b199c8e965ee54753fa5da', + error: null, + id: null +} +``` + +## Cercare Fondi + +È utile, quando si accetta Bitcoin, controllare i Bitcoin ricevuti su un indirizzo specifico nel tuo portafoglio. Ad esempio, se gestissi un negozio online che accetta Bitcoin, per ogni pagamento da un cliente, genereresti un nuovo indirizzo, mostreresti quell'indirizzo al cliente, quindi controlleresti il saldo dell'indirizzo dopo un po' di tempo, per assicurarti che l'importo corretto sia stato ricevuto: + +``` +agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', function (err, addressInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(addressInfo.result); +}); +``` + +> :information_source: **NOTE:** Ovviamente, dovrai inserire un indirizzo riconosciuto dalla tua macchina. + +Per impostazione predefinita, questa funzione controlla le transazioni che sono state confermate una volta, tuttavia puoi aumentare questo numero a un numero più alto come 6: + +``` +agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', 6, function (err, addressInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(addressInfo.result); +}); +``` + +### Cercare informazione sul Wallet + +Puoi anche cercare informazioni aggiuntive sul tuo portafoglio e visualizzare il tuo saldo, il conteggio delle transazioni, eccetera: + +``` +agent.getWalletInfo(function (err, walletInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(walletInfo.result); +}); +``` + +Il codice sorgente è disponibile come [walletinfo.js](src/18_3_walletinfo.js). + +``` +$ node walletinfo.js +0.008498 +{ + walletname: '', + walletversion: 169900, + balance: 0.010438, + unconfirmed_balance: 0, + immature_balance: 0, + txcount: 4, + keypoololdest: 1596567843, + keypoolsize: 999, + hdseedid: 'da5a1b058deb9e51ecffef1b0ddc069a5dfb2c5f', + keypoolsize_hd_internal: 1000, + paytxfee: 0, + private_keys_enabled: true, + avoid_reuse: false, + scanning: false +} +``` + +Invece di stampare tutti i dettagli associati al tuo portafoglio, puoi stampare informazioni specifiche, come il tuo saldo. Poiché viene accesso un oggetto JSON, questo può essere fatto cambiando la riga `console.log(walletInfo.result);` in `console.log(walletInfo.result.balance);`: + +## Creare un Indirizzo + +Puoi anche passare argomenti aggiuntivi ai comandi RPC. Ad esempio, il seguente genera un nuovo indirizzo legacy, con il flag `-addresstype`. + +``` +agent.getNewAddress('-addresstype', 'legacy', function (err, newAddress) { + if (err) + throw Error(JSON.stringify(err)); + console.log(newAddress.result); +}); +``` + +Questo è lo stesso che eseguire il seguente comando dal terminale: + +``` +$ bitcoin-cli getnewaddress -addresstype legacy +mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ +``` + +In BCRPC, puoi generalmente usare gli stessi flag di `bitcoin-cli` in BCRPC. Sebbene tu usi camelCase (`getNewAddress`) per i metodi, i flag, che sono normalmente separati da spazi sulla riga di comando, sono invece posti in stringhe e separati da virgole. + +## Inviare una Transazione + +Puoi inviare monete a un indirizzo più facilmente utilizzando la funzione `sendToAddress`: + +``` +agent.sendToAddress(newAddress.result, 0.00001, function(err, txid) { + if (err) + throw Error(JSON.stringify(err)); + console.log(txid.result); +}); +``` + +Questo dovrebbe stampare il txid della transazione: + +``` +1679bee019c61608340b79810377be2798efd4d2ec3ace0f00a1967af70666b9 +``` + +### Cercare una Transazione + +Potresti ora voler visualizzare una transazione, come quella che hai appena inviato. + +``` +agent.getTransaction(txid.result, function (err, transaction) { + if (err) + throw Error(JSON.stringify(err)); + console.log(transaction.result); +}); +``` + +Dovresti ottenere un output simile a questo: + +``` +{ + amount: 0.001, + confirmations: 4776, + blockhash: '000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a', + blockindex: 117, + blocktime: 1591857418, + txid: '1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df', + walletconflicts: [], + time: 1591857343, + timereceived: 1591857343, + 'bip125-replaceable': 'no', + details: [ + { + address: 'mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', + category: 'receive', + amount: 0.001, + label: '', + vout: 0 + } + ], + hex: '02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00' +} +``` + +Il codice completo è disponibile come [sendtx.js](src/18_3_sendtx.js). + +## Sommario: Accesso a Bitcoind con Node + +Con BCRPC puoi accedere a tutti i comandi RPC disponibili tramite `bitcoin-cli`, in JavaScript. Il [README di BCRPC](https://github.com/dgarage/bcrpc) ha alcuni esempi che usano promesse (gli esempi in questo documento usano callback). Il [JavaScript dietro di esso](https://github.com/dgarage/bcrpc/blob/master/index.js) è breve e leggibile. + +Sulla base di questi esempi, dovresti essere in grado di incorporare Bitcoin in un progetto Node.js e fare cose come inviare e ricevere monete. + +## What's Next? + +Learn more about "Talking to Bitcoin in Other Languages" nel [Capitolo 18.4: Accedere a Bitcoind con Python](18_4_Accedere_a_Bitcoind_con_Python.md). diff --git a/it/18_4_Accedere_a_Bitcoind_con_Python.md b/it/18_4_Accedere_a_Bitcoind_con_Python.md new file mode 100644 index 000000000..4ac6b9d20 --- /dev/null +++ b/it/18_4_Accedere_a_Bitcoind_con_Python.md @@ -0,0 +1,515 @@ +# 18.4: Accesso a Bitcoind con Python + +> :information_source: **NOTA:** Questa sezione è stata aggiunta di recente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +Questa sezione spiega come interagire con `bitcoind` utilizzando il linguaggio di programmazione Python e il [Python-BitcoinRPC](https://github.com/jgarzik/python-bitcoinrpc). + +## Configurare Python + +Se hai già installato Bitcoin Core, dovresti avere anche Python 3 disponibile. +Puoi verificarlo eseguendo: + +`$ python3 --version` + +Se restituisce un numero di versione (ad es., `3.7.3` o `3.8.3`) allora hai python3 installato. + +Tuttavia, se in qualche modo non hai Python installato, dovrai compilarlo da sorgente come segue. Consulta la variante ["Compilare Python da Sorgente"](17_4_Accessing_Bitcoind_with_Python.md#variant-build-python-from-source) prima di continuare. + +### Configurare BitcoinRPC + +Sia che tu abbia utilizzato un Python esistente o che lo abbia compilato da sorgente, ora sei pronto per installare la libreria `python-bitcoinrpc`: + +``` +$ pip3 install python-bitcoinrpc +``` + +Se non hai `pip` installato, dovrai eseguire il seguente comando: + +``` +$ sudo apt install python3-pip +``` + +(Poi ripeti le istruzioni `pip3 install python-bitcoinrpc`.) + +### Creare un Progetto BitcoinRPC + +Generalmente dovrai includere le dichiarazioni appropriate da `bitcoinrpc` nei tuoi progetti Bitcoin in Python. Quanto segue ti darà accesso ai comandi basati su RPC: + +``` +from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException +``` + +Potresti anche trovare utili i seguenti: + +``` +from pprint import pprint +import logging +``` + +`pprint` stamperà in modo leggibile la risposta `json` da `bitcoind`. + +`logging` stamperà la chiamata che fai a `bitcoind` e la risposta di `bitcoind`, il che è utile quando fai molte chiamate insieme. Se non vuoi l'output eccessivo nel terminale, commenta semplicemente il blocco `logging`. + +## Costruire la Tua Connessione + +Ora sei pronto per iniziare a interagire con `bitcoind` stabilendo una connessione. Crea un file chiamato `btcrpc.py` e digita quanto segue: + +``` +logging.basicConfig() +logging.getLogger("BitcoinRPC").setLevel(logging.DEBUG) +# rpc_user and rpc_password are set in the bitcoin.conf file +rpc_user = "StandUp" +rpc_pass = "6305f1b2dbb3bc5a16cd0f4aac7e1eba" +rpc_host = "127.0.0.1" +rpc_client = AuthServiceProxy(f"http://{rpc_user}:{rpc_pass}@{rpc_host}:18332", timeout=120) +``` + +Gli argomenti nell'URL sono `:@:`. Come al solito, l'`user` e il `pass` si trovano nel tuo `~/.bitcoin/bitcoin.conf`, mentre l'`host` è il tuo localhost e la porta è `18332` per testnet. L'argomento `timeout` è specificato poiché i socket vanno in timeout sotto carico pesante su mainnet. Se ottieni una risposta `socket.timeout: timed out`, sii paziente e aumenta il `timeout`. + +> :link: **MAINNET VS TESTNET:** La porta sarebbe 8332 per una configurazione mainnet. + +### Effettuare una Chiamata RPC + +Se `rpc_client` è stato inizializzato con successo, sarai in grado di inviare comandi RPC al tuo nodo bitcoin. + +Per utilizzare un metodo RPC da `python-bitcoinrpc`, utilizzerai l'oggetto `rpc_client` che hai creato, il quale fornisce la maggior parte delle funzionalità accessibili tramite `bitcoin-cli`, utilizzando gli stessi nomi dei metodi. + +Ad esempio, quanto segue recupererà il blockcount del tuo nodo: + +``` +block_count = rpc_client.getblockcount() +print("---------------------------------------------------------------") +print("Block Count:", block_count) +print("---------------------------------------------------------------\n") +``` + +Dovresti vedere il seguente output con `logging` abilitato: + +``` +DEBUG:BitcoinRPC:-3-> getblockcount [] +DEBUG:BitcoinRPC:<-3- 1773020 +--------------------------------------------------------------- +Block Count: 1773020 +--------------------------------------------------------------- +``` + +### Effettuare una Chiamata RPC con Argomenti + +Puoi utilizzare quel blockcount come argomento per recuperare l'hash del blocco di un blocco e anche per recuperare i dettagli di quel blocco. + +Questo viene fatto inviando comandi all'oggetto `rpc_client` con un argomento: + +``` +blockhash = rpc_client.getblockhash(block_count) +block = rpc_client.getblock(blockhash) +``` + +Il `getblockhash` restituirà un singolo valore, mentre il `getblock` restituirà un array associativo di informazioni sul blocco, che include un array sotto `block['tx']` che fornisce dettagli su ogni transazione all'interno del blocco: + +``` +nTx = block['nTx'] +if nTx > 10: + it_txs = 10 + list_tx_heading = "First 10 transactions: " +else: + it_txs = nTx + list_tx_heading = f"All the {it_txs} transactions: " +print("---------------------------------------------------------------") +print("BLOCK: ", block_count) +print("-------------") +print("Block Hash...: ", blockhash) +print("Merkle Root..: ", block['merkleroot']) +print("Block Size...: ", block['size']) +print("Block Weight.: ", block['weight']) +print("Nonce........: ", block['nonce']) +print("Difficulty...: ", block['difficulty']) +print("Number of Tx.: ", nTx) +print(list_tx_heading) +print("---------------------") +i = 0 +while i < it_txs: + print(i, ":", block['tx'][i]) + i += 1 +print("---------------------------------------------------------------\n") +``` + +### Eseguire il Codice + +Puoi recuperare [il codice sorgente](src/18_4_getinfo.py) ed eseguirlo con `python3`: + +``` +$ python3 getinfo.py +--------------------------------------------------------------- +Block Count: 1831106 +--------------------------------------------------------------- +--------------------------------------------------------------- +BLOCK: 1831106 +------------- +Block Hash...: 00000000000003b2ea7c2cdfffd86156ad1f5606ab58e128940a2534d1348b04 +Merkle Root..: 056a547fe59208167eef86fa694263728fb684119254b340c1f86bdd423a8082 +Block Size...: 52079 +Block Weight.: 128594 +Nonce........: 1775583700 +Difficulty...: 4194304 +Number of Tx.: 155 +First 10 transactions: +--------------------- +0 : d228d55112e3aa26265b0118cfdc98345c229d20fe074b9afb87107c03ce11b5 +1 : 92822e8e34fafb472b87c99ea3f3e16440452b3f361ed86c6fa62175173fb750 +2 : fa7c67600c14d4aa350a9674688f1429577954f4a6c5e4639d06c8964824f647 +3 : 3a91d1527e308e5603dafde7ab17824f441a73a779d2571d073466dc9e8451b2 +4 : 30fd0e5527b1522e7b26a4818b9edac80fe47c0c39fc34705478a49e684708d0 +5 : 24c5372b38c78cbaf5b0b305925502a491bc0c1b5758f50c0bd335abb6ae85f5 +6 : be70e125a5793efc5e32051fecba0668df971bdf371138c8261201c2a46b2d38 +7 : 41ebf52c847a59ba0aeb4425c74e89a01e91defa86a82785ff53ed4668054561 +8 : dc8211b4ce122f87692e7c203672e3eb1ffc44c0a307eafcc560323fcc5fae78 +9 : 59e2d8e11cad287eacf3207e64a373f65059286b803ef0981510193ae29cbc8c +--------------------------------------------------------------- +``` + +## Cercare Fondi + +Puoi recuperare in modo simile le informazioni del tuo wallet con l'RPC `getwalletinfo`: + +``` +wallet_info = rpc_client.getwalletinfo() +print("---------------------------------------------------------------") +print("Wallet Info:") +print("-----------") +pprint(wallet_info) +print("---------------------------------------------------------------\n") +``` + +Dovresti avere un output simile al seguente con `logging` disabilitato: + +``` +--------------------------------------------------------------- +#Wallet Info: +----------- +{'avoid_reuse': False, + 'balance': Decimal('0.07160443'), + 'hdseedid': '6dko666b1cc0d69b7eb0539l89eba7b6390kdj02', + 'immature_balance': Decimal('0E-8'), + 'keypoololdest': 1542245729, + 'keypoolsize': 999, + 'keypoolsize_hd_internal': 1000, + 'paytxfee': Decimal('0E-8'), + 'private_keys_enabled': True, + 'scanning': False, + 'txcount': 9, + 'unconfirmed_balance': Decimal('0E-8'), + 'walletname': '', + 'walletversion': 169900} +--------------------------------------------------------------- +``` + +Altri comandi informativi come `getblockchaininfo`, `getnetworkinfo`, `getpeerinfo` e `getblockchaininfo` funzioneranno in modo simile. + +Altri comandi possono darti informazioni specifiche su elementi selezionati all'interno del tuo wallet. + +### Recuperare un Array + +L'RPC `listtransactions` ti consente di visualizzare le ultime 10 transazioni sul tuo sistema (o un insieme arbitrario di transazioni utilizzando gli argomenti `count` e `skip`). Mostra come un comando RPC possa restituire un array facile da manipolare: + +``` +tx_list = rpc_client.listtransactions() +pprint(tx_list) +``` + +### Esplorare un UTXO + +Puoi utilizzare in modo simile `listunspent` per ottenere un array di UTXO sul tuo sistema: + +``` +print("Exploring UTXOs") +## List UTXOs +utxos = rpc_client.listunspent() +print("Utxos: ") +print("-----") +pprint(utxos) +print("------------------------------------------\n") +``` + +Per manipolare un array come quello restituito da `listtransactions` o `listunspent`, devi semplicemente prendere l'elemento appropriato dall'array appropriato: + +``` +## Select a UTXO - first one selected here +utxo_txid = utxos[0]['txid'] +``` + +Per `listunspent`, ottieni un `txid`. Puoi recuperare informazioni al riguardo con `gettransaction`, quindi decodificarle con `decoderawtransaction`: + +``` +utxo_hex = rpc_client.gettransaction(utxo_txid)['hex'] +utxo_tx_details = rpc_client.decoderawtransaction(utxo_hex) +print("Details of Utxo with txid:", utxo_txid) +print("---------------------------------------------------------------") +print("UTXO Details:") +print("------------") +pprint(utxo_tx_details) +print("---------------------------------------------------------------\n") +``` + +Questo codice è disponibile su [walletinfo.py](src/18_4_walletinfo.py). + +``` +$ python3 walletinfo.py +--------------------------------------------------------------- +#Wallet Info: +----------- +{'avoid_reuse': False, + 'balance': Decimal('0.01031734'), + 'hdseedid': 'da5a1b058deb9e51ecffef1b0ddc069a5dfb2c5f', + 'immature_balance': Decimal('0E-8'), + 'keypoololdest': 1596567843, + 'keypoolsize': 1000, + 'keypoolsize_hd_internal': 999, + 'paytxfee': Decimal('0E-8'), + 'private_keys_enabled': True, + 'scanning': False, + 'txcount': 6, + 'unconfirmed_balance': Decimal('0E-8'), + 'walletname': '', + 'walletversion': 169900} +--------------------------------------------------------------- + +Utxos: +----- +[{'address': 'mv9cjEnS2o1EygBMdrz99LzhM8KeEMoXDg', + 'amount': Decimal('0.00001000'), + 'confirmations': 1180, + 'desc': "pkh([ce0c7e14/0'/0'/25']02d0541b9211aecd25913f7fdecfc1b469215fa326d52067b1b3f7efbd12316472)#n06pq9q5", + 'label': '-addresstype', + 'safe': True, + 'scriptPubKey': '76a914a080d1a10f5e7a02d0a291f118982ed19e8cfcd788ac', + 'solvable': True, + 'spendable': True, + 'txid': '84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e', + 'vout': 0}, + {'address': 'tb1qrcf8c29966tvqxhwrtd2se3rj6jeqtll3r46a4', + 'amount': Decimal('0.01029734'), + 'confirmations': 1180, + 'desc': "wpkh([ce0c7e14/0'/1'/26']02c581259ba7e6aef6d7ea23adb08f7c7f10c4c678f2e097a4074639e7685d4805)#j3pctfhf", + 'safe': True, + 'scriptPubKey': '00141e127c28a5d696c01aee1adaa8662396a5902fff', + 'solvable': True, + 'spendable': True, + 'txid': '84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e', + 'vout': 1}, + {'address': 'mzDxbtYY3LBBBJ6HhaBAtnHv6c51BRBTLE', + 'amount': Decimal('0.00001000'), + 'confirmations': 1181, + 'desc': "pkh([ce0c7e14/0'/0'/23']0377bdd176f985b4af2f6bdbb22c2925b6007b6c07ba171f75e65990c002615e98)#3y6ef6vu", + 'label': '-addresstype', + 'safe': True, + 'scriptPubKey': '76a914cd339342b06042bb986a45e73d56db46acc1e01488ac', + 'solvable': True, + 'spendable': True, + 'txid': '1679bee019c61608340b79810377be2798efd4d2ec3ace0f00a1967af70666b9', + 'vout': 1}] +------------------------------------------ + +Details of Utxo with txid: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e +--------------------------------------------------------------- +UTXO Details: +------------ +{'hash': '0c6c27f58f122329bbc53a91f290b35ce23bd2708706b21a04cdc387dc8e2fd9', + 'locktime': 1831103, + 'size': 225, + 'txid': '84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e', + 'version': 2, + 'vin': [{'scriptSig': {'asm': '', 'hex': ''}, + 'sequence': 4294967294, + 'txid': '1679bee019c61608340b79810377be2798efd4d2ec3ace0f00a1967af70666b9', + 'txinwitness': ['3044022014b3e2359fb46d8cbc4cd30fa991b455edfa4b419a4c64a53fcdfc79e3ca89db022010cefc3268bc252d55f1982c426328b709b47d02332def9e2efb3b12de2cf0d301', + '0351b470e87b44e8e9607acf09b8d4543c51c93c17dc741176319e60202091f2be'], + 'vout': 0}], + 'vout': [{'n': 0, + 'scriptPubKey': {'addresses': ['mv9cjEnS2o1EygBMdrz99LzhM8KeEMoXDg'], + 'asm': 'OP_DUP OP_HASH160 ' + 'a080d1a10f5e7a02d0a291f118982ed19e8cfcd7 ' + 'OP_EQUALVERIFY OP_CHECKSIG', + 'hex': '76a914a080d1a10f5e7a02d0a291f118982ed19e8cfcd788ac', + 'reqSigs': 1, + 'type': 'pubkeyhash'}, + 'value': Decimal('0.00001000')}, + {'n': 1, + 'scriptPubKey': {'addresses': ['tb1qrcf8c29966tvqxhwrtd2se3rj6jeqtll3r46a4'], + 'asm': '0 1e127c28a5d696c01aee1adaa8662396a5902fff', + 'hex': '00141e127c28a5d696c01aee1adaa8662396a5902fff', + 'reqSigs': 1, + 'type': 'witness_v0_keyhash'}, + 'value': Decimal('0.01029734')}], + 'vsize': 144, + 'weight': 573} +--------------------------------------------------------------- +``` + +## Creare un Indirizzo + +Creare un nuovo indirizzo con Python 3 richiede solo l'uso di un RPC come `getnewaddress` o `getrawchangeaddress`. + +``` +new_address = rpc_client.getnewaddress("Learning-Bitcoin-from-the-Command-Line") +new_change_address = rpc_client.getrawchangeaddress() +``` + +In questo esempio, dai il comando `getnewaddress` con un argomento: l'etichetta `Learning-Bitcoin-from-the-Command-Line`. + +## Inviare una Transazione + +Creare una transazione in Python 3 richiede la combinazione di alcuni degli esempi precedenti (creare indirizzi e recuperare UTXO) con alcuni nuovi comandi RPC per creare, firmare e inviare una transazione, proprio come hai fatto in precedenza dalla riga di comando. + +Ci sono cinque passaggi: + +0. Creare due indirizzi, uno che fungerà da destinatario e l'altro per il resto. +1. Selezionare un UTXO e impostare i dettagli della transazione. +2. Creare una transazione grezza. +3. Firmare la transazione grezza con la chiave privata dell'UTXO. +4. Trasmettere la transazione sulla testnet bitcoin. + +### 1. Selezionare UTXO e Impostare i Dettagli della Transazione + +Nel seguente frammento di codice, selezioni prima l'UTXO che vuoi spendere. Poi ottieni il suo indirizzo, l'ID della transazione e l'indice del vettore dell'output. + +``` +utxos = rpc_client.listunspent() +selected_utxo = utxos[0] # again, selecting the first utxo here +utxo_address = selected_utxo['address'] +utxo_txid = selected_utxo['txid'] +utxo_vout = selected_utxo['vout'] +utxo_amt = float(selected_utxo['amount']) +``` + +Successivamente, recuperi anche l'indirizzo del destinatario a cui vuoi inviare i bitcoin, calcoli la quantità di bitcoin che vuoi inviare e calcoli la commissione per i miner e l'importo del resto. Qui, l'importo è diviso arbitrariamente in due e una commissione per i miner è impostata arbitrariamente. + +``` +recipient_address = new_address +recipient_amt = utxo_amt / 2 # sending half coins to recipient +miner_fee = 0.00000300 # choose appropriate fee based on your tx size +change_address = new_change_address +change_amt = float('%.8f'%((utxo_amt - recipient_amt) - miner_fee)) +``` + +> :warning: **ATTENZIONE:** Ovviamente un programma reale farebbe scelte più sofisticate su quale UTXO utilizzare, cosa fare con i fondi e quale commissione per i miner pagare. + +### 2. Creare Transazione Grezza + +Ora hai tutte le informazioni per inviare una transazione, ma prima di poterlo fare, devi creare una transazione. + +``` +txids_vouts = [{"txid": utxo_txid, "vout": utxo_vout}] +addresses_amts = {f"{recipient_address}": recipient_amt, f"{change_address}": change_amt} +unsigned_tx_hex = rpc_client.createrawtransaction(txids_vouts, addresses_amts) +``` + +Ricorda che il formato del comando `createrawtransaction` è: + +`$ bitcoin-cli createrawtransaction '[{"txid": , "vout": }]' '{"
": }'` + +Il `txids_vouts` è quindi un elenco e `addresses_amts` è un dizionario python, per corrispondere al formato di `createrawtransaction`. + +Se vuoi vedere di più sui dettagli della transazione che hai creato, puoi usare `decoderawtransaction`, sia in Python 3 che con `bitcoin-cli`. + +### 3. Firmare la Transazione Grezza + +Firmare una transazione è spesso la parte più complicata dell'invio di una transazione programmaticamente. Qui recuperi una chiave privata da un indirizzo con `dumpprivkey` e la inserisci in un array: + +``` +address_priv_key = [] # list of priv keys of each utxo +address_priv_key.append(rpc_client.dumpprivkey(utxo_address)) +``` + +Puoi quindi utilizzare quell'array (che dovrebbe contenere le chiavi private di ogni UTXO che viene speso) per firmare il tuo `unsigned_tx_hex`: + +``` +signed_tx = rpc_client.signrawtransactionwithkey(unsigned_tx_hex, address_priv_key) +``` + +Questo restituisce un oggetto JSON con l'hex della transazione firmata e se è stata firmata completamente o meno. + +### 4. Trasmettere la Transazione + +Infine, sei pronto per trasmettere la transazione firmata sulla rete bitcoin: + +``` +send_tx = rpc_client.sendrawtransaction(signed_tx['hex']) +``` + +### Eseguire il Codice + +Il [codice di esempio](src/18_4_sendtx.py) è pieno di istruzioni `print` per dimostrare tutti i dati disponibili in ogni punto: + +``` +$ python3 sendtx.py +Creating a Transaction +--------------------------------------------------------------- +Transaction Details: +------------------- +UTXO Address.......: mv9cjEnS2o1EygBMdrz99LzhM8KeEMoXDg +UTXO Txid..........: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e +Vector ID of Output: 0 +UTXO Amount........: 1e-05 +Tx Amount..........: 5e-06 +Recipient Address..: tb1qca0elxxqzw5xc0s3yq5qhapzzj90ka0zartu6y +Change Address.....: tb1qrveukqrvqm9h6fua99xvcxgnvdx507dg8e8hrt +Miner Fee..........: 3e-06 +Change Amount......: 2e-06 +--------------------------------------------------------------- + +--------------------------------------------------------------- +Unsigned Transaction Hex: 02000000015e53fb6f63b7defa28e61c28cfc3033361138a0d33dd1fad29ae58c6fe7f20840000000000ffffffff02f401000000000000160014c75f9f98c013a86c3e1120280bf422148afb75e2c8000000000000001600141b33cb006c06cb7d279d294ccc1913634d47f9a800000000 +--------------------------------------------------------------- + +--------------------------------------------------------------- +Signed Transaction: +---------------------- +{'complete': True, + 'hex': '02000000015e53fb6f63b7defa28e61c28cfc3033361138a0d33dd1fad29ae58c6fe7f2084000000006a47304402205da9b2234ea057c9ef3b7794958db6c650c72dedff1a90d2915147a5f6413f2802203756552aba0dd8ebd71b0f28341becc01b28d8b28af063d7c8ce89f9c69167f8012102d0541b9211aecd25913f7fdecfc1b469215fa326d52067b1b3f7efbd12316472ffffffff02f401000000000000160014c75f9f98c013a86c3e1120280bf422148afb75e2c8000000000000001600141b33cb006c06cb7d279d294ccc1913634d47f9a800000000'} +--------------------------------------------------------------- + +--------------------------------------------------------------- +TXID of sent transaction: 187f8baa222f9f37841d966b6bad59b8131cfacca861cbe9bfc8656bd16a44cc +``` + +## Sommario: Accesso a Bitcoind con Python + +Accedere a Bitcoind con Python è molto facile utilizzando la libreria `python-bitcoinrpc`. La prima cosa da fare è sempre stabilire una connessione con la tua istanza `bitcoind`, poi puoi chiamare tutte le API bitcoin come descritto nella documentazione di bitcoin-core. Questo rende facile creare programmi piccoli o grandi per gestire il tuo nodo, controllare i saldi o creare applicazioni interessanti sopra, accedendo alla piena potenza di `bitcoin-cli`. + +## Cosa c'è Dopo? + +Scopri di più su "Parlare con Bitcoin in Altri Linguaggi" in [18.5: Accesso a Bitcoind con Rust](18_5_Accessing_Bitcoind_with_Rust.md). + +## Variante: Compilare Python da Sorgente + +Se hai bisogno di installare Python 3 da sorgente, segui queste istruzioni, poi continua con ["Creare un Progetto BitcoinRPC"](18_4_Accessing_Bitcoind_with_Python.md#create-a-bitcoinrpc-project). + +### 1. Installare le Dipendenze + +``` +$ sudo apt-get install build-essential checkinstall +$ sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev +``` + +### 2. Scaricare e Estrarre Python + +``` +$ wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz +$ tar -xzf Python-3.8.3.tgz +``` + +### 3. Compilare il Sorgente Python e Controllare l'Installazione: + +``` +$ cd Python-3.8.3 +$ sudo ./configure --enable-optimizations +$ sudo make -j 8 # enter the number of cores of your system you want to use to speed up the build process. +$ sudo make altinstall +$ python3.8 --version +``` + +Dopo aver ottenuto l'output della versione, rimuovi il file sorgente: + +``` +$ rm Python-3.8.3.tgz +``` diff --git a/it/18_5_Accedere_a_Bitcoind_con_Rust.md b/it/18_5_Accedere_a_Bitcoind_con_Rust.md new file mode 100644 index 000000000..21994e2b7 --- /dev/null +++ b/it/18_5_Accedere_a_Bitcoind_con_Rust.md @@ -0,0 +1,382 @@ +# 18.5 Accedere a Bitcoind con Rust + +> :information_source: **NOTA:** Questa sezione è stata aggiunta recentemente al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Questa sezione spiega come interagire con `bitcoind` utilizzando il linguaggio di programmazione Rust e il [`bitcoincore-rpc` crate](https://github.com/rust-bitcoin/rust-bitcoincore-rpc). + +## Configurare Rust + +È necessario installare sia Rust che Cargo. + +Possono essere installati tramite `curl`. Utilizza semplicemente l'installazione "default": + +``` +$ curl https://sh.rustup.rs -sSf | sh +``` + +Se tutto va bene, dovresti vedere: + +``` +$ Rust is installed now. Great! +``` + +Dovrai quindi disconnetterti e ricollegarti, oppure aggiungere manualmente la directory binaria di Cargo al tuo percorso: + +``` +$ source $HOME/.cargo/env +``` + +### Configurare `bitcoincore-rpc` + +Per la maggior parte dei linguaggi di programmazione, è necessario installare una libreria Bitcoin RPC prima di creare il tuo primo progetto, ma qui lo farai come parte della creazione del progetto. + +### Creare un Progetto `bitcoincore-rpc` + +Puoi creare un nuovo progetto usando `cargo new btc_test`: + +``` +$ cargo new btc_test + Created binary (application) `btc_test` package +``` +Questo creerà una directory `btc_test` che contiene un esempio di codice sorgente "hello world" in `src/main.rs` e un file `Cargo.toml`. + +Compila ed esegui il codice con `cargo run`: + +``` +$ cd btc_test +$ cargo run + Compiling btc_test v0.1.0 (/home/standup/btc_test) + Finished dev [unoptimized + debuginfo] target(s) in 0.14s + Running `target/debug/btc_test` +Hello, world! +``` + +> :information_source: **NOTA:** se riscontri l'errore `linker ‘cc’ not found`, dovrai installare un compilatore C. Se sei su Linux, procedi con l'installazione degli [strumenti di sviluppo](https://www.ostechnix.com/install-development-tools-linux/). + +Per accedere al crate (libreria) `bitcoincore-rpc`, devi aggiungerlo al tuo file `Cargo.toml` nella sezione `dependencies`: + +``` +[dependencies] +bitcoincore-rpc = "0.11.0" +``` + +Quando esegui nuovamente `cargo run`, installerà il `crate` e le sue (numerose) dipendenze. + +``` +$ cargo run + Updating crates.io index + ... + Compiling bitcoin v0.23.0 + Compiling bitcoincore-rpc-json v0.11.0 + Compiling bitcoincore-rpc v0.11.0 + Compiling btc_test v0.1.0 (/home/standup/btc_test) + Finished dev [unoptimized + debuginfo] target(s) in 23.56s + Running `target/debug/btc_test` +Hello, world! +``` + +Quando usi `bitcoin-rpc`, in genere devi includere quanto segue: + +``` +use bitcoincore_rpc::{Auth, Client, RpcApi}; +``` + +## Costruire la Connessione + +Per creare un `RPC client` Bitcoin, modifica il file `src/main.rs`: + +``` +use bitcoincore_rpc::{Auth, Client, RpcApi}; +fn main() { + let rpc = Client::new( + "http://localhost:18332".to_string(), + Auth::UserPass("StandUp".to_string(), "password".to_string()), + ) + .unwrap(); +} +``` + +Come al solito, assicurati di inserire il tuo nome utente e password corretti da `~/.bitcoin/bitcoin.conf`. Qui, vengono utilizzati come argomenti per `Auth::UserPass`. + +> :link: **TESTNET vs MAINNET:** E, come al solito, usa la porta 8332 per mainnet. + +Quando hai finito, dovresti anche chiudere la connessione: + +``` + let _ = rpc.stop().unwrap(); +``` + +`cargo run` dovrebbe compilare ed eseguire correttamente l'esempio con un avviso `warning: unused variable: rpc` + +### Effettuare una Chiamata RPC + +Le chiamate RPC vengono effettuate utilizzando il `rpc` `Client` che hai creato: + +``` +let mining_info = rpc.get_mining_info().unwrap(); +println!("{:#?}", mining_info); +``` + +Generalmente, le parole nella chiamata RPC sono separate da `_`. Un elenco completo è disponibile nella [documentazione del crate](https://crates.io/crates/bitcoincore-rpc). + +### Effettuare una Chiamata RPC con Argomenti + +Inviare una chiamata RPC con argomenti utilizzando Rust richiede solo di sapere come è strutturata la funzione. Ad esempio, la funzione `get_block` è definita come segue nella [documentazione](https://docs.rs/bitcoincore-rpc/0.11.0/bitcoincore_rpc/trait.RpcApi.html#method.get_block): + +``` +fn get_block(&self, hash: &BlockHash) -> Result +``` + +Devi solo consentire che prenda in prestito un blockhash, che può essere recuperato (ad esempio) con `get_best_block_hash`. + +Ecco il codice completo per recuperare un block hash, trasformarlo in un block e stamparlo. + +``` + let hash = rpc.get_best_block_hash().unwrap(); + let block = rpc.get_block(&hash).unwrap(); + + println!("{:?}", block); +``` + +> **NOTA:** Un'altra chiamata possibile che abbiamo considerato per questa sezione era `get_address_info`, ma purtroppo, al momento della scrittura, la funzione `bitcoincore-rpc` non funziona con le versioni recenti di Bitcoin Core a causa del crate che non affronta gli ultimi cambiamenti dell'API in Bitcoin Core. Ci aspettiamo che questo venga risolto nella prossima release del crate, ma nel frattempo, _attenzione programmatore_. + +### Esegui il Codice + +Puoi accedere al [codice sorgente](src/18_5_main-getinfo.rs) ed eseguirlo. Sfortunatamente, le informazioni sul "Block" risulteranno un po' brutte perché questo esempio non include una libreria per renderle più leggibili. + +``` +$ cargo run + Compiling btc_test v0.1.0 (/home/standup/btc_test) + Finished dev [unoptimized + debuginfo] target(s) in 1.61s + Running `target/debug/btc_test` +GetMiningInfoResult { + blocks: 1832335, + current_block_weight: None, + current_block_tx: None, + difficulty: 4194304.0, + network_hash_ps: 77436285865245.1, + pooled_tx: 4, + chain: "test", + warnings: "Warning: unknown new rules activated (versionbit 28)", +} +Block { header: BlockHeader { version: 541065216, prev_blockhash: 000000000000027715981d5a3047daf6819ea3b8390b73832587594a2074cbf5, merkle_root: 4b2e2c2754b6ed9cf5c857a66ed4c8642b6f6b33b42a4859423e4c3dca462d0c, time: 1599602277, bits: 436469756, nonce: 218614401 }, txdata: [Transaction { version: 1, lock_time: 0, input: [TxIn { previous_output: OutPoint { txid: 0000000000000000000000000000000000000000000000000000000000000000, vout: 4294967295 }, script_sig: Script(OP_PUSHBYTES_3 8ff51b OP_PUSHBYTES_22 315448617368263538434f494e1d00010320a48db852 OP_PUSHBYTES_32 ), sequence: 4294967295, witness: [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] }], output: [TxOut { value: 19721777, script_pubkey: Script(OP_HASH160 OP_PUSHBYTES_20 011beb6fb8499e075a57027fb0a58384f2d3f784 OP_EQUAL) }, TxOut { value: 0, script_pubkey: Script(OP_RETURN OP_PUSHBYTES_36 aa21a9ed63363f3620ab5e38b8860a50c84050e5ec31af3636bbd73f01ba9f14103100ee) }] }, Transaction { version: 2, lock_time: 1832282, input: [TxIn { previous_output: OutPoint { txid: cbf880f73d421baf0aa4f0d28e63ba00e5bc6bd934b91eb0641354ce5ca42f7e, vout: 0 }, script_sig: Script(OP_PUSHBYTES_22 00146b8dbd32e5deb90d22934e1513bae6e70156cd50), sequence: 4294967294, witness: [[48, 68, 2, 32, 13, 89, 205, 30, 67, 24, 196, 83, 65, 224, 44, 138, 98, 58, 81, 135, 132, 209, 23, 166, 23, 44, 3, 228, 95, 102, 166, 214, 62, 38, 155, 147, 2, 32, 119, 2, 34, 246, 148, 255, 166, 10, 90, 52, 242, 32, 74, 241, 123, 148, 89, 199, 197, 3, 152, 134, 242, 215, 109, 61, 241, 241, 13, 70, 86, 207, 1], [2, 192, 145, 170, 206, 55, 4, 36, 138, 145, 217, 50, 19, 73, 130, 136, 245, 131, 184, 142, 239, 75, 13, 67, 17, 177, 57, 86, 151, 139, 89, 35, 109]] }], output: [TxOut { value: 1667908, script_pubkey: Script(OP_HASH160 OP_PUSHBYTES_20 908ca2b8b49ccf53efa2226afa85f6cc58dfd7e7 OP_EQUAL) }, TxOut { value: 9093, script_pubkey: Script(OP_DUP OP_HASH160 OP_PUSHBYTES_20 42ee67664ce16edefc68ad0e4c5b7ce2fc2ccc18 OP_EQUALVERIFY OP_CHECKSIG) }] }, ...] } +``` + +## Controllare i Fondi + +Puoi controllare i fondi senza argomenti opzionali utilizzando la funzione `get_balance`: + +``` +let balance = rpc.get_balance(None, None).unwrap(); +println!("Balance: {:?} BTC", balance.as_btc()); +``` + +Come mostrato, la funzione `as_btc()` aiuta a visualizzare il saldo in una forma leggibile: + +``` +Balance: 3433.71692741 BTC +``` + +## Creare un Indirizzo + +Creare un indirizzo dimostra come effettuare una chiamata RPC con più argomenti opzionali specificati (ad esempio, un'etichetta e un tipo di indirizzo). + +``` +// Generate a new address +let myaddress = rpc + .get_new_address(Option::Some("BlockchainCommons"), Option::Some(json::AddressType::Bech32)) + .unwrap(); +println!("address: {:?}", myaddress); +``` + +Questo richiederà anche di portare la definizione `json` nel contesto: + +``` +use bitcoincore_rpc::{json, Auth, Client, RpcApi}; +``` + +## Inviare una Transazione + +Ora hai tutto ciò che ti serve per creare una transazione, che verrà effettuata in cinque parti: + +1. Elenca gli UTXO +2. Popola le Variabili +3. Crea la Transazione Grezza +4. Firma la Transazione +5. Invia la Transazione + +### 1. Elenca gli UTXO + +Per iniziare la creazione di una transazione, devi prima trovare un UTXO da utilizzare. Il seguente codice prende il primo UTXO con almeno 0.01 BTC + +``` +let unspent = rpc +.list_unspent( + None, + None, + None, + None, + Option::Some(json::ListUnspentQueryOptions { + minimum_amount: Option::Some(Amount::from_btc(0.01).unwrap()), + maximum_amount: None, + maximum_count: None, + minimum_sum_amount: None, + }), +) +.unwrap(); + +let selected_tx = &unspent[0]; + +println!("selected unspent transaction: {:#?}", selected_tx); +``` + +Questo richiederà di portare più strutture nel contesto: + +``` +use bitcoincore_rpc::bitcoin::{Address, Amount}; +``` + +Nota che stai passando a `list_unspent` cinque variabili. Le prime quattro (`minconf`, `maxconf`, `addresses`, e `include_unsafe`) non sono utilizzate qui. La quinta è `query_options`, che non abbiamo usato prima, ma ha alcune potenti opzioni di filtro, inclusa la possibilità di guardare solo agli UTXO con un certo valore minimo (o massimo). + +### 2. Popola le Variabili + +Per iniziare a popolare le variabili di cui avrai bisogno per creare una nuova transazione, crea l'input dal `txid` e dal `vout` dell'UTXO che hai selezionato: + +``` +let selected_utxos = json::CreateRawTransactionInput { + txid: selected_tx.txid, + vout: selected_tx.vout, + sequence: None, +}; +``` + +Successivamente, puoi calcolare l'importo che intendi spendere sottraendo una commissione di mining dai fondi nell'UTXO: + +``` +// send all bitcoin in the UTXO except a minor value which will be paid to miners +let unspent_amount = selected_tx.amount; +let amount = unspent_amount - Amount::from_btc(0.00001).unwrap(); +``` + +Infine, puoi creare una mappa hash dell'indirizzo e dell'importo per formare l'output: + +``` +let mut output = HashMap::new(); +output.insert( + myaddress.to_string(), + amount, +); +``` + +Un altro trait è necessario per la variabile di output: `HashMap`. Ti permette di memorizzare +valori per chiave, di cui hai bisogno per rappresentare le informazioni `{address : amount}`. + +``` +use std::collections::HashMap; +``` + +### 3. Crea la Transazione Grezza + +Sei pronto per creare una transazione grezza: + +``` +let unsigned_tx = rpc + .create_raw_transaction(&[selected_utxos], &output, None, None) + .unwrap(); +``` + +### 4. Firma la Transazione + +Firmare la tua transazione può essere fatto con un semplice uso di `sign_raw_transaction_with_wallet`: + +``` +let signed_tx = rpc + .sign_raw_transaction_with_wallet(&unsigned_tx, None, None) + .unwrap(); + +println!("signed tx {:?}", signed_tx.transaction().unwrap()); +``` + +### 5. Invia la Transazione + +Infine, puoi trasmettere la transazione: + +``` +let txid_sent = rpc + .send_raw_transaction(&signed_tx.transaction().unwrap()) + .unwrap(); +println!("{:?}", txid_sent); +``` + +### Esegui il Codice + +Ora puoi eseguire il codice completo dal [codice sorgente](src/18_5_main-sendtx.rs). + +``` +$ cargo run + Compiling btc_test v0.1.0 (/home/standup/btc_test) +warning: unused variable: `unspent_amount` + --> src/main.rs:86:9 + | +86 | let unspent_amount = selected_tx.amount; + | ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unspent_amount` + | + = note: `#[warn(unused_variables)]` on by default + +warning: 1 warning emitted + + Finished dev [unoptimized + debuginfo] target(s) in 2.11s + Running `target/debug/btc_test` +Balance: 0.01031434 BTC +address: tb1qx5jz36xgt9q2rkh4daee8ewfj0g5z05v8qsua2 +selected unspent transaction: ListUnspentResultEntry { + txid: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e, + vout: 1, + address: Some( + tb1qrcf8c29966tvqxhwrtd2se3rj6jeqtll3r46a4, + ), + label: None, + redeem_script: None, + witness_script: None, + script_pub_key: Script(OP_0 OP_PUSHBYTES_20 1e127c28a5d696c01aee1adaa8662396a5902fff), + amount: Amount(1029734 satoshi), + confirmations: 1246, + spendable: true, + solvable: true, + descriptor: Some( + "wpkh([ce0c7e14/0\'/1\'/26\']02c581259ba7e6aef6d7ea23adb08f7c7f10c4c678f2e097a4074639e7685d4805)#j3pctfhf", + ), + safe: true, +} +unsigned tx Transaction { + version: 2, + lock_time: 0, + input: [ + TxIn { + previous_output: OutPoint { + txid: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e, + vout: 1, + }, + script_sig: Script(), + sequence: 4294967295, + witness: [], + }, + ], + output: [ + TxOut { + value: 1028734, + script_pubkey: Script(OP_0 OP_PUSHBYTES_20 352428e8c85940a1daf56f7393e5c993d1413e8c), + }, + ], +} +signed tx Transaction { version: 2, lock_time: 0, input: [TxIn { previous_output: OutPoint { txid: 84207ffec658ae29ad1fdd330d8a13613303c3cf281ce628fadeb7636ffb535e, vout: 1 }, script_sig: Script(), sequence: 4294967295, witness: [[48, 68, 2, 32, 98, 230, 199, 113, 156, 242, 158, 42, 148, 229, 239, 44, 9, 226, 127, 219, 72, 51, 26, 135, 44, 212, 179, 200, 213, 63, 56, 167, 0, 55, 236, 235, 2, 32, 41, 43, 30, 109, 60, 162, 124, 67, 20, 126, 4, 107, 124, 95, 9, 200, 132, 246, 147, 235, 176, 55, 59, 45, 190, 18, 211, 201, 143, 62, 163, 36, 1], [2, 197, 129, 37, 155, 167, 230, 174, 246, 215, 234, 35, 173, 176, 143, 124, 127, 16, 196, 198, 120, 242, 224, 151, 164, 7, 70, 57, 231, 104, 93, 72, 5]] }], output: [TxOut { value: 1028734, script_pubkey: Script(OP_0 OP_PUSHBYTES_20 352428e8c85940a1daf56f7393e5c993d1413e8c) }] } +b0eda3517e6fac69e58ae315d7fe7a1981e3a858996cc1e3135618cac9b79d1a +``` + +## Riepilogo: Accesso a Bitcoind con Rust + +`bitcoincore-rpc` è un crate semplice e robusto che ti permetterà di interagire con Bitcoin RPC utilizzando Rust. Tuttavia, al momento della scrittura, è rimasto indietro rispetto a Bitcoin Core, il che potrebbe causare alcuni problemi di utilizzo. + +## Cosa segue? + +Scopri di più su "Parlare con Bitcoin in Altri Linguaggi" nel [Capitolo 18.6: Accedere a Bitcoind con Swift](18_6_Accedere_a_Bitcoind_con_Swift.md). diff --git a/it/18_6_Accedere_a_Bitcoind_con_Swift.md b/it/18_6_Accedere_a_Bitcoind_con_Swift.md new file mode 100644 index 000000000..93318ec9b --- /dev/null +++ b/it/18_6_Accedere_a_Bitcoind_con_Swift.md @@ -0,0 +1,530 @@ +# 18.6: Accedere a Bitcoind con Swift + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe ancora essere in attesa di revisione. Attenzione lettore. + +Questa sezione spiega come interagire con `bitcoind` utilizzando il linguaggio di programmazione Swift e il proprio client RPC. + +## Configurare Swift sul tuo Mac + +Fino ad oggi, hai creato tutti i tuoi ambienti di sviluppo in linguaggi alternativi sul tuo nodo virtuale Debian. Tuttavia, quella non è la piattaforma migliore per Swift. Anche se esiste una versione di Swift disponibile per le piattaforme Ubuntu, non è completamente funzionale e funziona in modo leggermente diverso rispetto alla versione nativa di Swift per Mac. Una "variante" alla fine di questa sezione spiega come configurarla, ma attenzione, sarai in territorio inesplorato. + +Invece, suggeriamo di creare un ambiente Swift ottimale su un Mac. Ci sono quattro passaggi principali per farlo. + +### 1. Installa Xcode + +Avrai bisogno di `Xcode`, l'ambiente di sviluppo integrato per Swift e Objective-C. Questo può essere facilmente installato andando al Mac App Store e selezionando `Get` per Xcode. + +#### Alternativa: Installare Manualmente + +Alcuni consigliano di evitare l'installazione dall'App Store perché è un po' tutto o niente; inoltre, non funzionerà se stai ancora utilizzando Mojave perché vuoi evitare le incompatibilità di Catalina. In tal caso, puoi scaricare direttamente dall'[Area Sviluppatori](https://developer.apple.com/download/more/) di Apple. + +Se stai utilizzando Mojave, avrai bisogno del file `xip` per Xcode 10.3.1. Altrimenti, prendi l'ultima versione disponibile. + +Una volta scaricato, puoi fare clic sul file `xip` per estrarlo, quindi spostare l'app Xcode nella tua cartella Applicazioni. + +(In entrambi i casi, alla fine di questo passaggio dovresti avere Xcode installato nella tua cartella Applicazioni.) + +### 2. Installa il Gordian Server + +Avrai anche bisogno di un nodo Bitcoin sul tuo Mac, così da poter comunicare con esso. Tecnicamente, potresti usare un nodo remoto e accedervi con il login e la password RPC su internet. Tuttavia, suggeriamo invece di installare un nodo completo direttamente sul tuo Mac, perché è l'installazione più sicura e pulita, garantendo che nessuna delle tue comunicazioni lasci il tuo dispositivo. + +Per installare facilmente un nodo completo sul tuo Mac, usa il [GordianServer per MacOS](https://github.com/BlockchainCommons/GordianServer-macOS) di Blockchain Commons. Vedi le [istruzioni di installazione](https://github.com/BlockchainCommons/GordianServer-macOS#installation-instructions) nel README, ma generalmente tutto quello che devi fare è scaricare il file `dmg` corrente, aprirlo e installare l'app nella tua directory Applicazioni. + +Dopo, esegui l'App GordianServer e digli di `Start` Testnet. + +> :link: **TESTNET vs. MAINNET:** O `Start` Mainnet. + +#### 3. Rendi Accessibile il Tuo bitcoin-cli di Gordian + +Quando desideri accedere al `bitcoin-cli` creato da GordianServer sul tuo Mac locale, puoi trovarlo in `~/.standup/BitcoinCore/bitcoin-VERSION/bin/bitcoin-cli`, ad esempio `~/.standup/BitcoinCore/bitcoin-0.20.1/bin/bitcoin-cli`. + +Potresti voler creare un alias per questo: + +``` +alias bitcoin-cli="~/.standup/BitcoinCore/bitcoin-0.20.1/bin/bitcoin-cli -testnet" +``` + +> :link: **TESTNET vs. MAINNET:** Ovviamente, il parametro `-testnet` è richiesto solo se stai eseguendo su testnet. + +### 4. Trova le Informazioni di GordianServer + +Infine, avrai bisogno delle informazioni su `rpcuser` e `rpcpassword`. Questo si trova di default in `~/Library/Application Support/Bitcoin/bitcoin.conf` sotto Gordian. + +``` +$ grep rpc ~/Library/Application\ Support/Bitcoin/bitcoin.conf +rpcuser=oIjA53JC2u +rpcpassword=ebVCeSyyM0LurvgQyi0exWTqm4oU0rZU +... +``` + +## Costruisci la Tua Connessione Manualmente + +Al momento della scrittura, non esiste una libreria Bitcoin RPC aggiornata e facile da usare specifica per Swift, qualcosa che puoi semplicemente integrare e iniziare a usare immediatamente. Quindi, farai qualcosa che non hai mai fatto prima: costruire una connessione RPC manualmente. + +### Scrivi il Trasmettitore RPC + +Questo richiede solo la scrittura di una funzione che passa i comandi RPC a `bitcoind` nel formato corretto: + +``` +func makeCommand(method: String, param: Any, completionHandler: @escaping (Any?) -> Void) -> Void { +``` + +Le connessioni RPC a `bitcoind` usano il protocollo HTML, il che significa che devi fare tre cose: creare un URL; fare una URLRequest; e iniziare una URLSession. + +#### 1. Crea un URL + +All'interno della funzione, devi creare un URL dal tuo IP, porta, `rpcuser`, `rpcpassword` e wallet: + +``` + let testnetRpcPort = "18332" + let nodeIp = "127.0.0.1:\(testnetRpcPort)" + let rpcusername = "oIjA53JC2u" + let rpcpassword = "ebVCeSyyM0LurvgQyi0exWTqm4oU0rZU" + let walletName = "" +``` + +La connessione RPC effettiva a Bitcoin Core è costruita usando un URL del formato "http://rpcusername:rpcpassword@nodeIp/walletName": + +``` + let walletUrl = "http://\(rpcusername):\(rpcpassword)@\(nodeIp)/\(walletName)" + + let url = URL(string: walletUrl) +``` + +Questo significa che le tue variabili di esempio risultano nel seguente URL: + +``` +http://oIjA53JC2u:ebVCeSyyM0LurvgQyi0exWTqm4oU0rZU@127.0.0.1:18332/ +``` + +Che dovrebbe assomigliare molto all'URL usato in alcune delle sezioni precedenti per le connessioni RPC. + +#### 2. Crea una URLRequest + +Con quell'URL in mano, puoi ora creare una URLRequest, con il metodo `POST` e il tipo di contenuto `text/plain`. Il corpo HTTP è poi il consueto oggetto JSON che hai inviato ogni volta che ti connetti direttamente alle porte RPC di Bitcoin Core, come dimostrato per la prima volta utilizzando Curl nel [Capitolo 4.4](04_4_Intermezzo_Usare_Curl.md). + +``` + var request = URLRequest(url: url!) + request.httpMethod = "POST" + request.setValue("text/plain", forHTTPHeaderField: "Content-Type") + request.httpBody = "{\"jsonrpc\":\"1.0\",\"id\":\"curltest\",\"method\":\"\(method)\",\"params\":[\(param)]}".data(using: .utf8) +``` + +#### 3. Crea una URLSession + +Infine, sei pronto per costruire una URLSession attorno alla tua URLRequest. + +``` + let session = URLSession(configuration: .default) + let task = session.dataTask(with: request as URLRequest) { data, response, error in +``` + +Il completion handler per `dataTask` deve controllare gli errori: + + +``` + do { + + if error != nil { + + //Handle the error + + } else { +``` + + +E poi analizzare i dati che stai ricevendo. Qui, stai estraendo i risultati JSON in un `NSDictionary`: + + +``` + if let urlContent = data { + + do { + + let json = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableLeaves) as! NSDictionary +``` + + +Dopo di che, ci sono ulteriori gestioni degli errori e poi puoi eventualmente restituire il `result` dictionary utilizzando il `completionHandler` che hai definito per la nuova funzione `makeCommand`: + + +``` + if let errorCheck = json["error"] as? NSDictionary { + + if let errorMessage = errorCheck["message"] as? String { + + print("FAILED") + print(errorMessage) + + } + + } else { + + let result = json["result"] + completionHandler(result) + + } + + } catch { + + //Handle error here + + } +``` + + +Ovviamente, alla fine devi dire al `task` di iniziare: + + +``` + task.resume() +``` + +E questo è "tutto" quello che c'è da fare per realizzare quell'interazione RPC manualmente usando un linguaggio di programmazione come Swift. + +> :pray: **GRAZIE:** Grazie a @Fonta1n3 che ha fornito il [codice principale](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues/137) per il nostro Trasmettitore RPC. + +### Esegui una Chiamata RPC + +Avendo scritto la funzione RPC `makeCommand`, puoi inviare una chiamata RPC eseguendola. Ecco `getblockchaininfo`: + + +``` +let method = "getblockchaininfo" +let param = "" + +makeCommand(method: method,param: param) { result in + + print(result!) + +} +``` + +### Esegui una Chiamata RPC con Argomenti + +Allo stesso modo potresti ottenere il numero del blocco corrente da quelle informazioni e usarlo per (ridondantemente) ottenere l'hash del blocco corrente, utilizzando il parametro `param`: + +``` +let method = "getblockchaininfo" +let param = "" + +makeCommand(method: method,param: param) { result in + + let blockinfo = result as! NSDictionary + let block = blockinfo["blocks"] as! NSNumber + + let method = "getblockhash" + makeCommand(method: method,param: block) { result in + print("Blockhash for \(block) is \(result!)") + } + +} +``` + +### Esegui il Codice + +Il codice completo è disponibile nella [directory src](src/18_6_getinfo.playground). Caricalo nel tuo playground di Xcode e poi seleziona "Editor -> Run Playground" e dovresti ottenere risultati come: + +``` +{ + bestblockhash = 00000000000000069725608ebc5b59e520572a8088cbc57ffa5ba87b7f300ac7; + blocks = 1836745; + chain = test; + chainwork = 0000000000000000000000000000000000000000000001cc3e9f8e0bc6b71196; + difficulty = "16508683.81195478"; + headers = 1836745; + initialblockdownload = 0; + mediantime = 1601416765; + pruned = 0; + "size_on_disk" = 28205538354; + softforks = { + bip34 = { + active = 1; + height = 21111; + type = buried; + }; + bip65 = { + active = 1; + height = 581885; + type = buried; + }; + bip66 = { + active = 1; + height = 330776; + type = buried; + }; + csv = { + active = 1; + height = 770112; + type = buried; + }; + segwit = { + active = 1; + height = 834624; + type = buried; + }; + }; + verificationprogress = "0.999999907191804"; + warnings = "Warning: unknown new rules activated (versionbit 28)"; +} +Blockhash for 1836745 is 00000000000000069725608ebc5b59e520572a8088cbc57ffa5ba87b7f300ac7 +``` + +## Controlla i Fondi + +Con il tuo nuovo `makeCommand` per le funzioni RPC, puoi eseguire comandi simili a `getwalletinfo` o `getbalance`: + +``` +var method = "getwalletinfo" +var param = "" + +makeCommand(method: method,param: param) { result in + + print(result!) + +} + +method = "getbalance" +makeCommand(method: method,param: param) { result in + + let balance = result as! NSNumber + print("Balance is \(balance)") + +} +``` + +Che restituisce: + +``` +Balance is 0.01 +{ + "avoid_reuse" = 0; + balance = "0.01"; + hdseedid = bf493318f548df8e25c390d6a7f70758fd6b3668; + "immature_balance" = 0; + keypoololdest = 1599723938; + keypoolsize = 999; + "keypoolsize_hd_internal" = 1000; + paytxfee = 0; + "private_keys_enabled" = 1; + scanning = 0; + txcount = 1; + "unconfirmed_balance" = 0; + walletname = ""; + walletversion = 169900; +} +``` + +## Crea un Indirizzo + +Creare un indirizzo è abbastanza semplice, ma che dire di creare un indirizzo legacy con una specifica etichetta? Questo richiede due parametri nella tua chiamata RPC. + +Dato che la funzione `makeCommand` in questa sezione passa semplicemente i suoi `param` come il contenuto di un oggetto JSON, tutto ciò che devi fare è formattare correttamente quel contenuto. Ecco un modo per farlo: + +``` +method = "getnewaddress" +param = "\"learning-bitcoin\", \"legacy\"" + +makeCommand(method: method,param: param) { result in + + let address = result as! NSString + print(address) +} +``` + +Eseguendo questo nel playground di Xcode ottieni un risultato: + +``` +mt3ZRsmXHVMMqYQPJ8M74QjF78bmqrdHZF +``` + +Quel risultato è ovviamente un indirizzo Legacy; la sua etichetta può essere quindi controllata dalla riga di comando: + +``` +$ bitcoin-cli getaddressesbylabel "learning-bitcoin" +{ + "mt3ZRsmXHVMMqYQPJ8M74QjF78bmqrdHZF": { + "purpose": "receive" + } +} +``` + +Successo! + +> :information_source: **NOTA:** Come diciamo spesso in questi esempi di codifica, un programma del mondo reale sarebbe molto più sofisticato. In particolare, vorresti essere in grado di inviare un vero oggetto JSON come parametro, e poi avere il tuo programma `makeCommand` che lo analizza e lo immette nella URLSession in modo appropriato. Quello che abbiamo qui massimizza la leggibilità e la semplicità senza concentrarsi sulla facilità d'uso. + +## Invia una Transazione + +Come al solito, inviare una transazione (nel modo difficile) è un processo a più fasi: + +0. Generare o ricevere un indirizzo di ricezione +1. Trovare un UTXO non speso +2. Creare una transazione raw +3. Firmare la transazione raw +4. Inviare la transazione raw + +Userai l'indirizzo che hai generato nel passaggio precedente come destinatario. + +### 1. Trova un UTXO Non Speso + +Il comando `listunspent` RPC ti permette di trovare il tuo UTXO: + +``` + method = "listunspent" + param = "" + + makeCommand(method: method,param: param) { result in + + let unspent = result as! NSArray + let utxo = unspent[0] as! NSDictionary + + let txid = utxo["txid"] as! NSString + let vout = utxo["vout"] as! NSInteger + let amount = utxo["amount"] as! NSNumber + let new_amount = amount.floatValue - 0.0001 +``` + +Come in altri esempi, prenderai arbitrariamente il primo UTXO, e estrarrai da esso il `txid`, `vout` e l'importo `amount`. + +> :information_source **NOTA:** Ancora una volta, un programma reale sarebbe molto più sofisticato. + +### 2. Crea una Transazione Raw + +Creare una transazione raw è la cosa più difficile perché devi mettere a punto tutti i tuoi oggetti JSON, array e virgolette. Ecco come farlo in Swift, utilizzando la formattazione molto basilare dei parametri del trasmettitore: + +``` + method = "createrawtransaction" + param="[ { \"txid\": \"\(txid)\", \"vout\": \(vout) } ], { \"\(address)\": \(new_amount)}" + makeCommand(method: method,param: param) { result in + + let hex = result as! NSString +``` + +### 3. Firma la Transazione Raw + +Firmare la tua transazione richiede solo di eseguire il comando `signrawtransactionwithwallet` RPC, utilizzando il tuo nuovo `hex`: + +``` + method = "signrawtransactionwithwallet" + param = "\"\(hex)\"" + + makeCommand(method: method,param: param) { result in + + let signedhexinfo = result as! NSDictionary + let signedhex = signedhexinfo["hex"] as! NSString +``` + +### 4. Invia la Transazione Raw + +Inviare la tua transazione è altrettanto semplice: + +``` + method = "sendrawtransaction" + param = "\"\(signedhex)\"" + + makeCommand(method: method,param: param) { result in + + let new_txid = result as! NSString + print("TXID: \(new_txid)") + + } + } + } + } +} +``` + +Il codice per questo invio di transazione può essere trovato nella [directory src](src/18_6_sendtx.playground). + +## Utilizza Swift in Altri Modi + +Questo copre le nostre solite discussioni sulla programmazione di Bitcoin RPC in un linguaggio, ma Swift è un linguaggio particolarmente importante poiché può essere utilizzato su dispositivi mobili, uno dei luoghi principali per i wallet. Pertanto, potresti considerare alcune altre librerie: + +* Il framework [ios-Bitcoin](https://github.com/BlockchainCommons/iOS-Bitcoin) di Blockchain Commons converte la libreria Libbitcoin da C++ a Swift +* [Libwally Swift](https://github.com/blockchain/libwally-swift) è un wrapper Swift per Libwally + +## Sommario: Accesso a Bitcoind con Swift + +Swift è un linguaggio di programmazione moderno e robusto che purtroppo non ha ancora librerie RPC facili da usare ... il che ci ha appena dato l'opportunità di scrivere una funzione di accesso RPC da soli. Con questa a disposizione, puoi interagire con `bitcoind` su un Mac o costruire applicazioni companion su un iPhone, che è una combinazione perfetta per lavori Bitcoin airgapped. + +## E ora? + +Scopri Lightning in [Capitolo 19: Comprendere la Configurazione Lightning](19_0_Comprendere_la_Configurazione_Lightning.md). + +## Variante: Distribuire Swift su Ubuntu + +Se preferisci distribuire Swift su Ubuntu, puoi farlo, anche se la funzionalità non è la stessa. Alcuni dei codici in questo capitolo probabilmente genereranno errori che dovrai risolvere, e dovrai anche fare più lavoro per collegare le librerie C. + +Per iniziare, installa alcune librerie Debian richieste: + + + +``` +$ sudo apt-get install clang +$ sudo apt-get install libcurl4 libpython2.7 libpython2.7-dev +``` + +Se stai usando Debian 10 o superiore (e dovresti farlo), dovrai anche aggiornare alcune librerie per ottenere versioni più vecchie: + +``` +$ sudo apt-get install libtinfo5 libncurses5 +``` + +Dopo puoi scaricare e installare Swift: + +``` +$ wget https://swift.org/builds/swift-5.1.3-release/ubuntu1804/swift-5.1.3-RELEASE/swift-5.1.3-RELEASE-ubuntu18.04.tar.gz +$ tar xzfv swift-5.1.3-RELEASE-ubuntu18.04.tar.gz +$ sudo mv swift-5.1.3-RELEASE-ubuntu18.04 /usr/share/swift +``` + +Per poter usare la tua nuova installazione di Swift, devi aggiornare il tuo `PATH` nel tuo `.bashrc`: + +``` +$ echo "export PATH=/usr/share/swift/usr/bin:$PATH" >> ~/.bashrc +$ source ~/.bashrc +``` + +Ora puoi testare Swift con l'argomento `--version`: + +``` +$ swift --version +Swift version 5.1.3 (swift-5.1.3-RELEASE) +Target: x86_64-unknown-linux-gnu +``` + +### Crea un Progetto +Una volta installato Swift sulla tua macchina Ubuntu, puoi creare progetti con il comando `package init`: + +``` +$ mkdir swift-project +$ cd swift-project/ +/swift-project$ swift package init --type executable +Creating executable package: swift-project +Creating Package.swift +Creating README.md +Creating .gitignore +Creating Sources/ +Creating Sources/swift-project/main.swift +Creating Tests/ +Creating Tests/LinuxMain.swift +Creating Tests/swift-projectTests/ +Creating Tests/swift-projectTests/swift_projectTests.swift +Creating Tests/swift-projectTests/XCTestManifests.swift +``` + +Modificherai quindi `Sources/.../main.swift` e quando sei pronto per compilare, puoi usare il comando `build`: + +``` +$ swift build +[4/4] Linking swift-project +``` + +Infine, sarai in grado di eseguire il programma dalla directory `.build/debug`: + +``` +$ .build/debug/swift-project +Hello, world! +``` + +Good luck! diff --git a/it/19_0_Comprendere_la_Configurazione_Lightning.md b/it/19_0_Comprendere_la_Configurazione_Lightning.md new file mode 100644 index 000000000..2f8457ef0 --- /dev/null +++ b/it/19_0_Comprendere_la_Configurazione_Lightning.md @@ -0,0 +1,27 @@ +# Capitolo 19: Comprendere la Tua Configurazione Lightning + +> :information_source: **NOTA:** Questa è una bozza in corso, per raccogliere feedback dai primi revisori. Non è ancora pronta per l'apprendimento. + +Il capitolo precedente ha concluso il nostro lavoro con Bitcoin in senso stretto, tramite CLI, scripting e linguaggi di programmazione. Tuttavia, ci sono molte altre utilità all'interno dell'ecosistema Bitcoin: questo capitolo e il prossimo coprono ciò che potrebbe essere il più grande e importante: il Lightning Network. Qui inizierai a lavorare con l'interfaccia a riga di comando `lightning-cli`, comprendendo una configurazione c-lightning e le sue funzionalità, inclusi alcuni esempi e configurazioni di base. + +## Obiettivi per Questo Capitolo + +Dopo aver lavorato su questo capitolo, un sviluppatore sarà in grado di: + + * Valutare che un Nodo c-lightning sia Installato e Aggiornato + * Eseguire Comandi di Base del Portafoglio Lightning + * Creare un Canale Lightning + +Obiettivi di supporto includono la capacità di: + + * Comprendere la Configurazione Base di Lightning + * Comprendere l'Interazione tra Peer di Lightning + * Comprendere Come Funziona Lightning + +## Indice dei Contenuti + +* [Capitolo 19.1: Verificare la Configurazione Lightning](19_1_Verificare_la_Configurazione_Lightning.md) +* [Capitolo 19.2 Comprendere la Configurazione Lightning](19_2_Comprendere_la_Configurazione_Lightning.md) + * [Capitolo 19.2 Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning](19_2_Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning.md) +* [Capitolo 19.3 Creare un Canale in Lightning](19_3_Creare_un_Canale_in_Lightning.md) + diff --git a/it/19_1_Verificare_la_Configurazione_Lightning.md b/it/19_1_Verificare_la_Configurazione_Lightning.md new file mode 100644 index 000000000..6b9d64397 --- /dev/null +++ b/it/19_1_Verificare_la_Configurazione_Lightning.md @@ -0,0 +1,360 @@ +# 19.1: Verificare la Configurazione Lightning + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza preliminare che potrebbe essere ancora in attesa di revisione. Lettore avvisato.. + +In questa sezione, installerai e verificherai c-lightning, il tuo strumento per accedere al Lightning Network. + +> :book: ***Cos'è il Lightning Network?*** Il Lightning Network è una rete decentralizzata che utilizza la funzionalità dei contratti intelligenti della blockchain di Bitcoin per abilitare pagamenti istantanei tra una rete di partecipanti. Lightning è costruito come un protocollo di livello-2 che interagisce con Bitcoin per consentire agli utenti di scambiare i loro bitcoin "off-chain". + +> :book: ***Cos'è un protocollo di livello-2?*** Il livello 2 si riferisce a un protocollo secondario costruito sopra il sistema della blockchain di Bitcoin. L'obiettivo principale di questi protocolli è risolvere i problemi di velocità delle transazioni e di scalabilità presenti in Bitcoin: Bitcoin non è in grado di elaborare migliaia di transazioni al secondo (TPS), quindi sono stati creati protocolli di livello-2 per risolvere il problema della scalabilità della blockchain. Queste soluzioni sono anche conosciute come soluzioni di scalabilità "off-chain". + +## Installare C-Lightning + +Se hai utilizzato i [Bitcoin Standup Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts), potresti aver già installato Lightning all'inizio di questo corso. Puoi verificarlo vedendo se `lightningd` è in esecuzione: + + +``` +$ ps auxww | grep -i lightning +standup 31213 0.0 0.2 24144 10424 pts/0 S 15:38 0:00 lightningd --testnet +standup 31214 0.0 0.1 22716 7444 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/autoclean +standup 31215 0.0 0.2 22992 8248 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/bcli +standup 31216 0.0 0.1 22756 7604 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/keysend +standup 31217 0.0 0.1 22776 7648 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/pay +standup 31218 0.0 0.1 22720 7652 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/txprepare +standup 31219 0.0 0.1 22744 7716 pts/0 S 15:38 0:00 /usr/local/bin/../libexec/c-lightning/plugins/spenderp +standup 31227 0.0 0.1 22748 7384 pts/0 SL 15:38 0:00 /usr/local/libexec/c-lightning/lightning_hsmd +standup 31228 0.0 0.2 23044 8192 pts/0 S 15:38 0:00 /usr/local/libexec/c-lightning/lightning_connectd +standup 31229 0.0 0.1 22860 7556 pts/0 S 15:38 0:00 /usr/local/libexec/c-lightning/lightning_gossipd +standup 32072 0.0 0.0 6208 888 pts/0 S+ 15:50 0:00 grep -i lightning +``` + + +In caso contrario, dovrai installarlo ora. Sfortunatamente, se stai usando Debian dovrai installarlo a mano, compilando il codice sorgente — ma dovrebbe comunque essere abbastanza semplice se segui queste istruzioni. Se per caso sei su un sistema Ubuntu standard, prova invece a [Installare da Ubuntu ppa](#variant-install-from-ubuntu-ppa), e puoi sempre tentare [Installare Binaries Precompilati](#variant-install-pre-compiled-binaries). + +> :book: ***Cos'è c-lightning?*** Attualmente ci sono tre diverse implementazioni di Lightning: c-lightning, LND e Eclair. Dovrebbero essere tutte funzionalmente compatibili, basate sugli stessi [BOLT RFCs](https://github.com/lightningnetwork/lightning-rfc/blob/master/00-introduction.md), ma i dettagli dell'implementazione potrebbero essere diversi. Abbiamo scelto c-lightning come base del nostro corso perché fa anche parte dello stesso [Elements Project](https://github.com/ElementsProject) che contiene anche Libwally. + +### Compilare il Codice Sorgente di c-lightning + +Installare Lightning dal codice sorgente dovrebbe essere abbastanza semplice se segui queste istruzioni. + +Probabilmente _vorrai_ farlo su un nodo non potato, poiché lavorare con nodi potato su Lightning potrebbe causare problemi con l'installazione e l'uso. Se hai impostato il tuo nodo all'inizio di questo corso per essere potato, potresti volerlo sostituire con un nodo non potato ora. (Se stai usando testnet, dovresti essere in grado di usare lo stesso tipo di macchina che hai usato per il tuo nodo potato.) + +> :warning: **WARNING:** In realtà puoi eseguire c-lightning su un nodo potato. Tuttavia, come nota il [repo di Lightning](https://github.com/ElementsProject/lightning#pruning), potrebbero esserci problemi. Per farlo funzionare devi assicurarti che il tuo nodo Lightning stia cercando di aggiornare solo le informazioni sui blocchi che il tuo nodo Bitcoin non ha potato. Per farlo devi assicurarti (1) che il tuo nodo Bitcoin sia completamente aggiornato prima di avviare il tuo nodo Lightning per la prima volta; e (2) che il tuo nodo Lightning non rimanga troppo indietro rispetto al tuo nodo Bitcoin (per una potatura standard di 550 blocchi, non può essere spento per 4 o più giorni). Quindi, puoi farlo, ma introduce un certo rischio, il che non è una buona idea se stai eseguendo un servizio di produzione. + +Detto ciò, sei pronto per installare Lightning: + +Per prima cosa, installa le dipendenze, inclusi i requisiti di sviluppo. + + + +``` +$ sudo apt-get install -y \ + autoconf automake build-essential git libtool libgmp-dev \ + libsqlite3-dev python3 python3-mako net-tools zlib1g-dev libsodium-dev \ + gettext +$ sudo apt-get install -y valgrind python3-pip libpq-dev +``` + + +Questi possono richiedere un po' di tempo, perché ce ne sono diversi, e alcuni sono grandi. + +In secondo luogo, clona il repository di Lightning: + + + +``` +$ cd ~ +$ git clone https://github.com/ElementsProject/lightning.git +$ cd lightning +``` + + +Ora puoi usare il `pip3` che hai installato per installare ulteriori requisiti per la compilazione e configurare tutto: + + +``` +$ pip3 install -r requirements.txt +$ ./configure +``` + + +Ora, compila. Anche questo potrebbe richiedere del tempo a seconda della tua macchina. + + +``` +$ make +``` + + +Dopo, tutto quello che devi fare è installare: + + +``` +$ sudo make install +``` + + +## Controlla la Tua Installazione + +Puoi confermare di aver installato correttamente lightningd usando il parametro `help`: + + + +``` +$ lightningd --help +lightningd: WARNING: default network changing in 2020: please set network=testnet in config! +Usage: lightningd +A bitcoin lightning daemon (default values shown for network: testnet). +--conf= Specify configuration file +--lightning-dir= Set base directory: network-specific + subdirectory is under here + (default: "/home/javier/.lightning") +--network Select the network parameters (bitcoin, + testnet, regtest, litecoin or + litecoin-testnet) (default: testnet) +--testnet Alias for --network=testnet +--signet Alias for --network=signet +--mainnet Alias for --network=bitcoin + +``` + + +## Esegui lightningd + +Inizierai la tua esplorazione della rete Lightning con il comando `lightning-cli`. Tuttavia, `lightningd` _deve_ essere in esecuzione per usare `lightning-cli`, poiché `lightning-cli` invia comandi JSON-RPC al `lightningd` (tutto proprio come con `bitcoin-cli` e `bitcoind`). + +Se hai installato `c-lightning` a mano, ora dovrai avviarlo: + + + +``` +$ nohup lightningd --testnet & +``` + + +### Esegui lightningd come servizio + +Se preferisci, puoi installare `lightningd` come servizio che verrà eseguito ogni volta che riavvii la tua macchina. Il seguente farà così e lo avvierà immediatamente: + + + +``` +$ cat > ~/lightningd.service << EOF +# It is not recommended to modify this file in-place, because it will +# be overwritten during package upgrades. If you want to add further +# options or overwrite existing ones then use +# $ systemctl edit bitcoind.service +# See "man systemd.service" for details. +# Note that almost all daemon options could be specified in +# /etc/lightning/config, except for those explicitly specified as arguments +# in ExecStart= +[Unit] +Description=c-lightning daemon +[Service] +ExecStart=/usr/local/bin/lightningd --testnet +# Process management +#################### +Type=simple +PIDFile=/run/lightning/lightningd.pid +Restart=on-failure +# Directory creation and permissions +#################################### +# Run as standup +User=standup +# /run/lightningd +RuntimeDirectory=lightningd +RuntimeDirectoryMode=0710 +# Hardening measures +#################### +# Provide a private /tmp and /var/tmp. +PrivateTmp=true +# Mount /usr, /boot/ and /etc read-only for the process. +ProtectSystem=full +# Disallow the process and all of its children to gain +# new privileges through execve(). +NoNewPrivileges=true +# Use a new /dev namespace only populated with API pseudo devices +# such as /dev/null, /dev/zero and /dev/random. +PrivateDevices=true +# Deny the creation of writable and executable memory mappings. +MemoryDenyWriteExecute=true +[Install] +WantedBy=multi-user.target +EOF +$ sudo cp ~/lightningd.service /etc/systemd/system +$ sudo systemctl enable lightningd.service +$ sudo systemctl start lightningd.service +``` + + +### Abilita Connessioni Remote + +Se hai qualche tipo di firewall, dovrai aprire la porta 9735, per permettere agli altri nodi Lightning di parlarti. + +Se usi `ufw` da Bitcoin Standup, questo viene fatto come segue: + + +``` +$ sudo ufw allow 9735 +``` + + +## Verifica il tuo Nodo + +Puoi controllare se il tuo nodo Lightning è pronto confrontando l'output di `bitcoin-cli getblockcount` con il risultato `blockheight` da `lightning-cli getinfo`. + + + +``` +$ bitcoin-cli -testnet getblockcount +1838587 +$ lightning-cli --testnet getinfo +{ + "id": "03d4592f1244cd6b5a8bb7fba6a55f8a91591d79d3ea29bf8e3c3a405d15db7bf9", + "alias": "HOPPINGNET", + "color": "03d459", + "num_peers": 0, + "num_pending_channels": 0, + "num_active_channels": 0, + "num_inactive_channels": 0, + "address": [ + { + "type": "ipv4", + "address": "74.207.240.32", + "port": 9735 + }, + { + "type": "ipv6", + "address": "2600:3c01::f03c:92ff:fe48:9ddd", + "port": 9735 + } + ], + "binding": [ + { + "type": "ipv6", + "address": "::", + "port": 9735 + }, + { + "type": "ipv4", + "address": "0.0.0.0", + "port": 9735 + } + ], + "version": "v0.9.1-96-g6f870df", + "blockheight": 1838587, + "network": "testnet", + "msatoshi_fees_collected": 0, + "fees_collected_msat": "0msat", + "lightning-dir": "/home/standup/.lightning/testnet" +} +``` + + +In questo caso, il `blockheight` è mostrato come `1838587` da entrambi i comandi. + +Potresti invece ottenere un errore, a seconda della situazione precisa. + +Se il nodo Bitcoin è ancora in sincronizzazione con la rete bitcoin dovresti vedere un messaggio come questo: + + + +``` +"warning_bitcoind_sync": "Bitcoind is not up-to-date with network." +``` + + +Se il tuo lightning daemon non è aggiornato, riceverai un messaggio come questo: + + +``` +"warning_lightningd_sync": "Still loading latest blocks from bitcoind." +``` + + +Se hai provato a eseguire su una blockchain potato dove il nodo Bitcoin non era aggiornato quando hai avviato il nodo Lightning, riceverai messaggi di errore nel tuo log come questo: + + +``` +bitcoin-cli -testnet getblock 0000000000000559febee77ab6e0be1b8d0bef0f971c7a4bee9785393ecef451 0 exited with status 1 +``` + + +## Crea Alias + +Suggeriamo di creare alcuni alias per rendere più facile l'uso di c-lightning. + +Puoi farlo inserendoli nel tuo `.bash_profile`. + + + +``` +cat >> ~/.bash_profile < :link: **TESTNET vs MAINNET:** Quando hai impostato il tuo nodo, hai scelto di crearlo come un nodo Mainnet, Testnet o Regtest. Anche se questo documento presume un setup testnet, vale la pena capire come potresti accedere e usare gli altri tipi di setup, anche tutti sulla stessa macchina! Ma, se sei un utente per la prima volta, salta questo passaggio, poiché non è necessario per un setup di base. + +Quando lightningd si avvia, solitamente legge un file di configurazione la cui posizione dipende dalla rete che stai usando (predefinito: `~/.lightning/testnet/config`). Questo può essere cambiato con i flag `–conf` e `–lightning-dir`. + + + +``` +~/.lightning/testnet$ ls -la config +-rw-rw-r-- 1 user user 267 jul 12 17:08 config +``` + + +C'è anche un file di configurazione generale (predefinito: `~/.lightning/config`). Se vuoi eseguire diversi tipi di nodi contemporaneamente, devi lasciare il flag testnet (o regtest) fuori da questo file di configurazione. Dovresti quindi scegliere se stai usando il mainnet, il testnet o il tuo regtest ogni volta che esegui `lightningd` o `lightning-cli`. + +Il tuo setup potrebbe non avere effettivamente file di configurazione: c-lightning funzionerà con un buon setup predefinito senza di essi. + +## Sommario: Verificare la Configurazione Lightning + +Prima di iniziare a giocare con lightning, dovresti assicurarti che i tuoi alias siano impostati, che il tuo `lightningd` sia in esecuzione e che il tuo nodo sia sincronizzato. Potresti anche voler configurare qualche accesso a setup di lightning alternativi, su altre reti. + +## Cosa segue? + +Continua "Understanding Your Lightning Setup" col [Capitolo 19.2: Comprendere la ConfigurazioneLightning](19_2_Comprendere_la_Configurazione_Lightning.md). + +## Variante: Installare da Ubuntu ppa + +Se stai usando una versione di Ubuntu diversa da Debian, puoi installare c-lightning usando [Ubuntu ppa](https://launchpad.net/~lightningnetwork/+archive/ubuntu/ppa): + + + +``` +$ sudo apt-get install -y software-properties-common +$ sudo add-apt-repository -u ppa:lightningnetwork/ppa +$ sudo apt-get install lightningd +``` + + +## Variante: Installare Binaries Precompilati + +Un altro metodo per installare Lightning è usare i binaries precompilati sul [repo di Github](https://github.com/ElementsProject/lightning/releases). Scegli l'ultima tarball, come `clightning-v0.9.1-Ubuntu-20.04.tar.xz`. + +Dopo averlo scaricato, devi spostarti nella directory root e decomprimerlo: + + + +``` +$ cd / +$ sudo tar xf ~/clightning-v0.9.1-Ubuntu-20.04.tar.xz +``` + + +Attenzione: questo richiederà che tu abbia le stesse librerie precise utilizzate per creare il binary. Spesso è più facile ricompilare. diff --git a/it/19_2_Comprendere_la_Configurazione_Lightning.md b/it/19_2_Comprendere_la_Configurazione_Lightning.md new file mode 100644 index 000000000..4d7359137 --- /dev/null +++ b/it/19_2_Comprendere_la_Configurazione_Lightning.md @@ -0,0 +1,352 @@ +# 19.2: Comprendere la Configurazione Lightning + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore attenzione. + +Prima di iniziare ad accedere alla Lightning Network, dovresti avere una migliore comprensione del tuo setup. + +## Conosci la tua Directory di c-lightning + +Quando utilizzi c-lightning, tutto è conservato nella directory `~/.lightning`. + +La directory principale contiene solo le directory per le reti configurate, in questo caso testnet: + + + +``` +$ ls ~/.lightning +testnet +``` + + +La directory `~/.lightning/testnet` conterrà quindi il nucleo del tuo setup: + + +``` +$ ls ~/.lightning/testnet3 +config gossip_store hsm_secret lightningd.sqlite3 lightningd.sqlite3-journal lightning-rpc +``` + + +> :link: **TESTNET vs MAINNET:** Se stai usando mainnet, allora _tutto_ sarà invece posizionato nella directory principale `~/.lightning/bitcoin`. Questi vari setup si sovrappongono elegantemente, quindi se stai usando mainnet, testnet e regtest, troverai che `~/.lightning/bitcoin` contiene il tuo file di configurazione e i dati del mainnet, la directory `~/.lightning/testnet` contiene i tuoi dati del testnet e la directory `~/.lightning/regtest` contiene i tuoi dati del regtest. + +## Conosci i tuoi Comandi di lightning-cli + +La maggior parte del tuo lavoro iniziale sarà fatto con il comando `lightning-cli`, che offre un'interfaccia semplice a `lightningd`, proprio come fa `bitcoin-cli`. + +Hai già visto che il comando `help` ti fornisce un elenco di altri comandi: + + +``` +$ lightning-cli help +lightning-cli: WARNING: default network changing in 2020: please set network=testnet in config! +=== bitcoin === + +feerates style + Return feerate estimates, either satoshi-per-kw ({style} perkw) or satoshi-per-kb ({style} perkb). + +newaddr [addresstype] + Get a new {bech32, p2sh-segwit} (or all) address to fund a channel (default is bech32) + +reserveinputs outputs [feerate] [minconf] [utxos] + Reserve inputs and pass back the resulting psbt + +sendpsbt psbt + Finalize, extract and send a PSBT. + +signpsbt psbt + Sign this wallet's inputs on a provided PSBT. + +txdiscard txid + Abandon a transaction created by txprepare + +txprepare outputs [feerate] [minconf] [utxos] + Create a transaction, with option to spend in future (either txsend and txdiscard) + +txsend txid + Sign and broadcast a transaction created by txprepare + +unreserveinputs psbt + Unreserve inputs, freeing them up to be reused + +withdraw destination satoshi [feerate] [minconf] [utxos] + Send to {destination} address {satoshi} (or 'all') amount via Bitcoin transaction, at optional {feerate} + +=== channels === + +close id [unilateraltimeout] [destination] [fee_negotiation_step] + Close the channel with {id} (either peer ID, channel ID, or short channel ID). Force a unilateral close after {unilateraltimeout} seconds (default 48h). If {destination} address is provided, will be used as output address. + +fundchannel_cancel id + Cancel inflight channel establishment with peer {id}. + +fundchannel_complete id txid txout + Complete channel establishment with peer {id} for funding transactionwith {txid}. Returns true on success, false otherwise. + +fundchannel_start id amount [feerate] [announce] [close_to] [push_msat] + Start fund channel with {id} using {amount} satoshis. Returns a bech32 address to use as an output for a funding transaction. + +getroute id msatoshi riskfactor [cltv] [fromid] [fuzzpercent] [exclude] [maxhops] + Show route to {id} for {msatoshi}, using {riskfactor} and optional {cltv} (default 9). If specified search from {fromid} otherwise use this node as source. Randomize the route with up to {fuzzpercent} (default 5.0). {exclude} an array of short-channel-id/direction (e.g. [ '564334x877x1/0', '564195x1292x0/1' ]) or node-id from consideration. Set the {maxhops} the route can take (default 20). + +listchannels [short_channel_id] [source] + Show channel {short_channel_id} or {source} (or all known channels, if not specified) + +listforwards + List all forwarded payments and their information + +setchannelfee id [base] [ppm] + Sets specific routing fees for channel with {id} (either peer ID, channel ID, short channel ID or 'all'). Routing fees are defined by a fixed {base} (msat) and a {ppm} (proportional per millionth) value. If values for {base} or {ppm} are left out, defaults will be used. {base} can also be defined in other units, for example '1sat'. If {id} is 'all', the fees will be applied for all channels. + +=== network === + +connect id [host] [port] + Connect to {id} at {host} (which can end in ':port' if not default). {id} can also be of the form id@host + +disconnect id [force] + Disconnect from {id} that has previously been connected to using connect; with {force} set, even if it has a current channel + +listnodes [id] + Show node {id} (or all, if no {id}), in our local network view + +listpeers [id] [level] + Show current peers, if {level} is set, include logs for {id} + +ping id [len] [pongbytes] + Send peer {id} a ping of length {len} (default 128) asking for {pongbytes} (default 128) + +=== payment === + +createonion hops assocdata [session_key] + Create an onion going through the provided nodes, each with its own payload + +decodepay bolt11 [description] + Decode {bolt11}, using {description} if necessary + +delexpiredinvoice [maxexpirytime] + Delete all expired invoices that expired as of given {maxexpirytime} (a UNIX epoch time), or all expired invoices if not specified + +delinvoice label status + Delete unpaid invoice {label} with {status} + +invoice msatoshi label description [expiry] [fallbacks] [preimage] [exposeprivatechannels] + Create an invoice for {msatoshi} with {label} and {description} with optional {expiry} seconds (default 1 week), optional {fallbacks} address list(default empty list) and optional {preimage} (default autogenerated) + +listinvoices [label] + Show invoice {label} (or all, if no {label}) + +listsendpays [bolt11] [payment_hash] + Show sendpay, old and current, optionally limiting to {bolt11} or {payment_hash}. + +listtransactions + List transactions that we stored in the wallet + +sendonion onion first_hop payment_hash [label] [shared_secrets] [partid] + Send a payment with a pre-computed onion. + +sendpay route payment_hash [label] [msatoshi] [bolt11] [payment_secret] [partid] + Send along {route} in return for preimage of {payment_hash} + +waitanyinvoice [lastpay_index] [timeout] + Wait for the next invoice to be paid, after {lastpay_index} (if supplied). If {timeout} seconds is reached while waiting, fail with an error. + +waitinvoice label + Wait for an incoming payment matching the invoice with {label}, or if the invoice expires + +waitsendpay payment_hash [timeout] [partid] + Wait for payment attempt on {payment_hash} to succeed or fail, but only up to {timeout} seconds. + +=== plugin === + +autocleaninvoice [cycle_seconds] [expired_by] + Set up autoclean of expired invoices. + +estimatefees + Get the urgent, normal and slow Bitcoin feerates as sat/kVB. + +fundchannel id amount [feerate] [announce] [minconf] [utxos] [push_msat] + Fund channel with {id} using {amount} (or 'all'), at optional {feerate}. Only use outputs that have {minconf} confirmations. + +getchaininfo + Get the chain id, the header count, the block count, and whether this is IBD. + +getrawblockbyheight height + Get the bitcoin block at a given height + +getutxout txid vout + Get informations about an output, identified by a {txid} an a {vout} + +listpays [bolt11] + List result of payment {bolt11}, or all + +pay bolt11 [msatoshi] [label] [riskfactor] [maxfeepercent] [retry_for] [maxdelay] [exemptfee] + Send payment specified by {bolt11} with {amount} + +paystatus [bolt11] + Detail status of attempts to pay {bolt11}, or all + +plugin subcommand=start|stop|startdir|rescan|list + Control plugins (start, stop, startdir, rescan, list) + +sendrawtransaction tx + Send a raw transaction to the Bitcoin network. + +=== utility === + +check command_to_check + Don't run {command_to_check}, just verify parameters. + +checkmessage message zbase [pubkey] + Verify a digital signature {zbase} of {message} signed with {pubkey} + +getinfo + Show information about this node + +getlog [level] + Show logs, with optional log {level} (info|unusual|debug|io) + +getsharedsecret point + Compute the hash of the Elliptic Curve Diffie Hellman shared secret point from this node private key and an input {point}. + +help [command] + List available commands, or give verbose help on one {command}. + +listconfigs [config] + List all configuration options, or with [config], just that one. + +listfunds + Show available funds from the internal wallet + +signmessage message + Create a digital signature of {message} + +stop + Shut down the lightningd process + +waitblockheight blockheight [timeout] + Wait for the blockchain to reach {blockheight}, up to {timeout} seconds. + +=== developer === + +dev-listaddrs [bip32_max_index] + Show addresses list up to derivation {index} (default is the last bip32 index) + +dev-rescan-outputs + Synchronize the state of our funds with bitcoind + +--- +run `lightning-cli help ` for more information on a specific command +``` + +## Conosci le tue Informazioni su Lightning + +Una varietà di comandi `lightning-cli` può fornirti ulteriori informazioni sul tuo nodo Lightning. I più generali sono: + + +``` +$ lightning-cli --testnet listconfigs +$ lightning-cli --testnet listfunds +$ lightning-cli --testnet listtransactions +$ lightning-cli --testnet listinvoices +$ lightning-cli --testnet listnodes +``` + +* listconfigs: Il comando RPC `listconfigs` elenca tutte le opzioni di configurazione. +* listfunds: Il comando RPC `listfunds` visualizza tutti i fondi disponibili, sia in output non spesi (UTXOs) nel portafoglio interno, sia i fondi bloccati nei canali attualmente aperti. +* listtransactions: Il comando RPC `listtransactions` restituisce le transazioni tracciate nel portafoglio. Questo include depositi, prelievi e transazioni relative ai canali. +* listinvoices: Il comando RPC `listinvoices` recupera lo stato di una specifica fattura, se esiste, o lo stato di tutte le fatture se non viene fornito alcun argomento. +* listnodes: Il comando RPC `listnodes` restituisce i nodi che il tuo server ha appreso tramite messaggi di gossip, o un singolo nodo se è stato specificato l'ID del nodo. + +Ad esempio, `lightning-cli listconfigs` ti fornisce una varietà di informazioni sul tuo setup: + + +``` +c$ lightning-cli --testnet listconfigs +{ + "# version": "v0.8.2-398-g869fa08", + "lightning-dir": "/home/standup/.lightning", + "network": "testnet", + "allow-deprecated-apis": true, + "rpc-file": "lightning-rpc", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/fundchannel", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/autoclean", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/bcli", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/pay", + "plugin": "/usr/local/bin/../libexec/c-lightning/plugins/keysend", + "plugins": [ + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/fundchannel", + "name": "fundchannel" + }, + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/autoclean", + "name": "autoclean", + "options": { + "autocleaninvoice-cycle": null, + "autocleaninvoice-expired-by": null + } + }, + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/bcli", + "name": "bcli", + "options": { + "bitcoin-datadir": null, + "bitcoin-cli": null, + "bitcoin-rpcuser": null, + "bitcoin-rpcpassword": null, + "bitcoin-rpcconnect": null, + "bitcoin-rpcport": null, + "bitcoin-retry-timeout": null, + "commit-fee": "500" + } + }, + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/pay", + "name": "pay" + }, + { + "path": "/usr/local/bin/../libexec/c-lightning/plugins/keysend", + "name": "keysend" + } + ], + "disable-plugin": [], + "always-use-proxy": false, + "daemon": "false", + "wallet": "sqlite3:///home/user/.lightning/testnet/lightningd.sqlite3", + "wumbo": false, + "wumbo": false, + "rgb": "03fce2", + "alias": "learningBitcoin", + "pid-file": "/home/user/.lightning/lightningd-testnet.pid", + "ignore-fee-limits": false, + "watchtime-blocks": 144, + "max-locktime-blocks": 720, + "funding-confirms": 3, + "commit-fee-min": 200, + "commit-fee-max": 2000, + "cltv-delta": 6, + "cltv-final": 10, + "commit-time": 10, + "fee-base": 1, + "rescan": 15, + "fee-per-satoshi": 10, + "max-concurrent-htlcs": 483, + "min-capacity-sat": 10000, + "offline": "false", + "autolisten": true, + "disable-dns": "false", + "enable-autotor-v2-mode": "false", + "encrypted-hsm": false, + "rpc-file-mode": "0600", + "log-level": "DEBUG", + "log-prefix": "lightningd" +} +``` +## Sommario: Conoscere il Tuo Setup Lightning + +La directory `~/.lightning` contiene tutti i tuoi file, mentre `lightning-cli help` e una varietà di comandi informativi possono essere utilizzati per ottenere maggiori informazioni su come funziona il tuo setup e la Lightning Network. + +## Cosa Fare Dopo? + +Avrai bisogno di un secondo nodo Linode per testare il pagamento effettivo delle fatture. Se hai bisogno di supporto per configurarlo, leggi [Interludio: Intermezzo Accedere ad un Secondo Nodo Lightning](19_2_Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning.mdd). + +Altrimenti, continua col argomento "Comprendere il Tuo Setup Lightning" nel [Capitolo 19.3: Creare un Canale in Lightning](19_3_Creare_un_Canale_in_Lightning.md). diff --git a/it/19_2_Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning.md b/it/19_2_Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning.md new file mode 100644 index 000000000..878e8395f --- /dev/null +++ b/it/19_2_Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning.md @@ -0,0 +1,407 @@ +# Intermezzo: Accedere ad un Secondo Nodo Lightning + +> :information_source: **NOTE:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Quando hai giocato con Bitcoin, stavi accedendo a una rete esistente, e questo ha reso relativamente facile lavorarci: basta accendere `bitcoind` e interagisci immediatamente con la rete. Questo non è il modo in cui funziona Lightning: è fondamentalmente una rete peer-to-peer, costruita dalle connessioni tra due nodi individuali. In altre parole, per interagire con la rete Lightning, devi prima trovare un nodo a cui connetterti. + +Ci sono quattro modi per farlo (i primi tre dei quali sono possibili per la tua prima connessione): + +## Chiedere Informazioni su un Nodo + +Se qualcun altro ha già un nodo Lightning sulla rete di tua scelta, chiedi loro il loro ID. + +Se stanno eseguendo c-lightning, devono solo usare il comando `getinfo`: + + + +``` +$ lightning-cli getinfo +lightning-cli: WARNING: default network changing in 2020: please set network=testnet in config! + "id": "03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687", + "alias": "VIOLETGLEE", + "color": "03240a", + "num_peers": 0, + "num_pending_channels": 0, + "num_active_channels": 0, + "num_inactive_channels": 0, + "address": [ + { + "type": "ipv4", + "address": "74.207.240.32", + "port": 9735 + } + ], + "binding": [ + { + "type": "ipv6", + "address": "::", + "port": 9735 + }, + { + "type": "ipv4", + "address": "0.0.0.0", + "port": 9735 + } + ], + "version": "v0.9.1-96-g6f870df", + "blockheight": 1862854, + "network": "testnet", + "msatoshi_fees_collected": 0, + "fees_collected_msat": "0msat", + "lightning-dir": "/home/standup/.lightning/testnet" +} +``` + +Poi possono dirti il loro `id` (`03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687`). Dovranno anche dirti il loro indirizzo IP (`74.207.240.32`) e la porta (`9735`). + +## Creare un Nuovo Nodo c-lightning + +Tuttavia, per scopi di test, probabilmente vorrai avere un secondo nodo sotto il tuo controllo. Il modo più semplice per farlo è creare un secondo nodo c-lightning su una nuova macchina, utilizzando Bitcoin Standup, vedi il [Capitolo 2.1](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md) o compilandolo a mano, vedi il [Capitolo 19.1](19_1_Verificare_la_Configurazione_Lightning.md). + +Una volta che il tuo nodo è in esecuzione, puoi eseguire `getinfo` per recuperare le tue informazioni, come mostrato sopra. + +## Creare un Nuovo Nodo LND + +Tuttavia, per i nostri esempi nel prossimo capitolo, creeremo invece un nodo LND. Questo ci permetterà di dimostrare un po' della profondità dell'ecosistema Lightning mostrando come funzionano comandi simili sulle due diverse piattaforme. + +Un modo per creare un nodo LND è eseguire di nuovo gli Script Bitcoin Standup su una nuova macchina, ma questa volta scegliere LND, vedi il [Capitolo 2.1](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md). + +Un altro modo è compilare LND dal codice sorgente su una macchina dove stai già eseguendo un nodo Bitcoin, come segue. + +### Compilare il Codice Sorgente di LND + +Prima, devi scaricare e installare Go: + + +``` +$ wget --progress=bar:force https://dl.google.com/go/"go1.14.4"."linux"-"amd64".tar.gz -O ~standup/"go1.14.4"."linux"-"amd64".tar.gz +$ /bin/tar xzf ~standup/"go1.14.4"."linux"-"amd64".tar.gz -C ~standup +$ sudo mv ~standup/go /usr/local +``` + + +Assicurati che la versione di Go sia la più aggiornata (è `go1.14.4` al momento attuale), e che la piattaforma e l'architettura siano corrette per la tua macchina. (Quanto sopra funzionerà per Debian.) + +Aggiorna il tuo percorso: + + +``` +$ export GOPATH=~standup/gocode +$ export PATH="$PATH":/usr/local/go/bin:"$GOPATH"/bin +``` + + +Poi assicurati che `go` funzioni: + + +``` +$ go version +go version go1.14.4 linux/amd64 +``` + + +Avrai anche bisogno di `git` e `make`: + + +``` +$ sudo apt-get install git +$ sudo apt-get install build-essential +``` + + +Ora sei pronto per recuperare LND. Assicurati di ottenere la versione corrente (attualmente `v0.11.0-beta.rc4`). + + +``` +$ go get -d github.com/lightningnetwork/lnd +``` + + +E ora puoi compilare: + + +``` +$ cd "$GOPATH"/src/github.com/lightningnetwork/lnd +$ git checkout v0.11.0-beta.rc4 +$ make +$ make install + +``` +Questo verrà installato in `~/gocode/bin`, che è `$GOPATH/bin`. + +Dovresti spostarlo nelle directory globali: + + + +``` +$ sudo cp $GOPATH/bin/lnd $GOPATH/bin/lncli /usr/bin +``` + + +### Creare un File di Configurazione LND + +A differenza di c-lightning, dovrai creare un file di configurazione predefinito per LND. + +Tuttavia, prima, devi abilitare ZMQ sul tuo Bitcoind, se non l'hai già fatto nel [Capitolo 16.3](16_3_Ricevere_Notifiche_di_Bitcoind_in_C_tramite_Librerie_ZMQ.md). + +Questo richiede di aggiungere il seguente al tuo file `~/.bitcoin/bitcoin.conf` se non è già lì: + + + +``` +zmqpubrawblock=tcp://127.0.0.1:28332 +zmqpubrawtx=tcp://127.0.0.1:28333 +``` + + +Se stai usando un file di configurazione Bitcoin da Standup o un altro `conf` specializzato, assicurati di mettere i tuoi nuovi comandi nella sezione corretta. Idealmente, dovrebbero andare vicino alla parte superiore del file, altrimenti nella sezione `[test]` (supponendo, come al solito, che stai testando su testnet). + +Devi quindi riavviare bitcoin (o semplicemente riavviare la tua macchina). Puoi testare che stia funzionando come segue: + + +``` +$ bitcoin-cli getzmqnotifications +[ + { + "type": "pubrawblock", + "address": "tcp://127.0.0.1:28332", + "hwm": 1000 + }, + { + "type": "pubrawtx", + "address": "tcp://127.0.0.1:28333", + "hwm": 1000 + } +] +``` + + +Ora sei pronto per creare un file di configurazione. + +Prima, devi recuperare il tuo rpcuser e rpcpassword. Ecco un modo automatico per farlo: + + + +``` +$ BITCOINRPC_USER=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcuser | awk -F = '{print $2}') +$ BITCOINRPC_PASS=$(cat ~standup/.bitcoin/bitcoin.conf | grep rpcpassword | awk -F = '{print $2}') +``` + + +> :warning: **WARNING:** Ovviamente, non memorizzare mai la tua password RPC in una variabile di shell in un ambiente di produzione. + +Poi, puoi scrivere il file: + + + +``` +$ mkdir ~/.lnd +$ cat > ~/.lnd/lnd.conf << EOF +[Application Options] +maxlogfiles=3 +maxlogfilesize=10 +#externalip=1.1.1.1 # change to your public IP address if required. +alias=StandUp +listen=0.0.0.0:9735 +debuglevel=debug +[Bitcoin] +bitcoin.active=1 +bitcoin.node=bitcoind +bitcoin.testnet=true +[Bitcoind] +bitcoind.rpchost=localhost +bitcoind.rpcuser=$BITCOINRPC_USER +bitcoind.rpcpass=$BITCOINRPC_PASS +bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 +bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 +EOF +``` + + +### Creare un Servizio LND + +Infine, puoi creare un servizio LND per eseguire automaticamente `lnd`: + + + +``` +$ cat > ~/lnd.service << EOF +# It is not recommended to modify this file in-place, because it will +# be overwritten during package upgrades. If you want to add further +# options or overwrite existing ones then use +# $ systemctl edit lnd.service +# See "man systemd.service" for details. +# Note that almost all daemon options could be specified in +# /etc/lnd/lnd.conf, except for those explicitly specified as arguments +# in ExecStart= +[Unit] +Description=LND Lightning Network Daemon +Requires=bitcoind.service +After=bitcoind.service +[Service] +ExecStart=/usr/bin/lnd +ExecStop=/usr/bin/lncli --lnddir /var/lib/lnd stop +PIDFile=/run/lnd/lnd.pid +User=standup +Type=simple +KillMode=process +TimeoutStartSec=60 +TimeoutStopSec=60 +Restart=always +RestartSec=60 +[Install] +WantedBy=multi-user.target +EOF +``` +> (Non è consigliato modificare questo file sul posto, perché verrà +sovrascritto durante gli aggiornamenti dei pacchetti. Se vuoi aggiungere ulteriori +opzioni o sovrascrivere quelle esistenti, utilizza +$ systemctl edit lnd.service +Vedi "man systemd.service" per dettagli. +Nota che quasi tutte le opzioni del demone potrebbero essere specificate in +/etc/lnd/lnd.conf, eccetto quelle esplicitamente specificate come argomenti) + + +Poi devi installarlo e avviarlo: + + +``` +$ sudo cp ~/lnd.service /etc/systemd/system +$ sudo systemctl enable lnd +$ sudo systemctl start lnd +``` +(Prevedi che questo richieda un minuto la prima volta.) + +### Abilitare Connessioni Remote + +Proprio come con c-lightning, dovrai rendere LND accessibile ad altri nodi. Ecco come farlo se usi `ufw`, come nei setup Bitcoin Standup: + + + +``` +$ sudo ufw allow 9735 +``` + + +### Creare un Wallet + +La prima volta che esegui LND, devi creare un wallet: + + + +``` +$ lncli --network=testnet create +``` + + +LND ti chiederà una password e poi se vuoi inserire una mnemonic esistente (basta premere `n` per quest'ultima). + +Ora dovresti avere un `lnd` funzionante, che puoi verificare con `getinfo`: + + + +``` +$ lncli --network=testnet getinfo +{ + "version": "0.11.0-beta.rc4 commit=v0.11.0-beta.rc4", + "commit_hash": "fc12656a1a62e5d69430bba6e4feb8cfbaf21542", + "identity_pubkey": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "alias": "StandUp", + "color": "#3399ff", + "num_pending_channels": 0, + "num_active_channels": 0, + "num_inactive_channels": 0, + "num_peers": 2, + "block_height": 1862848, + "block_hash": "000000000000000ecb6fd95e1f486283d48683aa3111b6c23144a2056f5a1532", + "best_header_timestamp": "1602632294", + "synced_to_chain": true, + "synced_to_graph": false, + "testnet": true, + "chains": [ + { + "chain": "bitcoin", + "network": "testnet" + } + ], + "uris": [ + ], + "features": { + "0": { + "name": "data-loss-protect", + "is_required": true, + "is_known": true + }, + "5": { + "name": "upfront-shutdown-script", + "is_required": false, + "is_known": true + }, + "7": { + "name": "gossip-queries", + "is_required": false, + "is_known": true + }, + "9": { + "name": "tlv-onion", + "is_required": false, + "is_known": true + }, + "13": { + "name": "static-remote-key", + "is_required": false, + "is_known": true + }, + "15": { + "name": "payment-addr", + "is_required": false, + "is_known": true + }, + "17": { + "name": "multi-path-payments", + "is_required": false, + "is_known": true + } + } +} +``` + + +L'ID di questo nodo è `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543`. Sebbene questo comando non mostri l'indirizzo IP e la porta, dovrebbero essere l'indirizzo IP della tua macchina e la porta `9735`. + +## Ascoltare i Gossip + +Se eri già connesso alla rete Lightning e stavi "spettegolando" con i peer, potresti anche essere in grado di trovare informazioni sui peer automaticamente, tramite il comando `listpeers`: + + + +``` +c$ lightning-cli --network=testnet listpeers +{ + "peers": [ + { + "id": "0302d48972ba7eef8b40696102ad114090fd4c146e381f18c7932a2a1d73566f84", + "connected": true, + "netaddr": [ + "127.0.0.1:9736" + ], + "features": "02a2a1", + "channels": [] + } + ] +} +``` + + +Tuttavia, sicuramente non sarà il caso della tua prima interazione con la rete Lightning. + +## Sommario: Accesso a un Secondo Nodo Lightning + +Hai sempre bisogno di due nodi Lightning per formare un canale. Se non hai qualcun altro che sta testando con te, dovrai creare un secondo nodo, utilizzando c-lightning o (come faremo nei nostri esempi) LND. + +## Cosa Succede Dopo? + +Anche se hai eventualmente creato un LND, c-lightning rimarrà il cuore dei nostri esempi fino a quando non sarà necessario usare entrambi, in [Capitolo 19](19_0_Understanding_Your_Lightning_Setup.md). + +Continua a "Understanding Your Lightning Setup" nel [Capitolo 19.3: Creare un Canale in Lightning](19_3_Creare_un_Canale_in_Lightning.md). + diff --git a/it/19_3_Creare_un_Canale_in_Lightning.md b/it/19_3_Creare_un_Canale_in_Lightning.md new file mode 100644 index 000000000..80e1156fc --- /dev/null +++ b/it/19_3_Creare_un_Canale_in_Lightning.md @@ -0,0 +1,201 @@ +# 19.3: Creating a Lightning Channel + +> :information_source: **NOTE:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Ora comprendi le basi della tua configurazione Lightning e, si spera, hai creato o ricevuto informazioni su un secondo nodo Lightning. Sei pronto per creare il tuo primo canale della rete Lightning. Ovviamente, dovrai capire cos'è e come viene creato utilizzando c-lightning. + +> :book: ***Cos'è un Canale Lightning?*** In poche parole, un canale lightning è un tubo di denaro che consente trasferimenti di denaro veloci, economici e privati senza inviare transazioni alla blockchain. Più tecnicamente, un canale è una transazione Bitcoin multisignatura 2-of-2 on-chain che stabilisce una relazione finanziaria senza fiducia tra due persone o due agenti. Una certa quantità di denaro viene depositata nel canale, che poi mantiene un database locale con il saldo bitcoin per entrambe le parti, tenendo traccia di quanto denaro ciascuno ha dall'importo iniziale. I due utenti possono quindi scambiarsi bitcoin attraverso il loro canale Lightning senza mai scrivere sulla blockchain di Bitcoin. Solo quando vogliono chiudere il loro canale regolano i loro bitcoin sulla blockchain, in base alla divisione finale delle monete. + +> :book: ***Come Creano i Canali Lightning una Rete Lightning?*** Anche se un canale Lightning consente il pagamento solo tra due utenti, i canali possono essere collegati insieme per formare una rete che consente pagamenti tra membri che non hanno un canale diretto tra loro. Questo crea una rete tra più persone costruita da connessioni a coppie. + +In questa sezione, continueremo a utilizzare la nostra configurazione c-lightning come nodo principale. + +## Creare un Canale + +Creare un canale Lightning richiede i seguenti passaggi: + +* Finanziare il tuo wallet c-lightning con alcuni satoshi. +* Connettersi a un nodo remoto come peer. +* Aprire un canale. + +### Finanziare il Tuo Wallet c-lightning + +Per spostare fondi su un canale Lightning è necessario prima finanziare il tuo wallet c-lightning. + +> :book: ***Cos'è un wallet c-lightning?*** L'implementazione standard di c-lightning viene fornita con un wallet Bitcoin integrato che ti consente di inviare e ricevere transazioni bitcoin on-chain. Questo wallet verrà utilizzato per creare nuovi canali. + +La prima cosa che devi fare è inviare alcuni satoshi al tuo wallet c-lightning. Puoi creare un nuovo indirizzo usando il comando `lightning-cli newaddr`. Questo genera un nuovo indirizzo che può successivamente essere utilizzato per finanziare i canali gestiti dal nodo c-lightning. Puoi specificare il tipo di indirizzo desiderato; se non specificato, l'indirizzo generato sarà un bech32. + + + +``` +$ lightning-cli --testnet newaddr +{ + "address": "tb1qefule33u7ukfuzkmxpz02kwejl8j8dt5jpgtu6", + "bech32": "tb1qefule33u7ukfuzkmxpz02kwejl8j8dt5jpgtu6" +} +``` + +Puoi quindi inviare fondi a questo indirizzo utilizzando `bitcoin-cli sendtoaddress` (o qualsiasi altra metodologia preferita). Per questo esempio, lo abbiamo fatto nella transazione [11094bb9ac29ce5af9f1e5a0e4aac2066ae132f25b72bff90fcddf64bf2feb02](https://blockstream.info/testnet/tx/11094bb9ac29ce5af9f1e5a0e4aac2066ae132f25b72bff90fcddf64bf2feb02). + +Questa transazione è chiamata [transazione di finanziamento](https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#funding-transaction-output), e deve essere confermata prima che i fondi possano essere utilizzati. + +> :book: ***Cos'è una Transazione di Finanziamento?*** Una transazione di finanziamento è una transazione Bitcoin che deposita denaro in un canale Lightning. Può essere finanziata singolarmente (da un partecipante) o congiuntamente (da entrambi). Da lì in poi, le transazioni Lightning riguardano tutte il riassegnare la proprietà della transazione di finanziamento, ma si regolano sulla blockchain solo quando il canale viene chiuso. + +Per controllare il tuo saldo locale dovresti usare il comando `lightning-cli listfunds`: + + + +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [], + "channels": [] +} +``` + + +Poiché i fondi non hanno ancora sei conferme, non c'è alcun saldo disponibile. Dopo sei conferme dovresti vedere un saldo: + +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "11094bb9ac29ce5af9f1e5a0e4aac2066ae132f25b72bff90fcddf64bf2feb02", + "output": 0, + "value": 300000, + "amount_msat": "300000000msat", + "scriptpubkey": "0014ca79fcc63cf72c9e0adb3044f559d997cf23b574", + "address": "tb1qefule33u7ukfuzkmxpz02kwejl8j8dt5jpgtu6", + "status": "confirmed", + "blockheight": 1780680, + "reserved": false + } + ], + "channels": [] +} + +``` +Nota che il valore è elencato in satoshi o microsatoshi, non Bitcoin! + +> :book: ***Cosa sono i satoshi e gli msat?*** Hai già incontrato i satoshi molto tempo fa nel [Capitolo 3.4](03_4_Ricevere_una_Transazione.md). Un satoshi è un centomilionesimo di bitcoin, quindi 300.000 satoshi = 0,003 BTC. Un satoshi è la più piccola unità di valuta sulla rete Bitcoin. Ma, la rete Lightning può andare oltre, quindi 1.000 msat, o millisatoshi, equivalgono a un satoshi. Ciò significa che 1 msat è un centomiliardesimo di bitcoin, e 300.000.000 msat = 0,003 BTC. + +Ora che hai finanziato il tuo wallet c-lightning avrai bisogno di informazioni su un nodo remoto per iniziare il processo di creazione del canale. + +### Connettersi a un Nodo Remoto + +La prossima cosa che devi fare è connettere il tuo nodo a un peer. Questo viene fatto con il comando `lightning-cli connect`. Ricorda che se vuoi maggiori informazioni su questo comando, dovresti digitare `lightning-cli help connect`. + +Per connettere il tuo nodo a un peer remoto hai bisogno del suo id, che rappresenta la chiave pubblica del nodo di destinazione. Per comodità, `id` può essere della forma `id@host` o `id@host:port`. Potresti averlo recuperato con `lightning-cli getinfo` (su c-lightning) o `lncli --network=testnet getinfo` (su LND) come discusso nel [precedente interludio](19_2_Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning.md). + +Abbiamo selezionato il nodo LND, `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543`, che si trova all'indirizzo IP `45.33.35.151`, a cui ci connetteremo dal nostro nodo c-lightning: + + + +``` +$ lightning-cli --network=testnet connect 032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543@45.33.35.151 +{ + "id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "features": "02a2a1" +} +``` + + +### Aprire un Canale + +Il comando RPC fundchannel apre un canale di pagamento con un peer impegnando una transazione di finanziamento sulla blockchain. Dovresti usare il comando `lightning-cli fundchannel` per farlo, con i seguenti parametri: + +* **id** è l'id del peer restituito dalla connessione. +* **amount** è l'importo in satoshi preso dal wallet interno per finanziare il canale. Il valore non può essere inferiore al limite di polvere, attualmente impostato a 546, né superiore a 16.777.215 satoshi (a meno che i canali grandi non siano stati negoziati con il peer). +* **feerate** è una tariffa facoltativa utilizzata per la transazione di apertura e come tariffa iniziale per le transazioni di impegno e HTLC. +* **announce** è un flag facoltativo che determina se annunciare o meno questo canale. Il valore predefinito è true. Se desideri creare un canale privato non annunciato, impostalo su false. +* **minconf** specifica il numero minimo di conferme che devono avere gli output utilizzati nel processo di apertura del canale. Il valore predefinito è 1. +* **utxos** specifica gli utxos da utilizzare per finanziare il canale, come array di “txid:vout”. + +Ora puoi aprire il canale in questo modo: + + + +``` +$ lightning-cli --testnet fundchannel 032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543 100000 urgent true 1 +{ + "tx": "0200000000010193dc3337837f091718f47b71f2eae8b745ec307231471f6a6aab953c3ea0e3b50100000000fdffffff02a0860100000000002200202e30365fe321a435e5f66962492163302f118c13e215ea8928de88cc46666c1d07860100000000001600142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c024730440220668a7c253c9fd83fc1b45e4a52823fb6bc5fad30da36240d4604f0d6981a6f4502202aeb1da5fbbc8790791ef72b3378005fe98d485d22ffeb35e54a6fbc73178fb2012103b3efe051712e9fa6d90008186e96320491cfe1ef1922d74af5bc6d3307843327c76c1c00", + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "channel_id": "1d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d6966", + "outnum": 0 +} +``` +Per confermare lo stato del canale usa il comando `lightning-cli listfunds`: + + +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "unconfirmed", + "reserved": false + }, + { + "txid": "b5e3a03e3c95ab6a6a1f47317230ec45b7e8eaf2717bf41817097f833733dc93", + "output": 1, + "value": 200000, + "amount_msat": "200000000msat", + "scriptpubkey": "0014ed54b65eae3da99b23a48bf8827c9acd78079469", + "address": "tb1qa42tvh4w8k5ekgay30ugyly6e4uq09rfpqf9md", + "status": "confirmed", + "blockheight": 1862831, + "reserved": true + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_AWAITING_LOCKIN", + "channel_sat": 100000, + "our_amount_msat": "100000000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} + +``` +Mentre questo nuovo canale con 100.000 satoshi è non confermato, il suo stato sarà `CHANNELD_AWAITING_LOCKIN`. Nota che anche il cambio non confermato di `99847` satoshi appare come una nuova transazione nel wallet. Dopo che tutte le sei conferme sono completate, il canale cambierà allo stato `CHANNELD_NORMAL`, che sarà il suo stato permanente. A questo punto, apparirà anche un `short_channel_id`, come: + +``` + "short_channel_id": "1862856x29x0", +``` + +Questi valori indicano dove si trova la transazione di finanziamento sulla blockchain. Si presenta nella forma `block x txid x vout`. + +In questo caso, `1862856x29x0` significa: + +* Creato nel blocco 1862856; +* con un `txid` di 29; e +* un `vout` di 0. + +Potresti aver bisogno di utilizzare questo `short_channel_id` per determinati comandi in Lightning. + +Questa transazione di finanziamento può anche essere trovata onchain su [66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d](https://blockstream.info/testnet/tx/66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d) + +> :book: ***Cos'è la Capacità del Canale?*** In un canale Lightning, entrambe le parti del canale possiedono una parte della sua capacità. L'importo sul tuo lato del canale è chiamato *saldo locale* e l'importo sul lato del tuo peer è chiamato *saldo remoto*. Entrambi i saldi possono essere aggiornati molte volte senza chiudere il canale (quando il saldo finale viene inviato alla blockchain), ma la capacità del canale non può cambiare senza chiuderlo o modificarlo. La capacità totale di un canale è la somma del saldo detenuto da ciascun partecipante nel canale. + +## Sommario: Creazione di un Canale + +Devi creare un canale con un nodo remoto per poter ricevere e inviare denaro sulla rete Lightning. + +## Cosa Succede Dopo? + +Sei pronto per partire! Continua col [Capitolo 20: Usare Lightning](20_0_Usare_Lightning.md). + diff --git a/it/20_0_Usare_Lightning.md b/it/20_0_Usare_Lightning.md new file mode 100644 index 000000000..79a9de0a8 --- /dev/null +++ b/it/20_0_Usare_Lightning.md @@ -0,0 +1,25 @@ +# Chapter 20: Using Lightning + +> :information_source: **NOTE:** Questo è una bozza in corso, per ottenere feedback dai primi revisori. Non è ancora pronto per l'apprendimento. + +In questo capitolo continuerai a lavorare con l'interfaccia a riga di comando `lightning-cli`. Creerai fatture, eseguirai pagamenti e chiuderai canali, tutte le principali attività per l'utilizzo di Lightning. + +## Obiettivi per Questo Capitolo + +Dopo aver lavorato attraverso questo capitolo, uno sviluppatore sarà in grado di: + + * Eseguire pagamenti sulla rete Lightning. + * Applicare la chiusura a un canale Lightning. + +Gli obiettivi di supporto includono la capacità di: + + * Comprendere il formato delle fatture. + * Comprendere il ciclo di vita dei pagamenti della rete Lightning. + * Sapere come espandere la rete Lightning. + +## Sommario + + * [Capitolo 20.1: Generare una Richiesta di Pagamento](20_1_Generare_una_Richiesta_di_Pagamento.md) + * [Capitolo 20.2: Pagare una Fattura](20_2_Pagare_una_Fattura.md) + * [Capitolo 20.3: Chiudere un Canale Lightning](20_3_Chiudere_un_Canale_Lightning.md) + * [Capitolo 20.4: Espandere la Rete Lightning](20_4_Espandere_la_Rete_Lightning.md) diff --git a/it/20_1_Generare_una_Richiesta_di_Pagamento.md b/it/20_1_Generare_una_Richiesta_di_Pagamento.md new file mode 100644 index 000000000..2565bfd17 --- /dev/null +++ b/it/20_1_Generare_una_Richiesta_di_Pagamento.md @@ -0,0 +1,211 @@ +# 20.1: Generare una Richiesta di Pagamento + +> :information_source: **NOTE:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Questa sezione descrive come funzionano i pagamenti sulla rete Lightning, come creare una richiesta di pagamento (o _fattura_) e infine come interpretarla. L'emissione delle fatture dipende dall'avere un secondo nodo Lightning, come descritto in [Accedere ad un Secondo Nodo Lightning](19_2_Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning.md). Questi esempi utilizzeranno un nodo LND come nodo secondario, per dimostrare ulteriormente le possibilità della rete Lightning. Per differenziare tra i nodi in questi esempi, i prompt saranno mostrati come `c$` per il nodo c-lightning e `lnd$` come il nodo LND. Se vuoi riprodurre questi passaggi, dovresti [installare il tuo nodo LND secondario](19_2_Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning.md#creare-un-nuovo-nodo-lnd). + +> :book: ***Cos'è una Fattura?*** Quasi tutti i pagamenti effettuati sulla rete Lightning richiedono una fattura, che non è altro che una **richiesta di pagamento** fatta dal destinatario del denaro e inviata in vari modi all'utente pagante. Tutte le richieste di pagamento sono a uso singolo. Le fatture Lightning utilizzano la codifica bech32, già utilizzata da Segregated Witness per Bitcoin. + +## Creare una Fattura + +Per creare una nuova fattura su c-lightning dovresti usare il comando `lightning-cli --testnet invoice`. + +Ecco come funzionerebbe con c-lightning, utilizzando argomenti di un importo (in millisatoshi), un'etichetta e una descrizione. + + + +``` +c$ lightning-cli --testnet invoice 100000 joe-payment "The money you owe me for dinner" +{ + "payment_hash": "07a1c4bd7a38b4dea35f301c173cd8f9aac253b66bd8404d7ad829f226342490", + "expires_at": 1603305795, + "bolt11": "lntb1u1p0cw3krpp5q7suf0t68z6dag6lxqwpw0xclx4vy5akd0vyqnt6mq5lyf35yjgqdpj235x2grddahx27fq09hh2gr0wajjqmt9ypnx7u3qv35kumn9wgxqyjw5qcqp2sp5r3puay46tffdyzldjv39fw6tzdgu2hnlszamqhnmgjsuxqxavpgs9qy9qsqatawvx44x5qa22m7td84jau5450v7j6sl5224tlv9k5v7wdygq9qr4drz795lfnl52gklvyvnha5e5lx72lzzmgzcfnp942va5thmhsp5sx7c2", + "warning_capacity": "No channels", + "warning_mpp_capacity": "The total incoming capacity is still insufficient even if the payer had MPP capability." +} +``` + + +Tuttavia, per questo esempio genereremo invece una fattura su un nodo LND e poi la pagheremo sul nodo c-lightning. Questo richiede il comando leggermente diverso `addinvoice` di LND. Puoi usare l'argomento `--amt` per indicare l'importo da pagare (in millisatoshi) e aggiungere una descrizione usando l'argomento `--memo`. + + +``` +lnd$ lncli -n testnet addinvoice --amt 10000 --memo "First LN Payment - Learning Bitcoin and Lightning from the Command line." +{ + "r_hash": "6cacdedc95b89eec15e5244bd0957b88c0ab58b153eee549735b995344bc16bb", + "payment_request": "lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd", + "add_index": "1" +} +``` + + +Nota che queste fatture non fanno direttamente riferimento al canale che hai creato: è necessario per il pagamento, ma non per richiedere il pagamento. + +## Capire una Fattura + +La `bolt11` `payment_request` che hai creato è composta da due parti: una è leggibile dall'uomo e l'altra è costituita da dati. + +> :book: **Cos'è un BOLT?** I BOLT sono le singole [specifiche per la rete Lightning](https://github.com/lightningnetwork/lightning-rfc). + +### Leggere la Parte Leggibile della Fattura + +La parte leggibile della fattura inizia con `ln`. È `lnbc` per Bitcoin mainnet, `lntb` per Bitcoin testnet o `lnbcrt` per Bitcoin regtest. +Poi elenca i fondi richiesti nella fattura. + +Ad esempio, guarda la tua fattura dal nodo LND: + + + +``` +lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd +``` + + +La parte leggibile è `ln` + `tb` + `100u`. + +`lntb` dice che questa è una fattura della rete Lightning per Bitcoin Testnet. + +`100u` dice che è per 100 bitcoin moltiplicati per il moltiplicatore microsatoshi. Ci sono quattro moltiplicatori di fondi (facoltativi): + +* `m` (milli): moltiplica per 0,001 +* `u` (micro): moltiplica per 0,000001 +* `n` (nano): moltiplica per 0,000000001 +* `p` (pico): moltiplica per 0,000000000001 + +100 BTC * 0,000001 = 0,0001 BTC, che è lo stesso di 10.000 satoshi. + +### Leggere la Parte Dati della Fattura + +Il resto della fattura (`1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd`) contiene un timestamp, dati specificamente taggati e una firma. Ovviamente non puoi leggerlo da solo, ma puoi chiedere a `lightning-cli` di c-lightning di farlo con il comando `decodepay`: + + + +``` +c$ lightning-cli --testnet decodepay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd +{ + "currency": "tb", + "created_at": 1602702347, + "expiry": 3600, + "payee": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "msatoshi": 10000000, + "amount_msat": "10000000msat", + "description": "First LN Payment - Learning Bitcoin and Lightning from the Command line.", + "min_final_cltv_expiry": 40, + "payment_secret": "e946403bcb54764994306c743ed3bf1303af8ae6e7687d3cabcc3ee06dbf904d", + "features": "028200", + "payment_hash": "6cacdedc95b89eec15e5244bd0957b88c0ab58b153eee549735b995344bc16bb", + "signature": "304402202e73ebd1ef974594eb117e8301be781f2ba289041ab6abc558d432351d8365e902202a8151c3fd13419b9390c2b976503d2d064f2a6748b14cb0db64424cf4e572f4" +} + +``` + + +Ecco cosa significano gli elementi più rilevanti: + +1. `currency`: La valuta che viene pagata. +2. `created_at`: Tempo in cui è stata creata la fattura. Questo è misurato in tempo UNIX, che sono i secondi dal 1970. +3. `expiry`: Il tempo in cui il tuo nodo segna la fattura come non valida. Il valore predefinito è 1 ora o 3600 secondi. +4. `payee`: La chiave pubblica della persona (nodo) che riceve il pagamento della rete Lightning. +5. `msatoshi` e `amount_msat`: La quantità di satoshi da pagare. +6. `description`: La descrizione inserita dall'utente. +7. `payment_hash`: L'hash del preimage che viene utilizzato per bloccare il pagamento. Puoi riscattare un pagamento bloccato solo con il preimage corrispondente all'hash del pagamento. Questo consente il routing sulla rete Lightning senza dover fidarsi di terze parti, creando un **Pagamento Condizionale** da completare. +8. `signature`: La firma codificata DER. + +> :book: ***Cosa sono i Pagamenti Condizionali?*** Anche se i canali Lightning sono creati tra due partecipanti, più canali possono essere collegati insieme, formando una rete di pagamento che consente pagamenti tra tutti i partecipanti della rete, anche quelli senza un canale diretto tra loro. Questo viene fatto utilizzando un contratto intelligente chiamato **Hashed Time Locked Contract**. + +> :book: ***Cos'è un Hashed Time Locked Contract (HTLC)?*** Un Hashed Time Locked Contract è un pagamento condizionato che utilizza hashlock e timelock per garantire la sicurezza del pagamento. Il destinatario deve presentare un preimage di pagamento o generare una prova crittografica del pagamento prima di un determinato tempo, altrimenti il pagatore può annullare il contratto spendendolo. Questi contratti sono creati come output dalla **Commitment Transaction**. + +> :book: ***Cos'è una Commitment Transaction?*** Una Commitment Transaction è una transazione che spende la transazione di finanziamento originale. Ogni peer detiene la firma dell'altro peer, il che significa che entrambi possono spendere la loro commitment transaction quando vogliono. Dopo che ogni nuova commitment transaction viene creata, quella vecchia viene revocata. La commitment transaction è un modo in cui la transazione di finanziamento può essere sbloccata sulla blockchain, come discusso nel [Capitolo 20.3](20_3_Chiudere_un_Canale_Lightning.md). + +### Controlla la Tua Fattura + +Ci sono due elementi cruciali da controllare nella fattura. Il primo, ovviamente, è l'importo del pagamento, che hai già esaminato nella parte leggibile. Il secondo è il valore `payee`, che è il pubkey del destinatario (nodo): + + + +``` + "payee": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", +``` + + +Devi verificare che sia il destinatario previsto. + +Guardando indietro nel [Capitolo 20.3](20_3_Chiudere_un_Canale_Lightning.md), puoi vedere che è effettivamente l'ID del peer che hai utilizzato quando hai creato il tuo canale. Potresti anche verificarlo sul nodo opposto con il comando `getinfo`. + + + +``` +lnd$ lncli -n testnet getinfo +{ + "version": "0.11.0-beta.rc4 commit=v0.11.0-beta.rc4", + "commit_hash": "fc12656a1a62e5d69430bba6e4feb8cfbaf21542", + "identity_pubkey": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "alias": "StandUp", + "color": "#3399ff", + "num_pending_channels": 0, + "num_active_channels": 1, + "num_inactive_channels": 0, + "num_peers": 3, + "block_height": 1862983, + "block_hash": "00000000000000c8c2f58f6da2ae2a3884d6e84f55d0e1f585a366f9dfcaa860", + "best_header_timestamp": "1602702331", + "synced_to_chain": true, + "synced_to_graph": true, + "testnet": true, + "chains": [ + { + "chain": "bitcoin", + "network": "testnet" + } + ], + "uris": [ + ], + "features": { + "0": { + "name": "data-loss-protect", + "is_required": true, + "is_known": true + }, + "5": { + "name": "upfront-shutdown-script", + "is_required": false, + "is_known": true + }, + "7": { + "name": "gossip-queries", + "is_required": false, + "is_known": true + }, + "9": { + "name": "tlv-onion", + "is_required": false, + "is_known": true + }, + "13": { + "name": "static-remote-key", + "is_required": false, + "is_known": true + }, + "15": { + "name": "payment-addr", + "is_required": false, + "is_known": true + }, + "17": { + "name": "multi-path-payments", + "is_required": false, + "is_known": true + } + } +} +``` + +Tuttavia, il `payee` potrebbe anche essere qualcuno di nuovo, nel qual caso probabilmente dovrai verificare con il sito web o la persona che ha emesso la fattura per assicurarti che sia corretta. + +## Sommario: Generare una Richiesta di Pagamento + +Nella maggior parte dei casi è necessario ricevere una fattura per utilizzare i pagamenti della rete Lightning. In questo esempio ne abbiamo creata una manualmente, ma se avessi un ambiente di produzione, probabilmente avresti sistemi che lo fanno automaticamente ogni volta che qualcuno acquista prodotti o servizi. Ovviamente, una volta ricevuta una fattura, devi sapere come leggerla! + +## Cosa Succede Dopo? + +Continua a "Using Lightning" col [Capitolo 20.2: Pagare una Fattura](20_2_Pagare_una_Fattura.md). diff --git a/it/20_2_Pagare_una_Fattura.md b/it/20_2_Pagare_una_Fattura.md new file mode 100644 index 000000000..cbf2eef03 --- /dev/null +++ b/it/20_2_Pagare_una_Fattura.md @@ -0,0 +1,234 @@ +# 20.2: Pagare una Fattura + +> :information_source: **NOTE:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +In questo capitolo imparerai come pagare una fattura utilizzando il comando `lightning-cli pay`. Si presume che tu abbia già esaminato la fattura, come descritto nel [Capitolo 20.1](20_1_Generare_una_Richiesta_di_Pagamento.md) e determinato che fosse valida. + +## Controlla il tuo Saldo + +Ovviamente, la prima cosa che devi fare è assicurarti di avere abbastanza fondi per pagare una fattura. In questo caso, il canale configurato in precedenza con `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543` contiene 100.000 satoshi. Questo sarà il canale utilizzato per pagare la fattura. + + + +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_NORMAL", + "short_channel_id": "1862856x29x0", + "channel_sat": 100000, + "our_amount_msat": "100000000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} +``` + + +Se non avessi abbastanza fondi, dovresti creare un nuovo canale. + +## Paga la tua Fattura + +Usi il comando `lightning-cli pay` per pagare una fattura. Tenterà di trovare un percorso verso la destinazione indicata e inviare i fondi richiesti. Qui è molto semplice perché c'è un canale diretto tra il pagatore e il destinatario: + + + +``` +c$ lightning-cli --testnet pay lntb100u1p0cwnqtpp5djkdahy4hz0wc909y39ap9tm3rq2kk9320hw2jtntwv4x39uz6asdr5ge5hyum5ypxyugzsv9uk6etwwssz6gzvv4shymnfdenjqsnfw33k76twypskuepqf35kw6r5de5kueeqveex7mfqw35x2gzrdakk6ctwvssxc6twv5hqcqzpgsp5a9ryqw7t23myn9psd36ra5alzvp6lzhxua58609teslwqmdljpxs9qy9qsq9ee7h500jazef6c306psr0ncru469zgyr2m2h32c6ser28vrvh5j4q23c073xsvmjwgv9wtk2q7j6pj09fn53v2vkrdkgsjv7njh9aqqtjn3vd +{ + "destination": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "payment_hash": "6cacdedc95b89eec15e5244bd0957b88c0ab58b153eee549735b995344bc16bb", + "created_at": 1602704828.948, + "parts": 1, + "msatoshi": 10000000, + "amount_msat": "10000000msat", + "msatoshi_sent": 10000000, + "amount_sent_msat": "10000000msat", + "payment_preimage": "1af4a9bb830e49b6bc8f0bef980630e189e3794ad1705f06ad1b9c71571dce0c", + "status": "complete" +} +``` + + +Nota che qui tutti gli importi sono in `msat`, non `sat`! + +### Paga la tua Fattura Attraverso la Rete + +Tuttavia, _non_ è necessario avere un canale con un nodo per pagarlo. Deve solo esserci un percorso ragionevole attraverso la rete Lightning. + +Immagina di aver ricevuto questa piccola richiesta di pagamento per 11.111 msat: + + + +``` +c$ lightning-cli --testnet decodepay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7h058g9u4mthcaf9rl2f7g8zxsdp2t9hh2gr0wajjqmt9ypnx7u3qv35kumn9wgs8gmm0yyxqyjw5qcqp2sp5kj4xhrthmfgcgyl84zaqpl9vvdjwm5x368kr09fu5nym74setw4s9qy9qsq8hxjr73ee77vat0ay603e4w9aa8ag9sa2n55xznk5lsfrjffxxdj2k0wznvcfa98l4a57s80j7dhg0cc03vwqdwehkujlzxgm0xyynqqslwhvl +{ + "currency": "tb", + "created_at": 1602704929, + "expiry": 604800, + "payee": "02f3d74746934494fa378235e5bc44cfdbb5b8779d839263fb7f9218be032f6f61", + "msatoshi": 11111, + "amount_msat": "11111msat", + "description": "You owe me for dinner too!", + "min_final_cltv_expiry": 10, + "payment_secret": "b4aa6b8d77da518413e7a8ba00fcac6364edd0d1d1ec37953ca4c9bf56195bab", + "features": "028200", + "payment_hash": "e3e689117f7688ece226f1eb2eff35337d77d0e82f2bb5df1d4947f527c8388d", + "signature": "304402203dcd21fa39cfbcceadfd269f1cd5c5ef4fd4161d54e9430a76a7e091c929319b02202559ee14d984f4a7fd7b4f40ef979b743f187c58e035d9bdb92f88c8dbcc424c" +} +``` + + +Se provassi a pagarlo e non avessi un percorso verso il destinatario attraverso la rete Lightning, potresti aspettarti un errore come questo: + + +``` +c$ lightning-cli --testnet pay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7h058g9u4mthcaf9rl2f7g8zxsdp2t9hh2gr0wajjqmt9ypnx7u3qv35kumn9wgs8gmm0yyxqyjw5qcqp2sp5kj4xhrthmfgcgyl84zaqpl9vvdjwm5x368kr09fu5nym74setw4s9qy9qsq8hxjr73ee77vat0ay603e4w9aa8ag9sa2n55xznk5lsfrjffxxdj2k0wznvcfa98l4a57s80j7dhg0cc03vwqdwehkujlzxgm0xyynqqslwhvl +{ + "code": 210, + "message": "Ran out of routes to try after 11 attempts: see `paystatus`", + "attempts": [ + { + "status": "failed", + "failreason": "Error computing a route to 02f3d74746934494fa378235e5bc44cfdbb5b8779d839263fb7f9218be032f6f61: \"Could not find a route\" (205)", + "partid": 1, + "amount": "11111msat" + }, +... +``` + + +Ma cosa succederebbe se un host con cui avevi un canale aprisse un canale con il destinatario previsto? + +In tal caso, quando vai a pagare la fattura, funzionerà automaticamente! + + + +``` +c$ lightning-cli --testnet pay lntb111110p1p0cw43ppp5u0ngjytlw6ywec3x784jale4xd7h058g9u4mthcaf9rl2f7g8zxsdp2t9hh2gr0wajjqmt9ypnx7u3qv35kumn9wgs8gmm0yyxqyjw5qcqp2sp5kj4xhrthmfgcgyl84zaqpl9vvdjwm5x368kr09fu5nym74setw4s9qy9qsq8hxjr73ee77vat0ay603e4w9aa8ag9sa2n55xznk5lsfrjffxxdj2k0wznvcfa98l4a57s80j7dhg0cc03vwqdwehkujlzxgm0xyynqqslwhvl +{ + "destination": "02f3d74746934494fa378235e5bc44cfdbb5b8779d839263fb7f9218be032f6f61", + "payment_hash": "e3e689117f7688ece226f1eb2eff35337d77d0e82f2bb5df1d4947f527c8388d", + "created_at": 1602709081.324, + "parts": 1, + "msatoshi": 11111, + "amount_msat": "11111msat", + "msatoshi_sent": 12111, + "amount_sent_msat": "12111msat", + "payment_preimage": "ec7d1b28a7b877cd92b83be396899e8bfc3ecb0b4f944f65afb4be7d0ee72617", + "status": "complete" +} +``` +Questa è la vera bellezza della rete Lightning: senza alcuno sforzo da parte dei partecipanti peer-to-peer, i loro singoli canali diventano una rete! + +> :book: ***Come Funzionano i Pagamenti sulla Rete?*** Supponiamo che il nodo A abbia un canale aperto con il nodo B, il nodo B abbia un canale aperto con il nodo C e il nodo A riceva una fattura dal nodo C per 11.111 msat. Il nodo A paga al nodo B i 11.111 msat, più una piccola commissione, e poi il nodo B paga i 11.111 msat al nodo C. Abbastanza facile. Tranne ricordare che tutti i canali sono in realtà solo record di chi possiede quanto della transazione di finanziamento. Quindi, ciò che realmente accade è che 11.111 msat della transazione di finanziamento sul canale A-B passa da A a B, e poi 11.111 msat della transazione di finanziamento sul canale B-C passa da B a C. Ciò significa che sono richieste due cose affinché questo pagamento funzioni: in primo luogo, ogni canale deve avere una capacità sufficiente per il pagamento; e in secondo luogo, il pagatore su ogni canale deve possedere abbastanza capacità per effettuare il pagamento. + +Nota che in questo esempio sono stati inviati 12.111 msat per pagare una fattura di 11.111 msat: l'extra è una piccola commissione, molto ridotta, (non una percentuale) che è stata pagata all'intermediario. + +## Controlla il tuo Saldo + +Dopo aver effettuato un pagamento, dovresti vedere che i tuoi fondi sono cambiati di conseguenza. + +Ecco come apparivano i fondi per il nodo pagatore dopo il pagamento iniziale di 10.000 satoshi: + + +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_NORMAL", + "short_channel_id": "1862856x29x0", + "channel_sat": 90000, + "our_amount_msat": "90000000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} +``` + +Nota che la capacità del canale rimane a 100.000 satoshi (non cambia mai!), ma che `our_amount` è ora solo 90.000 satoshi (o 90.000.000 msat). + +Dopo aver pagato la seconda fattura, per 11.111 msat, i fondi cambiano di conseguenza: + +``` +$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_NORMAL", + "short_channel_id": "1862856x29x0", + "channel_sat": 89987, + "our_amount_msat": "89987000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} +``` + + +`our_amount` è ora solo 89.987 satoshi, avendo pagato 11.111 msat più una commissione di 1.000 msat. + +## Sommario: Pagare una Fattura + +Una volta che hai una fattura, è abbastanza facile pagarla con un solo comando in Lightning. Anche se non hai un canale con un destinatario, il pagamento è così semplice, a condizione che ci sia un percorso tra te e il nodo di destinazione. + +## Cosa Succede Dopo? + +Continua a "Usare Lighting" col [Capitolo 20.3: Chiudere un Canale Lightning](20_3_Chiudere_un_Canale_Lightning.md). + diff --git a/it/20_3_Chiudere_un_Canale_Lightning.md b/it/20_3_Chiudere_un_Canale_Lightning.md new file mode 100644 index 000000000..9e5ceb7fc --- /dev/null +++ b/it/20_3_Chiudere_un_Canale_Lightning.md @@ -0,0 +1,272 @@ +# 20.3: Chiudere un Canale Lightning + +> :information_source: **NOTE:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +In questo capitolo imparerai come chiudere un canale utilizzando l'interfaccia a riga di comando `lightning-cli close`. Chiudere un canale significa che tu e la tua controparte invierete il saldo concordato del canale alla blockchain, per cui dovrai pagare le commissioni di transazione della blockchain e aspettare che la transazione venga minata. Una chiusura può essere cooperativa o non cooperativa, ma funziona in entrambi i casi. + +Per chiudere un canale, devi prima conoscere l'ID del nodo remoto; puoi recuperarlo in uno dei due modi. + +## Trova i tuoi Canali per Fondi + +Puoi usare il comando `lightning-cli listfunds` per vedere i tuoi canali. Questo comando RPC visualizza tutti i fondi disponibili, sia in `outputs` non spesi (UTXO) nel wallet interno sia bloccati in canali attualmente aperti. + +``` +c$ lightning-cli --testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": true, + "state": "CHANNELD_NORMAL", + "short_channel_id": "1862856x29x0", + "channel_sat": 89987, + "our_amount_msat": "89987000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} + + "message_flags": 1, + "channel_flags": 2, + "active": true, + "last_update": 1595508075, + "base_fee_millisatoshi": 1000, + "fee_per_millionth": 1, + "delay": 40, + "htlc_minimum_msat": "1000msat", + "htlc_maximum_msat": "280000000msat", + "features": "" +} +``` + +Puoi recuperare l'ID del primo canale in una variabile in questo modo: + +``` +c$ nodeidremote=$(lightning-cli --testnet listfunds | jq '.channels[0] | .peer_id') +``` + + +## Trova i tuoi Canali con JQ + +L'altro modo per trovare i canali da chiudere è utilizzare il comando `listchannels`. Restituisce dati sui canali noti al nodo. Poiché i canali possono essere bidirezionali, fino a due nodi verranno restituiti per ogni canale (uno per ogni direzione). + +Tuttavia, la rete di gossip di Lightning è molto efficace, e quindi in breve tempo conoscerai migliaia di canali. Questo è ottimo per inviare pagamenti attraverso la rete Lightning, ma meno utile per scoprire i tuoi canali. Per farlo è necessario un po' di lavoro con `jq`. + +Prima di tutto, devi conoscere il tuo ID nodo, che può essere recuperato con `getinfo`: + +``` +c$ nodeid=$(lightning-cli --testnet getinfo | jq .id) +c$ echo $nodeid +"03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687" +c$ +``` +Puoi quindi usarlo per cercare in `listchannels` tutti i canali in cui il tuo nodo è sia la sorgente che la destinazione: + +``` +c$ lightning-cli --testnet listchannels | jq '.channels[] | select(.source == '$nodeid' or .destination == '$nodeid')' +{ + "source": "03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687", + "destination": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "short_channel_id": "1862856x29x0", + "public": true, + "satoshis": 100000, + "amount_msat": "100000000msat", + "message_flags": 1, + "channel_flags": 0, + "active": true, + "last_update": 1602639570, + "base_fee_millisatoshi": 1, + "fee_per_millionth": 10, + "delay": 6, + "htlc_minimum_msat": "1msat", + "htlc_maximum_msat": "99000000msat", + "features": "" +} +``` +Ecco di nuovo il nostro vecchio amico `032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543`, come destinazione. + +Una volta che sai cosa hai, puoi memorizzarlo in una variabile: + +``` +c$ nodeidremote=$(lightning-cli --testnet listchannels | jq '.channels[] | select(.source == '$nodeid' or .destination == '$nodeid') | .destination') +``` + + +## Chiudi un Canale + +Ora che hai un ID nodo remoto, sei pronto per usare il comando `lightning-cli close` per chiudere un canale. Per impostazione predefinita, tenterà di chiudere il canale cooperativamente con il peer; se vuoi chiuderlo unilateralmente, imposta l'argomento `unilateraltimeout` con il numero di secondi di attesa. (Se lo imposti a 0 e il peer è online, verrà comunque tentata una chiusura mutuale). In questo esempio, tenterai una chiusura mutuale. + + + +``` +c$ lightning-cli --testnet close $nodeidremote 0 +{ + "tx": "02000000011d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d69660000000000ffffffff021c27000000000000160014d39feb57a663803da116402d6cb0ac050bf051d9cc5e01000000000016001451c88b44420940c52a384bd8a03888e3676c150900000000", + "txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f", + "type": "mutual" +} +``` +La transazione di chiusura on-chain è [f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f](https://blockstream.info/testnet/tx/f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f). + +È questa transazione di chiusura che effettivamente distribuisce i fondi scambiati tramite transazioni Lightning. Questo può essere visto esaminando la transazione: + +``` +$ bitcoin-cli --named getrawtransaction txid=f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f verbose=1 +{ + "txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f", + "hash": "3a6b3994932ae781bab80e159314bad06fc55d3d33453a1d663f9f9415c9719c", + "version": 2, + "size": 334, + "vsize": 169, + "weight": 673, + "locktime": 0, + "vin": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "txinwitness": [ + "", + "304402207f8048e29192ec86019bc83be8b4cac5d1fc682374538bed0707f58192d41c390220512ebcde122d53747feedd70c09153a40c56d09a5fec02e47642afdbb20aa2ac01", + "3045022100d686a16084b60800fa0f6b14c25dca1c13d10a55c5fb7c6a3eb1c5f4a2fb20360220555f5b6e672cf9ef82941f7d46ee03dd52e0e848b9f094a41ff299deb8207cab01", + "522102f7589fd8366252cdbb37827dff65e3304abd5d17bbab57460eff71a9e32bc00b210343b980dff4f2723e0db99ac72d0841aad934b51cbe556ce3a1b257b34059a17052ae" + ], + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00010012, + "n": 0, + "scriptPubKey": { + "asm": "0 d39feb57a663803da116402d6cb0ac050bf051d9", + "hex": "0014d39feb57a663803da116402d6cb0ac050bf051d9", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q6w07k4axvwqrmggkgqkkev9vq59lq5we5fcrzn" + ] + } + }, + { + "value": 0.00089804, + "n": 1, + "scriptPubKey": { + "asm": "0 51c88b44420940c52a384bd8a03888e3676c1509", + "hex": "001451c88b44420940c52a384bd8a03888e3676c1509", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q28ygk3zzp9qv223cf0v2qwygudnkc9gfp30ud4" + ] + } + } + ], + "hex": "020000000001011d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d69660000000000ffffffff021c27000000000000160014d39feb57a663803da116402d6cb0ac050bf051d9cc5e01000000000016001451c88b44420940c52a384bd8a03888e3676c1509040047304402207f8048e29192ec86019bc83be8b4cac5d1fc682374538bed0707f58192d41c390220512ebcde122d53747feedd70c09153a40c56d09a5fec02e47642afdbb20aa2ac01483045022100d686a16084b60800fa0f6b14c25dca1c13d10a55c5fb7c6a3eb1c5f4a2fb20360220555f5b6e672cf9ef82941f7d46ee03dd52e0e848b9f094a41ff299deb8207cab0147522102f7589fd8366252cdbb37827dff65e3304abd5d17bbab57460eff71a9e32bc00b210343b980dff4f2723e0db99ac72d0841aad934b51cbe556ce3a1b257b34059a17052ae00000000", + "blockhash": "000000000000002a214b1ffc3a67c64deda838dd24d12154c15d3a6f1137e94d", + "confirmations": 1, + "time": 1602713519, + "blocktime": 1602713519 +} +``` +L'input della transazione è `66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d`, che era la transazione di finanziamento nel [Capitolo 19.3](19_3_Creare_un_Canale_in_Lightning.md). La transazione ha quindi due output, uno per il nodo remoto e l'altro per il wallet locale c-lightning. L'output all'indice 0 corrisponde al nodo remoto con un valore di 0.00010012 BTC; e l'output all'indice 1 corrisponde al nodo locale con un valore di 0.00089804 BTC. + +Lightning mostrerà allo stesso modo 89804 satoshi restituiti come un nuovo UTXO nel suo wallet: + +``` +$ lightning-cli --network=testnet listfunds +{ + "outputs": [ + { + "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "output": 1, + "value": 99847, + "amount_msat": "99847000msat", + "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c", + "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8", + "status": "confirmed", + "blockheight": 1862856, + "reserved": false + }, + { + "txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f", + "output": 1, + "value": 89804, + "amount_msat": "89804000msat", + "scriptpubkey": "001451c88b44420940c52a384bd8a03888e3676c1509", + "address": "tb1q28ygk3zzp9qv223cf0v2qwygudnkc9gfp30ud4", + "status": "confirmed", + "blockheight": 1863006, + "reserved": false + } + ], + "channels": [ + { + "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543", + "connected": false, + "state": "ONCHAIN", + "short_channel_id": "1862856x29x0", + "channel_sat": 89987, + "our_amount_msat": "89987000msat", + "channel_total_sat": 100000, + "amount_msat": "100000000msat", + "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d", + "funding_output": 0 + } + ] +} + +``` + +### Comprendere i Tipi di Chiusura dei Canali + +Il comando `close` RPC tenta di chiudere un canale cooperativamente con il suo peer o unilateralmente dopo che l'argomento `unilateraltimeout` è scaduto. Questo merita una discussione aggiuntiva, poiché va al cuore del design senza fiducia di Lightning: + +Ogni partecipante di un canale è in grado di creare quante più transazioni Lightning al proprio controparte consentite dai loro fondi. La maggior parte delle volte non ci saranno disaccordi tra i partecipanti, quindi ci saranno solo due transazioni on-chain, una di apertura e l'altra di chiusura del canale. Tuttavia, potrebbero esserci scenari in cui un peer non è online o non è d'accordo con lo stato finale del canale o dove qualcuno cerca di rubare fondi all'altra parte. Questo è il motivo per cui ci sono sia chiusure cooperative che forzate. + +#### Chiusura Cooperativa + +Nel caso di una chiusura cooperativa, entrambi i partecipanti al canale concordano di chiudere il canale e regolare lo stato finale sulla blockchain. Entrambi i partecipanti devono essere online; la chiusura viene eseguita trasmettendo una spesa incondizionata della transazione di finanziamento con un output per ciascun peer. + +#### Chiusura Forzata + +Nel caso di una chiusura forzata, solo un partecipante è online o i partecipanti non sono d'accordo sullo stato finale del canale. In questa situazione, un peer può eseguire una chiusura unilaterale del canale senza la cooperazione dell'altro nodo. Viene eseguita trasmettendo una transazione di impegno che si impegna a uno stato precedente del canale concordato da entrambe le parti. Questa transazione di impegno contiene lo stato del canale diviso in due parti: il saldo per ciascun partecipante e tutti i pagamenti pendenti (HTLC). + +Per eseguire questo tipo di chiusura, devi specificare un argomento `unilateraltimeout`. Se questo valore non è zero, il comando di chiusura chiuderà unilateralmente il canale quando viene raggiunto quel numero di secondi: + +``` +c$ lightning-cli --network=testnet close $newidremote 60 +{ + "tx": "0200000001a1091f727e6041cc93fead2ea46b8402133f53e6ab89ab106b49638c11f27cba00000000006a40aa8001df85010000000000160014d22818913daf3b4f86e0bcb302a5a812d1ef6b91c6772d20", + "txid": "02cc4c647eb3e06f37fcbde39871ebae4333b7581954ea86b27b85ced6a5c4f7", + "type": "unilateral" +} + +``` +## Sommario: Chiudere un Canale + +Quando chiudi un canale esegui una transazione on-chain terminando il tuo rapporto finanziario con il nodo remoto. Per chiudere un canale, devi tenere conto del suo stato e del tipo di chiusura che vuoi eseguire. + +## Cosa Succede Dopo? + +Continua a "Using Lightning" col [Capitolo 20.4:Espandere la Rete Lightning](20_4_Espandere_la_Rete_Lightning.md). + diff --git a/it/20_4_Espandere_la_Rete_Lightning.md b/it/20_4_Espandere_la_Rete_Lightning.md new file mode 100644 index 000000000..ac1879f17 --- /dev/null +++ b/it/20_4_Espandere_la_Rete_Lightning.md @@ -0,0 +1,60 @@ +# 20.4: Expanding the Lightning Network + +> :information_source: **NOTE:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Attenzione lettore. + +Questi due capitoli hanno coperto solo alcune delle attività più importanti con Lightning. C'è molto altro che si può fare e molta varietà possibile. Di seguito sono riportati alcuni suggerimenti per andare avanti. + +## Usa i Plugin di c-lightning + +c-lightning è un'implementazione leggera, altamente personalizzabile e conforme agli standard del protocollo Lightning Network. Estende le sue funzionalità utilizzando i Plugin. Principalmente, questi sono sottoprocessi che vengono avviati dal demone `lightningd` e possono interagire con `lightningd` in vari modi: + +* Le opzioni della riga di comando consentono ai plugin di registrare i propri argomenti della riga di comando, che vengono quindi esposti tramite `lightningd`. +* Il passaggio dei comandi JSON-RPC consente ai plugin di aggiungere i propri comandi all'interfaccia JSON-RPC. +* Le sottoscrizioni allo stream di eventi forniscono ai plugin un meccanismo di notifica push per `lightnind`. +* Gli hooks sono un'opzione primitiva che consente ai plugin di essere notificati sugli eventi nel demone `lightningd` e modificare il suo comportamento o trasmettere comportamenti personalizzati. + +Un plugin può essere scritto in qualsiasi linguaggio e può comunicare con `lightningd` attraverso stdin e stdout del plugin. JSON-RPCv2 è utilizzato come protocollo sopra i due stream, con il plugin che agisce come server e `lightningd` che agisce come client. + +Il repository GitHub di `lightningd` mantiene un elenco aggiornato di [plugin](https://github.com/lightningd/plugins) disponibili. + +## Usa Wallet Mobile + +Attualmente conosciamo due wallet Lightning mobili che supportano l'implementazione di c-lightning. + +Per i dispositivi iOS FullyNoded è un wallet Bitcoin open-source per iOS che si connette tramite Tor V3 authenticated service al tuo nodo completo. La funzionalità di FullyNoded è attualmente in fase di sviluppo attivo e in fase di beta testing iniziale. + +* [FullyNoded](https://github.com/Fonta1n3/FullyNoded/blob/master/Docs/Lightning.md) + +SparkWallet è un wallet GUI minimalista per c-lightning, accessibile via web o tramite app mobili e desktop per Android. + +* [SparkWallet](https://github.com/shesek/spark-wallet) + +## Usa Diverse Implementazioni di Lightning + +c-lightning non è la tua unica opzione. Oggi ci sono tre implementazioni ampiamente utilizzate del Lightning Network. Tutte seguono i documenti [Basis of Lightning Technology (BOLT)](https://github.com/lightningnetwork/lightning-rfc), che descrivono un protocollo di livello 2 per i trasferimenti di bitcoin off-chain. Le specifiche sono attualmente in corso di stesura. + +| Nome | Descrizione | BitcoinStandup | Linguaggio | Repository | +| ------------- | ------------- | :---: | ------------- | ------------- | +| C-lightning | Blockstream | X | C | [Download](https://github.com/ElementsProject/lightning) | +| LND | Lightning Labs | X | Go | [Download](https://github.com/lightningnetwork/lnd) | +| Eclair | ACINQ | - | Scala | [Download](https://github.com/ACINQ/eclair) | + +## Mantieni Backup + +Il tuo nodo Lightning deve essere online tutto il tempo, altrimenti la tua controparte potrebbe inviare uno stato precedente del canale e rubare i tuoi fondi. Tuttavia, c'è un altro scenario in cui i fondi possono essere persi, ed è quando si verifica un guasto hardware che impedisce al nodo di stabilire una chiusura cooperativa con la controparte. Questo probabilmente significherà che se non hai una copia esatta dello stato del canale prima del guasto, avrai uno stato non valido che potrebbe portare l'altro nodo a considerarlo un tentativo di frode e utilizzare la transazione di penalità. In questo caso, tutti i fondi andranno persi. Per evitare questa situazione indesiderata, esiste una soluzione basata sull'alta disponibilità del database postgresQL [esiste](https://github.com/gabridome/docs/blob/master/c-lightning_with_postgresql_reliability.md). + +Non abbiamo testato questa soluzione. + +## Sommario: Espandere il Lightning Network + +Puoi utilizzare diverse implementazioni, plugin, wallet mobili o backup per espandere la tua esperienza con Lightning. + +## Cosa Succede Dopo? + +Hai completato Learning Bitcoin from the Command Line, anche se se non hai mai visitato gli [Appendici](A0_Appendices.md) di configurazioni alternative, puoi farlo ora. + +Altrimenti, ti incoraggiamo a unirti alle comunità di sviluppatori, a programmare e a mettere in pratica le tue nuove conoscenze. + +Puoi anche aiutarci qui a Blockchain Commons con Issues o PR per Learning Bitcoin o per uno qualsiasi dei nostri altri repository, o puoi persino diventare un [Sponsor](https://github.com/sponsors/BlockchainCommons). Puoi anche aiutare spargendo la voce: fai sapere alle persone sui social media del corso e di cosa hai imparato! + +Ora vai là fuori e rendi la comunità Blockchain un posto migliore! diff --git a/it/A0_Appendici.md b/it/A0_Appendici.md new file mode 100644 index 000000000..b1518d3eb --- /dev/null +++ b/it/A0_Appendici.md @@ -0,0 +1,22 @@ +# Appendici + +Il corpo principale di questo corso suggerisce una configurazione piuttosto standard per il testing di Bitcoin. Quello che segue in queste appendici è una spiegazione migliore di quella configurazione e alcune opzioni per alternative. + +## Obiettivi per Questa Sezione + +Dopo aver lavorato su queste appendici, uno sviluppatore sarà in grado di: + + * Decidere tra Diversi Metodi per Creare una Blockchain Bitcoin + +Obiettivi di supporto includono la capacità di: + + * Comprendere la Configurazione di Bitcoin Standup + * Eseguire una Compilazione di Bitcoin Manualmente + * Comprendere la Potenza di Regtest + * Utilizzare un Ambiente Regtest + +## Indice dei Contenuti + + [Appendice A1_0 Comprendere Bitcoin Standup](A1_0_Comprendere_Bitcoin_Standup.md) + [Appendice A2_0 Compilare Bitcoin dal Codice Fonte](A2_0_Compilare_Bitcoin_dal_Codice_Fonte.md) + [Appendice A3_0 Usare Bitcoin Regtest](A3_0_Usare_Bitcoin_Regtest.md) diff --git a/it/A1_0_Comprendere_Bitcoin_Standup.md b/it/A1_0_Comprendere_Bitcoin_Standup.md new file mode 100644 index 000000000..c891067ca --- /dev/null +++ b/it/A1_0_Comprendere_Bitcoin_Standup.md @@ -0,0 +1,52 @@ +# Appendice 1: Comprendere Bitcoin Standup + +Il [Capitolo 2.1: Configurare Bitcoin Core VPS con StackScript](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md) spiega il processo di creazione di un nodo Bitcoin utilizzando i [Bitcoin-Standup-Scripts](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts). La seguente appendice spiega cosa fanno le principali sezioni dello script. Potresti voler seguire in [Linode Standup](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) in un'altra finestra. + +## Passo 1: Nome Host + +Il nome del tuo host è memorizzato in `/etc/hostname` e impostato con il comando `hostname`. Appare anche in `/etc/hosts`. + +## Passo 2: Fuso Orario + +Il fuso orario del tuo host è memorizzato in `/etc/timezone`, poi un file appropriato da `/usr/share/zoneinfo/` viene copiato in `/etc/localtime`. + +## Passo 3: Aggiornamento di Debian + +Il gestore di pacchetti `apt-get` viene utilizzato per aggiornare la tua macchina e per installare `gnupg`, il generatore di numeri casuali `haveged` e il firewall non complicato `ufw`. + +La tua macchina è configurata per rimanere automaticamente aggiornata con `echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean true" | debconf-set-selections`. + +## Passo 4: Configurazione di un Utente + +Viene creato un utente `standup`, che sarà utilizzato per le tue applicazioni Bitcoin. Ha anche permessi `sudo`, permettendoti di eseguire azioni privilegiate con questo account. + +Se hai fornito una chiave SSH, ti permetterà di accedere a questo account (altrimenti, devi usare la password creata durante la configurazione). + +Se hai fornito un indirizzo IP, l'accesso `ssh` sarà limitato a tale indirizzo, per `/etc/hosts.allow`. + +## Passo 5: Configurazione di Tor + +Tor è installato per fornire servizi protetti (nascosti) per accedere ai comandi RPC di Bitcoin attraverso il tuo server. Vedi il [Capitolo 14.1: Verificare la Configurazione Tor](14_1_Verificare_la_Configurazione_Tor.md) per ulteriori informazioni sulla tua Configurazione Tor. + +Se hai fornito un client autorizzato per i servizi nascosti, l'accesso sarà limitato a quella chiave, per `/var/lib/tor/standup/authorized_clients`. Se non lo hai fatto, il [Capitolo 14.2](14_2_Cambiare_Bitcoin_Hidden_Services.md) spiega come farlo in un secondo momento. + +## Passo 6: Installazione di Bitcoin + +Bitcoin è installato in `~standup/.bitcoin`. La tua configurazione è memorizzata in `~standup/.bitcoin/bitcoin.conf`. + +Assicurati che i checksum siano verificati per il [Capitolo 2.1: Configurare Bitcoin Core VPS con StackScript](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md), altrimenti potresti essere esposto a un attacco alla catena di approvvigionamento. + +## Passo 7: Installazione di QR Encoder + +Per mantenere tutto compatibile con [GordianSystem](https://github.com/BlockchainCommons/GordianSystem) viene creato un codice QR in `/qrcode.png`. Questo può essere letto da un client QuickConnect come [GordianWallet](https://github.com/BlockchainCommons/GordianWallet-iOS). + +## Conclusione — Comprendere Bitcoin Standup + +Bitcoin Standup utilizza script per cercare di eguagliare gran parte della funzionalità di un [GordianNode](https://github.com/BlockchainCommons/GordianNode-macOS). Dovrebbe fornirti un ambiente Bitcoin sicuro costruito su una base di Bitcoin Core e Tor per le comunicazioni RPC. + +## Cosa c'è di prossimo? + +Se eri nel processo di creazione di un nodo Bitcoin per l'uso in questo corso, dovresti tornare al[Capitolo 2.1: Configurare Bitcoin Core VPS con StackScript](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md). + +Se stai leggendo le appendici, continua con [Appendice A2: Compilare Bitcoin dal Codice Fonte](A2_0_Compilare_Bitcoin_dal_Codice_Fonte.md). + diff --git a/it/A2_0_Compilare_Bitcoin_dal_Codice_Fonte.md b/it/A2_0_Compilare_Bitcoin_dal_Codice_Fonte.md new file mode 100644 index 000000000..80b3092d3 --- /dev/null +++ b/it/A2_0_Compilare_Bitcoin_dal_Codice_Fonte.md @@ -0,0 +1,135 @@ +# Appendice 2: Compilare Bitcoin dal Codice Sorgente + +Questo corso presuppone che tu utilizzi uno script per creare un ambiente Bitcoin, utilizzando Bitcoin Standup per Linode per [§2.1](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), o tramite altri mezzi per [§2.2](02_2_Setting_Up_Bitcoin_Core_Other.md). Tuttavia, potresti preferire compilare Bitcoin manualmente. + +Questo ha i seguenti vantaggi: + +1. Sarai sempre aggiornato con l'ultima release. Avvertenza: Essere sempre aggiornati non è necessario per Bitcoin Core poiché il software è sempre retrocompatibile, il che significa che una vecchia versione di Bitcoin Core sarà ancora in grado di partecipare alla rete Bitcoin, anche se potresti non avere le ultime funzionalità. Dovresti sempre controllare le funzionalità di una nuova release prima di aggiornare. +2. Non dovrai dipendere dai binari precompilati di Bitcoin Core. Questo richiede meno fiducia. Anche se i manutentori di Bitcoin Core fanno un ottimo lavoro nel mantenere l'integrità del codice, un binario precompilato è a qualche passo di distanza dal codice sorgente. Quando compili dal codice sorgente, il codice può essere ispezionato prima della compilazione. +3. Puoi personalizzare la build, facendo cose come disabilitare il wallet o la GUI. + +## Prepara il tuo Ambiente + +Questo tutorial utilizza il sistema operativo Debian 10.4.kv0 su architettura amd64 (computer a 64 bit), ma puoi utilizzare questo tutorial su qualsiasi sistema basato su Debian (ad es. Ubuntu, Mint, ecc.). Per altri sistemi Linux, puoi adattare i seguenti passaggi con il gestore di pacchetti per quel sistema. + +Puoi avere una familiarità di base o nessuna familiarità con la riga di comando purché tu abbia entusiasmo. Il terminale è il tuo alleato più potente, non qualcosa da temere. Puoi semplicemente copiare e incollare i seguenti comandi per compilare bitcoin. (Un comando con "$" è un comando dell'utente normale, e uno con "#" è un comando del superutente/root.) + +Se il tuo utente non è nella lista dei sudoers, allora fai quanto segue: + + + +``` +$ su root + +# apt-get install sudo +# usermod -aG sudo +# reboot +``` + + +## Installa Bitcoin + +### Passo 1: Aggiorna il tuo Sistema + +Prima, aggiorna il sistema usando: + +``` +$ sudo apt-get update +``` +### Passo 2: Installa Git e le Dipendenze + +Installa `git`, che ti permetterà di scaricare il codice sorgente, e `build-essential`, che compila il codice: + +``` +$ sudo apt-get install git build-essential -y +``` + +Successivamente, installa le dipendenze rimanenti: + +``` +$ sudo apt-get install libtool autotools-dev automake pkg-config bsdmainutils python3 libssl-dev libevent-dev libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libminiupnpc-dev libzmq3-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler ccache -y +``` + +### Passo 3: Scarica il Codice Sorgente + +Una volta installate le dipendenze, scarica il repository (repo) contenente il codice sorgente di Bitcoin da github: + +``` +$ git clone https://github.com/bitcoin/bitcoin.git +``` + +Controlla il contenuto del repo: + +``` +$ ls bitcoin +```` +Dovrebbe approssimativamente corrispondere al seguente contenuto: + +![cloning the repo](./public/LBftCLI-compiling_bitcoin-git.png) + +### Passo 4: Installa Berkley DB v4.8 + +1. Entra nella directory `contrib`: `$ cd bitcoin/contrib/` +2. Esegui il seguente comando: ```$ ./install_db4.sh `pwd` ``` + +Una volta scaricato, dovresti vedere il seguente output. Prendi nota dell'output, lo userai per configurare bitcoin durante la compilazione: + +![db4](./public/LBftCLI-compiling_bitcoin-db4.png) + +### Passo 5: Compila Bitcoin Core + +Si consiglia di compilare da un branch taggato, che è più stabile, a meno che tu non voglia provare l'avanguardia dello sviluppo di bitcoin. Esegui il seguente comando per ottenere l'elenco dei tag, ordinati dal più recente: +``` +$ git tag -n | sort -V +``` +Poi scegli un tag come `v0.20.0`: +``` +$ git checkout +``` + +Una volta selezionato un branch tag, esegui i seguenti comandi all'interno della directory `bitcoin`. Il `` dovrebbe essere l'output dello script `install_db4.sh`. + +``` +$ ./autogen.sh +$ export BDB_PREFIX='/db4' +$ ./configure BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include" +$ make # build bitcoin core +``` + +### Passo 6: Testa la Build + +Se vuoi controllare la tua build (cosa che è una buona idea), esegui i seguenti test: + +1. `$ make check` eseguirà i Test Unitari, che dovrebbero tutti restituire `PASS`. +2. `$ test/functional/test_runner.py --extended` eseguirà test funzionali estesi. Ometti il flag `--extended` se vuoi saltare alcuni test. Questo richiederà un po' di tempo. + +### Passo 7: Esegui o Installa Bitcoin Core + +Ora che hai compilato Bitcoin Core dal codice sorgente, puoi iniziare a usarlo o installarlo per una disponibilità globale. + +#### Esegui Bitcoin Core senza Installarlo + +Per eseguire solo Bitcoin Core: + +`$ src/qt/bitcoin-qt` per avviare la GUI. +`$ src/bitcoind` per eseguire bitcoin sulla riga di comando. + +### Installa Bitcoin Core + +Per installare: + +`$ sudo make install` installerà bitcoin core globalmente. Una volta installato, puoi quindi eseguire bitcoin da qualsiasi parte nella riga di comando, proprio come qualsiasi altro software, così: `$ bitcoin-qt` per la GUI o `bitcoind` e poi `bitcoin-cli` per la riga di comando. + +## Finalizza il tuo Sistema + +Compilando Bitcoin dal codice sorgente, hai aumentato la fiducia nel tuo setup. Tuttavia, sei ben lontano dalla sicurezza aggiuntiva fornita da un setup Bitcoin Standup. Per risolvere questo, potresti voler seguire l'intero [Linode Stackscript](https://github.com/BlockchainCommons/Bitcoin-Standup-Scripts/blob/master/Scripts/LinodeStandUp.sh) e passo dopo passo eseguire tutti i comandi. L'unico punto in cui devi fare attenzione è nel Passo 6, che installa Bitcoin. Salta appena dopo aver verificato i tuoi binari e continua da lì. + +## Sommario: Compilare Bitcoin dal Codice Sorgente + +Se volevi la sicurezza aumentata di installare Bitcoin dal codice sorgente, ora dovresti averla. Speriamo che tu abbia anche seguito il Linode Stackscript per configurare un server più sicuro. + +## Cosa segue? + +* Se eri nel processo di creazione di un nodo Bitcoin per l'uso in questo corso, dovresti continuare con [Capitolo 3: Comprendere la Configurazione di Bitcoin](03_0_Comprendere_la_Configurazione_di_Bitcoin.md). + +* Se stai leggendo le appendici, continua con [Appendice 3: Usare Bitcoin Regtest ](A3_0_Usare_Bitcoin_Regtest.md). diff --git a/it/A3_0_Usare_Bitcoin_Regtest.md b/it/A3_0_Usare_Bitcoin_Regtest.md new file mode 100644 index 000000000..19c12a7bc --- /dev/null +++ b/it/A3_0_Usare_Bitcoin_Regtest.md @@ -0,0 +1,245 @@ +# Appendice 3: Usare Bitcoin Regtest + +> :information_source: **NOTA:** Questa sezione è stata recentemente aggiunta al corso ed è una bozza iniziale che potrebbe essere ancora in attesa di revisione. Lettore avvisato. + +La maggior parte di questo corso presume che tu utilizzi Mainnet o Testnet. Tuttavia, queste non sono le uniche opzioni. Durante lo sviluppo di applicazioni Bitcoin, potresti voler mantenere le tue applicazioni isolate da queste blockchain pubbliche. Per farlo, puoi creare una blockchain da zero utilizzando Regtest, che ha un altro grande vantaggio rispetto a Testnet: puoi scegliere quando creare nuovi blocchi, quindi hai il controllo completo sull'ambiente. + +## Avviare Bitcoind su Regtest + +Dopo aver [configurato Bitcoin-Core VPS](02_0_Configurare_Bitcoin-Core_VPS.md) o [compilato dal codice sorgente](A2_0_Compilare_Bitcoin_dal_Codice_Fonte.md), sei ora in grado di usare regtest. Per avviare il tuo `bitcoind` su regtest e creare una blockchain privata, usa il seguente comando: + + + +``` +$ bitcoind -regtest -daemon -fallbackfee=1.0 -maxtxfee=1.1 +``` + +Gli argomenti `-fallbackfee=1.0 -maxtxfee=1.1` eviteranno l'errore `Fee estimation failed. Fallbackfee is disabled`. + +Su regtest, di solito non ci sono abbastanza transazioni quindi bitcoind non può fornire una stima affidabile e, senza di essa, il wallet non creerà transazioni a meno che non venga esplicitamente impostata la tariffa. + +### Resettare la Blockchain Regtest + +Se lo desideri, puoi in seguito riavviare il tuo Regtest con una nuova blockchain. + +I wallet regtest e lo stato della blockchain (chainstate) sono salvati nella sottodirectory regtest della directory di configurazione di Bitcoin: + + +``` +user@mybtc:~/.bitcoin# ls +bitcoin.conf regtest testnet3 +``` + + +Per iniziare una nuova Blockchain usando regtest, tutto ciò che devi fare è eliminare la cartella `regtest` e riavviare Bitcoind: + + +``` +$ rm -rf regtest +``` + +## Generare un Wallet Regtest + +Prima di generare blocchi, è necessario caricare un wallet utilizzando `loadwallet` o crearne uno nuovo con `createwallet`. Dalla versione 0.21, Bitcoin Core non crea automaticamente nuovi wallet all'avvio. + +L'argomento `descriptors=true` crea un wallet descrittore nativo, che memorizza le informazioni scriptPubKey utilizzando descrittori di output. Se è `false`, creerà un wallet legacy, dove le chiavi sono usate per generare implicitamente scriptPubKeys e indirizzi. + + + +``` +$ bitcoin-cli -regtest -named createwallet wallet_name="regtest_desc_wallet" descriptors=true +``` + + +## Generare Blocchi + +Puoi generare (minare) nuovi blocchi su una catena regtest utilizzando il metodo RPC `generate` con un argomento per quanti blocchi generare. Ha senso utilizzare questo metodo solo su regtest; a causa dell'alta difficoltà è molto improbabile che produca nuovi blocchi su mainnet o testnet: + + + +``` +$ bitcoin-cli -regtest -generate 101 +[ + "57f17afccf28b9296048b6370312678b6d8e48dc3a7b4ef7681d18ed3d91c122", + "631ff7b8135ce633c774828be3b8505726459eb65c339aab981b10363befe5a7", + ... + "1162dbfe025c7da94ee1128dc26d518a94508f532c19edc0de6bc673a909d02c", + "20cb2e815c3d42d6a117a204a0b5e726ab641c826e441b5b3417aca33f2aba48" +] +``` +> :warning: AVVISO. Nota che devi aggiungere l'argomento `-regtest` dopo ogni comando `bitcoin-cli` per accedere correttamente al tuo ambiente Regtest. Se preferisci, puoi includere un comando `regtest=1` nel tuo file `~/.bitcoin/bitcoin.conf`. + +Poiché un blocco deve avere 100 conferme prima che quella ricompensa possa essere spesa, generi 101 blocchi, fornendo accesso alla transazione coinbase dal blocco #1. Poiché questa è una nuova blockchain che utilizza le regole predefinite di Bitcoin, i primi blocchi pagano una ricompensa di blocco di 50 bitcoin. A differenza di mainnet, in modalità regtest solo i primi 150 blocchi pagano una ricompensa di 50 bitcoin. La ricompensa si dimezza dopo 150 blocchi, quindi paga 25, 12,5, e così via... + +L'output è l'hash del blocco di ogni blocco generato. + +> :book: ***Cos'è una transazione coinbase?*** Una coinbase è la transazione senza input creata quando un nuovo blocco viene minato e data al minatore. È così che nuovi bitcoin entrano nell'ecosistema. Il valore delle transazioni coinbase diminuisce nel tempo. Su mainnet, si dimezza ogni 210.000 blocchi e termina completamente con il 6.929.999° blocco, attualmente previsto per il 22° secolo. A partire da maggio 2020, la ricompensa coinbase è di 6,25 BTC. + +### Verificare il Tuo Bilancio + +Dopo aver minato blocchi e ottenuto le ricompense, puoi verificare il bilancio sul tuo wallet: + + + +``` +$ bitcoin-cli -regtest getbalance +50.00000000 +``` + +## Usare il Regtest + +Ora dovresti essere in grado di utilizzare questo saldo per qualsiasi tipo di interazione sulla tua Blockchain privata, come inviare transazioni Bitcoin secondo [Capitolo 4](04_0_Inviare_Transazioni_Bitcoin.md). + +È importante notare che per completare qualsiasi transazione, dovrai generare (minare) nuovi blocchi, in modo che le transazioni possano essere incluse. + +Ad esempio, per creare una transazione e includerla in un blocco, dovresti prima usare il comando `sendtoaddress`: + + +``` +$ bitcoin-cli -regtest sendtoaddress [address] 15.1 +e834a4ac6ef754164c8e3f0be4f34531b74b768199ffb244ab9f6cb1bbc7465a +``` + + +L'output è l'hash della transazione inclusa nella blockchain. Puoi verificare i dettagli utilizzando il `gettransaction`: + + +``` +$ bitcoin-cli -regtest gettransaction e834a4ac6ef754164c8e3f0be4f34531b74b768199ffb244ab9f6cb1bbc7465a +{ + "amount": 0.00000000, + "fee": -0.00178800, + "confirmations": 0, + "trusted": false, + "txid": "e834a4ac6ef754164c8e3f0be4f34531b74b768199ffb244ab9f6cb1bbc7465a", + "walletconflicts": [ + ], + "time": 1513204730, + "timereceived": 1513204730, + "bip125-replaceable": "unknown", + "details": [ + { + "account": "", + "address": "mjtN3C97kuWMgeBbxdB7hG1bjz24Grx2vA", + "category": "send", + "amount": -15.10000000, + "label": "", + "vout": 1, + "fee": -0.00178800, + "abandoned": false + }, + { + "account": "", + "address": "mjtN3C97kuWMgeBbxdB7hG1bjz24Grx2vA", + "category": "receive", + "amount": 15.10000000, + "label": "", + "vout": 1 + } + ], + "hex": "020000000f00fe2c7b70b925d0d40011ce96f8991fee5aba9537bd1b6913b37c37b041a57c00000000494830450221009ad02bfeee2a49196a99811ace20e2e7fefd16d33d525884edbc64bf6e2b1db502200b94f4000556391b0998932edde3033ba2517733c7ddffb87d91f6b756629fe201feffffff06a9301a2b39875b68f8058b8e2ad0b658f505e44a67e1e1d039140ae186ed1f0000000049483045022100c65cd13a85af6fcfba74d2852276a37076c89a7642429aa111b7986eea7fd6c7022012bbcb633d392ed469d5befda8df0a6b96e1acfa342f559877edebc2af7cb93401feffffff434b6f67e5e068401553e89f739a3edc667504597f29feb8edafc2b081cc32d90000000049483045022100b86ecc43e602180c787c36465da7fc8d1e8bfba23d6f49c37190c20889f2dfa0022032c3aec3ceefbb7a33c040ef19090cacbfd6bc9c5cd8e94252eb864891c6f34501feffffff4c65b43f8568ce58fc4c55d24ba0742e9878a031fdfae0fadac7247f42cc1f8e0000000049483045022100d055acfce852259dde051dc61792f94277d094c5da96752f925582b8e739868f02205e69add76e6b001073ad6b7df5f32a681fc8513ee0f6e126ee1c2d45149bd91d01feffffff5a72d60b58300974c5d4731e29b437ea61b87b6733bb3ca6ce5548ef8887d05b0000000049483045022100a7f5b2ee656a5a904fb27f982210de6858dfb165777ec969a77ea1c2c82975a4022001a1a563dbc3714047ec855f7aee901e756b851e255f35435e85c2ba7b0abd8401feffffff60d68e9d5650d55bc9e0b2a65ed27a3b9bceac4955760aa1560408854c3b148d000000004948304502210081a6f0c8232c52f3eaca825965077e88b816e503834989be4afb3f44f87eb98202207ae8becb99efe379fb269f477e7bb70d117dcb83e106c53b7addaa9715029da101feffffff63e2239425aad544f6e1157d5ee245d2500d4e9e9daf8049e0a38add6246da890000000049483045022100e0ab1752e8fbb244b63f7dd5649f2222e0dc42fae293b758e0c28082f77560b60220013f72fbe50acf4af197890b4d18fa89094055ed66f9226a6b461cc4ff560f8e01feffffff6aad4151087f4209ace714193dd64f770305dfb89470b79cca538b88253fbbef0000000049483045022100fee4a5f7ec6e8b55bd6aa0e93b5399af724039171d998b926e8095b70953d5f202203db0d4ef9d1bd57aeff0fe3d47d4358ec0559135dac8107507741eef0638279201feffffff7ddbca5854e25e6a2dfeacfe5828267cd1ef5d86e1da573fe2c2b21b45ecd6ce0000000049483045022100bf45241525592df4625642972dbc940ef74771139dd844bc6a9517197d01488c02203c99ca98892cc2693e8fbb9a600962eec84494fb8596acf0d670822624e497c901feffffff8672949de559e76601684c4ac3731599fd965d0c412e7df9f8ec16038d4420a60000000049483045022100b5a9bd3c6718c6bd2a8300bbd1d9de0ff1c5d02aeb6a659c52bb88958e7e3b0302207f710db1ef975c22edf54e063169aae31bbe470166cc0e5c34fd27b730b8e7d001feffffff8e006b0bb8cef2c5c2a11c8c2aa7d3ba01cb4386c7f780c45bc1014142b425f00000000048473044022046dc9db8daeb09b7c0b9f48013c8af2d0a71f688adaa8d91b40891768c852d4a02204fa15da6d58851191344a56c63bf51a540ec03f73117a3446230bb58a8a4bcce01feffffffbad05b8f86182b9b7c9c5aaa9ce3dc8d08a76848e49a2d9b8dcfb0f764bb26ca000000004847304402200682379dc36cb486309eac4913f41ac19638525677edad45ca8d9a2b0728b12f02203fb44f8a46cbc4c02f5699d7d4d9cd810bdf7e7c981b421218ccbcb7b73845f501feffffffd35228fe9ef0a742eacffc4a13f15ed7ba23854e6cb49d5010810ac11b5bdf690000000048473044022030045b882500808bd707f4654becc63de070818c82716310d39576decdd724e3022034d3b41cb5e939f0011bb5251be7941b6077fde5f4eff59afd8e49a2844288f701fefffffff5ae4cbd4ae8d68b5a34be3231cdc88b660447175f39cf7a86397f37641d4aa70000000049483045022100afe16f0de96a8629d6148f93520d690f30126c37e7f7f05300745a1273d7eb7202200933f6b371c4ea522570f3ec2aee9be2b59730b634e828f543bcdb019cf4749901fefffffff633f61ac61683221cc3d2665cf4bcf193af1c8ffe9d3d756ba83cc5eb7643250000000049483045022100ef0b8853c94d60634eff2fc1d4d75872aacb0a2d3242308b7ee256b24739c614022069fe9be8288bdd635871c263c46be710c001729d43f6fbc1350ed1a693c4646301feffffff0250780000000000001976a91464ed7fb2fe0b06f4cad0d731b122222e3e91088a88ac80c5005a000000001976a9142fed0f02d008f89f6a874168e506e2d4f9bcbfb888acd32b0000" +} +``` + + +Tuttavia, devi ora finalizzarla creando blocchi sulla blockchain. +La maggior parte delle applicazioni richiede sei conferme di blocchi per considerare la transazione come irreversibile. Se questo è il tuo caso, puoi minare altri sei blocchi nella tua catena regtest: + + + +``` +$ bitcoin-cli -regtest -generate 6 +[ + "33549b2aa249f0a814db4a2ba102194881c14a2ac041c23dcc463b9e4e128e9f", + "2cc5c2012e2cacf118f9db4cdd79582735257f0ec564418867d6821edb55715e", + "128aaa99e7149a520080d90fa989c62caeda11b7d06ed1965e3fa7c76fa1d407", + "6037cc562d97eb3984cca50d8c37c7c19bae8d79b8232b92bec6dcc9708104d3", + "2cb276f5ed251bf629dd52fd108163703473f57c24eac94e169514ce04899581", + "57193ba8fd2761abf4a5ebcb4ed1a9ec2e873d67485a7cb41e75e13c65928bf3" +] +``` + + + +## Test con NodeJS + +Quando sei su regtest, sei in grado di simulare casi limite e attacchi che potrebbero verificarsi nel mondo reale, come il double spend. + +Come discusso altrove in questo corso, l'uso di librerie software potrebbe darti accesso più sofisticato ad alcuni comandi RPC. In questo caso, [bitcointest di dgarage](https://github.com/dgarage/bitcointest) per NodeJS può essere utilizzato per simulare una transazione da un wallet all'altro; puoi controllare [la loro guida](https://www.npmjs.com/package/bitcointest) per simulazioni di attacchi più specifiche, come il double spend. + +Vedi il [Capitolo 18.3](18_3_Accedere_a_Bitcoind_con_NodeJS.md) per le informazioni più aggiornate sull'installazione di NodeJS, poi aggiungi `bitcointest`: + + + +``` +$ npm install -g bitcointest +``` + + +Dopo aver installato `bitcointest`, puoi creare un file `test.js` con il seguente contenuto: + + +``` +file: test.js + +const { BitcoinNet, BitcoinGraph } = require('bitcointest'); +const net = new BitcoinNet('/usr/local/bin', '/tmp/bitcointest/', 22001, 22002); +const graph = new BitcoinGraph(net); + +try { + + console.log('Launching nodes...'); + + const nodes = net.launchBatchS(4); + const [ n1, n2 ] = nodes; + net.waitForNodesS(nodes, 20000); + + console.log('Connected!'); + const blocks = n1.generateBlocksS(110); + console.info('Generated 110 blocks'); + + console.log(`n2.balance (before) = ${n2.getBalanceS()}`); + + const sometxid = n1.sendToNodeS(n2, 100); + console.log(`Generated transaction = ${sometxid}`); + n1.generateBlocksS(110); + n2.waitForBalanceChangeS(0); + + const sometx = n2.getTransactionS(sometxid); + console.log(`n2.balance (after) = ${n2.getBalanceS()}`); + + +} catch (e) { + console.error(e); + net.shutdownS(); + throw e; +} +``` + + +Come mostrato, questo genererà blocchi e una transazione: + + +``` +$ node test.js +Launching nodes... +Connected! +Generated 110 blocks +n2.balance (before) = 0 +Generated transaction = 91e0040c26fc18312efb80bad6ec3b00202a83465872ecf495c392a0b6afce35 +n2.after (before) = 100 + +``` + + +## Riepilogo: Usare Bitcoin Regtest + +Un ambiente regtest per Bitcoin funziona proprio come qualsiasi ambiente testnet, tranne per il fatto che hai la possibilità di generare blocchi rapidamente e facilmente. + +> :fire: ***Qual è il potere del regtest?*** Il più grande potere del regtest è che puoi minare blocchi rapidamente, permettendoti di accelerare la blockchain, per testare transazioni, timelocks e altre funzionalità su cui altrimenti dovresti aspettare a lungo. Tuttavia, l'altro potere è che puoi eseguirlo privatamente, senza connetterti a una blockchain pubblica, permettendoti di testare idee proprietarie prima di rilasciarle nel mondo. + +## Cosa viene dopo? + +Se hai visitato questa Appendice mentre lavoravi su un'altra parte del corso, dovresti tornarci. + +Altrimenti, hai raggiunto la fine! Altre persone che hanno seguito questo corso sono diventate sviluppatori ed ingegneri Bitcoin professionisti, inclusi alcuni che hanno contribuito a [Blockchain Commons](https://www.blockchaincommons.com/). Ti incoraggiamo a fare lo stesso! Basta iniziare a lavorare su un po' di codice Bitcoin con ciò che hai imparato. diff --git a/it/CLA.md b/it/CLA.md new file mode 100644 index 000000000..bc23cb6b6 --- /dev/null +++ b/it/CLA.md @@ -0,0 +1,55 @@ +# Contributor License Agreement + +Version 1.0 + +Name: `$name` + +E-Mail: `$email` + +Legal Jurisdiction: Wyoming, United States of America + +Project: https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line + +Date: `$date` + +## Purpose + +This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time. + +## License + +I hereby license Blockchain Commons, LLC to: + +1. do anything with my contributions that would otherwise infringe my copyright in them + +2. do anything with my contributions that would otherwise infringe patents that I can or become able to license + +3. sublicense these rights to others on any terms they like + +## Reliability + +I understand that Blockchain Commons will rely on this license. I may not revoke this license. + +## Awareness + +I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it. + +## Copyright Guarantee + +I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately. + +## Patent Guarantee + +I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms. + +## Open Source Guarantee + +I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms. + +## Disclaimers + +***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.*** + +--- + +To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./CLA-signed/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com). diff --git a/it/CONTRIBUIRE.md b/it/CONTRIBUIRE.md new file mode 100644 index 000000000..2aff51a54 --- /dev/null +++ b/it/CONTRIBUIRE.md @@ -0,0 +1,65 @@ +# Contributing + +We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: + +- Reporting a bug +- Discussing the current state of the code +- Submitting a fix +- Proposing new features +- Becoming a maintainer + +## We Develop with Github +We use GitHub to host code, to track issues and feature requests, and to accept Pull Requests. + +## Report Bugs using Github's [issues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) + +If you find bugs, mistakes, or inconsistencies in this project's code or documents, please let us know by [opening a new issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues/new), but consider searching through existing issues first to check and see if the problem has already been reported. If it has, it never hurts to add a quick "+1" or "I have this problem too". This helps prioritize the most common problems and requests. + +### Write Bug Reports with Detail, Background, and Sample Code + +[This is an example](http://stackoverflow.com/q/12488905/180626) of a good bug report by @briandk. Here's [another example from craig.hockenberry](http://www.openradar.me/11905408). + +**Great Bug Reports** tend to have: + +- A quick summary and/or background +- Steps to reproduce + - Be specific! + - Give sample code if you can. [The stackoverflow bug report](http://stackoverflow.com/q/12488905/180626) includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing +- What you expected would happen +- What actually happens +- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) + +People *love* thorough bug reports. I'm not even kidding. + +## Submit Code Changes through Pull Requests + +Simple Pull Requests to fix typos, to document, or to fix small bugs are always welcome. + +We ask that more significant improvements to the project be first proposed before anybody starts to code as an [issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) or as a [draft Pull Request](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/pulls), which is a [nice new feature](https://github.blog/2019-02-14-introducing-draft-pull-requests/) that gives other contributors a chance to point you in the right direction, give feedback on the design, and maybe discuss if related work is already under way. + +### Use a Consistent Coding Style + +* We indent using two spaces (soft tabs) +* We ALWAYS put spaces after list items and method parameters ([1, 2, 3], not [1,2,3]), around operators (x += 1, not x+=1), and around hash arrows. +* This is open-source software. Consider the people who will read your code, and make it look nice for them. It's sort of like driving a car: Perhaps you love doing donuts when you're alone, but with passengers the goal is to make the ride as smooth as possible. + +### Use [Github Flow](https://guides.github.com/introduction/flow/index.html) for Pull Requests + +We use [Github Flow](https://guides.github.com/introduction/flow/index.html). When you submit Pull Requests, please: + +1. Fork the repo and create your branch from `master`. +2. If you've added code that should be tested, add tests. +3. If you've changed APIs, update the documentation. +4. Ensure the test suite passes. +5. Make sure your code lints. +6. Issue that Pull Request! + +### Submit Under the BSD-2-Clause Plus Patent License + +In short, when you submit code changes, your submissions are understood to be available under the same [CC-BY](./LICENSE-CC-BY-4.0.md) license that covers the project. We also ask all code contributors to GPG sign the [Contributor License Agreement (CLA.md)](./CLA.md) to protect future users of this project. Feel free to contact the maintainers if that's a concern. + +## References + +Portions of this CONTRIBUTING.md document were adopted from best practices of a number of open source projects, including: +* [Facebook's Draft](https://github.com/facebook/draft-js/blob/master/CONTRIBUTING.md) +* [IPFS Contributing](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) diff --git a/it/Leggimi.md b/it/Leggimi.md new file mode 100644 index 000000000..ba453ae3a --- /dev/null +++ b/it/Leggimi.md @@ -0,0 +1,301 @@ +# Imparare Bitcoin dalla riga di comando 2.2.0 +### _by Christopher Allen and Shannon Appelcline_ + +![](https://www.blockchaincommons.com/images/projects/lbtc-screen.png) + +Learning Bitcoin from the Command Line è un tutorial per lavorare con Bitcoin (e Lightning) che insegna l'interazione diretta con i server stessi, come il modo più robusto e sicuro per iniziare a lavorare con le criptovalute. + +> NOTA: questa è una bozza in lavorazione, in modo da poter ricevere feedback dai primi revisori. Non è ancora pronta per l'uso. + +_Questo tutorial presuppone che tu abbia una minima conoscenza di base su come usare l'interfaccia della riga di comando. In caso contrario, sono disponibili molti tutorial e ne ho uno per utenti Mac su https://github.com/ChristopherA/intro-mac-command-line._ + +## Traduzioni + +* [English](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line) - Traduzione v2.0.1 +* [Portuguese](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/portuguese-translation/pt/README.md) - Traduzione v2.0.1 +* [Spanish](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/spanish-translation/es/README.md) - Traduzione v2.0.1 +* [Italiano](https://github.com/lutxoitalico/Learning-Bitcoin-from-the-Command-Line/blob/master/Leggimi.md) - Traduzione da v2.2.0 + +Se desideri effettuare la tua traduzione, guarda qui [Contribuire](CONTRIBUIRE.md). + +## Indice di contenuti + +### PRIMA PARTE: PREPARATI PER BITCOIN + +**Status:** Prima traduzione completa, da revisionare. + +* [01_0: Introduzione alla programmazione con Bitcoin Core e Lightning](01_0_Introduzione.md) + * [01_1 Introduzione a Bitcoin](01_1_Introduzione_a_Bitcoin.md) + +* [02_0 Configurare Bitcoin-Core VPS](02_0_Configurare_Bitcoin-Core_VPS.md) + * [02_1 Configurare Bitcoin-Core_VPS in un colpo con StackScript](02_1_Configurare_Bitcoin-Core_VPS_con_StackScript.md) + * [02_2 Configurare Bitcoin Core con Altri Mezzi](02_2_Configurare_Bitcoin_Core_Altri_Mezzi.md) + +### SECONDA PARTE: USARE BITCOIN-CLI + +**Status:** Prima traduzione completa, da revisionare. + +* [3_0 Comprendere la Configurazione di Bitcoin](03_0_Comprendere_la_Configurazione_di_Bitcoin.md) + * [03_1 Verificare la configurazione Bitcoin](03_1_Verificare_la_configurazione_Bitcoin.md) + * [03_2 Capire la Configurazione di Bitcoin](03_2_Capire_la_configurazione_di_Bitcoin.md) + * [03_3 Configurare la Wallet](03_3_Configurare_la_Wallet.md) + * [03_3 Intermezzo Utilizzare Variabili nella Linea di Comando ](03_3_Intermezzo_Utilizzare_Variabili_nella_Linea_di_Comando.md) + * [03_4 Ricevere una Transazione](03_4_Ricevere_una_Transazione.md) + * [03_5 Comprendere il Descriptor](003_5_Comprendere_il_Descriptor.md) + +* [04_0 Inviare Transazioni Bitcoin](04_0_Inviare_Transazioni_Bitcoin.md) + * [04_1 Inviare Monete Modo Semplice](04_1_Inviare_Monete_Modo_Semplice.md) + * [04_2 Creare una Transazione Grezza](04_2_Creare_una_Transazione_Grezza.md) + * [04_2 Intermezzo Usare JQ](04_2_Intermezzo_Usare_JQ.md) + * [04_3 Creare una Transazione Grezza con Alias ](04_3_Creare_una_Transazione_Grezza_con_Alias.md) + * [04_4 Inviare Monete con Transazione Grezza](04_4_Inviare_Monete_con_Transazione_Grezza.md) + * [04_4 Intermezzo_Usare Curl](04_4_Intermezzo_Usare_Curl.md) + * [04_5 Inviare Monete con Transazione Grezza Automatizzata](04_5_Inviare_Monete_con_Transazione_Grezza_Automatizzata.md) + * [04_6 Creare una Transazione Segwit](04_6_Creare_una_Transazione_Segwit.md) + +* [05_0 Controllare Transazioni Bitcoin](05_0_Controllare_Transazioni_Bitcoin.md) + * [05_1 Guardare le Transazioni Ferme](05_1_Guardare_le_Transazioni_Ferme.md) + * [05_2 Rinviare le Transazioni con RBF](05_2_Rinviare_le_Transazioni_con_RBF.md) + * [05_3 Pagare una Transaccion con CPFP](05_3_Pagare_una_Transaccion_con_CPFP.md) + +* [06_0 Ampliare le Transazioni Bitcoin con Multifirme](06_0_Ampliare_le_Transazioni_Bitcoin_con_Multifirme.md) + * [06_1 Inviare una Transazione a un Indirizzo Multifirma](06_1_Inviare_una_Transazione_a_un_Indirizzo_Multifirma.md) + * [06_2 Spendere una Transazione con un Indirizzo Multifirma](06_2_Spendere_una_Transazione_con_un_Indirizzo_Multifirma.md) + * [06_3 Inviare e Ricevere una Multifirma Automatizzata](06_3_Inviare_e_Ricevere_una_Multifirma_Automatizzata.md) + +* [07_0 Ampliare le Transazioni Bitcoin con PSBTs](07_0_Ampliare_le_Transazioni_Bitcoin_con_PSBTs.md) + * [07_1 Creare una Transazione Bitcoin Parzialmente Firmata](07_1_Creare_una_Transazione_Bitcoin_Parzialmente_Firmata.md) + * [07_2 Usare una Transazione Bitcoin Parzialmente Firmata](07_2_Usare_una_Transazione_Bitcoin_Parzialmente_Firmata.md) + * [07_3 Integrazione con Hardware Wallets](07_3_Integrazione_con_Hardware_Wallets.md) + +* [08_0 Ampliare Altre Transazioni Bitcoin](08_0_Ampliare_Altre_Transazioni_Bitcoin.md) + * [08_1 Inviare una Transazione con Blocco temporale](08_1_Inviare_una_Transazione_con_Blocco_temporale.md) + * [08_2 Inviare una Transazione con Dati](08_2_Inviare_una_Transazione_con_Dati.md) + +### TERZA PARTE: BITCOIN SCRIPTING + +**Status:** Prima traduzione parziale, da revisionare... + +* [09_0 Introduzione script di Bitcoin](09_0_Introduzione_script_di_Bitcoin.md) + * [09_1 Le basi delle transazioni](09_1_Le_basi_delle_transazioni.md) + * [09_2 Eseguire uno Script di Bitcoin](09_2_Eseguire_uno_Script_di_Bitcoin.md) + * [09_3 Provare uno Script Bitcoin](09_3_Provare_uno_Script_Bitcoin.md) + * [09_4 Programmare una P2PKH](09_4_Programmare_una_P2PKH.md) + * [09_5 Programmare una P2WPKH](09_5_Programmare_una_P2WPKH.md) + +* [10_0 Inserire Scripts di Bitcoin in Transazioni P2SH](10_0_Inserire_Scripts_di_Bitcoin_in_Transazioni_P2SH.md) + * [10_1 Comprendere la Base di P2SH](10_1_Comprendere_la_Base_di_P2SH.md) + * [10_2 Construire la Struttura di P2SH](10_2_Construire_la_Struttura_di_P2SH.md) + * [10_3 Eseguire uno Script Bitcoin con P2SH](10_3_Eseguire_uno_Script_Bitcoin_con_P2SH.md) + * [10_4 Programmare una Multifirma](10_4_Programmare_una_Multifirma.md) + * [10_5 Programmare uno Script Segwit](10_5_Programmare_uno_Script_Segwit.md) + * [10_6 Spendere una Transazione P2SH](10_6_Spendere_una_Transazione_P2SH.md) + +* [11_0 Potenziare Blocchi Temporali con Scripts di Bitcoin](11_0_Potenziare_Blocchi_Temporali_con_Scripts_di_Bitcoin.md) + * [11_1 Comprendere le Opzioni dei BlocchiTemporali](11_1_Comprendere_le_Opzioni_dei_Blocchi_Temporali.md) + * [11_2 Usare CLTV negli Scripts](11_2_Usare_CLTV_negli_Scripts.md) + * [11_3 Usare CSV negli Scripts](11_3_Usare_CSV_negli_Scripts.md]) + +* [12_0 Ampliando Scripts di Bitcoin](12_0_Ampliando_Scripts_di_Bitcoin.md) + * [12_1 Usare Script Condizionati](12_1_Usare_Script_Condizionati.md) + * [12_2 Usare Altri Comandi di Scripting](12_2_Usare_Altri_Comandi_di_Scripting.md) + +* [13_0 Progettare Scripts di Bitcoin reali](13_0_Progettare_Scripts_di_Bitcoin_reali.md) + * [Capitolo 13.1 Scrivere Scripts Puzzle](13_1_Scrivere_Scripts_Puzzle.md) + * [Capitolo 13.2 Scrivere Scripts Multifirma Complessi](13_2_Scrivere_Scripts_Multifirma_Complessi.md) + * [Capitolo 13.3 Potenziare_Bitcoin_con_Scripts](13_3_Potenziare_Bitcoin_con_Scripts.md) + +### QUARTA PARTE: RISERVATEZZA + +**Status:** Prima traduzione, da revisionare... + +* [14_0 Usare Tor](14_0_Usare_Tor.md) + * [14_1 Verificare la Configurazione Tor](14_1_Verificare_la_Configurazione_Tor.md) + * [14_2 Cambiare Bitcoin Hidden Services](14_2_Cambiare_Bitcoin_Hidden_Services.md) + * [14_3 Aggiungere SSH Hidden Services](14_3_Aggiungere_SSH_Hidden_Services.md) +* [15_0 Usare i2p](15_0_Usare_i2p.md) + * [15_1 Servizi i2p](15_1_Servizi_i2p.md) + +### QUINTA PARTE: PROGRAMMARE CON RPC + +**Status:** Prima traduzione, da revisionare... + +* [16 0 Parlare a Bitcoind con C](16_0_Parlare_a_Bitcoind_con_C.md) + * [16_1 Accedere a Bitcoind con Librerie RPC](16_1_Accedere_a_Bitcoind_con_Librerie_RPC.md) + * [16_2 Programare Bitcoind in C con Librerie RPC](16_2_Programare_Bitcoind_in_C_con_Librerie_RPC.md) + * [13_3 Ricevere Notifiche di Bitcoind in C tramite Librerie ZMQ](16_3_Ricevere_Notifiche_di_Bitcoind_in_C_tramite_Librerie_ZMQ.md) + +* [17_0 Programmare Bitcoin con Libwally](17_0_Programmare_Bitcoin_con_Libwally.md) + * [17_1 Configurare Libwally](17_1_Configurare_Libwally.md) + * [17_2 Usare BIP39 in Libwally](17_2_Usare_BIP39_in_Libwally.md) + * [17_3 Usare BIP32 in Libwally](17_3_Usare_BIP32_in_Libwally.md) + * [17_4 Usare PSBTs in Libwally](17_4_Usare_PSBTs_in_Libwally.md) + * [17_5 Usare Scripts in Libwally](17_5_Usare_Scripts_in_Libwally.md) + * [17_6 Usare Altre Funzioni in Libwally](17_6_Usare_Altre_Funzioni_in_Libwally.md) + * [17_7 Integrare Libwally e Bitcoin-CLI](17_7_Integrare_Libwally_e_Bitcoin-CLI.md) + +* [18_0 Parlare a Bitcoind in Altri Linguaggi](18_0_Parlare_a_Bitcoind_in_Altri_Linguaggi.md) + * [18_1 Accedere a Bitcoind con Go](18_1_Accedere_a_Bitcoind_con_Go.md) + * [18_2 Accedere a Bitcoind con Java](18_2_Accedere_a_Bitcoind_con_Java.md) + * [18_3 Accedere a Bitcoind con NodeJS](18_3_Accedere_a_Bitcoind_con_NodeJS.md) + * [18_4 Accedere a Bitcoind con Python](18_4_Accedere_a_Bitcoind_con_Python.md) + * [18_5 Accedere a Bitcoind con Rust](18_5_Accedere_a_Bitcoind_con_Rust.md) + * [18_6 Accedere a Bitcoind con Swift](18_6_Accedere_a_Bitcoind_con_Swift.md) + +### SESTA PARTE: USARE LIGHTNING-CLI + +**Status:** Prima traduzione, da revisionare... + +* [19_0_Comprendere_La_Configurazione_Lightning.md](19_0_Comprendere_La_Configurazione_Lightning.md) + * [19_1: Verificare la Configurazione Lightning](19_1_Verificare_la_Configurazione_Lightning.md) + * [19_2 Comprendere la Configurazione Lightning](19_2_Comprendere_la_Configurazione_Lightning.md) + * [19_2 Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning](19_2_Intermezzo_Accedere_ad_un_Secondo_Nodo_Lightning.md) + * [19_3 Creare un Canale in Lightning](19_3_Creare_un_Canale_in_Lightning.md) + +* [20_0 Usare Lightning](20_0_Usare_Lightning.md) + * [20_1 Generare una Richiesta di Pagamento](20_1_Generare_una_Richiesta_di_Pagamento.md) + * [20_2 Pagare una Fattura](20_2_Pagare_una_Fattura.md) + * [20_3 Chiudere un Canale Lightning](20_3_Chiudere_un_Canale_Lightning.md) + * [20_4 Espandere la Rete Lightning](20_4_Espandere_la_Rete_Lightning.md) + +### APENDICE + +**Status:** Prima traduzione, da revisionare... + +* [Appendici](A0_Appendici.md) + * [A1_0 Comprendere Bitcoin Standup](A1_0_Comprendere_Bitcoin_Standup.md) + * [A2_0 Compilare Bitcoin dal Codice Fonte](A2_0_Compilare_Bitcoin_dal_Codice_Fonte.md) + * [A3_0 Usare Bitcoin Regtest](A3_0_Usare_Bitcoin_Regtest.md) + +## Status - Beta + +La versione v2.1.0 di **Learning Bitcoin from the Command Line** è completa e ha subito modifiche e integrazioni. È pronta per l'uso + +Stiamo anche valutando in via provvisoria cosa potremmo includere in una [v3.0](TODO-30.md) del corso. Se desideri supportare un lavoro di questo tipo, diventa uno [sponsor GitHub](https://github.com/sponsors/BlockchainCommons) o supportaci sul nostro [BTCPay Server](https://btcpay.blockchaincommons.com/) e facci sapere che **Learning Bitcoin** ti ha spinto a collaborare. + +### Lo storico delle revisioni + +#### 2.2.0 (Luglio 2024) +* [Traduzione in Italiano, lavori in corso](https://github.com/lutxoitalico/Learning-Bitcoin-from-the-Command-Line) + +#### 2.2.0 (17 Novembre, 2021) + +* [Traduzione in Portogese](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master/pt) +* [Traduzione in Spagnolo](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master/es) + +#### 2.1.0 (12 Ottobre, 2021) + +* Nuovo capitolo 15 (i2p). +* Aggiunte correzioni all'utilizzo del portafoglio da 0.21 +* Aggiornata l'installazione ai nuovi script Bitcoin per 22.0 +* Incorporate numerose correzioni rivelate dai primi progetti di traduzione + +#### 2.0.1 (15 Giugno, 2021) + +* Numerose piccole correzioni successive alla 2.0 +* Pensate come base per le traduzioni (2.2.0), ma è scivolato dentro anche il materiale 2.1.0 su i2p + +#### 2.0.0 (3 novembre 2020) + +* Seconda versione importante di Learning Bitcoin +* Aggiunto materiale su Segwit, Tor, portafogli hardware, lightning, regtest +* Lavoro completamente incompiuto precedente sulla programmazione utilizzando una varietà di linguaggi + +#### 1.0.0 (pre-2020) + +* Versione originale, estesa ma incompleta +* Conteneva sezioni complete su setup, bitcoin-cli e scripting + +## Origine, autori, copyright e licenze +Salvo diversa indicazione (in questo file [Leggimi](Leggimi.md) o nei commenti dell'intestazione del file), i contenuti di questo repository sono coperti da Copyright © 2020 di Blockchain Commons, LLC e sono concessi in licenza con [CC-BY](./LICENSE-CC-BY-4.0.md). + +## Supporto finanziario + +*Learning Bitcoin from the Command Line* è un progetto di [Blockchain Commons](https://www.blockchaincommons.com/). Siamo orgogliosamente una società di beneficenza sociale "senza scopo di lucro" impegnata nell'open source e nello sviluppo aperto. Il nostro lavoro è finanziato interamente da donazioni e partnership collaborative con persone come te. Ogni contributo verrà speso per creare strumenti, tecnologie e tecniche aperte che sostengano e facciano progredire l'infrastruttura di sicurezza blockchain e Internet e promuovano un web aperto. + +Per supportare finanziariamente l'ulteriore sviluppo di *Learning Bitcoin from the Command Line* e altri progetti, ti preghiamo di considerare di diventare un Patreon di Blockchain Commons tramite un patrocinio mensile continuo come [Sponsor GitHub](https://github.com/sponsors/BlockchainCommons). Puoi anche supportare Blockchain Commons con bitcoin sul nostro [BTCPayServer](https://btcpay.blockchaincommons.com/). + +## Contribuire + +Incoraggiamo i contributi pubblici tramite issues e pull request! Si prega di rivedere [CONTRIBUIRE.md](CONTRIBUIRE.md) per i dettagli sul nostro processo di sviluppo. Tutti i contributi a questo repository richiedono un [Contributor License Agreement](./CLA.md) firmato GPG. + +se si desidera fornire una traduzione di Learning Bitcoin in un'altra lingua, si prega di consultare anche [TRADURRE.md](TRADURRE.md). + +### Discussioni + +Il posto migliore per parlare di Blockchain Commons e dei suoi progetti è nelle nostre aree di discussione GitHub. + +[**Discussioni su Blockchain Commons**](https://github.com/BlockchainCommons/Community/discussions). Per sviluppatori, stagisti e utenti di Blockchain Commons, si prega di utilizzare l'area discussioni del [repository della community](https://github.com/BlockchainCommons/Community) per parlare di problemi generali di Blockchain Commons, del programma di tirocinio o di argomenti diversi da quelli trattati dalla [Gordian Developer Community](https://github.com/BlockchainCommons/Gordian-Developer-Community/discussions) o dalla +[Gordian User Community](https://github.com/BlockchainCommons/Gordian/discussions).' + +### Altre domande e problemi + +In quanto community open source e open-development, Blockchain Commons non ha le risorse per fornire supporto diretto ai nostri progetti. Si prega di considerare l'area discussioni come un luogo in cui è possibile ottenere risposte alle domande. In alternativa, si prega di utilizzare la funzionalità [issues](../../issues) di questo repository. Purtroppo, non possiamo fare promesse sui tempi di risposta. + +Se la tua azienda ha bisogno di supporto per utilizzare i nostri progetti, non esitare a contattarci direttamente per conoscere le opzioni. Potremmo essere in grado di offrirti un contratto per il supporto da uno dei nostri collaboratori, oppure potremmo essere in grado di indirizzarti a un'altra entità che può offrirti il ​​supporto contrattuale di cui hai bisogno. + +### Crediti + +Le seguenti persone hanno contribuito direttamente a questo repository. Puoi aggiungere il tuo nome qui partecipando. Il primo passo è imparare come contribuire dalla nostra documentazione [CONTRIBUTING.md](./CONTRIBUTING.md). + + +| Name | Role | Github | Email | GPG Fingerprint | +| ----------------- | ------------------- | ------------------------------------------------- | ------------------------------------- | -------------------------------------------------- | +| Christopher Allen | Lead Author | [@ChristopherA](https://github.com/ChristopherA) | \ | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | +| Shannon Appelcline | Lead Author | [@shannona](https://github.com/shannona) | \ | 7EC6 B928 606F 27AD | + + +Di seguito sono elencati altri collaboratori: + +| Role | Names | +| ------------------- | ---------------------------------------- | +| ***Contributors:*** | [gg2001](https://github.com/gg2001) (Go, Node.js sections), [gorazdko](https://github.com/gorazdko) (Rust section), [Javier Vargas](https://github.com/javiervargas) (C, Java, Lightning, Tor sections), [jodobear](https://github.com/jodobear) (Appendix: Compiling Bitcoin, Python section), [Prayank]( https://github.com/prayank23) (i2p sections) | +| ***Reviewers:*** | Glen Willem [@gwillem](https://github.com/gwillem) | +| ***Sponsors:*** | Blockstream Corporation | + +### Crediti di traduzione + +Grazie ai volontari che hanno dedicato molto tempo alla scrittura e alla revisione delle traduzioni in altre lingue del corso originale in lingua inglese. + +#### Traduzione in portoghese + +| Name | Role | Github | +| ----------------- | ------------------- | ------------------------------------------------- | +| Namcios | Translator & Reviewer | [@namcios](https://github.com/namcios) | +| Korea | Translator & Reviewer | [@KoreaComK](https://github.com/KoreaComK) | +| Luke Pavsky | Translator & Reviewer | [@lukedevj](https://github.com/lukedevj) | +| hgrams | Translator & Reviewer | [@hgrams](https://github.com/hgrams) | + +#### Traduzione in Spagnolo + +| Name | Role | Github | +| ---------- | -------- | ------------ | +| Ian Culp | Translator & Reviewer | [@icculp](https://github.com/icculp) | +| Maxi Goyheneche | Translator | [@maxcrowar](https://github.com/maxcrowar) | +| Said Rahal | Translator | [@srahalh](https://github.com/srahalh) | +| César A. Vallero | Translator & Reviewer | [@csralvall](https://github.com/csralvall) | +| Javier Vargas | Translator & Reviewer | [@javiervargas](https://github.com/javiervargas) | + +#### Traduzione in Italiano + +| Name | Role | Github | +| ---------- | -------- | ------------ | +| Lutxo | Translator | [@lutxoitalico](https://github.com/lutxoitalico) | + +## Divulgazione responsabile + +Vogliamo mantenere tutti i nostri software sicuri per tutti. Se hai scoperto una vulnerabilità di sicurezza, apprezziamo il tuo aiuto nel segnalarcela in modo responsabile. Purtroppo al momento non siamo in grado di offrire bug bounty. + +Ti chiediamo di offrirci buona fede e di fare del tuo meglio per non far trapelare informazioni o danneggiare alcun utente, i suoi dati o la nostra community di sviluppatori. Ti preghiamo di darci un ragionevole lasso di tempo per risolvere il problema prima di pubblicarlo. Non frodare i nostri utenti o noi nel processo di scoperta. Ti promettiamo di non intraprendere azioni legali contro i ricercatori che segnalano un problema, a condizione che facciano del loro meglio per seguire queste linee guida. + +### Segnalazione di una vulnerabilità + +Segnala sospette vulnerabilità di sicurezza in privato tramite e-mail a ChristopherA@BlockchainCommons.com (non utilizzare questa e-mail per supporto). Ti preghiamo di NON creare problemi visibili pubblicamente per sospette vulnerabilità di sicurezza. + +Le seguenti chiavi possono essere utilizzate per comunicare informazioni sensibili agli sviluppatori: + +| Name | Fingerprint | +| ----------------- | -------------------------------------------------- | +| Christopher Allen | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | + +Puoi importare una chiave eseguendo il seguente comando con l'impronta digitale individuale: `gpg --recv-keys ""` Assicurati di mettere le virgolette attorno alle impronte digitali che contengono spazi. diff --git a/it/TRADURRE.md b/it/TRADURRE.md new file mode 100644 index 000000000..49f59fc47 --- /dev/null +++ b/it/TRADURRE.md @@ -0,0 +1,114 @@ +# Tradurre: Impara Bitcoin dalla riga di comando + +Grazie per il tuo interesse nella traduzione di Learning Bitcoin dalla riga di comando! Quella che segue è la nostra procedura standard per farlo. In caso di domande, contattaci. + +1. **Si prega di seguire la nostra normale procedura per i collaboratori.** + * Leggi [CONTRIBUIRE](CONTRIBUIRE.md). + * Compila un [Contratto di licenza per collaboratore](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/CLA.md), firmalo con GPG e invialo come un Pull Request. Assicurati che ciò venga fatto per tutti coloro che contribuiscono alla traduzione. +1. **Scegli una versione.** + * Scegli una [Versione](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/releases) come base della tua traduzione. Generalmente suggeriamo l'ultima versione. Ciò garantirà la coerenza di tutti i file nella tua traduzione, ti isolera di eventuali modifiche che potremmo apportare e renderà più facile vedere cosa cambia quando creiamo una nuova versione. + * Se sembra che non ci sia una nuova versione da un po', invia un issue dicendo che sei interessato a iniziare una nuova traduzione e chiedendo se avrebbe senso che ci sia un nuovo rilascio importante prima di farlo. Se c'è stato qualcosa di degno di nota, e non siamo nel mezzo delle cose, probabilmente creeremo una nuova patch o una versione minore. Se siamo nel bel mezzo del lavoro, ti suggeriremo semplicemente di utilizzare la versione precedente. + * Etichetta il tuo sommario e ogni capitolo o sezione con la versione utilizzata. +1. **Richiedi un Branch.** + * Presenta un [Issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) richiedendo un nuovo branch per la tua traduzione. + * Questo sarà per noi il luogo principale in cui raccoglieremo il lavoro sulla traduzione nel tempo. + * Creeremo una directory di primo livello per la tua traduzione completa utilizzando il [codice lingua ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), ad esempio `es` (spagnolo), "fr" (francese) o "pt" (portoghese). Il lavoro dovrebbe essere svolto in quella directory. + +1. **Biforca il ramo.** + * Una volta creato un ramo di traduzione, ti consigliamo di inserirlo nel tuo account GitHub. + * Generalmente, suggeriamo di creare un ramo di lavoro da quel ramo di traduzione per ogni capitolo separato. Ciò ti consentirà di affrontare il processo di scrittura/revisione/revisione per ogni singolo capitolo senza che questo rimanga intrappolato con i tuoi nuovi contenuti per i capitoli futuri e ci consentirà di unire i capitoli man mano che vengono completati, che è la nostra preferenza , e aiuterà tutti a tenere traccia di dove si trovano le cose. + * Assicurati di [firmare i tuoi commit](https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification/signing-commits). +1. **Invia i PR un capitolo alla volta.** + * Invia i tuoi PR per la traduzione dal tuo work fork al nostro ramo di traduzione in lotti di non più di un singolo capitolo alla volta. + * Invia in gruppi più piccoli se ha senso, ad esempio perché persone diverse scrivono sezioni diverse. + * Ancora una volta, suggeriamo che ci sia un ramo per ogni capitolo, quindi quando invii il tuo PR per un capitolo, di solito creerai un ramo per il capitolo successivo. +1. **Richiedi l'approvazione da parte di un madrelingua.** + * Nessuno potrà mai apportare una modifica eccezionale al proprio lavoro, quindi richiediamo che ogni sezione sia approvata da qualcuno diverso dal traduttore originale. + + * Ciò significa fondamentalmente che qualsiasi team di traduzione _dovrebbe_ contenere almeno due membri, un traduttore e un redattore oppure due persone che si scambiano i ruoli di traduttore e redattore. Se il tuo team non ha un secondo membro, possiamo chiamare un redattore/approvatore quando invii un PR, ma è possibile che non saremo in grado di trovarne uno e il tuo duro lavoro languirà, quindi è meglio averne uno in anticipo. + + * Per rendere il processo di modifica e revisione più semplice, indipendente e ottimizzato, suggeriamo a te e al revisore di [richiedere l'accesso ai rispettivi fork](https://docs.github.com/en/enterprise-server@3.0/github /configurazione-e-gestione-del-tuo-account-utente-github/gestione-dell'accesso-ai-tui-repository-personali/invito-dei-collaboratori-a-un-repository-personale). Una volta invitato, il _revisore_ può quindi: + + 1. Effettuare facilmente il checkout del PR nel computer locale con [GitHub CLI](https://cli.github.com/) eseguendo `gh pr checkout `. Ciò creerà automaticamente un ramo con il codice PR su cui il revisore potrà lavorare. + + 2. Quindi, esegui le modifiche con commit firmati. + + 3. Esegui "git push" dopo aver terminato la revisione per far sì che le modifiche si riflettano nel PR. +1. **Richiedi l'approvazione al Blockchain Commons Team.** + * Una volta che un capitolo o una sezione sono stati approvati da un madrelingua, richiedi l'approvazione a qualcuno del team Blockchain Commons: attualmente [@shannona](https://github.com/shannona). +1. **Continua!** + * Continua il processo, non più di un capitolo alla volta, finché non avrai un libro completo. + * Sii consapevole della portata complessiva del progetto. A partire dalla versione 2.01, Imparare Bitcoin dalla riga di comando ha una lunghezza di 120.000 parole. Come libro, sarebbero 250-400 pagine, a seconda del formato e del layout. (Circa 90.000 parole di questo sono testo da tradurre, mentre il resto è codice.) Vuoi assicurarti di avere il tempo per quel livello di impegno prima di iniziare. +1. **Facci sapere quando hai finito.** + * Una volta completata la traduzione, invia un problema per farci sapere che il ramo di traduzione è pronto per essere unito al master. + * Questo ci permetterà anche di annunciare la traduzione completata e di collegarla al file README principale +1. **Aggiorna la tua traduzione con le nuove versioni** + * Ci auguriamo che le traduzioni restino aggiornate con le nuove versioni, in particolare quelle maggiori e secondarie, che probabilmente includeranno nuovi contenuti e aggiornamenti. Attualmente, questi si verificano solo ogni pochi anni + * Se hai deciso di interrompere l'aggiornamento di una traduzione, faccelo sapere, in modo che possiamo far sapere alla comunità che stiamo cercando un nuovo traduttore per continuare ad aggiornare una traduzione. + +### ESEMPIO DI FLUSSO DI LAVORO + +Il capitolo 3 ha 7 sottosezioni: 3.0, 3.1, 3.2, 3.3, Interludio 3.3, 3.4 e 3.5. +Supponiamo che tu voglia tradurlo in francese. + +Un approccio alla sua traduzione potrebbe essere quello di creare un ramo "francese-3" da +ramo "francese-traduzione" (creato nel passaggio precedente). Quindi crea un file +file di traduzione per la sottosezione 3.0. Quando pensi che il capitolo 3.0 sia +pronto per la revisione, applichi le modifiche e continui con il file successivo, +sottosezione 3.1. Ripeti la stessa procedura per questo file e tutti i successivi. +Successivamente, il tuo ramo "francese-3" divergerà dal ramo base +("traduzione francese" in questo caso) da 7 diversi commit, uno per ciascuno +sottosezione, oltre ad alcuni altri commit se hai dimenticato di apportare alcune modifiche o necessità +per correggere gli altri. A questo punto sei pronto per applicare le modifiche al tuo +fork e aprire una richiesta pull al repository originale. + +Nel processo di revisione discuterai alcune decisioni con il tuo revisore e +introdurre nuove modifiche sotto forma di commit se è necessario modificare alcune parti +delle tue modifiche. Non dimenticare di rendere significative queste modifiche +e fare un PR nel Fork. Dopo aver perfezionato le modifiche, il tuo revisore +accetterà le tue modifiche e richiederà l'unione di tali modifiche sul file +ramo "traduzione francese". Tieni presente che puoi anche inviare le modifiche e +crea la tua richiesta pull dopo il tuo primo commit. Ciò consentirà al revisore +per iniziare la revisione prima di terminare la traduzione di tutti i capitoli. + +Puoi tenere traccia dello stato della traduzione di quel particolare capitolo nel file +corpo della richiesta pull, con il seguente modello: + +``` +Questo pull request crea la versione del capitolo + di Imparare Bitcoin dalla riga di comando. + +Cose da controllare: +- Rispettare i nomi dei file e dei capitoli da [README] tradotto (locale/percorso/a/README). +- Traduzione corretta. +- Coerenza dei termini: revisione del file ["memoria di traduzione"](locale/percorso/del/file). +- Buona punteggiatura. +- Links corretti. +- Bella formattazione. + +| Sottocapitolo | Tradotto | Recensito | Fatto | +| ------------- | :--------------: | :--------------: | :--------------: | +| _0_ |
  • [ ]
|
  • [ ]
|
  • [ ]
| +| _1_ |
  • [ ]
|
  • [ ]
|
  • [ ]
| +| _2_ |
  • [ ]
|
  • [ ]
|
  • [ ]
| +| _3_ |
  • [ ]
|
  • [ ]
|
  • [ ]
| +| _ecc_ |
  • [ ]
|
  • [ ]
|
  • [ ]
| +``` + +### SUGGERIMENTI FINALI: +- _Mantenere le righe inferiori a 80 caratteri_. Il parser Markdown li formatterà correttamente + (ricontrollalo) e il processo di revisione sarà più semplice. +- _Traduci prima il file `README.md`_ e usalo come riferimento per la traduzione + di tutti i seguenti nomi di capitoli, nomi di file e nomi di collegamenti. Il README + rappresenta lo stato del ramo master al momento dell'inizio del + processo di traduzione. Verrà consultato da tutti i traduttori per sapere come fare + tradurre i nomi di file e capitoli. Cercare di raggiungere un accordo con l'altro + traduttori su quei nomi prima di scrivere qualsiasi capitolo e proseguire oltre + modifiche di questo file al minimo. +- _Crea un file di "memoria di traduzione"_ con le parole speciali che potresti avere + più traduzioni negli stessi contesti e la traduzione scelta per + loro. I buoni candidati per essere in questo elenco sarebbero parole specifiche del dominio, + come: multisig, input, output, script, timelock, locktime, hash, ecc. + + +Grazie ancora!