Pensez Blockchain

La référence en chaîne de blocs au Québec

 
Capture d’écran 2019-12-09 à 16.56.13.png
 

Dans la première partie, nous avons expliqué qu’une transaction est composée de deux éléments : les « inputs » qui font référence aux UTXO d’anciennes transactions et les « outputs » qui permettent de créer les nouveaux UTXO. Pour rappel, UTXO signifie « unspent transaction output », une transaction reçue qui n’a pas été dépensée.

Lorsqu’il fait référence à une ancienne transaction, l’émetteur résout un problème cryptographique (à l’aide de sa clé privée) pour prouver que la transaction lui était bien attribuée. Il génère ensuite de nouveaux problèmes cryptographiques (à l’aide de la clé publique des bénéficiaires) pour créer de nouveaux UTXO. Dans cette partie, nous allons expliquer comment le langage pour les transactions Bitcoin fonctionne et comment il est possible de verrouiller et déverrouiller des UTXO. 

Langage pour les transactions Bitcoin

Le langage pour les transactions Bitcoin s’appelle Script et son fonctionnement est basé sur un empilement.

En programmation, un empilement est un type de structure de données assez simple. Il est seulement possible d’ajouter une nouvelle donnée au-dessus de la pile ou bien d’enlever celle qui est déjà au-dessus. Un empilement peut être visualisé comme un tas de cartes sur lequel il est possible soit d’ajouter une nouvelle carte en haut du tas, soit d’enlever celle du dessus. Ce type de structure est aussi appelé Dernier-Entrée-Premier-Sortie (Last-In-First-Out ou LIFO en anglais).

 Dans un empilement, les nombres sont ajoutés au-dessus du tas. Les opérateurs (addition, soustraction, etc) peuvent prendre un ou plusieurs nombres, les manipuler puis ajouter le résultat au-dessus du tas. Enfin, les conditions peuvent prendre un ou plusieurs nombres, les manipuler et renvoyer à un Booléen : vrai ou faux (true ou false). Par exemple, OP_EQUAL va prendre deux nombres et regarder s’ils sont équivalents. Si c’est le cas, il ajoutera TRUE au-dessus de la pile.

 Illustrons cela avec un exemple (cet exemple est tiré de Mastering Bitcoin de Adreas M. Antonopoulos) : 2 3 OP_ADD 5 OP_EQUAL (qui sera lu de gauche à droite).

 
Capture d’écran 2019-12-09 à 17.32.47.png
 
 
Capture d’écran 2019-12-09 à 17.32.55.png
 

Dans une transaction Bitcoin, la pile doit être composée uniquement d’un TRUE pour que la transaction soit considérée comme valide.

Le langage Script est intentionnellement incomplet au sens de Turing. Cela signifie qu’il manque certains opérateurs. Il n’y a pas, par exemple, de boucle pour éviter qu’un nœud soit bloqué par une boucle infinie.

Script de verrouillage et de déverrouillage

Comme expliqué dans la première partie, le script de verrouillage se situe dans les « outputs » de la transaction. Il permet d’énoncer les conditions pour dépenser l’UTXO. La condition la plus courante est simplement de posséder la clé privée qui correspond à l’adresse où les bitcoins ont été envoyés. On parle alors de Pay-To-Public-Key-Hash (P2PKH), payer au hash de la clé publique. Cependant, il existe de nombreuses autres conditions moins connues dont nous parlerons plus tard.

Le script de déverrouillage est quant à lui écrit dans « l’input » de la transaction. Comme expliqué plus tôt, cette partie fait référence à un ancien UTXO et possède le script qui remplit les conditions pour le déverrouiller (pour le dépenser).

Lorsqu’il reçoit la transaction, un nœud de validation du réseau Bitcoin va dans un premier temps vérifier sa validité. Pour cela, il va regarder dans la partie « input » de la transaction pour trouver la référence à un ancien UTXO dans un bloc déjà validé. Il va ensuite chercher le script de verrouillage de cette UTXO dans « l’output » de la transaction de ce bloc. Pendant ce temps, il va également commencer à lire le script de déverrouillage qui se trouve dans la partie « input » de la transaction actuelle. Celui-ci est lu avec le langage Script, c’est-à-dire, en faisant une pile. Cette pile sera ensuite dupliquée (pour des raisons de sécurité) et le script de verrouillage sera lu (sera ajouté à la pile). Si le résultat final est TRUE (et que c’est le seul objet qu’il reste dans la pile), alors la transaction sera considérée comme valide et pourra être ajoutée dans le prochain bloc.

Voici un exemple de script de verrouillage et de déverrouillage pour une transaction payée au hash de la clé publique (similaire à l’adresse) :

 
Capture d’écran 2019-12-09 à 17.18.48.png
 

Pour déverrouiller le script, il faut présenter la signature et sa clé publique. Voici comment cela sera lu :

 
Capture d’écran 2019-12-09 à 17.32.06.png
 
 
Capture d’écran 2019-12-09 à 17.32.32.png
 
 
Capture d’écran 2019-12-09 à 17.32.21.png
 

Ici, la transaction aurait été invalide si clé publique donnée dans le script de déverrouillage, une fois hachée, ne correspondait pas au hash de la clé publique dans le script de verrouillage. Elle n’aurait pas fonctionné non plus si la signature et la clé publique données dans le script de déverrouillage ne correspondaient pas.

Qu’est-ce qu’une signature et qu'entendons-nous par sa correspondance avec une clé publique ? C’est ce que nous allons développer maintenant.

Signature digitale

En cryptographie, une signature digitale est un objet qui permet d’affirmer qu’une personne (le signataire) est bien à l’origine d’un message. Dans la chaîne de blocs Bitcoin, la signature (ECDSA) permet d’autoriser une transaction de manière indéniable et non modifiable.

Dans une transaction Bitcoin, une signature est générée par un algorithme à partir de la clé privée et du hash de la transaction (ou d’une partie de la transaction). Un deuxième algorithme permet à tout le monde de vérifier l’authenticité de cette signature en utilisant la clé publique créée à partir de la clé privée qui a signé le message (le hash de la transaction dans notre cas). Tout le monde peut vérifier que seule la personne qui possède la clé privée est à l’origine de la signature (et donc de la transaction).

Vous pouvez voir plus d’informations sur les clés privées, les clés publiques et le cryptage asymétrique ici et ici.

Dans sa forme la plus courante, la signature utilise le hash de toute la transaction (toutes les « inputs », toutes les « outputs » et autres champs). Cela permet de s’assurer qu’aucun champ ne soit modifié. Mais ceci n’est pas obligatoire : il est par exemple possible de faire un chèque en blanc en ne signant que les « inputs ». Ainsi, n’importe qui pourra venir modifier la transaction en ajoutant son adresse dans le script de verrouillage et récupérer les bitcoins. Cela peut également être utilisé pour des collectes de fonds où chaque personne pourra ajouter et signer sa propre « input » (et « l’output ») d'une plus grande transaction. Tant que l’objectif de levé de fonds n’est pas atteint, la transaction est invalide (puisque « l’output » est plus grande que la somme des « inputs »).

Il existe de nombreuses combinaisons possibles qui sont indiquées à la fin de la signature (par un SIGHASH flag).

Ainsi, nous avons expliqué le fonctionnement par empilement du langage Script utilisé pour les transactions. Nous avons également montré comment fonctionne le verrouillage et déverrouillage de script pour pouvoir dépenser les UTXO dans une transaction Bitcoin en présentant l’exemple le plus couramment utilisé : le payement au hash de la clé publique ou P2PKH. Nous avons également montré qu’il était possible de créer différents types de transactions en fonction de la partie de la transaction utilisée dans la signature (SIGHASH).

Cependant, il existe de nombreux autres types de transactions qui peuvent être effectuées à l’aide de différents opérateurs du langage Script. C’est ce que nous présenterons dans une troisième partie.