Glossaire / Minage et consensus
Bloc sérialisé
- Qu'est-ce qu'un bloc sérialisé ?
- Un bloc sérialisé est la chaîne d'octets exacte qu'un bloc devient sur le réseau ou sur le disque : l'en-tête de 80 octets, un nombre de transactions, puis chaque transaction dans l'ordre.
Spécifié dans BIP-144.
La sérialisation est la manière dont un bloc abstrait devient quelque chose que vous pouvez hacher, envoyer et stocker. Le bloc de genèse se sérialise en 285 octets : 80 pour l'en-tête, 1 pour le nombre de transactions et 204 pour son unique transaction coinbase. Si vous avez déjà collé du hex brut dans un explorateur de blocs ou lancé getblock avec verbosity 0, c'est ce que vous regardiez.
Comment cela fonctionne
Trois éléments se succèdent dans un bloc sérialisé et seul le premier a une longueur fixe.
L'en-tête fait toujours 80 octets, dans cet ordre : une version de 4 octets, le hash de 32 octets de l'en-tête précédent, la racine de merkle de 32 octets, un horodatage de 4 octets, l'encodage de cible nBits de 4 octets et un nonce de 4 octets. Vient ensuite le nombre de transactions, écrit en compactSize, un entier de longueur variable qui occupe 1 octet pour les nombres inférieurs à 253 et jusqu'à 9 octets pour tout ce qui est énorme. Puis les transactions elles-mêmes, chacune entièrement sérialisée, la coinbase en premier.
Depuis le BIP144, le même bloc a deux sérialisations valides. La forme stripped laisse les témoins entièrement de côté et c'est ce que les logiciels antérieurs à 2017 attendent. La forme complète les inclut, en marquant chaque transaction portant un témoin par un octet 0x00 suivi d'un indicateur 0x01 là où le nombre d'entrées se trouverait autrement. Les deux encodent le bloc identique et les deux produisent le hash de bloc identique, car le hash ne couvre que ces 80 octets d'en-tête et la racine de merkle qu'ils contiennent engage les identifiants de transaction, qui sont calculés à partir de l'encodage stripped. Cette séparation est le sens littéral de segregated witness.
Une habitude surprend tout le monde au moins une fois : les entiers multi-octets sont écrits en little endian, donc l'horodatage 0x495FAB29 apparaît sur le réseau sous la forme 29 ab 5f 49, et les hash sont affichés dans l'ordre inverse de leur ordre d'octets sérialisé. Un hash de bloc que vous copiez depuis un explorateur n'est pas la séquence d'octets qui se trouve dans le fichier.
Où le voir
Les blocs sérialisés circulent sur le réseau pair-à-pair dans un message block. Chaque message porte d'abord une enveloppe de 24 octets : une chaîne de démarrage de 4 octets, f9beb4d9 sur le mainnet, un nom de commande de 12 octets, une longueur de charge utile de 4 octets et une somme de contrôle de 4 octets tirée des quatre premiers octets d'un double SHA-256 sur la charge utile. Bitcoin Core plafonne toute charge utile d'un seul message à 4 000 000 octets, une limite du réseau et non du consensus.
Les mêmes octets arrivent sur votre disque. Bitcoin Core ajoute les blocs à des fichiers nommés blk00000.dat et au-delà, chacun plafonné à 128 MiB, avec la chaîne de démarrage identique et un préfixe de longueur avant chaque bloc pour que le fichier puisse être parcouru linéairement. Le bloc de genèse fait exception : il est compilé dans le logiciel comme une constante plutôt que téléchargé, ce qui en fait l'ancre par rapport à laquelle un nœud en synchronisation mesure tout le reste.
Pour un usage courant, la sérialisation apparaît via le RPC getblock à verbosity 0, via l'onglet raw ou hex de la plupart des explorateurs, et dans les outils qui permettent de décoder un bloc à la main. Quiconque vérifie qu'un explorateur lui a dit la vérité finit ici, car l'hex est la seule représentation que personne n'a reformatée.
Bloc sérialisé vs bloc
Un bloc est l'objet ; un bloc sérialisé est l'un de ses encodages. La distinction était cosmétique jusqu'en 2017, quand SegWit a donné à chaque bloc deux encodages valides de longueurs différentes, si bien que la taille d'un bloc est devenue une question qui demande une précision. Bitcoin Core y répond de trois façons dans une seule réponse RPC : size pour la sérialisation complète, strippedsize pour celle sans témoins et weight pour le nombre que les règles appliquent réellement.