Introduction au script Bitcoin
Table des matières
Introduction
Comment le Bitcoin fonctionne-t-il ?
Comprendre la pile Bitcoin
Pay-to-Pubkey (P2PK)
Pay-to-Pubkey-Hash (P2PKH)
Pay-to-Script-Hash (P2SH)
Transactions SegWit (P2WPKH et P2WSH)
Pour conclure
Introduction au script Bitcoin
AccueilArticles
Introduction au script Bitcoin

Introduction au script Bitcoin

Avancé
Published Jul 10, 2020Updated Jan 18, 2022
13m

Introduction

Le Bitcoin est parfois appelé argent programmable. En raison de sa nature numérique, il permet aux utilisateurs de bénéficier d'une grande flexibilité lorsqu'il s'agit de définir des conditions pour la façon dont les fonds peuvent être dépensés.
Nous parlons de portefeuilles et de pièces lorsqu'on en vient au Bitcoin. Mais nous pourrions aussi considérer les portefeuilles comme des clés, les pièces comme des chèques et la blockchain comme des rangées successives de coffres-forts verrouillés. Chaque coffre-fort est doté d'une fente mince, de sorte que n'importe qui peut déposer des chèques ou regarder à quelle valeur les coffres-forts sont valorisés. Cependant, seul le détenteur de la clé pourra accéder à l'intérieur.

Lorsqu'un détenteur de clé souhaite donner de l'argent à quelqu'un d'autre, il déverrouille sa boîte. Il établit un nouveau chèque faisant référence à l'ancien (qui est ensuite détruit) et l'enferme dans une boîte que le destinataire peut ouvrir. Pour le dépenser, le nouveau bénéficiaire répète le processus.

Dans cet article, nous allons examiner de plus près Script, le langage de programmation interprété par les nœuds sur le réseau Bitcoin. Le langage Script est ce qui régit le mécanisme de verrouillage/déverrouillage mentionné pour les coffres-forts.


Comment le Bitcoin fonctionne-t-il ?

En reprenant notre raisonnement ci-dessus, on pourrait dire que chaque transaction comporte deux parties : une clé (pour déverrouiller votre boîte) et une serrure. Vous utilisez votre clé pour ouvrir la boîte contenant le chèque que vous souhaitez envoyer, puis vous en ajoutez une nouvelle à une nouvelle boîte avec un cadenas différent. Pour dépenser ce qui se trouve dans la nouvelle boîte, vous avez besoin d'une autre clé.
Plutôt simple, non ? Vous pouvez également obtenir un peu de variation sur les types de serrures dans le système. Certains coffres-forts exigent peut-être que vous fournissiez plusieurs clés, et d'autres ont peut-être besoin que vous prouviez que vous connaissez un secret. Il y a tout un tas de conditions que les gens peuvent définir.
Notre clé, c'est ce que nous appelons un scriptSig. Et le verrou, notre scriptPubKey. Si nous examinons ces composants de manière un peu plus détaillée, nous constatons qu'ils sont en fait constitués de bits de données et de blocs de code. Lorsqu'ils sont combinés, ils créent un petit programme.

Lorsque vous effectuez une transaction, vous diffusez cette combinaison sur le réseau. Chaque nœud qui le reçoit vérifie le programme, qui lui indique si la transaction est valide. Sinon, il sera simplement rejeté et vous ne pourrez pas dépenser les fonds verrouillés.

Les chèques (pièces) que vous détenez sont appelés sorties de transaction non dépensées (UTXO). Les fonds peuvent être utilisés par quiconque peut fournir la clé correspondant à la serrure. Plus précisément, la clé est le scriptSig et le verrou est le scriptPubKey.
Si les UTXO se trouvent dans votre portefeuille, ils auront probablement une condition indiquant que seule la personne qui peut prouver la propriété de cette clé publique peut déverrouiller ces fonds. Pour en déverrouiller, vous devez fournir une scriptSig qui inclut une signature numérique, en utilisant la clé privée qui correspond à la clé publique spécifiée dans la scriptPubKey. Tout cela sera bientôt plus clair.


Comprendre la pile Bitcoin

Le script est ce que l'on appelle un langage basé sur la pile. Cela signifie que, lorsque nous lisons un ensemble d'instructions, nous les plaçons dans ce qui peut être considéré comme une colonne verticale. La liste A, B, C, par exemple, donnerait une pile avec A en bas et C en haut. Lorsque les instructions nous indiquent de faire quelque chose, nous fonctionnons sur un ou plusieurs éléments en commençant par le haut de la pile.


Les éléments A, B et C sont ajoutés et retirés de la pile.


Nous pouvons distinguer les données (comme les signatures, les hachages et les clés publiques) et les instructions (ou les opcodes). Les instructions permettent de retirer des données et d'en faire quelque chose. Voici un exemple de ce à quoi cela pourrait ressembler :
<xyz> <md5 hasher> <d16fb36f0911f878998c136191af705e> <check if equal>
En rouge, nous avons les données, et en bleu, nous avons les opcodes. Nous lisons de gauche à droite, c'est pourquoi nous avons d'abord placé la chaîne <xyz> sur la pile. Vient ensuite l'opcode < md5 hasher>. Celui-ci n'existe pas dans Bitcoin, mais supposons qu'il supprime l'élément supérieur de la pile (<xyz>) et le hache à l'aide de l'algorithme MD5. Ensuite, la sortie est de nouveau ajoutée à la pile. La sortie ici est d16fb36f0911f878998c136191af705e.
Quelle coïncidence ! Le prochain élément à ajouter est < d16fb36f0911f878998c136191af705e>, de sorte que notre pile comporte maintenant deux éléments identiques. Enfin, < check if equal> fait sauter deux éléments et vérifie s'ils sont égaux. Si tel est le cas, il ajoute <1> à la pile. Sinon, il ajoute <0>.
Nous devons mettre fin à notre liste d'instructions. Notre script aurait pu échouer de deux façons : si l'élément restant était un zéro, ou si l'un des opérateurs le faisait échouer lorsque certaines conditions n'étaient pas remplies. Nous n'avions pas de tels opérateurs dans cet exemple, et nous nous retrouvons avec un élément non nul (< 1> ), donc notre script était valide. Ces règles sont également valables pour les transactions réelles en bitcoins.

Ce n'était qu'un programme simulé. Jetons un coup d'œil à certains exemples réels maintenant.


Pay-to-Pubkey (P2PK)

Pay-to-Pubkey (P2PK) est très simple. Il s'agit de verrouiller les fonds à une clé publique particulière. Si vous souhaitez recevoir des fonds de cette manière, vous devez fournir à l'expéditeur votre clé publique, et non une adresse Bitcoin.

La toute première transaction entre Satoshi Nakamoto et Hal Finney en 2009 était une P2PK. Cette structure était très utilisée durant les premiers jours du Bitcoin, mais aujourd'hui, le système Pay-to-Pubkey-Hash (P2PKH) l'a largement remplacée.
Le script de verrouillage d'une transaction P2PK suit le format <clé publique> OP_CHECKSIG. Plutôt simple, non ? Vous avez peut-être deviné que OP_CHECKSIG vérifie la signature par rapport à la clé publique fournie. Ainsi, notre scriptSig sera une simple <signature >. N'oubliez pas que le scriptSig est la clé de la serrure.



Difficile de faire plus simple. Une signature est ajoutée à la pile, suivie d'une clé publique. OP_CHECKSIG les fait apparaître et vérifie la signature par rapport à la clé publique. Si tel est le cas, il ajoute <1> à la pile. Sinon, il ajoute <0>.

Pour des raisons que nous allons expliquer dans la section suivante, P2PK n'est plus vraiment utilisé.


Pay-to-Pubkey-Hash (P2PKH)

La transaction de type « Pay-to-Pubkey-Hash » (P2PKH) est désormais le type de transaction le plus courant. À moins que vous ne vous donniez du mal pour télécharger des logiciels archaïques, votre portefeuille l'utilise par défaut.

La scriptPubKey dans P2PKH est la suivante :

OP_DUP OP_HASH160 <hash de clé publique> OP_EQUALVERIFY OP_CHECKSIG

Avant d'introduire le scriptSig, décomposons ce que les nouveaux opcodes vont faire :


OP_DUP

OP_DUP fait sortir le premier élément, puis le duplique. Il rajoute ensuite les deux à la pile. Cela nous permet d'effectuer une opération sur le duplicata sans affecter l'original.


OP_HASH160

Cela extrait le premier élément et le hache deux fois. Le premier hash sera effectué avec l'algorithme SHA-256. La sortie SHA-256 est ensuite hachée avec l'algorithme RIPEMD-160. Ensuite, la sortie est de nouveau ajoutée à la pile.


OP_EQUALVERIFY

OP_EQUALVERIFY combine deux autres opérateurs : OP_EQUAL et OP_VERIFY. OP_EQUAL fait sortir deux éléments et vérifie s'ils sont identiques. S'ils le sont, il ajoute un 1 à la pile. Si ce n'est pas le cas, il ajoute un 0. OP_VERIFY fait apparaître l'élément supérieur et vérifie s'il est vrai (c'est-à-dire non nul). Si ce n'est pas le cas, la transaction échoue. Ainsi utilisé OP_EQUALVERIFY entraîne l'échec de la transaction si les deux éléments supérieurs ne correspondent pas.

Cette fois, le scriptSig ressemble à ceci :

<signature> <clé publique>

Vous devez fournir une signature et la clé publique correspondante pour déverrouiller les sorties P2PKH.



Vous pouvez voir ce qui se passe dans le GIF ci-dessus. Ce n'est pas très différent d'un script P2PK. Nous ajoutons juste une étape supplémentaire pour vérifier que la clé publique correspond au hachage dans le script.

Il y a cependant quelque chose à noter. Dans un script de verrouillage P2PKH, la clé publique n'est pas visible. On peut seulement voir son hash. Si nous allons sur un explorateur de blockchain et regardons une sortie P2PKH qui n'a pas été utilisée, nous ne pouvons pas déterminer la clé publique. Elle n'est révélée que lorsque le destinataire décide de transférer les fonds.
Cela présente quelques avantages. Le premier est que le hachage de clé publique est tout simplement plus facile à transmettre qu'une clé publique complète. Satoshi l'a lancé en 2009 pour cette raison. Le hachage de clé publique porte aujourd'hui le nom d'adresse Bitcoin.
Le deuxième avantage est que les hachages de clés publiques pourraient fournir une couche supplémentaire de sécurité contre l'informatique quantique. Comme notre clé publique n'est pas connue avant que nous ayons dépensé les fonds, il est encore plus difficile pour les autres de calculer la clé privée. Il faudrait inverser les deux tours de hachage (RIPEMD-160 et SHA-256) pour l'obtenir.



Pay-to-Script-Hash (P2SH)

Pay-to-Script-Hash (P2SH) était un développement très intéressant pour Bitcoin. Il permet à l'expéditeur de verrouiller les fonds au hachage d'un script. Il n'a pas besoin de savoir ce que fait réellement le script. Prenez le hachage SHA-256 suivant :

e145fe9ed5c23aa71fdb443de00c7d9b4a69f8a27a2e4fbb1fe1d0dbfb6583f1

Vous n'avez pas besoin de connaître l'entrée du hachage pour y verrouiller des fonds. Toutefois, la personne souhaitant dépenser les fonds doit fournir le script utilisé pour le hacher et doit satisfaire les conditions de ce script.

Le hachage ci-dessus a été créé à partir du script suivant :

<multiplier par 2> <4> <vérifier si égal>

Si vous voulez dépenser les pièces liées à cette scriptPubKey, vous ne devez pas seulement fournir ces commandes. Vous avez également besoin d'un scriptSig qui fait en sorte que le script terminé soit évalué à Vrai. Dans cet exemple, c'est un élément que vous <multipliez par 2> pour obtenir un résultat de <4>. Bien sûr, cela signifie que notre scriptSig est juste <2>.

En réalité, la scriptPubKey pour une sortie P2SH est :

OP_HASH160 <hash redeemScript> OP_EQUAL

Aucun nouvel opérateur ici. Mais, nous avons un nouvel élément : <redeemScript hash>. Comme son nom l'indique, il s'agit d'un hachage du script que nous devons fournir pour échanger les fonds (appelé redeemScript). La scriptSig changera en fonction de ce qui se trouve dans le redeemScript. En règle générale, cependant, il s'agit d'une combinaison de signatures et de clés publiques jointes, suivies du redeemScript (obligatoire) :

< signature> <clé publique> <redeemScript>

Notre évaluation diffère un peu de l'exécution de la pile que nous avons vue jusqu'à présent. Elle se déroule en deux parties. La première consiste simplement à vérifier que vous avez fourni le hachage correct.



Vous remarquerez que nous ne faisons rien avec les éléments précédant le redeemScript. Ils ne sont pas utilisés à ce stade. Nous avons atteint la fin de ce mini programme, et l'élément supérieur n'est pas zéro. Cela signifie qu'il est valide.

Mais nous n'avons pas encore fini. Les nœuds réseau reconnaissent cette structure comme P2SH, de sorte qu'ils ont les éléments de scriptSig en attente dans une autre pile. C'est là que la signature et la clé publique seront utilisées.
Jusqu'à présent, nous avons traité le redeemScript comme un élément. Mais maintenant, il sera interprété comme des instructions, pouvant représenter à peu près tout. Prenons l'exemple d'un script de verrouillage P2PKH, auquel nous devons fournir les <signature> et <clé publique> qui correspondent à un <hash de clé publique> à l'intérieur du <redeemScript>.



Une fois que votre redemScript a été étendu, vous pouvez vous apercevoir que nous obtenons une situation qui ressemble exactement à une transaction P2PKH classique. A partir de là, vous le faites tourner comme vous le feriez habituellement.

Nous avons montré ce qu'on appelle un script P2SH(P2PKH) ici, mais il est peu probable que vous en rencontriez un dans la réalité. Rien ne vous empêche d'en créer un, mais cela ne vous donne aucun avantage supplémentaire et ne fait qu'occuper plus d'espace dans un bloc (et donc coûter plus cher).

Le P2SH s'avèrent généralement utile pour les transactions compatibles avec SegWit ou les transactions multisignatures. Les transactions multisig peuvent être très volumineuses, car elles peuvent nécessiter plusieurs clés. Avant la mise en œuvre de Pay-to-Script-Hash, un expéditeur devait énumérer toutes les clés publiques possibles dans son script de verrouillage.

Mais avec P2SH, peu importe la complexité des conditions de dépenses. Le hachage du redeemScript est toujours de taille fixe. Les coûts sont donc répercutés sur le ou les utilisateurs qui veulent déverrouiller le script de verrouillage.

La compatibilité SegWit est un autre cas où le P2SH s'avère utile (nous entrerons dans les détails de la différence de structure des transactions dans la section suivante). SegWit était un soft fork qui a entraîné une modification des formats de bloc/transaction. Comme il s'agit d'une mise à jour facultative, tous les logiciels de portefeuille ne reconnaissent pas les changements.

Le fait que les clients englobent le hachage du script SegWit dans P2SH importe peu. Comme pour toutes les transactions de ce type, ils n'ont pas besoin de savoir quel sera le redeemScript de déverrouillage.


Transactions SegWit (P2WPKH et P2WSH)

Pour une présentation davantage complète de SegWit, consultez le Guide du débutant sur Segregated Witness.
Pour comprendre le format de transaction dans SegWit, il vous suffit de savoir que nous n'avons plus seulement un scriptSig et une scriptPubKey. Nous avons désormais aussi un nouveau champ appelé witness. Les données que nous avions l'habitude de conserver dans le scriptSig sont déplacées vers le witness, le scriptSig est donc vide.

Si vous avez rencontré des adresses commençant par « bc1 », c'est ce que nous appelons SegWit-native (par opposition à SegWit-compatible, qui commence par « 3 » puisqu'il s'agit d'adresses P2SH).


Pay-to-Witness-Pubkey-Hash (P2WPKH)

Pay-to-Witness-Pubkey-Hash (P2WPKH) est la version SegWit de P2PKH. Notre witness ressemble à ceci :

<signature> <clé publique>

Vous remarquerez qu'il est identique au scriptSig de P2PKH. Ici, le scriptSig est vide. En attendant, la scriptPubKey ressemble aux éléments suivants :

<OP_0> <hash de la clé publique>

Cela semble étrange, n'est-ce pas ? Où sont les opcodes pour nous permettre de comparer la signature, la clé publique et son hachage ?

Nous ne montrons pas d'opérateurs supplémentaires ici, car les nœuds qui reçoivent la transaction savent quoi en faire en fonction de la longueur du <hachage de la clé publique>. Ils calculeront la longueur et comprendront qu'elle doit être exécutée dans le même style qu'une transaction P2PKH.
Les nœuds non mis à jour ne savent pas comment interpréter la transaction de cette manière, mais cela n'a pas d'importance. Selon les anciennes règles, il n'y a pas de témoin, donc ils lisent un scriptSig vide et quelques données. Ils l'évaluent et l'indiquent comme valide, selon eux n'importe qui pourrait dépenser la sortie. C'est pourquoi SegWit est considéré comme un soft fork rétrocompatible.


Pay-to-Witness-Script-Hash (P2WSH)

Pay-to-Witness-Script Hash (P2WSH) est le nouveau P2SH. Si vous avez tenu jusqu'ici, vous pouvez probablement comprendre à quoi cela ressemblera, mais nous allons tout de même regarder ensemble. Notre witness est ce que l'on mettrait normalement dans le scriptSig. Dans un P2WSH qui englobe une transaction P2PKH, par exemple, cela pourrait ressembler à ceci :

<signature> <clé publique>

Voici notre scriptPubKey :

<OP_0> <script hash>

Les mêmes règles s'appliquent. Les nœuds SegWit lisent la longueur du hachage du script et déterminent qu'il s'agit d'une sortie P2WSH, qui est évaluée de la même manière que P2SH. Pendant ce temps, les vieux noeuds voient juste la sortie comme une sortie que tout le monde peut dépenser.


Pour conclure

Dans cet article, nous avons appris un peu plus sur les éléments constitutifs du Bitcoin. Résumons-les rapidement :


Type de scriptDescription

Pay-to-Pubkey (P2PK)

Verrouille les fonds sur une clé publique particulière

Pay-to-Pubkey-Hash (P2PKH)

Verrouille les fonds sur un hash de clé publique particulière (c'est-à-dire une adresse).

Pay-to-Script-Hash (P2SH)

Verrouille les fonds sur le hash d'un script que le destinataire peut fournir.

Pay-to-Witness-Pubkey-Hash (P2WPKH)

Version SegWit de P2PK

Pay-to-Witness-Script-Hash (P2WSH)

Version SegWit de P2SH


Une fois que vous avez approfondi vos connaissances sur le Bitcoin, vous commencez à comprendre pourquoi il a tant de potentiel. Les transactions peuvent être constituées de nombreux composants différents. Avec ces éléments constitutifs, les utilisateurs disposent d'une grande flexibilité lorsqu'il s'agit de fixer des conditions sur la manière et le moment de dépenser les fonds.