Dans cet article, nous avons essayé d'examiner en détail les modifications du protocole Bitcoin survenues à la suite de la mise à jour de la softfork de Segregated Witness. Nous avons abordé les problèmes liés à la malléabilité des transactions, au maintien de la compatibilité descendante, à l'augmentation du débit, aux nouveaux formats de sérialisation des transactions, aux nouvelles options de script, au format d'adresse Bech32 et à ses avantages, aux concepts de poids, de taille et de taille virtuelle. De plus, voici les statistiques les plus importantes sur l'adaptation de la mise à jour et les réponses aux questions fréquemment posées sur le sujet de cette mise à jour sont présentées.
Avant de procéder à une description détaillée de toutes les modifications de cette mise à jour, nous vous suggérons de vous familiariser avec l'idée principale du témoin distinct. Littéralement, le témoin séparé est traduit de l'anglais par «témoin distinct». Le concours Bitcoin implique que la preuve de la propriété des pièces sera stockée séparément des données de base de transaction, comme indiqué dans le diagramme.

Si nous considérons la mise à jour du protocole dans son intégralité, elle comprend de nombreuses autres améliorations. SegWit vous permet d'augmenter la bande passante du réseau, de séparer les preuves de propriété des pièces du reste des données de transaction, de corriger les lacunes du format de transaction associées à la possibilité de modifier les données dans les transactions signées (malléabilité des transactions), tout en maintenant une compatibilité descendante avec les versions précédentes du protocole. Et la plus grande valeur de cette mise à jour est qu'elle vous permet de mettre en œuvre de nombreuses solutions hors chaîne très importantes en plus du protocole Bitcoin.
Problème et solution de malléabilité des transactions
L'essentiel est que lorsque vous travaillez dans Bitcoin, il est possible de modifier la transaction afin qu'elle reste correcte pendant la vérification. Ces modifications sont très mineures, elles n'affectent pas les adresses de l'expéditeur et du destinataire, mais elles suffisent à modifier le résultat du hachage. En d'autres termes, la transaction transférera les pièces à leurs adresses précédentes, mais sa valeur de hachage modifiée ne correspondra plus à la transaction modifiée avec celle d'origine.
De toute évidence, la situation décrite ci-dessus ne peut se produire qu'avec des transactions qui n'ont pas encore reçu de confirmation. Sans sa solution, il est impossible d'obtenir un fonctionnement fiable des protocoles hors chaîne, qui comprennent la construction de chaînes de transactions non confirmées. Étant donné que lors de la compilation d'une transaction, toutes les données ne sont pas signées (par exemple, vous ne pouvez pas signer scriptSig), il existe la possibilité de plusieurs types d'attaques:
- Modifiez le format de signature . Dans le protocole Bitcoin, le format de signature n'est pas strictement approuvé et dépend de la mise en œuvre de la bibliothèque OpenSSL, dans laquelle le format strict n'est pas non plus défini pour la signature. Un tiers peut modifier la transaction interceptée, ce qui entraînera une modification de la valeur de hachage.
- Impact directement sur scriptSig . Comme indiqué précédemment, scriptSig contient un ensemble d'opérations pour vérifier la preuve qu'un utilisateur particulier est le propriétaire des pièces. Mais en plus de ces opérations, vous pouvez en ajouter d'autres. Quelques opérations inoffensives qui n'affectent rien entraîneront une modification de la valeur de hachage de la transaction.
Ainsi, vous pouvez modifier la valeur de hachage d'une transaction sans avoir accès aux clés privées. Pourquoi la modification d'une valeur de hachage est-elle si indésirable?
Tout d'abord, il convient de noter qu'il est possible de créer une copie de la transaction d'origine, d'y ajouter des modifications qui n'affecteront pas son exactitude lors de la vérification et de l'envoyer au réseau. Une copie modifiée avec une valeur de hachage différente dépense les mêmes pièces que l'original, elle peut donc rivaliser avec la transaction d'origine pour confirmation.
Les protocoles hors chaîne ont été mentionnés ci-dessus. Pour leur mise en œuvre, une solution au problème de la malléabilité des transactions est nécessaire. Au cœur de leur travail se trouve la construction de chaînes de transactions non confirmées. La modification de la valeur de hachage de la première transaction entraînera la nullité de toute la chaîne des transactions non confirmées.
La mise à jour de SegWit a défini des règles strictes pour remplir les champs, afin que les problèmes associés à la malléabilité des transactions pour les transactions du nouveau format puissent être considérés comme résolus. Cela nous a permis de spécifier des données et de les sérialiser sans ambiguïté, éliminant la dualité.
Compatibilité descendante lors de la distribution d'un bloc sur un réseau
Selon les anciennes règles, la taille maximale des blocs est de 1 Mo et contient des transactions avec des preuves intégrées. Bien que les nouvelles règles supposent que la taille maximale du bloc de base est de 1 Mo, il existe en outre une structure de données avec des preuves. Par conséquent, la taille totale du nouveau bloc dépasse 1 Mo.
Pour des raisons de compatibilité descendante, les règles de protocole permettent aux anciens nœuds de fonctionner avec de nouveaux blocs, mais ils ne recevront le bloc que dans la configuration de base avec une taille maximale de 1 Mo. La structure des témoins n'est pas disponible pour eux. Les nouveaux nœuds obtiennent un bloc complet avec des transactions et des preuves. La figure suivante vous aidera à vous familiariser avec cette question.

À gauche, un schéma du fonctionnement du protocole Bitcoin avant l'activation de Segregated Witness. Le bloc avait une taille maximale de 1 Mo et il était réparti entre différents nœuds de réseau sous une seule forme.
Comme la taille du bloc est limitée, le nombre de transactions qui peuvent y être placées est également limité, et la capacité du système en dépend. Bien sûr, lorsque la question s'est posée d'augmenter le débit, la première chose qu'ils ont commencé à chercher était les moyens d'augmenter la taille maximale des blocs.
Comment augmenter le débit
Considérez les deux principaux moyens de résoudre le problème de l'augmentation du débit du système. Toute offre est soigneusement vérifiée et testée par l'équipe de développement du protocole Bitcoin. Si la communauté est parvenue à un accord et a décidé de mettre en œuvre la proposition dans le protocole, une mise à jour est publiée.
Mise à jour Hardfork. La mise à jour la plus courante consiste à augmenter la taille du bloc. Il est supposé qu'une unité acceptera plus de transactions, augmentant ainsi le débit. Cependant, une telle unité ne sera pas acceptée par les nœuds fonctionnant selon l'ancien protocole, dont les règles stipulent que la taille de bloc maximale ne peut pas dépasser 1 MV. Un tel changement nécessite hardfork, qui est plus complexe sur le plan organisationnel que softfork.
Mise à jour SoftFork. Le témoin séparé nous permet de résoudre ce problème avec la fourche souple. Comment exactement? Il nous permet de diviser le bloc en deux parties, dont la première stocke les transactions et la seconde contient des preuves. Dans le même temps, les nouveaux nœuds de réseau reçoivent les deux parties, tandis que les anciens ne reçoivent qu'un bloc de transaction de 1 Mo. Les anciens nœuds ne peuvent pas recevoir de blocs avec preuves et, par conséquent, ne peuvent pas valider les transactions qu'ils reçoivent, mais cela leur permet de participer à la recherche d'un consensus et de ne pas recourir au hardfork, mais de passer progressivement à de nouveaux logiciels.
Innovations à témoin distinct
Tenez compte de ce qui est inclus dans la mise à jour des témoins séparés. La première et la plus importante innovation de Segregated Witness est le nouveau format de sérialisation des transactions. En plus des champs déjà connus, il y a trois nouveaux champs dans la nouvelle transaction: marqueur, drapeau, qui sont utilisés pour le contrôle de version et dans ce cas ils sont strictement définis, mais dans les protocoles suivants ils peuvent changer, ainsi que le champ témoin. Le témoin (données de témoin) est en fait un ensemble de preuves de propriété de pièces de monnaie qui est retiré de la partie principale de la transaction. Structurellement, cela ressemble à un ensemble d'entrées, chaque élément de données témoin correspondant à une entrée avec un numéro spécifique, ce qui vous permet de comparer les preuves avec des pièces spécifiques dépensées.
Identifiant de transaction témoin
Pour obtenir l'identifiant de transaction (identifiant de transaction, txid), vous devez apporter la transaction elle-même à une séquence de données dans un format de sérialisation spécial, puis obtenir la valeur de hachage à partir de cette séquence de données. Avec l'introduction de Segregated Witness, un nouvel identifiant, un identifiant de transaction témoin (wtxid) et un nouveau format de sérialisation, respectivement, sont apparus. Pour les transactions plus anciennes qui dépensent de l'argent sans utiliser Segregated Witness, wtxid sera identique à txid car aucun nouveau champ ne sera ajouté à Segregated Witness.

Wtxid est nécessaire pour construire un arbre Merkle alternatif pour preuve. Il est construit de la même manière que pour les transactions ordinaires, seul wtxid est utilisé à la place du hachage de transaction. En conséquence, wtxid sont hachés par paires et donnent la racine Merkle.
Il est important de noter que la racine Merkle est insérée dans une transaction coinbase, et non dans l'en-tête de bloc. Si root était dans l'en-tête du bloc, la structure du bloc changerait. Les nœuds qui prennent en charge l'ancien protocole ne pouvaient pas fonctionner avec de tels blocs. Et tous les efforts pour maintenir la compatibilité ascendante reposeraient sur cette incohérence. Par conséquent, root est inséré dans l'une des sorties de la transaction coinbase. Lorsque tous les nœuds passent à Témoin séparé, cette situation peut changer et de nouvelles approches seront envisagées.
Programmes témoins pour fixer les conditions de dépenses des pièces
Voyons comment le script de transactions de témoin séparé est construit et comment il permet aux anciens nœuds de réseau de comprendre que les transactions de témoin séparé sont correctes, malgré le fait qu'ils ne reçoivent pas de preuve de propriété des pièces.
Le script décrivant les règles pour dépenser des pièces d'une transaction de nouveau format se compose de deux parties. La première partie est l'octet de version témoin (l'octet spécifiant la version du programme témoin). Il peut prendre des valeurs de 0 à 16 (OP0-OP16), maintenant il utilise OP0. À l'avenir, de nouvelles versions du protocole peuvent apparaître avec la prise en charge d'autres versions du programme témoin. La deuxième partie est le programme des témoins. Cette partie peut avoir une taille de 2 à 40 octets.
Le programme Witness est le résultat du hachage d'un script de témoin. Le script témoin lui-même contient une description complète des conditions de dépense des pièces. Les données des témoins contiennent une preuve de propriété des pièces qui doivent satisfaire aux conditions du script des témoins. En conséquence, les données des témoins se composent toujours de deux parties: un script de témoin et une preuve de propriété des pièces.
Il convient de noter que le programme témoin ne contient aucune opération (correspondance des valeurs de hachage, vérification des signatures électroniques), et le script lui-même commence par le code OP0, par conséquent, il est valable pour tous les anciens nœuds. De plus, les nœuds qui n'ont pas été mis à jour vers SegWit ne vérifient pas la preuve de la propriété des pièces pour les sorties de nouveau format; ils considèrent que ce gaspillage est correct dans tous les cas. Strictement parlant, les anciens nœuds accepteront les transactions d'un nouveau format même si leur émetteur ne possède pas réellement les pièces correspondantes. C'est pourquoi SegWit exige que les propriétaires de la plupart des puissances minières Bitcoin acceptent cette mise à jour. Une autre caractéristique est que le scriptSig d'une transaction qui dépense des pièces de la sortie du nouveau format sera vide.
Nouvelles options pour définir les conditions de dépenses des pièces
Avec l'introduction de SegWit, deux formats standard pour scriptPubKey ont été proposés, qui sont devenus une alternative aux deux formats les plus courants pour définir les règles de dépense des pièces avant que cette mise à jour ne paraisse. Considérons-les dans l'ordre.
Payer pour assister au hachage de clé publique (P2WPKH) est un analogue du hachage de clé publique à payer. Quelle est sa différence? Comme indiqué précédemment, le scriptSig n'est pas rempli et reste vide. Toutes les preuves de propriété des pièces sont transférées à la structure de données des témoins.
Dans ce cas, le script considéré précédemment, la version et le hachage de la clé publique, qui est le programme témoin, sont insérés dans scriptPubKey. Un nœud sur le réseau distingue un tel script de dépenses des autres en raison du fait qu'il en a une version et une taille de données de 20 octets. Une autre version et une taille différente comportent des règles de dépenses différentes.

Dans ce cas, scriptPubKey contient deux parties: le numéro de version témoin est zéro et la valeur de hachage de la clé publique du destinataire. ScriptSig sera vide et les données des témoins contiendront une signature électronique et une clé publique pour le vérifier.
Le hachage de script Pay toitness (P2WSH) est un analogue du hachage de pay to script standard. Dans ce cas, un script personnalisé peut être utilisé pour définir les règles de dépense des pièces. Comment un hôte distingue-t-il un tel script du précédent? Dans ce cas, la version a toujours une valeur de un, et le programme témoin prend 32 octets et est une valeur de hachage du script témoin. Si une transaction arrive sur un hôte contenant un script qui aura la première version, mais que sa taille diffère des valeurs de 20 ou 32 octets, alors l'hôte rejettera cette transaction car il ne saura pas comment travailler avec.
Les données des témoins ici sont divisées en deux parties. Le premier contient un ensemble de preuves de la propriété des pièces, c'est-à-dire un ensemble de signatures. Dans la deuxième partie, un script témoin est placé, dont le contenu définit simplement les règles de dépense des pièces, mais dans ce cas, il est indiqué au moment de la dépense, et au moment de l'envoi des pièces, sa valeur de hachage a été indiquée.

Dans ce cas, scriptPubKey contient deux parties: le numéro témoin de la version est zéro et la valeur de hachage du script témoin pour le cas de la signature multiple 1 sur 2. ScriptSig sera vide et les données des témoins contiendront la signature électronique et le script témoin d'origine en texte clair.
Wrapper P2SH
Le nouveau format de script est différent de l'ancien. Par conséquent, les anciens services et portefeuilles ne sauront pas comment travailler avec ce format de script et comment le composer. Pour des raisons de compatibilité descendante, les transactions de témoins séparés utilisant P2SH utilisent un «wrapper» spécial, qui vous permet de créer une transaction qui possède des propriétés de transaction de témoin séparé, mais qui ne diffère pas du P2SH habituel pour le monde extérieur.
P2SH est utilisé pour simplifier le travail de l'expéditeur et ne pas lui imposer les détails de la mise en œuvre du script de rachat du destinataire. Dans ce cas, le destinataire donne à l'expéditeur uniquement la valeur de hachage Redeem Script, et le script lui-même passe à scriptSig avec la preuve.

Dans ce cas, scriptPubKey contient une opération de hachage, une valeur de hachage de script de rachat et une opération de comparaison (comme pour l'ancienne version de P2SH). ScriptSig contiendra ici la valeur de hachage de la clé publique, et les données témoins contiendront la signature électronique et la clé publique.
Cette approche permet aux portefeuilles numériques non mis à jour d'envoyer des transactions à des adresses de témoins distincts, sans rien savoir des nouvelles façons de définir les conditions pour dépenser des pièces.
Nouveau format d'adresse Bech32
Il convient de mentionner séparément les adresses Bech32 qui sont considérées comme des adresses SegWit natives. Pour la majeure partie de son histoire, Bitcoin a utilisé le codage Base58 pour les adresses avec l'ajout d'une somme de contrôle, qui est un résultat tronqué du double hachage à l'aide de la fonction de hachage SHA-256. Ils faisaient partie du logiciel d'origine et leur champ d'application a été étendu en BIP13 pour P2SH. Mais le jeu de caractères et l'algorithme de somme de contrôle ont des limites:
- l'adresse dans Base58 occupe plus de mémoire dans les codes QR, car elle ne peut pas utiliser le mode de représentation alphanumérique;
- base58 est très gênant pour une écriture fiable sur papier, pour taper à partir d'un clavier mobile ou pour lire à haute voix;
- le hachage de double somme de contrôle est lent;
- Le décodage en base58 est complexe et relativement lent.

La mise à jour SegWit comprend une nouvelle classe de sorties (programmes témoins) et deux de ses cas: P2WPKH et P2WSH. Leur fonctionnalité est indirectement disponible pour les anciens nœuds grâce à l'utilisation de P2SH, mais il sera plus optimal et plus sûr de l'utiliser directement, pour cela, il est nécessaire d'introduire un nouveau format d'adresse.
Spécification d'adresse Bech32
L'adresse Bech32 ne comporte pas plus de 90 caractères et contient:
- Une partie lisible par l'homme. Cela inclut les données qui peuvent avoir besoin d'être transmises ou qui ont quelque chose à voir avec le propriétaire de l'adresse, d'au moins 1 caractère. Par exemple, par défaut pour les adresses de réseau principal, les caractères sont «bc» et pour testnet, les caractères sont «tb».
- Un délimiteur toujours égal à 1. Si "1" est autorisé à l'intérieur de la partie lisible par l'homme, alors le séparateur est le dernier des caractères "1".
- La partie de données a une longueur d'au moins 6 caractères et se compose uniquement de caractères alphanumériques, à l'exclusion de "1", "b", "i" et "o". Ici, la version du programme témoin et les données du programme témoin lui-même (de 2 à 40 octets) sont utilisées ici comme données principales.

Pourquoi inclure un séparateur dans les adresses? Cela vous permet de séparer clairement la partie lisible par l'homme de la partie lisible par les données, en évitant les collisions potentielles avec d'autres parties lisibles par l'homme qui utilisent le préfixe. Il évite également les restrictions de jeu de caractères pour la partie lisible par l'homme. Le séparateur est 1 car l'utilisation d'un caractère non alphanumérique rend difficile la copie des adresses (sans double-cliquer dans plusieurs applications). Par conséquent, un caractère alphanumérique a été sélectionné en dehors du jeu de caractères principal. En outre, l'utilisation du système numérique de base 32 s'accompagne d'une augmentation de la longueur d'adresse de 15% par rapport au système numérique de base 58, mais cela n'a pas d'importance lors de la copie d'adresses.
Adresses de contrôle Bech32
Les 6 derniers caractères de l'adresse sont une somme de contrôle. La somme de contrôle est construite sur la base du code BCH, qui garantit la détection de toute erreur n'affectant pas plus de 4 caractères, et la probabilité que la somme de contrôle converge lorsque plus de 4 erreurs sont faites est l'une des 109.
L'un des avantages de l'utilisation des codes BCH est qu'ils peuvent être utilisés pour corriger des erreurs. Si jusqu'à 4 erreurs ont été commises dans l'adresse, elles seront corrigées automatiquement. Et si plus d'erreurs sont commises, elles seront détectées avec une forte probabilité, mais sans possibilité de correction automatique.
Majuscules et minuscules dans l'adresse
Les minuscules sont utilisées lorsqu'une valeur de caractère est requise pour une somme de contrôle.
Le logiciel affiche toujours l'intégralité de la chaîne d'adresse Bech32 en minuscules. (, QR-), . , , , . , QR- , - , 45% , .
, Segregated Witness, , . Segregated Witness . 1 MB. . , .
(weight units). 3, witness data 1. , , witness data 3 , . . .
block weight = base size * 3 + total sizeblock weight – ( )
base size – ( )
total size – ( )
, , . .
, , , , 4 . Segregated Witness , .
, . (virtual size) , , , spb (satoshi per byte).
virtual size = weight units / 4Segregated Witness 4 , , . , . , . , , . , witness data (base size) 1 MB, 4 MB.
: « witness data?». . , 1 MB 4 MB. . 1.8 MB. ? 60% . 1 MB, 40% , .
400000 * 4 = 1600000600000 * 1 = 6000001600000 + 600000 = 22000004000000 / 2200000 = 1.81 MB, , 1.8 MB. , .
2018 SegWit 35% . Segregated Witness (, Electrum Bitxfy).
BitMex Research. 1 MB, 2 MB. , , SegWit .
BitMex Research, .
, Segregated Witness off-chain Bitcoin. , lightning network – SegWit, , .
Foire aux questions
— , Segregated Witness RBF (replace-by-fee)?, replace by fee Segregated Witness , , , , sequence number . , , , , .
— ?- , . ScriptSig, , , . , , - . , , , - .
— witness data?, Segregated Witness . , , , . , . : , , ( ), , Witness data, . .
— , RFC3548 z-base-32 Bech32 ?Le jeu de caractères est choisi de manière à minimiser l'ambiguïté associée à leur similitude visuelle. L'ordre est sélectionné pour minimiser le nombre de paires de caractères qui diffèrent en moins d'un bit de données. La somme de contrôle est choisie pour maximiser la probabilité de détecter un petit nombre d'erreurs, ce qui améliore son efficacité pour les erreurs typiques.