La mécanique du Bitcoin [mooc Bitcoin week #03]
Si vous débarquez sur cet article, je vous conseille de passer par les articles précédents et au moins celui de la semaine dernière.
Nous avons vu jusque là que dans le bitcoin :
- on ne pouvait qu’ajouter des transactions au registre (ledger en anglais)
- que le processus de consensus était totalement décentralisé
- ce sont les mineurs qui construisent les blocs afin de valider des transactions
Mais au fait, une transaction à quoi ça ressemble exactement ? Idem pour le bloc.

Cette semain, nous plongeons dans les entrailles des transactions et des blocs pour comprendre comment le lien se fait entre tout ce qu’on a pu voir jusque là !
#Bitcoin Transactions
Avant de rentrer dans le coeur des transactions, prenons l’exemple où il n’y a qu’une transaction par block. Une première transaction est créée avec un bloc (réalisée par Alice) qui lui permet de gagner les 25 bitcoins de récompense.
Puis elle créé une transaction de 17 btc vers Bob qu’elle signe. Puis Bob à son tour créé une autre transaction de 8 btc vers Carole (qu’il signe aussi). Et il créé une seconde transaction de 5 btc vers Alice.

Ensuite, Alice créé une transaction de 15 btc vers David.

Sauf que vous avez dû remarquer, nous n’avons pas la notion de “compte courant global” par utilisateur qui permettrait de dire facilement si Alice a le montant suffisant pour créditer David.
25 — 17 + 5 = 13 btc, c’est ce que possède Alice au moment où elle créé cette transaction. En fait, avec le Bitcoin, pour valider une transaction, il va falloir repartir du premier bloc de la blockchain et dérouler l’historique des transactions.
C’est plus facile à comprendre en changeant légèrement la réprésentation :

Ce premier bloc attribue 25 btc à Alice.
Puis Alice créé la transaction qui envoie 17 btc à Bob :

Plusieurs choses à dire :
- dans les Inputs, 1[0] signifie : output du bloc 1, situé à l’indice 0 (le premier en fait). Cela fait référence au 25 btc récupéré par l’output 0 du bloc 1
- dans les outputs, nous voyons deux éléments : 17 vers Bob et 8 vers Alice.
En fait, dans une transaction, la totalité l’input est consommé. Puisque vous avez suivi l’article de la semaine précédente, vous vous souvenez sans doute que si les montants en sortie sont inférieurs aux inputs, la différence part en pourboire au créateur du bloc. Ainsi, Alice ne laisse pas de pourboire dans ce cas et envoie les 8 btc restant de l’input à une de ses adresses. 17 + 8 = 25, le compte est bon.

On continue et de la même manière, Bob créé la transaction du bloc 3 en récupérant la sortie du bloc 2, indice 0 (et oui, il ne peut pas créer une transaction avec l’argent de quelqu’un d’autre). Et il en envoit 8 à Carole et 7 à lui. Et enfin, Alice créé une transaction partant de la sortie du bloc 2, indice 1, et envoit 6 btc à David et 2 btc à elle-même (si c’est pas clair, regardez simplement le schéma ci-dessus).
De cette manière, il est en fait plus facile de se repérer : une transaction a un input identifié, et on peut voir très facilement si les fonds sont disponibles ou pas.

## D’autres formes de transactions
En fait, on s’est limité à un seul input, mais on peut très bien en mettre beaucoup plus pour faire un paiement groupé :

Sur l’illustration ci-dessus, la transaction du bloc 3 prend les sorties du bloc 2 (indices 0 et 1) pour tout envoyer à David. Et bien évidemment, Carol et Bob signent la partie qui les concernent pour prouver qu’ils autorisent cette transaction. C’est la même chose quand vous allez au restaurant et diviser la note.
## Et en vrai, ça ressemble en quoi ?
Bon, allez, on met les schémas de côté et on regarde concrètement à quoi ressemble une transaction Bitcoin.

Il y a trois parties principales :
- des metadata : hash de la transaction et des infos en plus (nombre d’inputs, d’outputs, taille totale…)
- les inputs : un tableau avec le détail des inputs
- les outputs : un tableau avec le détail des outpus
## Input
L’attribut “in” représentant les inputs a la forme suivante :

Nous voyons que chaque input est constitué des champs suivants :
prev_out
: qui permet de situer à quelle sortie on fait référence.hash
= identité du block, etn
= l’indice de la sortie à prendrescriptSig
: ensemble constitué de la signature (prouvant que la sortie précédente est bien destinée à la personne qui créé cette transaction) et la clé publique en question :scriptSig = signature + publicKey
## Outputs
Concernant les outputs, nous avons les choses suivantes :

value
: le montant à envoyer en satoshi (1 bitcoin = 100 millions de satoshis)scriptPubKey
: un script … qui semble contenir entre autres le hash de l’adresse du destinataire (de la clé publique) … Hmm, nous allons voir exactement ce que c’est dans la suite.
# Bitcoin Scripts
Du coup, nous venons de voir que la sortie précise bien plus que la clé du destinataire, mais bien un script. Ce script est écrit avec le langage Bitcoin Script (ou juste Script) créé pour l’occasion. Dans notre cas, il y a 4 instructions et une donnée (la clé publique du destinataire) :
OP_DUP OP_HASH160 69e02e18....3d42e OP_EQUALVERIFY OP_CHECKSIG
En fait, en entrée, scriptSig
est également un script. Rappelez-vous, c’est un script composé de la signature et de la clé publique.
Pour former le script complet, il faut prendre le scriptPubKey
de la transaction précédente (dans notre cas, la transaction 1 qui a crédité Alice de 25 btc) et le scriptSig
de la transaction qu’on créé. En exécutant scriptPubKey_transaction1 et scriptSig_transaction2
, il ne doit pas y avoir d’erreur. En d’autres termes, prouver qu’Alice a le droit de dépenser ses bitcoins via cette transaction 2, elle doit prouver que sont scriptSig
remplit bien les conditions du scripPubKey
précédent.

Si ce script s’exécute sans erreur, alors la transaction considérée comme valide.
## Bitcoin scripting language
Sans trop rentrer dans les détails, le langage de script et un langage de programmation orienté en stack, très adapté aux opérationx cryptographiques.
Regardons étape par étape comment notre transaction est validée.
Voici les différentes opérations du script :

Dans un langage à stack (ou à pile), on empile les données les unes au dessus des autres et les opérations consomment un certain nombre de données de la pile (en commençant par le haut).
Etape 1 : ajouter la signature d’Alice à la pile

Etape 2 : ajouter la clé publique d’Alice

Etape 3 : on duplique la dernière donnée (ici, la clé publique)

Etape 4 : on calcule le hash de la dernière donnée

Etape 5 : on ajoute le hash de la clé publique du destinataire (depuis la transaction précédente, donc dans ce c’est Alice) :
Etape 6 : vérifier l’égalité des derniers termes. Si OK, continuer :

Etape 7 : vérifier que la signature a bien été réalisée par cette clé publique. Si OK, on a terminé avec succès !

La subtilité est de voir que sriptSig
et scriptPubKey
ne viennent pas de la même transaction. En fait, maintenant que le script s’est exécuté avec succès, Alice met dans le scriptPubKey
de la transaction 2 (où elle envoit à Bob) une sorte de défi :
“quiconque réussira à exécuter ce script avec succès, pourra dépenser l’argent de la transaction”
Dans ce sriptPubKey
, elle met les différentes opérations et le hash de la clé publique de Bob.
Pour que Bob puisse les dépenser dans la transaction 3, il devra mettre dans scriptSig
sa clé publique (et la signature de la transaction, qui pour rappel est faite avec la clé privée de Bob).
Est-ce plus clair ? Car le mooc ne l’a pas forcément bien mis en évidence et j’ai dû faire quelques recherches complémentaires. Je vous laisse consulter les ressources complémentaires disponibles en fin d’article.
# Applications of Bitcoin Scripts
En réalité, dans le script, on peut mettre des choses beaucoup plus poussées. On peut programmer des conditions comme on le souhaite.
Par exemple, lors d’un achat e-commerce. Si Alice souhaite acheter un produit à Bob, Alice ne souhaite pas payer avant d’avoir bien reçu le produit (qui peut être endommagé voire, jamais envoyé). Du coup, Alice peut créer une transaction de paiement, mais qui aura besoin d’au moins 2 signatures parmi 3 personnes : Alice, Bob et un tiers de confiance. Tant que 2 signatures n’ont pas été obtenues, l’argent reste bloqué.
Si Alice reçoit bien le colis, elle va signer la transaction, Bob également (et oui, il veut être payer lui !). On est bon.
Par contre, si un problème arrive, Alice ne signera pas. C’est donc au tiers de confiance de déterminer à qui attribuer les fonds : Alice ou Bob en fonction du litige. On aura donc la signature du tiers de confiance et de la personne “jugée” apte à recevoir les fonds.
Ce qui est intéressant dans ce cas est que le tiers de confiance n’intervient que s’il y a litige (qui doit rester exceptionnel), pas quand tout se passe normalement.
Dans les fais, 99% des transactions avec le Bitcoin sont “classiques” et sont de la forme que nous avons détaillés juste avant. C’est ce qu’on appelle le “multisignature”.
# Bitcoin Blocks
Nous avons fait le tour des transactions, passons maintenant au niveau supérieur : les blocs.

On a ici :
- un header : hash, version, référence au block précédent, nonce, nombre de transactions (n_tx)
- et la liste des transactions : tx : […]
Et on retrouve tout ce qu’on a pu dire jusque là :
- le block référence le block précédent
- le nonce permet de vérifier que casse-tête est bien rempli
- le hash de l’arbre de Merkle permet de s’assurer que la liste des transactions n’a pas été compromise
Il existe plein de sites web pour visualiser tout cela, allez-y c’est assez passionnant et on se perd très rapidement dans ce grand labyrinthe :
A part, cela il n’y pas grand chose à dire de plus sur les blocs. Vous voyez, ce n’était pas si sorcier que cela.
# The Bitcoin Network
Un petit mot sur le réseau du Bitcoin avant d’aller plus loin. Pour faire simple, c’est un réseau P2P que chacun peut rejoindre (après avoir installé un client bitcoin) et où tous les noeuds sont égaux.

On ne va pas s’en faire une montagne, donc avançons 😉 .
# Limitations & Improvements
Nous avons vu beaucoup de paramètres fixes : moyenne de 10 minutes entre chaque bloc, récompense figée … Tout cela est écrit en dur dans le code des clients Bitcoin.

Forcément, cela a un impact sur beaucoup de choses, notamment le nombre de transactions que l’on peut envoyer dans la blockchain. Ce nombre est largement inférieur aux nombres que traitent Visa ou PayPal. Donc, en gros, si vous cherchez une technologie pour faire des transactions à la vitesse de la lumière, il faudra envisager une autre techno (mais il existe plein de “alt-coins”, des coins alternatives s’inspirant du Bitcoin mais ayant leurs spécificité).

Il y a d’autres points limitants. La cryptographie est une des briques essentielles au Bitcoin et il n’y a pourtant qu’une seul algorithme de signature (ECDSA/P256). Idem pour les fonctions de hashage qui sont en dur dans le code. Or, on estime que les algorithmes seront cassés d’ici 2040…
C’est pour cela que vous avez peut-être entendu parler de Hard-Fork ou Soft-Fork qui sont des mise à jour plus ou moins douloureuses dans le protocole. On en reparlera plus tard.
Conclusion
Cette semaine, nous avons vraiment plongé dans les entrailles du bitcoin et sa blockchain : anatomie des transations et des blocks. S’il ne fallait retenir qu’une chose : tout est lié de bout en bout, et tout à chacun peut vérifier la conformité de la blockchain.
Je vous rassure, la semaine prochaine, on prend du recul et on va voir concrètement comment on stocke et on utilise les bitcoins.
Sommaire
- Semaine 01 : Introduction à la Crypto et aux Cryptomonnaies
- Semaine 02 : Comment le Bitcoin arrive-t-il à être décentralisé ?
- Semaine 03 : La Mécanique du Bitcoin
- Semaine 04 : Comment Stocker et Utiliser des Bitcoins
- Semaine 05 : Bitcoin Mining
- Semaine 06 : Bitcoin et Anonymat
- Semaine 07 à 11: article commun
Sources et ressources complémentaires