Traçage et graphes de transactions · Leçon 6 sur 6
Outils, reproductibilité et validation
15 min de lecture
Presque tout traçage de cryptomonnaies est réalisé à l’aide de logiciels, dont beaucoup sont propriétaires, évoluent rapidement et imposent des choix méthodologiques. Le tribunal n’a pas besoin de faire confiance à l’outil, mais il doit pouvoir se fier à la conclusion. Cette confiance repose sur la démonstration que les faits peuvent être établis à nouveau à partir des données brutes de la chaîne, que l’outil a été testé pour la tâche à accomplir, que chaque paramètre, version et source d’étiquettes a été consigné, et qu’une autre personne exécutant les mêmes requêtes sur les mêmes données obtient les mêmes lignes. Les habitudes qui rendent les requêtes peu coûteuses (périmètres restreints, plages figées, versions explicites) sont aussi celles qui les rendent reproductibles.
Le panorama des outils
Ce ne sont pas les noms des produits qui importent, mais ce que chaque catégorie apporte aux éléments de preuve.
| Catégorie | Exemples | Apport | Statut probatoire |
|---|---|---|---|
| Logiciels de nœud | Bitcoin Core, Geth, Erigon (open source) | Données brutes validées de la chaîne | Source de référence pour les faits |
| Explorateurs de blocs | Explorateurs web publics | Vues pratiques, souvent assorties d’étiquettes | Aide au travail ; ne constitue pas une pièce du dossier sans capture accompagnée de sa provenance |
| ETL et entrepôts de données | Cadres ETL open source, jeux de données publics de blockchains | Tables permettant d’utiliser SQL à grande échelle | Faits si les données sont rapprochées de celles d’un nœud |
| Plateformes d’investigation | Plateformes commerciales ; projets open source tels que GraphSense | Regroupements, étiquettes, vues en graphe, moteurs d’allocation | Interprétation ; nécessite une validation et la communication des paramètres |
| Scripts et notebooks internes | SQL, Python | Exactement la logique que vous choisissez | Méthode interne ; doit elle-même être testée |
La plupart des services en utilisent plusieurs à la fois : une plateforme pour explorer et dégager des pistes, un nœud et leurs propres requêtes pour établir les faits, et un rapport fondé sur les deux. La pile de données elle-même est traitée dans la leçon 2.7.
Faits, transformations et interprétations
Chaque résultat d’outil mêle trois couches. Les faits sont les données brutes de la chaîne : txid, sorties, montants, blocs. Les transformations déterministes rendent les données brutes lisibles : conversion d’unités, décodage d’événements, traces. Les interprétations ajoutent une appréciation : regroupements, étiquettes, identifications de monnaie rendue, résultats d’allocation.
Un outil peut se tromper à chaque couche. Il peut mal analyser les données (nombre de décimales d’un jeton, transfert interne omis, réorganisation mal gérée), présenter des lacunes de couverture (jeton non indexé, chaîne non prise en charge, données en retard sur la tête de chaîne), ou appliquer des paramètres par défaut que l’examinateur n’a jamais choisis (heuristique de monnaie rendue activée, méthode d’allocation prédéfinie). La règle de travail est la suivante : chaque fait figurant dans un rapport d’analyse forensique doit pouvoir être relié à des données brutes qu’un tiers peut vérifier sur son propre nœud, et chaque interprétation doit préciser sa méthode et ses paramètres. Une capture d’écran d’une vue en graphe illustre ; elle ne prouve pas. Conservez les exports sous-jacents.
Reproduire un traçage à partir des données brutes
Avant de présenter un traçage dans un rapport, reproduisez-le indépendamment de l’outil qui l’a produit :
- exportez le chemin établi par l’outil sous forme de table des sauts : txid, référence de sortie ou de journal, hauteur de bloc, montant en unités de base ;
- établissez à nouveau les mêmes champs à partir de votre propre nœud ou d’un entrepôt de données rapproché d’un nœud ;
- comparez-les champ par champ ;
- recalculez les allocations avec votre propre script selon la méthode déclarée ;
- consignez les différences et la manière dont chacune a été résolue.
-- Comparer les sauts exportés par l’outil aux valeurs établies à nouveau à partir de notre propre nœud
SELECT t.hop_id, t.txid, t.out_ref,
t.amount_base AS tool_amount, n.amount_base AS node_amount,
t.block_height AS tool_height, n.block_height AS node_height,
CASE
WHEN n.txid IS NULL THEN 'NOT FOUND ON NODE'
WHEN t.amount_base <> n.amount_base
OR t.block_height <> n.block_height THEN 'MISMATCH'
ELSE 'OK'
END AS check_result
FROM tool_hops t
LEFT JOIN node_hops n ON n.txid = t.txid AND n.out_ref = t.out_ref
ORDER BY t.hop_id;
La jointure gauche conserve chaque saut signalé par l’outil : un saut absent des données du nœud apparaît donc sous la valeur « NOT FOUND ON NODE » au lieu de disparaître. Les montants sont comparés sous forme d’entiers en unités de base ; une erreur de décimales apparaît donc comme un écart d’une puissance de dix. La requête ne vérifie que les faits ; leur concordance ne dit rien de la justesse des étiquettes ou des identifications de monnaie rendue de l’outil.
Valider les outils
Les normes applicables aux laboratoires exigent de démontrer que les méthodes, ainsi que les outils qui les mettent en œuvre, sont adaptés à l’usage prévu. ISO/IEC 17025 exige que les laboratoires valident les méthodes non normalisées, les méthodes développées par le laboratoire et les méthodes normalisées utilisées en dehors de leur domaine d’application prévu ou modifiées d’une autre manière (clause 7.2.2). ISO/IEC 27041 fournit des lignes directrices pour s’assurer que les méthodes d’investigation sont appropriées et adéquates. Le système qualité qui encadre ces activités est traité dans la leçon 8.3 ; ici, l’accent est mis sur les outils.
Le document du SWGDE intitulé Exigences minimales pour les tests des outils utilisés en analyse forensique numérique et multimédia (document 18-Q-001, version 2.1, mars 2024) décrit trois stratégies de test, toutes applicables aux outils de blockchain : les tests sur des jeux de données connus (données d’entrée dont le résultat attendu est connu), les tests comparatifs (au moins deux outils, dont on vérifie la cohérence) et les tests empiriques (résultats vérifiés par rapport à d’autres données). Il demande des enregistrements de test précisant l’objectif et le périmètre, la personne chargée du test, la date, la procédure, les jeux de données et les résultats attendus, les résultats obtenus avec leurs anomalies, ainsi que les limites constatées. Il recommande également de tester à nouveau les outils internes lors de leur première utilisation et après chaque révision, et les outils de recherche après les mises à jour majeures. Le programme Computer Forensics Tool Testing (CFTT) du NIST propose un modèle de structuration des tests : il est axé sur les fonctionnalités et prévoit la rédaction d’une spécification des exigences, des assertions et des cas de test pour chaque fonction de l’outil avant les tests.
Un plan de test pratique énumère chaque fonction d’un outil de blockchain et lui associe un résultat attendu connu :
| Fonction | Test à résultat attendu connu |
|---|---|
| Analyse des montants et des frais | Transactions comportant de nombreuses sorties, de la poussière et des types de scripts inhabituels, vérifiées par rapport à un nœud |
| Transferts internes | Appels de contrats qui versent de l’ETH, comparés à une trace issue d’un nœud doté de fonctions de traçage |
| Gestion des jetons | Jetons à 6 et 18 décimales, jeton prélevant des frais au transfert, jeton contrefait reprenant un symbole existant |
| Regroupement | Transactions réalisées par le service lui-même à partir de portefeuilles qu’il contrôle, ainsi que des données de référence publiques telles que des adresses publiées par les autorités ; mesurer la précision et le rappel (leçon 4.4) |
| Moteur d’allocation | Le registre de calcul détaillé de la leçon 3.3 : FIFO doit renvoyer 30 000, 20 000 et 0 USDT |
Les transactions de test contrôlées sont particulièrement précieuses, car le service connaît la réalité de la propriété et de la monnaie rendue. Toutes les constatations sont consignées dans un registre des limites connues, que les examinateurs consultent avant de s’appuyer sur l’outil et qui peut être communiqué aux parties.
Des requêtes peu coûteuses et reproductibles
Les tables couvrant tout l’historique comptent des milliards de lignes, et une même question peut coûter quelques centimes et prendre quelques secondes, ou entraîner une dépense substantielle et une heure d’exécution.
Comment les moteurs lisent les données. Les entrepôts stockent les données par colonne : une requête ne lit donc que les colonnes qu’elle nomme ; SELECT * lit aussi les volumineuses données d’appel, et la facturation à la lecture est proportionnelle au nombre d’octets lus. Les grandes tables sont partitionnées, généralement par jour d’horodatage des blocs ou par plage de blocs, et un filtre sur la colonne de partitionnement permet au moteur d’ignorer des partitions entières (élagage des partitions). LIMIT 10 ne réduit pas le coût d’une lecture sur la plupart des entrepôts, et un filtre sur une colonne autre que celle de partitionnement, telle que to_address, n’élague rien. Vérifiez les octets ou les partitions au moyen d’une exécution à blanc ou de EXPLAIN avant d’interroger tout l’historique. À titre d’ordre de grandeur, Ethereum produit environ 7 200 blocs par jour (un par créneau de 12 secondes), soit environ 50 000 blocs par semaine ; Bitcoin en produit environ 144 par jour.
Plages de blocs et fenêtres temporelles. Les analystes raisonnent en hauteurs de bloc ; les tables sont partitionnées par temps. Consultez la petite table blocks pour trouver les horodatages couvrant la plage, puis filtrez la grande table selon les deux critères : des horodatages littéraux élargis à des journées entières sur la colonne de partitionnement brute, et la plage de blocs exacte. Une fenêtre fournie par une jointure ou une sous-requête, ou une colonne enveloppée dans une fonction telle que CAST(block_timestamp AS DATE), peut désactiver l’élagage sur certains moteurs.
Extraire une seule fois. Récupérez tous les transferts impliquant les adresses de l’affaire dans la plage de blocs concernée au moyen d’une seule requête bien filtrée, enregistrez-les dans une petite table ou un fichier Parquet, puis effectuez vos itérations localement. La lecture coûteuse n’a lieu qu’une fois, et l’extrait sert également d’instantané figé des éléments de preuve.
L’échantillonnage convient à l’exploration d’une table ou au test d’une logique, jamais aux totaux, au traçage ou aux événements rares : la valeur sur la chaîne se concentre dans quelques transferts importants qu’un échantillon de 1 % manque généralement. L’échantillonnage au niveau du stockage (TABLESAMPLE SYSTEM) renvoie des lignes regroupées et, sur certains moteurs, un échantillon différent à chaque exécution. Un filtre fondé sur le hachage, tel que la sélection des hachages de transaction se terminant par 00, conserve environ 1 ligne sur 256 (0,39 %), les mêmes à chaque exécution, sans toutefois réduire le coût de la lecture.
Chargements incrémentaux. Les traitements de surveillance ne devraient traiter que les nouveaux blocs, mais les blocs récents peuvent être réorganisés, et un traitement qui se contente d’ajouter des lignes conserve celles de blocs qui n’existent plus. Chaque exécution devrait supprimer puis recharger une plage de reprise (par exemple, à partir du bloc chargé le plus élevé moins 64) jusqu’au dernier bloc finalisé, dans une seule transaction de base de données, afin qu’une nouvelle exécution produise la même table : le traitement est idempotent. Sur Ethereum, la finalité est normalement atteinte après environ deux époques, soit quelque 13 minutes ; sur Bitcoin, une plage de reprise d’au moins six blocs est une convention courante.
Consigner les versions, les paramètres et les sources d’étiquettes
Un résultat est reproductible lorsqu’une autre personne, ou vous-même un an plus tard, peut exécuter la même requête sur les mêmes données et obtenir les mêmes lignes. Cela exige un périmètre figé (plages de blocs, jamais CURRENT_DATE ni « les 30 derniers jours ») ; du SQL placé sous gestion de versions et référencé par son commit ; un résultat déterministe, trié selon une clé complète telle que le numéro de bloc suivi de l’index du journal, sans fonctions approximatives dans les chiffres présentés ; et des versions de données consignées pour l’instantané du jeu de données et les entrées modifiables telles que les tables d’étiquettes et de prix. Chaque exécution d’analyse fait ensuite l’objet d’un enregistrement conservé dans le dossier de l’affaire :
{
"run_id": "CF-2026-0142-R07",
"started_utc": "2026-03-05T08:40:12Z",
"tool": {"category": "investigation platform", "version": "8.4.1", "data_through_block": 939336},
"node": {"client": "Bitcoin Core", "version": "29.0", "tip_height": 939388},
"settings": {"allocation": "haircut", "hop_limit": 6, "change_heuristic": "on",
"stop_at": "labeled custodial services"},
"labels_used": [
{"address": "bc1q…dx7e", "label": "Exchange K deposit", "source": "platform cluster 4471",
"basis": "co-swept with known deposits", "retrieved_utc": "2026-03-05T08:52:40Z"}
],
"queries": [{"file": "rederive_hops.sql", "commit": "9c41e2a", "blocks": [938940, 939050]}],
"exports": [{"file": "R07_hops.csv", "sha256": "3b1f…9e02"}],
"examiner": "EX-07"
}
L’enregistrement fige la version de l’outil et la hauteur de bloc atteinte par ses données, qui peuvent être en retard sur la tête de chaîne du nœud, ainsi que chaque paramètre qui modifie les résultats. Chaque étiquette est accompagnée de sa source, de son fondement et de sa date et heure de récupération, car les étiquettes changent. Chaque export est haché, afin qu’un réviseur puisse confirmer qu’il a reproduit exactement les mêmes lignes. Le véritable nom de l’outil figure dans l’enregistrement réel. La conservation de ces fichiers est traitée dans les leçons 8.2 et 8.3.
Valider les données par rapport à un nœud
Les jeux de données sont constitués par des logiciels susceptibles de défaillir. Avant d’intégrer un chiffre à un rapport, vérifiez-en un échantillon par rapport à la source (leçon 2.6) : comparez un solde calculé à eth_getBalance, ou à balanceOf appelé via eth_call, au même bloc ; comparez les hachages de blocs stockés à ceux du nœud (getblockhash sur Bitcoin, eth_getBlockByNumber sur les chaînes EVM) pour détecter des lignes provenant de blocs orphelins ; comparez le nombre de transactions de chaque bloc aux lignes effectivement chargées ; et vérifiez la continuité.
-- Contrôle de continuité : lacunes dans les numéros de blocs et ruptures des liens avec les parents
SELECT number, prev_number, parent_hash, prev_hash
FROM (SELECT number, parent_hash,
LAG(number) OVER (ORDER BY number) AS prev_number,
LAG(hash) OVER (ORDER BY number) AS prev_hash
FROM blocks
WHERE number BETWEEN 21100000 AND 21107199) AS s
WHERE number <> prev_number + 1 -- un bloc manquant
OR parent_hash <> prev_hash; -- un bloc d’une autre branche
Toute ligne renvoyée signale un problème : un bloc manquant ou un bloc stocké qui n’est pas relié à son prédécesseur. Un résultat vide sur la plage de blocs de l’affaire, associé à des vérifications ponctuelles concordantes, permet d’écrire que les données ont été validées.
Lorsque les outils divergent
Les divergences entre outils sont normales et utiles : elles indiquent où commence l’interprétation. Reprenez le parcours de la leçon 3.2. L’outil A indique que 0,90909091 BTC de la rançon ont atteint bc1q…dx7e et étiquette cette adresse comme une adresse de dépôt de la plateforme d’échange K. L’outil B indique 1,20000000 BTC et ne lui attribue aucune étiquette. Partez du premier point de divergence et remontez aux données brutes :
| Divergence | Cause profonde identifiée | Résolution |
|---|---|---|
| Montant | L’outil A utilise par défaut la méthode proportionnelle ; l’outil B applique FIFO selon l’ordre des entrées et des sorties au sein de chaque transaction, ce qui attribue la totalité de la sortie de 1,2 BTC à la rançon | Les deux calculs sont corrects selon leur règle ; indiquez la méthode déclarée et la plage de valeurs dans le rapport |
| Étiquette | L’étiquette de l’outil A repose sur un balayage regroupant des dépôts connus de la plateforme d’échange K ; l’outil B ne dispose d’aucune source d’étiquette pour ce regroupement | Vérifiez le balayage sur un nœud ; présentez l’attribution comme une heuristique de niveau C jusqu’à confirmation par la plateforme d’échange K |
Les causes courantes comprennent des regroupements différents (un outil a fusionné deux regroupements), des identifications différentes de monnaie rendue, des sources ou des dates d’étiquettes différentes, des méthodes d’allocation par défaut différentes, des transferts internes ou des jetons manquants, et des blocs de clôture différents. Consignez la divergence, sa cause et sa résolution dans le dossier de l’affaire, et ne la tranchez jamais en choisissant l’outil qui donne la réponse la plus commode. Les experts de la défense examinent souvent de près l’opacité des outils et la provenance des étiquettes (leçon 8.4).
Points clés pour l’examen : les catégories d’outils et l’apport de chacune aux éléments de preuve ; les faits, les transformations déterministes et les interprétations, ainsi que les défaillances possibles des outils à chaque couche ; pourquoi les faits présentés doivent pouvoir être établis à nouveau à partir des données brutes et pourquoi les captures d’écran n’ont qu’un rôle d’illustration ; la reproduction d’un traçage et la comparaison des exports d’outils avec les données d’un nœud ; la clause 7.2.2 d’ISO/IEC 17025 et ISO/IEC 27041 ; les trois stratégies de test du SWGDE, les enregistrements de test et les nouveaux tests ; le modèle du NIST CFTT axé sur les fonctionnalités ; les tests à résultat attendu connu et le registre des limites connues ; le coût de la lecture par colonne, l’élagage des partitions au moyen de plages littérales et la conversion des plages de blocs en fenêtres temporelles ; les cas où l’échantillonnage est acceptable ; les chargements incrémentaux avec une plage de reprise en cas de réorganisation jusqu’à la tête de chaîne finalisée ; les éléments d’une requête reproductible et les champs d’un enregistrement d’exécution ; les contrôles auprès d’un nœud concernant les soldes, les hachages de blocs, les décomptes et la continuité ; le diagnostic et la consignation des divergences entre outils.
Questions d’entraînement
Vérifiez votre compréhension. Ces questions ne comptent pas pour l’examen.
Connectez-vous pour enregistrer votre progression et reprendre là où vous vous êtes arrêté. C’est gratuit. Se connecter