Tracciamento e grafi delle transazioni · Lezione 1 di 6
Grafi delle transazioni e metriche dei grafi
15 min di lettura
Quasi ogni domanda di tracciamento, da "dove sono finiti i fondi rubati?" a "questo deposito è esposto a un servizio soggetto a sanzioni?", è una domanda su un grafo. La scelta di ciò che si rappresenta come nodi e archi determina implicitamente quali risposte siano possibili e, una volta creato il grafo, occorrono metodi per individuare ciò che conta senza esaminare manualmente migliaia di archi. Questa lezione mostra come costruire un grafo difendibile, quindi presenta le metriche e le strutture ricorrenti che gli analisti utilizzano per interpretarlo e spiega perché nessuna di esse costituisca, da sola, una prova.
Tre grafi dagli stessi dati
Gli stessi dati dei blocchi possono essere modellati in tre modi, tra i quali gli analisti passano costantemente.
| Grafo | Nodi | Archi | Impiego ottimale |
|---|---|---|---|
| Grafo delle transazioni | Transazioni (e, nelle blockchain UTXO, gli output che creano) | Un output creato da una transazione e speso da un'altra | Tracciamento UTXO esatto e senza perdita di informazioni |
| Grafo degli indirizzi | Indirizzi | Valore inviato da un indirizzo a un altro | Blockchain basate sul modello ad account, panoramiche rapide |
| Grafo delle entità | Cluster o servizi etichettati | Flussi aggregati tra entità | Redazione di rapporti, esposizione, analisi delle controparti |
Il grafo delle transazioni è quello più vicino ai dati grezzi. In Bitcoin ogni output rimane non speso oppure viene consumato da un solo input successivo; pertanto, le relazioni di spesa formano un grafo orientato aciclico preciso: il denaro non può fluire a ritroso nel tempo e nulla viene inferito. Il grafo degli indirizzi rappresenta ciascun indirizzo come un nodo. È naturale per le blockchain basate sul modello ad account, nelle quali un trasferimento avviene effettivamente da un account a un altro, ma nelle blockchain UTXO introduce ambiguità, come mostra l'esempio seguente. Il grafo delle entità sostituisce gli indirizzi con cluster ("Hot wallet dell'exchange X"). È quello mostrato nella maggior parte dei rapporti, ma ogni nodo dipende dal raggruppamento in cluster e dall'attribuzione, che hanno propri tassi di errore (lezione 4.1); occorre quindi mantenere espandibili i livelli sottostanti a ogni arco tra entità.
Molti strumenti di tracciamento visivo disegnano un grafo bipartito ibrido con due tipi di nodi, indirizzi e transazioni: gli archi vanno da un indirizzo a una transazione (un input) e da una transazione a un indirizzo (un output). Questo conserva l'esattezza del grafo delle transazioni mostrando al contempo chi detiene cosa.
Archi: direzione, peso e tempo
Un arco utile contiene più informazioni di "A ha pagato B". Come minimo, occorre memorizzare:
- Direzione: origine e destinazione. Il tracciamento in avanti segue gli archi uscenti; il tracciamento a ritroso segue quelli entranti.
- Peso: l'importo in unità native dopo la conversione decimale, eventualmente accompagnato dal suo valore in una valuta di riferimento al momento del trasferimento, citando la fonte del prezzo.
- Tempo: altezza del blocco e timestamp del blocco in UTC. L'altezza ordina gli eventi in modo affidabile; i timestamp sono approssimativi (lezione 2.1).
- Identità: hash della transazione più indice dell'output (UTXO), oppure indice del log o posizione nella traccia (modello ad account), affinché l'arco sia univoco e verificabile mediante un nodo.
- Asset: moneta nativa o indirizzo del contratto del token. Non sommare mai archi relativi ad asset diversi.
Due indirizzi possono essere collegati da numerosi archi in momenti diversi (un multigrafo). Aggregarli in un unico arco "totale inviato" è adatto a una visualizzazione, ma distrugge l'ordinamento da cui dipende il tracciamento: i fondi arrivati dopo un pagamento non possono averlo finanziato.
Da una transazione UTXO agli archi
Si consideri una transazione Bitcoin decodificata 4f3a…c21e al blocco 871.204, arricchita con l'indirizzo e il valore di ciascun output speso (gli input grezzi fanno riferimento soltanto a un outpoint, quindi questi campi vengono forniti da un indicizzatore o da una seconda interrogazione):
| Lato | Riferimento | Indirizzo | Valore (BTC) |
|---|---|---|---|
| Input | 9b1e…04aa:1 | bc1q…7k3f | 0,60000000 |
| Input | c07d…e912:0 | bc1q…m2pz | 0,50000000 |
| Output 0 | 4f3a…c21e:0 | bc1q…x9td | 0,80000000 |
| Output 1 | 4f3a…c21e:1 | bc1q…h4wa | 0,29000000 |
Gli input ammontano complessivamente a 1,10 BTC e gli output a 1,09 BTC; la commissione è quindi di 0,01 BTC.
Nel grafo delle transazioni questo corrisponde a un nodo con due archi entranti (gli outpoint) e due archi uscenti (gli output); non è necessaria alcuna ipotesi. Nel grafo degli indirizzi, Bitcoin non specifica quale input abbia finanziato quale output, perché gli input vengono riuniti. Considerando tutti gli abbinamenti si ottengono quattro archi (2 input × 2 output), di cui occorre scegliere i pesi. La scelta comune è l'allocazione proporzionale: il primo input ha fornito 0,60 ÷ 1,10 = 54,55% del valore, quindi gli viene attribuito il 54,55% di ciascun output, mentre al secondo viene attribuito il 45,45%.
| Arco | Calcolo | Peso (BTC) |
|---|---|---|
| bc1q…7k3f → bc1q…x9td | 0,80 × 0,5455 | 0,4364 |
| bc1q…7k3f → bc1q…h4wa | 0,29 × 0,5455 | 0,1582 |
| bc1q…m2pz → bc1q…x9td | 0,80 × 0,4545 | 0,3636 |
| bc1q…m2pz → bc1q…h4wa | 0,29 × 0,4545 | 0,1318 |
La somma dei pesi è 1,09 BTC; la commissione esce dal grafo (alcuni analisti aggiungono un nodo pozzo "commissione" affinché il valore si conservi). Una transazione con 50 input e 50 output creerebbe 2.500 archi di questo tipo, motivo per cui i consolidamenti e i pagamenti in blocco sovraccaricano i grafi degli indirizzi. Stabilire se bc1q…h4wa sia un pagamento o un resto è un'inferenza distinta (lezione 4.2), e la ponderazione proporzionale è soltanto una delle regole di allocazione (lezione 3.3).
Dai dati del modello ad account agli archi
Nelle blockchain di tipo Ethereum, gli archi provengono da tre fonti e un grafo costruito a partire da una sola di esse ometterà parte del denaro:
- Transazioni di primo livello con
valuediverso da zero: dal firmatario all'indirizzoto. - Trasferimenti interni di moneta nativa effettuati dai contratti durante l'esecuzione, che compaiono soltanto nelle tracce (frame
callcon valore). - Trasferimenti di token, decodificati dai log: un evento ERC-20
Transfer(address,address,uint256)ha topic00xddf252ad…b3ef, il mittente e il destinatario nei topic 1 e 2 e l'importo grezzo nel campo dati.
Escludere le transazioni annullate mediante revert (status della ricevuta = 0) e i frame di traccia annullati mediante revert: non hanno trasferito nulla, sebbene il mittente abbia comunque pagato il gas. Trattare i contratti come nodi etichettati, perché un router DEX o un contratto di token è un meccanismo, non una controparte. Uno swap produce solitamente due archi in asset diversi, utente → pool e pool → utente (lezione 5.2).
La maggior parte del lavoro sui grafi inizia con una lista di archi piatta in un data warehouse, costruita a partire dallo schema generico della lezione 2.7 e salvata come tabella edges, riutilizzata dalle query di questo modulo e del successivo:
-- Lista di archi (salvata come edges): ETH nativo dalle tracce più trasferimenti ERC-20
SELECT block_number, block_timestamp, transaction_hash,
from_address AS src, to_address AS dst,
'ETH' AS asset, value / 1e18 AS amount -- da wei a ETH
FROM traces
WHERE value > 0
AND (call_type IS NULL OR call_type = 'call') -- nessuna delegatecall o staticcall
AND status = 1 AND tx_status = 1 -- solo frame eseguiti con successo
AND block_number BETWEEN 21000000 AND 21050000
UNION ALL
SELECT tt.block_number, tt.block_timestamp, tt.transaction_hash,
tt.from_address, tt.to_address,
tt.token_address, tt.amount_raw / POWER(10, tk.decimals)
FROM token_transfers AS tt
JOIN tokens AS tk ON tk.token_address = tt.token_address -- decimali per token
WHERE tt.block_number BETWEEN 21000000 AND 21050000;
La parte relativa alle tracce include sia le chiamate di primo livello sia quelle interne, quindi non richiede la tabella transactions. UNION ALL conserva le righe apparentemente identiche, che rappresentano trasferimenti reali e distinti, e l'intervallo di blocchi condiviso mantiene il risultato delimitato e riproducibile. L'inner join elimina silenziosamente i token assenti da tokens; confrontare il numero di righe (la lezione 2.9 tratta i filtri sulle tracce, la lezione 2.8 i join).
Scelte pratiche prima del tracciamento
- Delimitare il grafo. Definire un punto di partenza, una finestra temporale e un limite di salti prima di eseguire la query; un'espansione senza limiti raggiunge ogni exchange nel giro di pochi salti e cessa di costituire evidenza.
- Contrassegnare i supernodi. Gli hot wallet degli exchange, i bridge e i contratti più utilizzati hanno milioni di archi; contrassegnarli come punti di arresto.
- Adattare l'archiviazione alla domanda. Le liste di archi SQL sono adatte all'aggregazione e al filtraggio; i database a grafo e librerie come NetworkX o igraph sono adatti alla ricerca di percorsi e alla centralità, perciò molti team esportano un sottografo delimitato in uno strumento per grafi.
- Conservare la provenienza su ogni arco: txid, indice, altezza del blocco e query che lo ha prodotto, affinché un altro analista possa ricostruire lo stesso grafo.
Grado e flusso di valore
Le metriche più semplici sono conteggi e somme per nodo, calcolati su una finestra temporale fissa e un singolo asset:
- Grado entrante: numero di controparti distinte che hanno inviato al nodo. Grado uscente: numero di controparti a cui il nodo ha inviato.
- Grado ponderato: valore totale ricevuto e inviato.
- Rapporto di transito: valore in uscita ÷ valore in entrata nella finestra. Un rapporto prossimo a 1 con un breve tempo di detenzione contraddistingue un intermediario che inoltra ciò che riceve anziché conservarlo.
- Periodo di attività e tempo di detenzione: prima e ultima attività e tempo tra ricezione e invio.
Queste metriche, da sole, distinguono molti ruoli. Un wallet personale ha un grado basso e detiene i fondi per settimane. Un indirizzo di deposito di un exchange presenta pochi afflussi da mittenti diversi e deflussi verso un'unica destinazione, il wallet di raccolta. Un hot wallet ha gradi nell'ordine delle decine di migliaia. Un intermediario di riciclaggio ha spesso grado entrante 1, grado uscente da 2 a 20, un rapporto di transito prossimo a 1 e un tempo di detenzione di pochi minuti. La query seguente profila un mese di archi relativi alla moneta nativa.
WITH io AS ( -- una riga per ciascun lato di ogni arco
SELECT dst AS address, src AS peer, amount AS amt_in, 0 AS amt_out, block_timestamp AS ts
FROM edges WHERE asset = 'ETH'
UNION ALL
SELECT src, dst, 0, amount, block_timestamp
FROM edges WHERE asset = 'ETH'
)
SELECT address,
COUNT(DISTINCT CASE WHEN amt_in > 0 THEN peer END) AS in_degree,
COUNT(DISTINCT CASE WHEN amt_out > 0 THEN peer END) AS out_degree,
SUM(amt_in) AS value_in, SUM(amt_out) AS value_out,
SUM(amt_out) / NULLIF(SUM(amt_in), 0) AS pass_through,
MIN(ts) AS first_seen, MAX(ts) AS last_seen
FROM io
WHERE ts >= TIMESTAMP '2026-03-01' AND ts < TIMESTAMP '2026-04-01'
GROUP BY address
HAVING COUNT(DISTINCT CASE WHEN amt_out > 0 THEN peer END) >= 20;
La CTE trasforma ogni arco in una riga per il destinatario e una per il mittente, così un solo GROUP BY restituisce entrambe le direzioni; NULLIF evita la divisione per zero e HAVING conserva i nodi con forte diramazione in uscita. La finestra rileva soltanto l'attività al suo interno: un indirizzo finanziato a febbraio mostra a marzo un rapporto di transito molto superiore a 1.
Centralità
La centralità misura quanto un nodo sia importante per la struttura del grafo, non soltanto quanto sia attivo.
| Metrica | Che cosa misura | Impiego tipico |
|---|---|---|
| Centralità di grado | Numero di connessioni dirette | Individuare hub e servizi |
| Centralità di intermediazione | Frequenza con cui il nodo si trova sui cammini minimi tra altri nodi | Individuare intermediari e colli di bottiglia tra gruppi altrimenti separati |
| PageRank | Importanza ereditata da nodi vicini importanti | Ordinare i nodi in grandi grafi di flusso |
In un sottografo investigativo, un indirizzo con elevata centralità di intermediazione ma grado modesto è spesso il nodo più interessante: il collettore a cui ritorna ogni percorso di dispersione, oppure l'unico ponte tra un cluster legato a un furto e gli exchange usati per monetizzare i fondi. Calcolare la centralità su un sottografo delimitato con i servizi come punti terminali; sull'intera blockchain, gli exchange e i contratti più utilizzati dominano ogni graduatoria. Le librerie per grafi calcolano queste metriche; il solo SQL gestisce il grado, ma non la centralità di intermediazione.
Schemi: fan-out, fan-in e peel chain
Il fan-out si verifica quando un nodo invia a molti nodi in un breve periodo; il fan-in quando molti nodi inviano a uno solo. Entrambi sono normali (prelievi in blocco, raccolte di fondi, pagamenti ai miner, airdrop); le domande da porsi sono chi siano le parti e che cosa accada dopo:
- Dispersione: un indirizzo legato a un furto distribuisce fondi a decine di nuovi indirizzi senza storico precedente, con importi simili. Gli importi simili e i destinatari nuovi distinguono questo schema da un pagamento aziendale.
- Raccolta: molte vittime di una truffa pagano un unico indirizzo (fan-in), che inoltra poi il totale.
- Consolidamento: nelle blockchain UTXO, una transazione fan-in che spende molti output insieme costituisce anche evidenza per il raggruppamento in cluster (lezione 4.1).
Una peel chain, descritta nello studio del 2013 "A Fistful of Bitcoins" di Meiklejohn e colleghi, inizia con un importo elevato su un indirizzo. Ogni transazione distacca un piccolo pagamento e invia il grande resto a un nuovo indirizzo, che ripete il processo. Con una commissione di 0,01 BTC per passaggio:
| Passaggio | Input | Importo distaccato | Residuo (resto) |
|---|---|---|---|
| T1 | 50,00 | 1,20 → deposito presso un exchange | 48,79 |
| T2 | 48,79 | 0,80 → deposito presso un exchange | 47,98 |
| T3 | 47,98 | 2,50 → broker OTC | 45,47 |
| T4 | 45,47 | 0,95 → deposito presso un exchange | 44,51 |
Indizi: un input e due output per transazione; un output molto più grande, speso poco dopo in una transazione con la stessa struttura; lo stesso tipo di script e le stesse impronte del wallet; salti distanziati di pochi minuti o blocchi. Uno studio del 2023 di Gong, Chow, Yiu e Ting ("Analyzing the Peeling Chain Patterns on the Bitcoin Blockchain") ha rilevato che circa il 71% delle transazioni nelle catene identificate distaccava meno dell'1% dell'input e che circa il 79% delle catene veniva creato nell'arco di un giorno. Il resto trasporta la maggior parte del valore, quindi l'analista lo segue e registra ogni distacco come punto di monetizzazione. La struttura non è intrinsecamente illecita: un wallet che paga fatture attingendo a un unico saldo elevato, o un hot wallet che paga i prelievi uno alla volta, presenta lo stesso aspetto.
Stratificazione, cicli e motivi
La stratificazione, la fase del riciclaggio che allontana i fondi dalla loro origine, appare sulla blockchain sotto forma di lunghe catene di indirizzi nuovi e di breve durata, rapidi salti automatizzati, suddivisioni e riunificazioni, swap di asset e passaggi tra blockchain. Nessun singolo salto è sospetto; lo è la combinazione. Il round-tripping è il ritorno di valore al nodo di origine, o a un altro nodo della stessa parte: un ciclo. I cicli brevi possono gonfiare il volume di scambio di un token o NFT (wash trading), simulare uno storico di pagamenti o far ricircolare fondi attraverso un servizio. Il rilevamento dei cicli funziona meglio su un grafo delle entità, perché una parte che restituisce fondi a un proprio indirizzo diverso forma un ciclo soltanto dopo il raggruppamento in cluster.
Un motivo è una piccola struttura di sottografo che ricorre più spesso di quanto previsto dal caso. Un dataset sintetico ampiamente utilizzato per addestrare modelli antiriciclaggio (Altman e colleghi, NeurIPS 2023) ne genera otto: fan-out, fan-in, gather-scatter, scatter-gather, ciclo, bipartito, stack e casuale. Nello scatter-gather, una fonte suddivide i fondi tra intermediari che li inoltrano tutti a un'unica destinazione, aggiungendo salti senza cambiare la titolarità; il gather-scatter consiste in molte fonti che convergono su un nodo che disperde il totale, tipico di un indirizzo di raccolta di una truffa; uno stack è costituito da due livelli di intermediari completamente connessi. Le ricerche di motivi sono query su pattern in database a grafo oppure self-join con vincoli temporali sulla lista di archi. La finestra temporale è il parametro chiave: uno scatter-gather nell'arco di un'ora è un segnale forte; nell'arco di un anno è normale attività commerciale.
Segnali, non conclusioni
Gli archi sono fatti registrati; ruoli, schemi e motivi sono interpretazioni che ammettono spiegazioni lecite. Trattare ciascuno di essi come un motivo per approfondire, combinare segnali indipendenti prima di formulare un'inferenza e registrare le soglie utilizzate (soglie di grado, finestre temporali, tolleranze sugli importi), affinché un altro analista possa riprodurle e contestarle.
Focus sull'esame: la differenza tra grafi delle transazioni, degli indirizzi e delle entità e gli impieghi adatti a ciascuno; perché il grafo di spesa UTXO è esatto mentre il grafo degli indirizzi richiede un'ipotesi di allocazione; il calcolo dei pesi proporzionali degli archi per una transazione con più input e più output; gli attributi necessari per ogni arco e il motivo per cui gli archi paralleli mantengono i propri timestamp; le tre fonti degli archi del modello ad account e il motivo per cui quelli annullati mediante revert vengono esclusi; la delimitazione di un grafo e il trattamento dei supernodi come punti di arresto; grado, rapporto di transito e tempo di detenzione come indicatori di ruolo; centralità di intermediazione su un sottografo delimitato; fan-in, fan-out, peel chain (e il motivo per cui si segue il resto), cicli e motivi scatter-gather come segnali che richiedono riscontri e soglie documentate.