Données on-chain et SQL · Leçon 2 sur 9
Transactions Bitcoin brutes et types de scripts
15 min de lecture
Les explorateurs présentent une transaction Bitcoin sous forme de listes ordonnées d’adresses et de montants, mais cette vue résulte du décodage d’octets bruts, et certaines informations affichées ne figurent pas du tout dans la transaction. La lecture de la structure brute indique à un enquêteur ce qui est enregistré sur la chaîne et ce qu’un outil a déduit, pourquoi les frais ne peuvent pas être calculés à partir d’une transaction seule, et quels champs portent les empreintes de portefeuille sur lesquelles reposent les heuristiques ultérieures. La lecture des formats d’adresse vous indique le type de script utilisé, ce qui permet de circonscrire le logiciel de portefeuille et son époque, ainsi que les informations qui deviendront publiques lorsque les fonds seront dépensés.
La sérialisation, champ par champ
Une transaction est stockée et relayée sous forme de chaîne d’octets. Depuis SegWit (BIP 141, activé en août 2017), il existe deux formes : la forme historique et la forme étendue de BIP 144, utilisée lorsqu’au moins une entrée comporte des données de témoin.
| Champ | Taille | Remarques |
|---|---|---|
| version | 4 octets | Entier en petit-boutiste, généralement 1 ou 2 |
| marqueur, indicateur | 2 octets | 00 01, présents uniquement dans la forme SegWit |
| nombre d’entrées | variable | Entier CompactSize |
| entrées | variable | Chacune : txid précédent (32), indice de sortie (4), longueur du scriptSig et scriptSig, séquence (4) |
| nombre de sorties | variable | Entier CompactSize |
| sorties | variable | Chacune : valeur en satoshis (8), longueur du scriptPubKey et scriptPubKey |
| témoin | variable | Forme SegWit uniquement : pour chaque entrée, un nombre d’éléments et les éléments |
| locktime | 4 octets | Hauteur de bloc ou instant à partir duquel la transaction est valide |
Les entiers sont en petit-boutiste : l’octet de poids faible vient en premier. Un entier CompactSize occupe un octet pour les valeurs inférieures à 253 ; sinon, il comporte un octet de préfixe (fd, fe ou ff) suivi de 2, 4 ou 8 octets. Voici une transaction SegWit à une entrée et deux sorties, décomposée en champs, avec les valeurs longues tronquées :
02000000 version 2
00 01 marqueur et indicateur SegWit
01 nombre d’entrées 1
ab09…1d7c txid précédent, ordre interne des octets (32 octets)
01000000 indice de sortie précédente 1
00 longueur du scriptSig 0 (entrée SegWit native)
fdffffff séquence 0xfffffffd
02 nombre de sorties 2
40420f0000000000 valeur 1 000 000 sat
16 0014 3c1e…9d02 script, 22 octets : P2WPKH
0c6a070000000000 valeur 485 900 sat
16 0014 77b4…e051 script, 22 octets : P2WPKH
02 47 3044…01 21 02a1…5f témoin : 2 éléments, signature (71 octets), clé publique (33 octets)
00000000 locktime 0
Lisez la première valeur en inversant ses octets : 40 42 0f 00 … devient 0x0f4240, soit 1 000 000 satoshis (0,01 BTC). Notez ce qui est absent : aucune adresse d’expéditeur, aucun montant d’entrée et aucuns frais.
Entrées et points de sortie
Une entrée ne contient pas de fonds ; elle pointe vers une sortie antérieure, appelée point de sortie et notée txid:vout. Le txid de 32 octets contenu dans l’entrée est stocké dans l’ordre interne des octets, inverse de celui affiché par les explorateurs : ab09…1d7c dans les octets devient 7c1d…09ab à l’écran. Oublier cette inversion est une cause classique de message « transaction introuvable ».
Le montant et le script dépensé se trouvent dans la sortie précédente ; pour savoir qui a payé et combien, vous devez donc rechercher chaque point de sortie. Le scriptSig de l’entrée (scripts historiques) ou son témoin (scripts SegWit) fournit les données qui satisfont les conditions de la sortie précédente, généralement des signatures et des clés publiques. Une entrée coinbase, qui crée de nouveaux bitcoins, possède un txid précédent entièrement nul et l’indice 0xffffffff.
Séquence, version, locktime et empreintes de portefeuille
Les champs qui entourent les entrées et les sorties semblent être de simples éléments standard, mais ils véhiculent des informations :
- Séquence. Les valeurs inférieures à
0xfffffffesignalent la possibilité de remplacement selon BIP 125,0xfffffffdétant un choix courant. Depuis Bitcoin Core 28.0 (2024), les nœuds acceptent les remplacements par défaut, que la transaction d’origine ait signalé cette possibilité ou non ; aujourd’hui, cette valeur sert donc surtout d’empreinte. Les verrouillages temporels relatifs (BIP 68) utilisent le même champ. - Version. Presque toujours 1 ou 2 ; la version 2 est nécessaire pour les verrouillages temporels relatifs, et les portefeuilles diffèrent dans leur choix de version.
- Locktime. Interprété comme une hauteur de bloc en dessous de 500 000 000 et comme un horodatage Unix au-delà ; zéro signifie qu’il n’y a aucune restriction. De nombreux portefeuilles le définissent à la hauteur courante pour dissuader les mineurs de réécrire des blocs récents afin d’en récupérer les frais (anti-fee-sniping) ; un locktime de 880 213 dans une transaction confirmée à la hauteur 880 214 renseigne donc sur le logiciel qui l’a construite.
Ces valeurs, avec les types de scripts utilisés, l’ordre des sorties et l’encodage des signatures, forment une empreinte de portefeuille. Une empreinte ne prouve rien à elle seule ; une combinaison cohérente d’une transaction à l’autre constitue l’un des signaux utilisés dans la leçon 4.2 pour distinguer un paiement d’un rendu de monnaie.
Scripts de sortie et formats d’adresse
Chaque sortie contient une valeur en satoshis et un scriptPubKey, la condition permettant de la dépenser. Les scripts standard suivent des modèles fixes ; leur type peut donc être déterminé à partir des premiers octets. Une adresse est un encodage d’un script standard, et non un champ de la transaction : les décodeurs la déduisent, et son format révèle le type de script.
| Type | Modèle de scriptPubKey | Octets | Défini dans | Encodage | Adresse | type Bitcoin Core |
|---|---|---|---|---|---|---|
| P2PKH | 76 a9 14 {20} 88 ac | 25 | version d’origine | Base58Check, version 0x00 | 1…, jusqu’à 34 caractères | pubkeyhash |
| P2SH | a9 14 {20} 87 | 23 | BIP 16 | Base58Check, version 0x05 | 3…, 34 caractères | scripthash |
| P2WPKH | 00 14 {20} | 22 | BIP 141 | bech32 | bc1q…, 42 caractères | witness_v0_keyhash |
| P2WSH | 00 20 {32} | 34 | BIP 141 | bech32 | bc1q…, 62 caractères | witness_v0_scripthash |
| P2TR | 51 20 {32} | 34 | BIP 341 | bech32m | bc1p…, 62 caractères | witness_v1_taproot |
| OP_RETURN | 6a … | variable | — | aucun | aucune | nulldata |
Dans P2PKH, 76 a9 14 … 88 ac correspond à OP_DUP OP_HASH160 {empiler 20 octets} OP_EQUALVERIFY OP_CHECKSIG. Les sorties SegWit commencent par un opcode de version (00 pour la version 0, 51 pour la version 1, Taproot), suivi de l’empilement du programme. Une sortie OP_RETURN est démontrablement non dépensable et contient des données, pas de valeur. Les réseaux de test utilisent d’autres préfixes (m ou n pour P2PKH, 2 pour P2SH, tb1 pour SegWit) ; une adresse de réseau de test isolée dans un jeu de données est donc facile à repérer. Certains anciens scripts, comme les premières sorties de paiement à clé publique et les scripts multisignatures nus, n’ont aucune adresse standard ; les entrepôts de données peuvent laisser la colonne d’adresse vide, et un filtre sur address IS NOT NULL les élimine silencieusement.
Base58Check
Les adresses historiques prennent un octet de version, lui ajoutent la charge utile de 20 octets (un HASH160 d’une clé publique ou d’un script), ajoutent une somme de contrôle constituée des 4 premiers octets de SHA-256(SHA-256(version ‖ charge utile)), puis écrivent les 25 octets dans un alphabet de 58 caractères sans 0, O, I ni l. Chaque octet nul initial devient un 1 initial, ce qui explique pourquoi toutes les adresses P2PKH commencent par ce caractère. L’encodage est sensible à la casse et la somme de contrôle rejette presque toutes les fautes de frappe. L’octet de version est la clé de classification : 0x00 signifie P2PKH, 0x05 P2SH, toute autre valeur désigne un autre réseau ou une autre cryptomonnaie.
Bech32 et bech32m
Les adresses SegWit natives utilisent bech32 (BIP 173) : une partie lisible par l’humain (bc pour le réseau principal, tb pour le réseau de test), le séparateur 1, et une partie de données dans un alphabet de 32 caractères qui exclut 1, b, i et o. Le premier caractère des données est la version du témoin (q = 0, p = 1), suivie du programme et d’une somme de contrôle de 6 caractères. Un programme de 20 octets donne 42 caractères (P2WPKH), un programme de 32 octets en donne 62 (P2WSH). Bech32 s’écrit entièrement en minuscules (les majuscules sont autorisées pour les codes QR, mais un mélange de casse doit être rejeté), comporte au plus 90 caractères, et sa somme de contrôle détecte toute erreur affectant jusqu’à quatre caractères.
Il présente un défaut : lorsqu’une chaîne se termine par p, l’insertion ou la suppression de caractères q juste avant celui-ci peut laisser la somme de contrôle valide. Les longueurs de programme strictes de la version 0 rendent ce défaut généralement sans conséquence, mais les versions ultérieures autorisent d’autres longueurs ; BIP 350 a donc introduit bech32m, identique à l’exception de la constante de somme de contrôle (0x2bc830a3 au lieu de 1). La version 0 conserve bech32 ; les versions 1 à 16, dont Taproot, utilisent bech32m, et les décodeurs doivent rejeter une somme de contrôle inadaptée à chaque version. Dans les chaînes de traitement, ne classez jamais les adresses sur le seul critère « commence par bc1 » : lisez le quatrième caractère et la longueur. Les analyseurs syntaxiques écrits avant 2021 peuvent rejeter des adresses bc1p valides, et une chaîne de traitement qui supprime les lignes impossibles à analyser sous-estime l’activité Taproot sans avertissement.
Données de témoin, poids et taille
SegWit déplace les signatures dans un témoin distinct. Son contenu dépend du type de sortie dépensée :
- P2WPKH : une signature DER avec un octet sighash (généralement 71 ou 72 octets) et une clé publique compressée de 33 octets.
- P2WSH : les éléments qui satisfont les conditions, suivis du script de témoin lui-même ; la politique de dépense ne devient donc visible qu’au moment où la sortie est dépensée.
- P2TR par chemin de clé : une signature Schnorr de 64 octets (BIP 340), ou de 65 octets avec un type sighash autre que celui par défaut. Une dépense par chemin de script révèle un script (BIP 342) et un bloc de contrôle.
- SegWit encapsulé dans P2SH : le scriptSig ne contient qu’un court script de rachat tel que
0014…, et les signatures se trouvent dans le témoin.
Les octets du témoin bénéficient d’une pondération réduite. BIP 141 définit le poids comme taille de base × 3 + taille totale, la taille de base excluant le marqueur, l’indicateur et le témoin ; la taille virtuelle (vsize) correspond au poids ÷ 4, arrondi à l’entier supérieur, et les taux de frais sont exprimés par vbyte. Dans l’exemple, la forme de base fait 113 octets et la section de témoin, marqueur et indicateur compris, ajoute 109 octets, soit 222 octets au total. Le poids est de 113 × 3 + 222 = 561, et 561 ÷ 4, arrondi à l’entier supérieur, donne 141 vbytes.
La vue décodée et les frais
L’appel getrawtransaction de Bitcoin Core avec un niveau de détail de 2 renvoie la transaction décodée, ainsi que chaque sortie dépensée (prevout) et les frais, lorsque le nœud dispose des données d’annulation du bloc (la leçon 2.1 traite des appels au nœud) :
{
"txid": "4f3a…c21e", "hash": "9b07…e4d2",
"version": 2, "size": 222, "vsize": 141, "weight": 561, "locktime": 0,
"vin": [{
"txid": "7c1d…09ab", "vout": 1,
"scriptSig": {"asm": "", "hex": ""},
"txinwitness": ["3044…01", "02a1…5f"],
"prevout": {"value": 0.01500000, "height": 868120,
"scriptPubKey": {"type": "witness_v0_keyhash", "address": "bc1q…7k3f"}},
"sequence": 4294967293
}],
"vout": [
{"value": 0.01000000, "n": 0,
"scriptPubKey": {"type": "witness_v0_keyhash", "address": "bc1q…m2d8"}},
{"value": 0.00485900, "n": 1,
"scriptPubKey": {"type": "witness_v0_keyhash", "address": "bc1q…x9qa"}}
],
"fee": 0.00014100
}
Les frais ne sont jamais inscrits dans la transaction ; ils correspondent aux entrées moins les sorties. Ici, l’unique point de sortie vaut 1 500 000 sat, les sorties totalisent 1 000 000 + 485 900 = 1 485 900 sat, les frais sont donc de 14 100 sat, et 14 100 ÷ 141 = 100 sat/vB. Un simple appel à decoderawtransaction renvoie la même structure sans prevout ni fee, car il ne peut pas consulter les sorties précédentes. Les montants arrivent en BTC sous forme de nombres JSON ; convertissez-les en nombres entiers de satoshis avant tout calcul (leçon 2.6). Une transaction coinbase n’a pas de frais : ses sorties réclament la subvention plus tous les autres frais. La leçon 2.9 présente le même calcul en SQL sur les tables d’entrées et de sorties.
txid et wtxid
Le txid est le double SHA-256 de la transaction sérialisée sans marqueur, indicateur ni témoin ; le wtxid est le hachage de la forme SegWit complète, et Bitcoin Core l’affiche sous le nom hash. Sans données de témoin, les deux sont identiques. L’exclusion du témoin a corrigé la malléabilité par des tiers : modifier l’encodage d’une signature changeait auparavant le txid d’une transaction par ailleurs identique. Les modifications du témoin ne changent désormais que le wtxid, si bien que des chaînes de transactions non confirmées peuvent se référencer mutuellement en toute sécurité. Les blocs s’engagent sur les wtxid au moyen d’un engagement de témoin dans la coinbase. Dans les rapports, identifiez les transactions par leur txid dans l’ordre d’affichage des octets.
Ce que les scripts révèlent sur les portefeuilles et la conservation des fonds
Les formats d’adresse retracent l’histoire des portefeuilles :
1…: anciens portefeuilles, services limités aux formats historiques, certains portefeuilles de plateformes d’échange établis de longue date ; une nouvelle activité P2PKH aujourd’hui indique souvent un logiciel ancien ou personnalisé.3…: ambigu jusqu’à la dépense : multisignature ou portefeuille à clé unique utilisant SegWit imbriqué, un choix par défaut courant vers 2017–2019. Lors de la dépense, le script de rachat lève l’ambiguïté :0014plus 20 octets correspond à P2WPKH imbriqué,0020plus 32 octets à P2WSH imbriqué, et un script se terminant parae(OP_CHECKMULTISIG) à la multisignature classique.bc1q…: type de réception par défaut de la plupart des portefeuilles grand public ces dernières années ; P2WSH sur 62 caractères signifie généralement multisignature ou autre script personnalisé.bc1p…: portefeuilles ayant adopté Taproot après son activation au bloc 709 632 en novembre 2021, ainsi que les outils d’inscription et de jetons.
Les types de scripts peuvent aussi être mélangés au sein d’une transaction : si toutes les entrées sont P2WPKH et que les sorties sont une P2WPKH et une P2SH, la sortie dont le type correspond à celui des entrées est plus susceptible d’être le rendu de monnaie (une heuristique, pas un fait ; voir la leçon 4.2).
Multisignature classique
La multisignature classique masque sa politique tant que les fonds restent non dépensés (seul un hachage figure sur la chaîne) et la publie lors de la première dépense. Une entrée P2WSH à 2 signatures sur 3 :
witness[0] (vide) -- élément factice requis par OP_CHECKMULTISIG
witness[1] 3044…01 -- première signature (DER, octet sighash 01)
witness[2] 3045…01 -- deuxième signature
witness[3] 5221…21…21…53ae -- OP_2 <key1> <key2> <key3> OP_3 OP_CHECKMULTISIG
52 correspond à OP_2 (deux signatures requises), chaque 21 empile une clé de 33 octets, 53 correspond à OP_3 et ae à OP_CHECKMULTISIG. Une seule dépense révèle le seuil, les trois clés publiques et les deux qui ont signé. Les dépositaires appliquent souvent des politiques distinctives (2 sur 3, 3 sur 5), et la présence de la même clé publique dans de nombreux scripts multisignatures relie ces adresses à un même détenteur de clé bien plus sûrement que les heuristiques comportementales. De nombreux portefeuilles trient les clés par ordre lexicographique (BIP 67), ce qui constitue en soi une petite empreinte.
Taproot
Taproot combine des signatures Schnorr avec des clés de 32 octets ne contenant que la coordonnée x (BIP 340), une clé de sortie Q = P + t·G où P est une clé interne et où l’ajustement t engage P et la racine de Merkle d’un arbre de scripts facultatif (BIP 341), ainsi que des règles de script qui remplacent OP_CHECKMULTISIG par OP_CHECKSIGADD (BIP 342).
| Dépense | Témoin | Ce qu’un analyste apprend |
|---|---|---|
| Multisignature P2WSH à 2 signatures sur 3 | Deux signatures plus le script complet | Le seuil, toutes les clés, les clés qui ont signé |
| P2TR par chemin de clé | Une signature de 64 octets (65 avec sighash explicite) | Rien sur la politique |
| P2TR par chemin de script | Script de la feuille, ses entrées, bloc de contrôle de 33 + 32m octets | La seule condition utilisée, sa profondeur m, la clé interne |
Sur le chemin de clé, un portefeuille à clé unique, un groupe n sur n utilisant l’agrégation de clés (MuSig2) et un schéma à seuil ont tous la même apparence. Le chemin de script ne révèle que la feuille utilisée, même si la longueur du chemin de Merkle laisse filtrer des informations sur la taille de l’arbre. Taproot supprime l’empreinte multisignature chaque fois que le chemin de clé est utilisé ; il ne masque ni les montants, ni le graphe, ni la chronologie, et le format bc1p lui-même distingue toujours ses utilisateurs. Les dépenses par chemin de script portent aussi des inscriptions : depuis 2023, des témoins volumineux comportant une enveloppe OP_FALSE OP_IF … OP_ENDIF intègrent des images et des données de jetons, un motif à exclure de l’analyse des paiements.
Points clés pour l’examen : préparez-vous à décoder ou à classer, et pas seulement à restituer des connaissances : ordre et taille des champs, valeurs en petit-boutiste et CompactSize ; points de sortie et ordre inversé des octets du txid ; modèles de scriptPubKey, BIP, préfixes et longueurs (1,3,bc1qsur 42 et 62 caractères,bc1psur 62) ; octets de version Base58Check et distinction entre bech32 et bech32m ; fait que les adresses, les montants d’entrée et les frais sont déduits, et non stockés ; calcul du poids et de la vsize ; calcul des frais à partir des sorties précédentes ; distinction entre txid et wtxid et malléabilité ; manière dont une dépense P2SH lève l’ambiguïté, ce qu’une dépense multisignature révèle, et ce que les dépenses Taproot par chemin de clé et par chemin de script masquent.
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