Esplora i moduli fondamentali di Bitcoin Core. Clicca su qualsiasi riga di codice per leggere la spiegazione in linguaggio semplice — senza dover sapere programmare.
La catena di blocchi immutabile
Come si spediscono i bitcoin
Chiavi private e portafogli
La rete decentralizzata
La blockchain è il cuore di Bitcoin: un registro pubblico e immutabile di tutte le transazioni mai avvenute. Ogni "blocco" contiene un gruppo di transazioni e un riferimento al blocco precedente, formando una catena.
Un blocco è come una pagina di un libro mastro. Contiene decine di transazioni, una data, e un'impronta digitale del blocco precedente. Questo crea la "catena".
Ogni blocco contiene l'hash del precedente. Modificare un blocco significherebbe ricalcolare tutti i blocchi successivi — computazionalmente impossibile.
| 1 | // Copyright (c) 2009-2023 The Bitcoin Core developers | ▶ |
Spiegazione
Questa è una nota di copyright. Indica che il codice è scritto e mantenuto dagli sviluppatori di Bitcoin Core dal 2009 (anno della nascita di Bitcoin) fino al 2023.
Come la firma dell'autore su un libro — dice chi ha scritto il codice e quando.
| ||
| 2 | // Distributed under the MIT software license | ▶ |
Spiegazione
La licenza MIT è una licenza open source molto permissiva. Significa che chiunque può usare, copiare, modificare e distribuire questo codice liberamente, anche per scopi commerciali, a patto di mantenere questa nota.
Come dire: "Questo è liberamente disponibile — usalo come vuoi, ma non togliere la firma."
| ||
| 3 | #ifndef BITCOIN_CHAIN_H | ▶ |
Spiegazione
#ifndef significa "se non è definito". Insieme alla riga successiva, questo è un header guard: evita che questo file venga caricato due volte nello stesso programma, il che causerebbe errori.
Come un controllo "hai già letto questa pagina?". Se sì, salta. Evita di ripetere le istruzioni.
| ||
| 4 | #define BITCOIN_CHAIN_H | ▶ |
Spiegazione
#define "marca" il file come già caricato. La prossima volta che il compilatore vede #ifndef BITCOIN_CHAIN_H, sa che è già stato incluso e lo salta.
| ||
| 5 | #include <uint256.h> | ▶ |
Spiegazione
#include importa un altro file di codice. uint256.h definisce il tipo di dato che rappresenta un numero a 256 bit — usato per gli hash SHA-256 di Bitcoin. Un hash a 256 bit è un numero con 78 cifre decimali.
Come "importa il capitolo sugli hash" da un altro libro dello stesso scaffale.
| ||
| 6 | #include <arith_uint256.h> | ▶ |
Spiegazione
Importa un file per fare operazioni aritmetiche su numeri a 256 bit (addizione, confronto, ecc.). Necessario per confrontare le difficoltà di mining.
| ||
| 7 | class CBlockIndex { | ▶ |
Spiegazione
class crea un tipo di dato personalizzato. CBlockIndex è la struttura che rappresenta un singolo blocco nella blockchain. La "C" davanti è una convenzione del codice Bitcoin per indicare una "classe". Tutto ciò che è racchiuso tra le parentesi graffe { } appartiene a questa classe.
Come creare uno schema per una scheda di archivio: definisci quali campi avrà ogni scheda (numero blocco, data, hash, ecc.).
| ||
| 8 | public: | ▶ |
Spiegazione
public: significa che le variabili e funzioni che seguono sono accessibili da qualsiasi parte del programma. È il contrario di private:, che nasconde i dati all'esterno.
Come la parte di un modulo compilabile che tutti possono vedere e riempire, vs la parte interna riservata all'ufficio.
| ||
| 9 | uint256 phashBlock; | ▶ |
Spiegazione
phashBlock è il hash di questo blocco — la sua "impronta digitale" univoca a 256 bit. Come un'impronta digitale umana, è unica per ogni blocco. Se cambi anche solo un byte nel blocco, l'hash cambia completamente. Il tipo uint256 è un intero senza segno da 256 bit.
Come il codice a barre su un prodotto: identifica univocamente quel preciso blocco nell'intera catena.
| ||
| 10 | CBlockIndex* pprev; | ▶ |
Spiegazione
pprev è un puntatore al blocco precedente. La * indica che è un puntatore (una freccia che punta a un altro oggetto in memoria). Questo è esattamente ciò che crea la "catena" nella blockchain: ogni blocco tiene un riferimento diretto al blocco che lo precede.
Come ogni pagina di un libro che dice "continua da pagina X". È il collegamento fisico tra un blocco e il precedente.
| ||
| 11 | int nHeight; | ▶ |
Spiegazione
nHeight è l'altezza del blocco — cioè la sua posizione nella catena, partendo da 0 (il blocco Genesis). Il blocco #0 è quello creato da Satoshi Nakamoto il 3 gennaio 2009. Al 2024, l'altezza supera i 820.000 blocchi.
Come il numero di piano di un grattacielo. Il piano 0 è il piano terra (il blocco Genesis), ogni blocco aggiunto sale di un piano.
| ||
| 12 | int64_t nTime; | ▶ |
Spiegazione
nTime è il timestamp del blocco — l'ora esatta in cui il blocco è stato minato, espresso come numero di secondi trascorsi dalla mezzanotte del 1 gennaio 1970 (Unix timestamp). int64_t è un intero a 64 bit, sufficiente per rappresentare date fino all'anno 292 miliardi.
Come il timbro postale su una lettera: certifica quando il blocco è stato "spedito" nella rete.
| ||
| 13 | uint32_t nBits; | ▶ |
Spiegazione
nBits rappresenta la difficoltà di mining di questo blocco, in formato compresso. La difficoltà determina quanto deve essere piccolo l'hash per essere accettato dalla rete. Si ricalibra ogni 2016 blocchi (~2 settimane) per mantenere un tempo medio di 10 minuti per blocco.
Come regolare la difficoltà di un puzzle: se troppi miner trovano la soluzione troppo in fretta, il puzzle diventa più difficile.
| ||
| 14 | uint32_t nNonce; | ▶ |
Spiegazione
nNonce è il numero casuale che i miner modificano milioni di volte al secondo per trovare un hash valido. "Nonce" sta per "number used once". È il campo che i miner cambiano durante il mining finché non trovano un hash che inizia con abbastanza zeri.
Come girare una rotella di combinazione: il miner prova ogni numero finché il lucchetto non si apre (= hash valido trovato).
| ||
| 15 | int64_t GetBlockTime() const { | ▶ |
Spiegazione
Questa è una funzione (metodo) chiamata GetBlockTime. Restituisce (int64_t) il tempo del blocco. La parola const garantisce che questa funzione non modifica nulla — legge solo. Le funzioni sono blocchi di codice riutilizzabili che fanno una cosa specifica.
Come premere il tasto "ora" su un orologio digitale: ti dà l'informazione senza cambiare nulla.
| ||
| 16 | return (int64_t)nTime; | ▶ |
Spiegazione
return restituisce un valore alla parte del programma che ha chiamato questa funzione. Il (int64_t) è un cast: converte nTime (che era uint32_t) nel tipo int64_t, garantendo che non ci siano problemi con numeri grandi o negativi.
| ||
| 17 | } | ▶ |
Spiegazione
La parentesi graffa chiusa } segna la fine della funzione GetBlockTime. Tutto il codice tra la { di apertura e questa } appartiene a quella funzione.
| ||
| 18 | bool IsValid() const; | ▶ |
Spiegazione
IsValid() è una funzione che restituisce un bool (booleano: vero o falso). Verifica se questo blocco è valido secondo le regole del protocollo Bitcoin: formato corretto, difficoltà rispettata, transazioni valide, ecc. Il ; finale indica che questa è solo la dichiarazione — il corpo della funzione è definito altrove.
Come il controllo di sicurezza in aeroporto: risponde solo sì/no alla domanda "questo blocco può passare?"
| ||
| 420 | bool CheckProofOfWork(uint256 hash, unsigned int nBits) { | ▶ |
Spiegazione
Questa funzione verifica la Proof of Work (prova di lavoro) — il meccanismo fondamentale di Bitcoin. Controlla che l'hash del blocco sia effettivamente minore del target di difficoltà. Riceve l'hash calcolato e il valore di difficoltà (nBits).
Come un esaminatore che controlla: "hai davvero risolto questo puzzle difficile? Mostrami la soluzione."
| ||
| 421 | arith_uint256 bnTarget; | ▶ |
Spiegazione
Crea una variabile bnTarget di tipo arith_uint256 che conterrà il valore target: il numero massimo che l'hash del blocco deve avere per essere valido. Più basso è il target, più difficile è il mining.
| ||
| 422 | bnTarget.SetCompact(nBits); | ▶ |
Spiegazione
SetCompact decomprime nBits nel numero target completo a 256 bit. Bitcoin usa una rappresentazione compressa (4 byte) per la difficoltà per risparmiare spazio nell'header del blocco.
| ||
| 423 | if (UintToArith256(hash) > bnTarget) | ▶ |
Spiegazione
Questo è il controllo centrale del mining. Converte l'hash in un numero e lo confronta con il target. Se l'hash è maggiore del target, il blocco non è valido. I miner cercano un hash che sia minore del target. Statisticamente, un hash su X miliardi soddisfa questa condizione.
Come lanciare un dado enorme con miliardi di facce e sperare di ottenere un numero basso. Il miner lancia il dado (cambia il nonce) finché non ottiene un numero abbastanza basso.
| ||
| 424 | return false; | ▶ |
Spiegazione
Se l'hash è troppo grande (mining non valido), la funzione restituisce false — blocco rifiutato. Questo è il meccanismo che rende impossibile falsificare un blocco senza rifarlo il lavoro computazionale.
| ||
| 425 | return true; | ▶ |
Spiegazione
Se arriviamo a questa riga, significa che l'hash è valido (minore del target). La funzione restituisce true: il blocco ha superato il controllo della Proof of Work e può essere aggiunto alla blockchain.
| ||
Una transazione Bitcoin è il meccanismo con cui i bitcoin si spostano da un indirizzo all'altro. Ogni transazione ha degli "input" (da dove vengono i bitcoin) e degli "output" (dove vanno).
Gli input fanno riferimento agli output di transazioni precedenti. Non esiste il concetto di "saldo": i bitcoin sono sempre output non spesi (UTXO).
Per spendere bitcoin, devi firmare la transazione con la tua chiave privata. La rete verifica la firma con la chiave pubblica corrispondente.
| 1 | class CTxIn { | ▶ |
Spiegazione
CTxIn rappresenta un input di transazione. Un input dice: "sto usando questi bitcoin che qualcuno mi ha inviato in una transazione precedente". Ogni transazione può avere uno o più input.
Come dichiarare "prendo i soldi dal mio conto A" prima di fare un pagamento.
| ||
| 2 | public: | ▶ |
Spiegazione
Sezione pubblica: questi campi sono accessibili da tutto il programma.
| ||
| 3 | COutPoint prevout; | ▶ |
Spiegazione
prevout è il riferimento all'output della transazione precedente che stiamo spendendo. Contiene l'hash della transazione passata e l'indice dell'output specifico (una transazione può avere più output). Questo crea la "catena" di proprietà dei bitcoin.
Come indicare "sto usando l'assegno numero 47 che mi ha dato Maria il 3 marzo" — un riferimento preciso a un'entrata precedente.
| ||
| 4 | CScript scriptSig; | ▶ |
Spiegazione
scriptSig è lo script di sblocco. Contiene la firma digitale e la chiave pubblica del mittente. È la "prova" che chi sta inviando i bitcoin ha davvero il diritto di farlo. Senza una firma valida, la transazione viene rifiutata dalla rete.
Come la firma in calce a un assegno bancario: dimostra che sei tu il proprietario del conto e hai autorizzato il pagamento.
| ||
| 5 | uint32_t nSequence; | ▶ |
Spiegazione
nSequence è un campo multipurpose. Originariamente pensato per le transazioni sostitutive, oggi è usato principalmente per i timelock relativi (RBF - Replace-by-Fee) e per SegWit. Permette di dire "questa transazione non può essere confermata prima di X blocchi".
| ||
| 6 | class CTxOut { | ▶ |
Spiegazione
CTxOut rappresenta un output di transazione. Un output dice: "mando questi bitcoin a questo indirizzo". È l'altra metà di CTxIn. Gli output non spesi (UTXO - Unspent Transaction Output) formano il "saldo" dell'intera rete.
Come un assegno che emetti: specifica quanto vale e chi può incassarlo.
| ||
| 7 | CAmount nValue; | ▶ |
Spiegazione
nValue è la quantità di bitcoin in questo output, espressa in satoshi (1 BTC = 100.000.000 satoshi). Usare satoshi come unità base evita errori con i decimali. CAmount è in realtà un int64_t — un intero a 64 bit.
Come i centesimi di euro: invece di scrivere €0,00001 BTC, Bitcoin conta tutto in "centesimi" chiamati satoshi.
| ||
| 8 | CScript scriptPubKey; | ▶ |
Spiegazione
scriptPubKey è lo script di blocco. Definisce le condizioni che devono essere soddisfatte per spendere questi bitcoin. Normalmente contiene l'hash dell'indirizzo Bitcoin del destinatario. Solo chi possiede la chiave privata corrispondente può creare un scriptSig valido.
Come scrivere su un assegno "pagabile solo a Mario Rossi con documento d'identità". Definisce chi può riscuotere.
| ||
| 9 | class CTransaction { | ▶ |
Spiegazione
CTransaction è la transazione completa: raggruppa uno o più CTxIn e uno o più CTxOut. Una transazione è valida quando: la somma degli input ≥ somma degli output, tutte le firme sono valide, e gli UTXO referenziati non sono già stati spesi.
| ||
| 10 | const int32_t nVersion; | ▶ |
Spiegazione
nVersion indica la versione del formato della transazione. Attualmente Bitcoin usa le versioni 1 e 2. La versione 2 (introdotta con BIP 68) abilita i timelock relativi tramite nSequence. La parola const indica che una volta impostata, non può essere cambiata.
| ||
| 11 | const std::vector<CTxIn> vin; | ▶ |
Spiegazione
vin è la lista degli input. std::vector è un array dinamico (lista) della libreria standard C++. Può contenere zero o più CTxIn. Una transazione con vin vuoto è la "coinbase transaction" — la ricompensa al miner per aver trovato il blocco.
Come la sezione "provenienza fondi" di un bonifico, dove puoi indicare uno o più conti da cui stai prelevando.
| ||
| 12 | const std::vector<CTxOut> vout; | ▶ |
Spiegazione
vout è la lista degli output. Una transazione tipica ha 2 output: uno per il destinatario e uno di "resto" che torna al mittente. La differenza tra input totali e output totali è la commissione al miner.
Come la sezione "destinazione" di un bonifico: puoi mandare a più destinatari in una volta sola.
| ||
| 13 | const uint32_t nLockTime; | ▶ |
Spiegazione
nLockTime è il timelock assoluto. Può essere 0 (nessun lock), un'altezza di blocco, o un timestamp Unix. Se impostato, la transazione non può essere inclusa in nessun blocco fino a quando la blockchain non raggiunge quell'altezza o timestamp.
Come un assegno postdatato: "questo pagamento non può essere incassato prima del 1° gennaio 2025".
| ||
| 14 | uint256 GetHash() const; | ▶ |
Spiegazione
GetHash() calcola e restituisce il TXID (Transaction ID) — l'identificatore univoco della transazione. È calcolato con SHA-256 doppio (SHA256d) su tutti i campi della transazione. Il TXID è quello che vedi quando cerchi una transazione su un block explorer.
Come il numero di ricevuta di un bonifico: un codice univoco che identifica questa specifica transazione tra tutte quelle mai avvenute.
| ||
Il wallet Bitcoin gestisce le chiavi crittografiche che provano la proprietà dei bitcoin. Non contiene bitcoin in sé — contiene le chiavi per accedere agli UTXO registrati nella blockchain.
La chiave privata è un numero casuale a 256 bit. Da essa si deriva la chiave pubblica (matematica a curve ellittiche), e dall'indirizzo Bitcoin. Non è possibile risalire alla chiave privata dalla pubblica.
I wallet moderni generano tutte le chiavi da un unico "seed" di 12/24 parole. Puoi ricostruire tutto il wallet da quella frase seme — perdere le parole significa perdere i bitcoin.
| 1 | class CKey { | ▶ |
Spiegazione
CKey rappresenta una chiave privata Bitcoin. È il dato più sensibile dell'intero sistema. Chiunque posseda questa chiave può spendere i bitcoin associati. Internamente è gestita con molta cura per non esporla mai in memoria più del necessario.
Come il PIN del tuo bancomat: il segreto assoluto che non deve mai essere condiviso o esposto.
| ||
| 2 | private: | ▶ |
Spiegazione
La sezione private: è accessibile solo dall'interno della classe. I dati sensibili come i byte della chiave privata sono dichiarati qui per protezione — nessuna parte esterna del codice può leggerli o modificarli direttamente.
| ||
| 3 | unsigned char keydata[32]; | ▶ |
Spiegazione
keydata è l'array di 32 byte (256 bit) che contiene effettivamente la chiave privata. Ogni byte va da 0 a 255 (unsigned char). 32 byte = 2^256 combinazioni possibili — più atomi dell'universo osservabile. La probabilità di indovinare una chiave privata è astronomicamente bassa.
Come una cassaforte con una combinazione di 78 cifre decimali — impossibile da indovinare con la forza bruta.
| ||
| 4 | bool fCompressed; | ▶ |
Spiegazione
fCompressed indica se la chiave pubblica derivata da questa chiave privata è in formato compresso (33 byte) o non compresso (65 byte). I wallet moderni usano sempre il formato compresso per risparmiare spazio. Questa scelta influenza l'indirizzo Bitcoin risultante.
| ||
| 5 | public: | ▶ |
Spiegazione
Inizia la sezione pubblica: queste funzioni sono l'interfaccia sicura attraverso cui il resto del codice interagisce con la chiave privata, senza mai accedere ai dati grezzi.
| ||
| 6 | void MakeNewKey(bool fCompressed); | ▶ |
Spiegazione
MakeNewKey() genera una nuova chiave privata casuale. Usa il generatore di numeri casuali crittograficamente sicuro del sistema operativo (CSPRNG). Il parametro fCompressed determina se la chiave pubblica sarà compressa. void significa che non restituisce nulla — modifica l'oggetto direttamente.
Come il momento in cui la banca ti assegna un PIN casuale per la prima volta — un numero unico generato in modo sicuro.
| ||
| 7 | CPubKey GetPubKey() const; | ▶ |
Spiegazione
GetPubKey() deriva e restituisce la chiave pubblica corrispondente. Usa la crittografia a curva ellittica secp256k1 (la stessa di Bitcoin). La derivazione è unidirezionale: dalla chiave privata si ottiene la pubblica, ma non viceversa. La chiave pubblica può essere condivisa liberamente.
Come il numero di conto corrente che puoi dare a chiunque voglia inviarti soldi — è pubblico e sicuro da condividere.
| ||
| 8 | bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig) const; | ▶ |
Spiegazione
Sign() crea una firma digitale ECDSA. Prende l'hash della transazione (hash) e produce la firma (vchSig). La firma è matematicamente legata sia alla transazione sia alla chiave privata — cambiare anche un solo bit della transazione invaliderebbe la firma. Il simbolo & indica passaggio per riferimento (efficienza).
Come firmare un contratto con una firma impossibile da falsificare, che certifica sia l'identità del firmatario sia che il documento non è stato alterato.
| ||
| 100 | class CWallet : public WalletStorage { | ▶ |
Spiegazione
CWallet è la classe principale del portafoglio. Il : public WalletStorage significa che eredita da WalletStorage (ereditarietà in C++): CWallet ha tutte le funzionalità di WalletStorage più le proprie. Gestisce chiavi, transazioni, saldi e interazione con la blockchain.
| ||
| 101 | SecureString GetPassphrase() const; | ▶ |
Spiegazione
GetPassphrase() restituisce la passphrase di cifratura del wallet. SecureString è una stringa speciale che viene cancellata dalla memoria immediatamente dopo l'uso, per non lasciare tracce della password in memoria anche dopo che non serve più.
Come un post-it che si autodistrugge dopo la lettura — sicuro perché non lascia tracce.
| ||
| 102 | CAmount GetBalance() const; | ▶ |
Spiegazione
GetBalance() calcola il saldo del wallet sommando tutti gli UTXO (output non spesi) associati agli indirizzi del wallet. Non è un numero memorizzato — viene calcolato ogni volta scorrendo la blockchain. Restituisce il valore in satoshi.
Come contare tutte le banconote nel portafoglio ogni volta che vuoi sapere quanto hai — non c'è un numero scritto da qualche parte, si conta ogni volta.
| ||
| 103 | bool CreateTransaction(const std::vector<CRecipient>& vecSend, | ▶ |
Spiegazione
CreateTransaction() è la funzione che costruisce una nuova transazione da inviare. Riceve la lista dei destinatari (vecSend: a chi mandare e quanto), seleziona gli UTXO da usare come input, calcola il resto, aggiunge la commissione al miner, e firma tutto con la chiave privata.
Come compilare un bonifico bancario: inserisci i destinatari, l'importo, e la banca (= wallet) seleziona automaticamente da quale conto prelevare e calcola le commissioni.
| ||
Bitcoin è una rete peer-to-peer: non c'è un server centrale. Ogni nodo si connette direttamente agli altri, propaga transazioni e blocchi, e mantiene una copia della blockchain.
Un nodo Bitcoin si connette tipicamente a 8-125 peer. Quando riceve una nuova transazione o blocco, la verifica e la propaga agli altri nodi — come un'onda che si espande.
Le informazioni si diffondono come pettegolezzi: ogni nodo le racconta ai vicini, che le raccontano ai loro vicini. In secondi, l'intera rete sa di una nuova transazione.
| 1 | class CNode { | ▶ |
Spiegazione
CNode rappresenta una connessione a un peer della rete. Ogni nodo Bitcoin mantiene una lista di CNode — uno per ogni altro nodo a cui è connesso. Contiene le informazioni sulla connessione, le statistiche, e le code di messaggi in entrata e uscita.
Come la rubrica del telefono: ogni CNode è un contatto con cui il tuo nodo sta parlando.
| ||
| 2 | const NodeId id; | ▶ |
Spiegazione
id è l'identificatore univoco di questa connessione — un numero intero assegnato progressivamente. Non è l'indirizzo IP, ma un ID interno al nodo. const significa che non cambia per tutta la durata della connessione.
| ||
| 3 | CAddress addr; | ▶ |
Spiegazione
addr è l'indirizzo IP e porta del peer (es. 192.168.1.1:8333). La porta standard di Bitcoin è 8333. CAddress supporta IPv4, IPv6, e anche indirizzi Tor (.onion) per la privacy.
Come l'indirizzo fisico di un amico: dove trovarlo sulla rete per parlargli.
| ||
| 4 | std::atomic<int64_t> nLastRecv; | ▶ |
Spiegazione
nLastRecv registra l'ultimo timestamp in cui si è ricevuto un messaggio da questo peer. std::atomic garantisce che l'accesso a questa variabile sia thread-safe — più thread possono leggerla/scriverla contemporaneamente senza conflitti. Usato per rilevare peer disconnessi (timeout).
Come annotare "ultima volta che ho sentito Marco: ieri alle 15:00". Se non risponde per troppo tempo, si considera disconnesso.
| ||
| 5 | bool fInbound; | ▶ |
Spiegazione
fInbound distingue le connessioni in entrata (true: il peer si è connesso a noi) da quelle in uscita (false: siamo noi ad esserci connessi). I nodi accettano fino a 125 connessioni in entrata e ne mantengono circa 8-10 in uscita per sicurezza.
| ||
| 6 | uint64_t nSendBytes; | ▶ |
Spiegazione
nSendBytes conta il totale di byte inviati a questo peer. Usato per le statistiche di banda. Un nodo completo che propaga la blockchain usa tipicamente centinaia di GB al mese in upload.
| ||
| 200 | bool ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv) { | ▶ |
Spiegazione
ProcessMessage() è il cuore della comunicazione P2P. Viene chiamata ogni volta che si riceve un messaggio da un peer. pfrom è il nodo mittente, strCommand è il tipo di messaggio (es. "tx", "block", "inv", "ping"), vRecv è il contenuto del messaggio in formato binario.
Come il centralino di un ufficio: riceve le chiamate e le smista al reparto giusto in base all'argomento.
| ||
| 201 | if (strCommand == "inv") { | ▶ |
Spiegazione
Il messaggio "inv" (inventory) è un annuncio: "ho queste transazioni/blocchi, li vuoi?" Invece di mandare subito i dati completi, i nodi si annunciano a vicenda. Solo se il ricevente non ce li ha, li richiede. Questo evita di trasmettere dati duplicati.
Come dire "ho comprato il giornale di oggi, lo vuoi?" prima di consegnarlo — non lo porti a casa di tutti, solo a chi non ce l'ha.
| ||
| 202 | std::vector<CInv> vInv; | ▶ |
Spiegazione
Crea una lista vuota di CInv (inventory items). Ogni CInv contiene un tipo (transazione o blocco) e un hash. Un singolo messaggio "inv" può annunciare fino a 50.000 elementi contemporaneamente.
| ||
| 203 | vRecv >> vInv; | ▶ |
Spiegazione
L'operatore >> qui è la deserializzazione: converte il flusso di byte grezzi (vRecv) nella struttura dati vInv. È come "decodificare" il messaggio binario ricevuto dalla rete in qualcosa che il programma può usare.
Come tradurre un messaggio in codice Morse in lettere leggibili.
| ||
| 204 | for (const CInv& inv : vInv) { | ▶ |
Spiegazione
Questo è un ciclo for (range-based) che itera su ogni elemento della lista vInv. Per ogni annuncio ricevuto, il codice che segue controlla se lo abbiamo già oppure no. La sintassi for (auto& item : lista) è il modo moderno C++ di scorrere una lista.
Come scorrere un elenco di titoli di giornale, uno per uno, per vedere quali non hai ancora letto.
| ||
| 205 | if (!AlreadyHave(inv)) { | ▶ |
Spiegazione
AlreadyHave() controlla se questa transazione o blocco è già nella mempool (transazioni in attesa) o nella blockchain. Il ! è la negazione: il codice dentro l'if viene eseguito solo se NON abbiamo già quell'elemento.
| ||
| 206 | pfrom->AskFor(inv); | ▶ |
Spiegazione
AskFor() invia al peer un messaggio "getdata": "inviami quell'elemento che hai annunciato". L'operatore -> è usato per accedere ai metodi di un puntatore (pfrom è un puntatore a CNode). Solo a questo punto i dati reali vengono trasferiti.
Come rispondere "sì, mandamelo!" dopo che un amico ti ha detto "ho un articolo interessante".
| ||
| 207 | } else if (strCommand == "tx") { | ▶ |
Spiegazione
Il messaggio "tx" contiene una transazione completa. Quando un nodo riceve questo messaggio, decodifica la transazione, la valida (firme, saldo, ecc.) e se è valida la aggiunge alla mempool (pool di transazioni in attesa di essere incluse in un blocco) e la propaga agli altri peer.
Come ricevere il giornale che avevi richiesto — ora lo leggi per verificare che sia autentico, poi lo passi ai vicini.
| ||
| 208 | } else if (strCommand == "block") { | ▶ |
Spiegazione
Il messaggio "block" contiene un blocco completo. È il messaggio più importante: quando un miner trova un blocco valido, lo propaga immediatamente. Il nodo ricevente verifica la Proof of Work, tutte le transazioni contenute, e se tutto è valido lo aggiunge alla propria blockchain.
Come ricevere la notizia di un nuovo capitolo di storia: verifichi che sia autentico, poi aggiorni i tuoi libri e avvisi gli altri.
| ||
| 209 | } else if (strCommand == "ping") { | ▶ |
Spiegazione
Il messaggio "ping" è il controllo di connettività — come il ping di rete tradizionale. Viene inviato periodicamente per verificare che il peer sia ancora connesso. Il ricevente risponde con un "pong". Se non risponde entro il timeout, la connessione viene chiusa.
Come bussare alla porta per capire se c'è ancora qualcuno — "ci sei?" "sì!" Se non risponde, si considera che non c'è più.
| ||
Questa guida è completamente gratuita e open source, come Bitcoin stesso. Se ti ha aiutato a capire come funziona il protocollo più rivoluzionario della storia della moneta, considera di supportare il progetto.
// BTCPay Server · on-chain & Lightning
Qualsiasi importo è benvenuto