Introduction

Bitcoin était la toute première crypto-monnaie décentralisée qui est rendue publique par une entité mystérieuse, se nommant Satoshi Nakamoto.  Ses principes généraux étaient annoncés dans un papier historique  en janvier 2009.  En fait, Satoshi fait référence à  a un message de plus de 10 ans au par avant par Wei Dai où le principe de base est déjà esquissé.  Satoshi s'est donné la tâche de détailler la proposition de façon conceptuelle et technique.   Dans son papier, Satoshi ne donne pas ces détails techniques, mais donne les lignes selon lesquelles le système bitcoin va fonctionner.

Bitcoin étant la première crypto monnaie réellement opérationnelle, Satoshi a dû faire beaucoup de choix techniques, mais aussi conceptuels dans les grandes lignes qu'il avait défini.  Beaucoup de ces choix ont été de puissance prophétique, mais certains choix ont été moins heureux.  Parmi les conséquences imprévus de ces choix, nous mentionnons les plus importants selon moi:

  • la centralisation du minage
  • l'anonymat ratée
  • le processus de minage hautement gaspillant des ressources et de l'électricité
  • le manque d'interchangeabilité des coins
  • le petit nombre de transactions par seconde et/ou l'énorme taille de la block chain
  • la violence des chocs de division par deux du gain par bloc
  • le statut mitigé du langage de programmation pour exprimer des contrats intelligents.

De nouvelles crypto monnaies ont introduit beaucoup d'avancées technologiques qui prennent en compte ces difficultés.  Beaucoup de ces crypto monnaies n'ont, malheureusement, pas le succès de bitcoin, même si on peut apprécier leurs avancés techniques.  Bitcoin a rencontré une difficulté imprévue.  Le système de croyance monétaire qui soutient la valeur économique de bitcoin dépend de la vérifiabilité des règles acceptées.  Mais cela implique que ces règles sont quasi impossible à changer sans mettre en péril le système de croyances monétaire.  Même si la plupart des utilisateurs de bitcoin reconnaissent certains de ces problèmes, il n'y a pas de moyen pour changer les règles sans tuer la croyance que ces règles ne changeront jamais.  Tout changement de protocole établi est difficile dans l'industrie, mais cela n'a pas empêché d'arriver à HTML 5.  La nécessité de croyance en règles éternelles rend, cependant, toute modification des ordres de grandeur plus difficiles, voire impossibles.

Ainsi, de toutes les crypto monnaies, bitcoin restera sans doute la moins évoluée, mais néanmoins celle qui connaît le plus grand succès à ce jour.  Je ne dis pas cela pour dénigrer le travail de Satoshi, au contraire.  Satoshi est le seul inventeur d'une crypto monnaie qui devait le faire sans exemple dans le monde réel avec un retour d'expérience.  C'est la nature même de la croyance monétaire qui interdit, visiblement, au premier protocole d'évoluer, sinon, bitcoin serait la monnaie la plus avancée en ce jour.

Ceci dit, le système bitcoin est étonnement flexible, et des astuces de l'intérieur du système ont permis de trouver des solutions à certains de ces difficultés.

Le coté technique de bitcoin est relativement compliqué, et comprend essentiellement deux parties: la block chain, et le protocol pair-à-pair de communication.  La partie fondamentale reste cependant la block chain car c'est ce qui restera.  Dans la mesure où on déciderait de modifier le protocol réseau, cela n'aurait pas beaucoup d'influence sur le système de croyances de bitcoin, car la chose à vérifier, c'est la block chain.   Les communications auront disparu, mais la block chain reste.  Ainsi, nous allons nous limiter à l'analyse de la block chain, et nous allons utiliser cela pour indiquer les fonctionnements essentielles du système bitcoin.

La structure numérique de la block chain

La structure numérique de la block chain est composée de deux couches: le bloc, et la transaction.   La nature cryptographique de la crypto monnaie bitcoin nécessite la description au niveau du bit individuel de tout le système afin d'expliquer comment fonctionne bitcoin.  La block chain est une liste numérotée de blocs, et chaque bloc est une liste bien définie de bits.  Si nous changions un seul bit dans cette liste, cela changerait tous les hashages cryptographiques.  Ainsi, même si la description technique peut paraître fastidieuse, elle est essentielle si nous voulons décrire comment fonctionne ce système.  En réalité, il s'avère que le niveau de détail peut s'arrêter au niveau de l'octet.

Structure du bloc

Un bloc est une liste ordonnée d'octets, dont la description détaillée suivra.  La structure générale d'un bloc est ainsi:

  1. Un numéro magique de 4 octets.  C'est 0xF9BEB4D9 en notation hexadécimale (le premier octet est 0xF9, le deuxième est 0xBE, ....)
  2. 4 octets qui représentent le nombre d'octets qui restent dans le bloc à compter du suivant
  3. l'entête de bloc, de 80 octets
  4. un entier à taille variable du nombre de transactions qui vont suivre (entre 1 et 9 octets)
  5. la liste des transactions (qui sont aussi des listes d'octets ordonnés)

L'entier non signé de 32 bit est coupé en octets selon la façon little-endian (l'octet le plus signifiant est le dernier dans la série).  C'est aussi pour cela que le numéro magique est souvent noté 0xD9B4BEF9, car si on l'interprète comme entier non signé, il est enregistré dans l'ordre inverse (little endian).   Nous allons regarder l'entête de bloc en détail bien sûr, mais considérons le point 4 d'abord: la représentation de taille variable d'un entier non signé.  Si le nombre est plus petit que 253, alors la représentation se fait en un octet.  Si le nombre est égal ou supérieur à 253, mais inférieur à 65535, alors la représentation contiendra 3 octets: le premier sera 0xFD et les deux suivants seront la représentation non signé du nombre en forme little-endian (notez que le premier octet 0xFD reste bien le premier).   Si le nombre est plus grand que 65535, mais plus petit que 4 milliards, 5 octets seront utilisés: 0xFE suivi d'une représentation little-endian de l'entier non signé.  Finalement, pour des nombres plus grand que 4 milliards, 9 octets seront utilisés: 0xFF suivi de la représentation sur 8 octets en ordre little endian de l'entier non signé. En fait, d'autres limites dans le système bitcoin font que cette possibilité ne se présentera jamais.

L'entête du bloc a une structure spécifique et est un élément cryptographique du système bitcoin.  L'entête fait exactement 80 octets:

  1. le numéro de version du bloc, sur 4 octets
  2. le hasch de l'entête de bloc précédent, sur 32 octets (256 bits)
  3. le hasch de l'arbre Merkle des transactions dans ce bloc, sur 32 octets (256 bits)
  4. le temps actuel en secondes depuis 1970, en 4 octets
  5. le but actuel, en 4 octets
  6. le nonce en 4 octets

C'est cette entête qui sera haché,  et sur lequel la preuve de travail sera livrée.  Le lien avec le hasch du bloc précédent est ce qui fait les liens entre les blocs pour en faire une bloc chain ; l'arbre de Merkle fixe chaque octet dans chaque transaction.  Le nonce sera la preuve de travail.

Comme l'entête de bloc sera le lien de la chaîne, la sécurisation de l'invariabilité des transactions, et l’irréversibilité de la preuve de travail, donc le "graver en pierre du consensus", il faut bien sûr qu'on comprenne chaque octet de cet entête.  Tous les entiers sont des non-signés en convention little endian.  Ainsi, la version est souvent 0x01 suivi de 0x00 trois fois (donc le numéro 1, normalement écrit 0x00 00 00 01, car la notation normale est big-endian).

Les hasch sont aussi enregistré en forme "little endian" dans la mesure où on interprète les hasch comme des grands entiers.  Comme la preuve de travail  exige que le hasch sera un petit nombre en fonction de la difficulté, se seront donc les derniers octets des 32 octets des hasch qui seront zéro, et non les premiers.  Par contre, l'ordre des octets dans le hasch est bien l'ordre des octets comme ils sortent de l'algorithme standardisé de hashage (deux fois l'application de SHA-256).  Ce n'est que leur interprétation en grand nombre, pour appliquer la difficulté, qui est little-endian.

Le temps actuel est aussi, bien sûr, little-endian.

Le but actuel est une sorte de "nombre flottant", avec un exposant d'un seul octet, et une mantisse de 3 octets en représentation signée. Le but représente approximativement le grand nombre qui est la limite supérieure de la valeur numérique d'un hash acceptable.  Plus que ce nombre est petit, plus que la difficulté est grande.  Le hash du bloc doit donc être inférieur à ce but.  L'exposant (le 4ième octet) est en fait le nombre de chiffres significatifs non-zéros quand on écrit le but dans la base 256.  Cet exposant est augmenté de 1 si le chiffre le plus significatif non-zéro est plus grand que 127.  Les 3 octets "mantisse" sont les 3 plus grands nombres significatifs (dont un zéro si on avait augmenté l'exposant de 1).  La mantisse est enregistrée en ordre inverse (little-endian).

Le nonce est 4 octets, et donc bien trop petit pour servir comme nonce.  4 octets permettent 232 = 4 milliards de possibilités, et donc 4 milliards de hashes différents.  Si la difficulté est supérieure à 4 milliards (et c'est le cas depuis très, très longtemps), alors il ne sera quasiment jamais possible de trouver le bon nonce pour satisfaire à la difficulté, comme initialement prévu.   On peut bien sur gagner quelques bits de "nonce" en faussant un peu le tampon de temps de quelque secondes, mais ceci reste dérisoire.  La seule solution est de modifier les transactions, et de calculer un nouveau hash de l'arbre de Merkle.  Ceci est une erreur de conception du système bitcoin (le nonce est beaucoup trop petit), car l'idée était explicitement que seulement l'entête de bloc nécessitait modification dans la preuve de travail.   D'un autre coté, cette idée même, que seulement les entêtes jouent un rôle dans la preuve de travail est en soi une erreur de conception, car cela mène à des avantages d'échelle et à la centralisation du minage.  Mais en tout cas, ces règles ont été choisi, et sont maintenant gelés à jamais.  En fait, la taille du nonce était trop petit dès le début, car la difficulté de démarrage était déjà 232.  La difficulté était déjà un sur 4 milliards. 

Regardons le bloc genèse de bitcoin:

F9 BE B4 D9  -- Nombre magique
1D 01 00 00 -- Nombre d'octets dans le bloc
01 00 00 00 -- Numéro de version
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -- hash précédent (il n'y en a pas !)
3B A3 ED FD 7A 7B 12 B2 7A C7 2C 3E 67 76 8F 61 7F C8 1B C3 88 8A 51 32 3A 9F B8 AA 4B 1E 5E 4A -- Merkle hash
29 AB 5F 49 -- secondes depuis 1970
FF FF 00 1D -- le but
1D AC 2B 7C -- le nonce
01 -- une transaction suivra.
01 00 00 00
01
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF
4D
04 FF FF 00 1D 01 04 45 54 68 65 20 54 69 6D 65 73 20 30 33 2F 4A 61 6E 2F 32 30 30 39 20 43 68 61 6E 63 65 6C 6C 6F 72 20 6F 6E 20 62 72 69 6E 6B 20 6F 66 20 73 65 63 6F 6E 64 20 62 61 69 6C 6F 75 74 20 66 6F 72 20 62 61 6E 6B 73
FF FF FF FF
01
00 F2 05 2A 01 00 00 00
43
41 04 67 8A FD B0 FE 55 48 27 19 67 F1 A6 71 30 B7 10 5C D6 A8 28 E0 39 09 A6 79 62 E0 EA 1F 61 DE B6 49 F6 BC 3F 4C EF 38 C4 F3 55 04 E5 1E C1 12 DE 5C 38 4D F7 BA 0B 8D 57 8A 4C 70 2B 6B F1 1D 5F AC
00 00 00 00

Le bloc genèse de bitcoin a une structure minimaliste mais normale d'un bloc.  L'entête est marquée en gras et la liste de transactions en italique.

Structure de transaction

La liste de transactions est une succession de transactions.  Chaque transaction prend la forme suivante:

  1. Le numéro de version de transaction: 4 octets d'un entier non signé en ordre little-endian
  2. Le nombre d'entrées de la transaction (entier de longueur variable, de 1 à 9 octets)
  3. La liste des entrées
  4. Le nombre de sorties de la transaction (entier de longueur variable, de 1 à 9 octets)
  5. La liste des sorties
  6. Le "lock time" sur 4 octets, en entier non signé en ordre little-endian

Structure d'une entrée

Une transaction peut avoir plusieurs entrées, ou seulement une.  Chacune de ces entrées prend la forme suivante:

  1. Le hash de la transaction précédente qui contient la sortie qui sera maintenant l'entrée (32 octets)
  2. L'index de la sortie dans cette transaction (4 octets, non signé, little-endian)
  3. La longueur du script qui suivra, en entier de longueur variable (1 à 9 octets)
  4. Le scriptsig, avec le nombre d'octets donné en 3.
  5. Le numéro de séquence (4 octets, non signé en ordre little endian)

Il y a une transaction spéciale, qui est la première transaction dans la liste, qui a comme "entrée", la création de nouveaux bitcoins.  En fait, toute l'entrée de cette transaction n'a pas de sens, mais le système exige quand-même au moins une entrée.  Au lieu du scriptsig, il est ainsi possible d'écrire n'importe quoi, et c'est un endroit où on peut inclure du texte aléatoire dans la block chain comme décidé par le créateur du bloc.  Cet endroit est appelé la coinbase.   Les sorties de cette coinbase sont, par contre, des sorties tout à fait normales que le créateur du bloc peut décider (et donc s'attribuer les coins fraîchement créés).  Ces sorties vont d'ailleurs aussi collectionner tous les pourboires des transactions (c'est à dire, la différence entre la somme de toutes les sorties, et la somme de toutes les entrées de toutes les transactions).

La coinbase est aussi utilisée comme un nonce supplémentaire, car chaque fois qu'on change la coinbase, cela changera le hash de l'arbre Merkle et donne donc un autre hash de l'entête.   Il faudra jouer sur la coinbase pour satisfaire la difficulté, car le nonce prévu à cet effet est donc, comme nous avons vu, beaucoup trop petit.

Structure d'une sortie

Une transaction peut avoir plusieurs sorties et chacune prend la forme suivante:

  1. La valeur (le nombre de "satoshi", c'est à dire 10-8 bitcoin) en entier non signé 8 octets en notation little-endian
  2. La longueur du script en entier de longueur variable
  3. Le script de sortie, prenant une des deux formes: transaction output script, ou pubkey script hash avec le nombre d'octets donné en 2.

Regardons de nouveau le bloc genèse de bitcoin, après l'entête.  Le bloc genèse ne contient qu'une transaction, la coinbase.

01 00 00 00 -- Numéro de version de transaction
01 -- Le nombre d'entrées. Il faut au moins une entrée (bidon dans ce cas) Va suivre la première (et seule) entrée
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -- le hash de la transaction contenant la sortie (bidon ici)
FF FF FF FF -- l'index de la sortie dans cette transaction (aussi bidon)

4D -- la longueur du scriptsig, qui est juste la coinbase dans ce cas
04 FF FF 00 1D 01 04 45 54 68 65 20 54 69 6D 65 73 20 30 33 2F 4A 61 6E 2F 32 30 30 39 20 43 68
61 6E 63 65 6C 6C 6F 72 20 6F 6E 20 62 72 69 6E 6B 20 6F 66 20 73 65 63 6F 6E 64 20 62 61 69 6C
6F 75 74 20 66 6F 72 20 62 61 6E 6B 73

FF FF FF FF -- le numéro de séquence (sans signification ici)
01 -- Le nombre de sorties (il n'y en a qu'une dans cette transaction)
00 F2 05 2A 01 00 00 00 -- le nombre de satoshis, ici donc 50 bitcoin, ou 5 000 000 000 satoshis, donc 1 2A 05 F2 00 en notation hexadécimale
43 -- la longueur du script qui suivra
41 04 67 8A FD B0 FE 55 48 27 19 67 F1 A6 71 30 B7 10 5C D6 A8 28 E0 39 09 A6 79 62 E0 EA 1F 61
DE B6 49 F6 BC 3F 4C EF 38 C4 F3 55 04 E5 1E C1 12 DE 5C 38 4D F7 BA 0B 8D 57 8A 4C 70 2B 6B F1
1D 5F AC -- le script de sortie

00 00 00 00 -- le lock time

Satoshi a caché un message dans sa coinbase.  Quand on interprète les octets comme des caractères ASCII, on lit:

1D 01 04 45 54 68 65 20 54 69 6D 65 73 20 30 33 2F 4A 61 6E 2F 32 30 30 39 20 43 68 61 6E 63 65 
6C 6C 6F 72 20 6F 6E 20 62 72 69 6E 6B 20 6F 66 20 73 65 63 6F 6E 64 20 62 61 69 6C 6F 75 74 20
66 6F 72 20 62 61 6E 6B 73

The Times 03/Jan/2009 Chancellor on brink of second bailout for banks

Il y avait effectivement un article dans le journal The Times le 3 janvier 2009, qui était intitulé ainsi.  La signification est double.  D'abord, cela prouve que ce bloc a été créé après le 3 janvier 2009 (ce qui sera important pour le calcul de la difficulté, lié au temps réel, ce qui démontre que Satoshi n'a pas "miné" des bitcoin dans sa cave depuis 5 ans par exemple) ; et bien sûr cela va graver dans la pierre à jamais le débacle du système monétaire qu'on pourrait voir comme totalement corrompu comme le prouve ce "bailout" ; c'est une des raisons d'avoir inventé bitcoin.

Les scripts

Si bitcoin était juste une crypto monnaie avec la seule ambition de faire des transactions, la section suivante n'aurait pas de sens, mais bitcoin est aussi un premier essai au concepte de contrats intelligents.  La façon dont c'est fait en bitcoin est essentiellement qu'un contrat intelligent est une transaction qui sera exécutée quand une combinaison de conditions sera satisfaite.  Bien sûr une simple transaction peut être vue sous cet angle aussi: c'est le contrat élémentaire avec une seule condition: que le propriétaire précédent prouve qu'il est bien le propriétaire précédent et est d'accord avec la transaction pour désigner un nouveau propriétaire.  Mais il y a plus de possibilités que cela.

Le principe général est le suivant: Il y a un "script" associé à chaque sortie de transaction, et il y a un "sigscript" à chaque entrée de la transaction suivante qui fait référence à cette sortie précédente.   La condition pour que la transaction se fasse peut se voir ainsi: le sigscript est suivi du script de sortie dans cet ordre (en réalité, il y un problème de sécurité avec ceci, et la façon de le faire est plus compliquée, mais conceptuellement nous pouvons nous imaginer qu'on exécute le sigscript, et en suite, le script de sortie).  Si le résultat de cette exécution est "vrai", alors la transaction est acceptée, si l'exécution donne "faux", alors la transaction est rejetée. 

Le langage script de bitcoin est relativement rudimentaire.  Ce sont des instructions qui font des opérations sur ce qu'on peut appeler une pile, et peuvent retourner un "true" ou un "false".  Les instructions sont codés dans des simples octets, éventuellement suivi d’opérandes de longueur variable.  D'une certaine façon, on peut voir le script de sortie comme un défi, que le sigscript doit relever.   Le langage script a aussi accès a la block chain, et à la transaction actuelle.   Bien que simple et rudimentaire à première vue, le scripting dans bitcoin ouvre un nombre de possibilités énorme, mais bien sûr la plus simple est la transaction normale d'un propriétaire à un autre.   Si bitcoin se limitait à cela, il n'y aurait pas besoin de langage script, bien sûr, mais comme il y a ce langage, il faut donc aussi exprimer cette simple transaction par un script.

Le script de sortie d'une simple transaction est:

OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

et le script de signature (sigscript) qui relève le défi est:

<sig> <pubKey>

Ainsi, quand nous combinons les deux pour vérification, il se passe les choses suivantes:

<sig> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

Le script total est donc une concaténation du script de signature suivi du script de sortie (le défi).

D'abord, la signature est poussé sur la pile.  Ensuite, la clé publique (de l'ancien propriétaire) est poussé sur la pile.

L'instruction OP_DUP fait une copie du dernier truc sur la pile, ce qui est donc la clé publique, qui se retrouve maintenant deux fois sur la pile:

<sig> <pubkey> <pubkey>

L'instruction OP_HASH160 calcule le hash de 160 bits du dernier truc sur le stack, donc la clé publique.  La pile est donc maintenant:

<sig> <pubkey> <hash160 of pubkey>

Ensuite  <pubKeyHash> est poussée sur la pile (de la sortie).  La pile est maintenant:

<sig> <pubkey> <hash160 of pubkey> <pubKeyHash>

L'opération OP_EQUALVERIFY vérifie si les deux derniers trucs sur la pile sont les mêmes.  Si ce n'est pas le cas, le script s'arrête avec un "false".  Dans cette instruction, nous vérifions donc si la clé publique fournie par le prétendent propriétaire correspond bien à celle à qui la sortie était destinée.  Si c'est bon, le script continue.  La pile est maintenant:

<sig> <pubkey>

L'instruction OP_CHECKSIG va vérifier si la signature de la transaction en cours correspond bien à la clé publique fournie.  Mais il y a un problème de principe: la signature fait partie elle-même de la transaction.   Au moment de signer, cette signature n'est bien sûr pas encore connue, et il est donc impossible de signer un message contenant sa propre signature.  Ainsi, les choses deviennent plus compliqués.

Ce qui se passe, c'est que la transaction actuelle (à vérifier) est enlevée de toutes ses scriptsigs d'entrée.  Par contre, toutes les sorties seront gardées.  On adapte aussi les indicateurs de longueur de script (ceux des scriptsigs sont mis à 0).  Ensuite, l'ancien script de sortie (qu'on est en train d'exécuter) de la sortie de la transaction référencée est mis à la place du scriptsig qu'on est en train de vérifier mais qu'on avait enlevé.  On adapte de nouveau l'indicateur de longueur de script pour ce cas.  La signature même contient un octet supplémentaire spécifiant le type de hash à utiliser, et cet octet est changé en 4 octets qui indiquent le code de hashage.  Ces 4 octets sont ajoutés à la chaîne d'octets de la transaction modifiée.

Cette chaîne d'octets est en suite hashée (double SHA-256).  Finalement, on vérifie si la signature donnée dans le sigscript est la signature de cet hash, avec la clé publique donnée, en utilisant la technique de la signature cryptographique des courbes elliptiques comme défini dans le système bitcoin.

Considérons un exemple, un bloc de 2011:

F9 BE B4 D9 A1 23 00 00 
-- en-tête
01 00 00 00 98 D9 02 9C EB 0E F7 BB 3A F1 35 E7 7E 26 DA F9
03 56 0C 7F
14 DE 1D EB 5F 4B 00 00 00 00 00 00 07 DE 60 9F
04 A4 BE 2C 1B 23 E0 93 DB 7E 8E D5 08 47 7B 0B
E7 32 65 F7
1E 8F 8C BF 45 34 9C 9E 84 37 B3 4D AC B5 00 1B 0C 17 39 BC
1B
-- nombre de transactions (27)
-- transaction coinbase 01 00 00 00 01 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF
FF FF 07 04 AC B5 00 1B 01 0B FF FF FF FF 01 40 34 15 2A 01 00 00 00 43 41 04 C5 8F 32 C8 E2 F7
24 EB E7 BF 94 C2 45 1C EE 28 BA 07 03 0A 2C AC EC C7 1C 28 14 00 1A 51 E6 6C B0 EC AF AA 15 2F
74 8E DB 8E A0 7C B2 76 AB 2F B3 43 8C 15 06 8D 96 52 26 65 DE 10 CB 3B 48 A7 AC 00 00 00 00
01 00 00 00 -- version
01 -- une entree
78 3F 1D 91 43 77 F8 E7 19 37 A0 4B 9A 4D 22 D8 EC 16 E5 14 AD 35 70 8C 80 2D E6 09 C3 0F 3C 1F -- hash de la transaction correspondante
00 00 00 00 -index de sortie
8B -- longueur du scriptsig
48 30 45 02 21 00 CF 7B F3 A0 D4 E8 FC E0 71 2C 48 1F 20 A3 4D 26 6A DE CB 3A 8D 2B 69 95 D4 DD
C2 AE CA EA F9 F3 02 20 6E 92 39 F1 36 B2 81 42 37 97 87 1A AE 7C 40 40 93 9F 4B 82 0E 9D 27 CF
76 42 FF 67 BA E8 C6 3D 01 41 04 86 79 12 72 F2 37 A7 C8 00 6F 54 AB 11 D8 26 B3 54 72 98 9F C3
3A 7D 02 4A 57 A9 3E 25 EB 7E D0 EA 9B D9 05 E7 CC 98 F4 5D 64 07 5A D0 EF 9D AD 73 8F 87 90 BE
83 F6 87 8B 95 67 0C 36 02 15 1D -- le scriptsig de la première (et seule) entrée
FF FF FF FF -- le sequence number de cette entrée
02 -- nombre de sorties de cette transaction
00 CA 9A 3B 00 00 00 00 --montant de la première sortie: exactement 10 bitcoin
19 -- longueur du script de sortie de la première sortie
76 A9 14 61 2C D0 3B B0 A9 FB 52 60 34 72 88 FF FE 14 13 1D 4F C5 90 88 AC -- script de sortie
00 BD 0A 42 00 00 00 00 -- montant de la deuxième sortie: 11.08 bitcoin
19 -- longueur du script de sortie de la deuxième sortie.
76 A9 14 F8 30 46 C8 6F C7 2D D6 95 EA 0C 14 F7 83 A9 F8 8C 9C 55 40 88 AC -- script
00 00 00 00 -- lock time de la transaction
01 00 00 00 -- la version de la transaction suivante
02 -- deux entrées
86 46 F8 D8 1E 99 4E 10 CE 37 69 70 3D AE F6 38 76 F6 D7 96 AD 54 A8 8B AE F3 29 70 08 A4 32 5D
-- hash de la transaction contenant la sortie dépensée dans la première entrée
01 00 00 00 -- index de cette sortie
8B -- longueur du scriptsig pour cette sortie
48 30 45 02 20 4B 5C 60 42 12 D9 B3 E2 61 C4 3A 5D FD 09 D7 CA AF FF 72 DA 44 4B 86 5F 0E AC 1C
BC 6C 89 D4 B8 02 21 00 DB 5D AF CC 67 9B 78 F9 A6 D4 08 CC AC BB 47 E8 92 FE 86 62 C2 99 95 A3
D4 74 BD 40 CC D8 EE 0C 01 41 04 E6 79 D4 D7 5E FF C8 6F A0 50 E9 BC 8B 19 DA 65 8E 8C 61 A4 09
67 72 23 FD 86 5B 62 7D 9B 46 4C EB 13 02 E1 61 85 1B 5B CD 13 AD 20 6D 26 C5 8C 02 E0 2D 7F 22
A9 7D 1A 64 A4 DE E9 53 10 B5 B7 -- scriptsig de la première entrée
FF FF FF FF -- sequence number
CD CB B0 EA 3D 58 5E CA 95 10 A0 4A 01 C8 2F FC EC 34 0F 3B 3C 03 45 36 09 9E A8 76 39 22 28 2E
-- hash de la transaction contenant la sortie associée à cette deuxième entrée
01 00 00 00 -- index de cette sortie dans cette transaction
8C -- longueur du scriptsig pour cette sortie
49 30 46 02 21 00 BC AF FF F5 20 90 3C 67 D4 B2 77 91 FE 96 11 50 7E 43 B5 F2 3C F7 73 2C 12 52
12 B0 65 B4 A2 C9 02 21 00 BF C3 14 5C 51 73 8A 20 84 43 4C 09 2F 38 48 FC D3 27 FE 85 C5 33 CB
91 86 EE EA 55 80 7A 1D 48 01 41 04 91 9A 77 6A 35 A7 2A 2D 11 E3 F7 BB E7 BF 50 6E 52 A8 66 86
B4 7D 25 C7 55 77 94 EF 08 F2 59 6A 1E F0 75 67 60 3B 99 8E E4 8F B3 95 C6 6C 28 FB 42 14 14 29
FB C0 D1 E3 BB 49 6D 9F FC E0 F8 4B -- scriptsig
FF FF FF FF -- sequence number
02 -- nombre de sorties de cette transaction (ici, 2)
00 F2 05 2A 01 00 00 00 -- montant de la première sortie (50 bitcoin)
19 -- longueur du premier script de sortie
76 A9 14 8C B5 0A C1 25 3B C2 21 DD 67 3F 66 35 E6 70 33 66 0E 53 73 88 AC -- script de sortie
C0 B0 60 06 00 00 00 00 -- montant de la deuxième sortie (1.07 bitcoin)
19 -- longueur du deuxième script de sortie
76 A9 14 A3 08 8B 97 43 B7 7D AC 81 96 2F CC 37 DB BF 42 3E CC 40 A4 88 AC -- script de sortie
00 00 00 00 -- lock time
01 00 00 00 -- version de la transaction suivante
01 -- une seule entrée
...

Le bloc est bien plus long (car il contient 27 transactions), et fait 9 kilo octet, mais nous en avons étudié qu'une partie, avec deux transactions.  La partie italique vient avant la liste de transactions, et contient l'entête du bloc.  Le seul octet 1B indique que la liste des transactions contiendra 27 transactions, dont la première, soulignée, est la coinbase ou 50 nouveaux bitcoins sont donnés au créateur du bloc.  Nous étudions les deux transactions suivantes.  La première a une entrée et deux sorties, la deuxième a deux entrées et deux sorties. 

Regardons le deuxième script de sortie de la première transaction.  C'est 25 octets:

76 A9 14 F8 30 46 C8 6F C7 2D D6 95 EA 0C 14 F7 83 A9 F8 8C 9C 55 40 88 AC 

Ce script est un défi standard pour une simple transaction, de la forme:

OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

Est-ce que nous pouvons reconnaître ces parties ?

OP_DUP a le code 0x76 et OP_HASH160 a le code 0xA9.  Nous trouvons en effet 0x76 et 0xA9 comme les deux premiers octets.

OP_CHECKSIG a le code 0xAC qui est effectivement le dernier octet du script, et OP_EQUALVERIFY a le code 0x88 qui est l'octet précédent.

L'octet souligné, 0x14, indique que les 20 octets suivants (14 en hexadécimal) doivent être poussés sur la pile.

Ces 20 octets sont l'adresse bitcoin brute du récipient:

F8 30 46 C8 6F C7 2D D6 95 EA 0C 14 F7 83 A9 F8 8C 9C 55 40

Ce n'est pas sous cette forme qu'une adresse bitcoin est connue, car une adresse bitcoin transmise contient un code de vérification et un indicateur de version, ce qui ne fait pas partie de la version brute de l'adresse qu'on trouve sur la block chain.

Ainsi, nous pouvons reconnaître maintenant des sorties de transaction simples: ils commencent toujours avec 3 octets: 76, A9 14 et ils terminent avec 88 AC.  Entre les deux, on trouve l'adresse bitcoin brute du récipient, qui consiste toujours de 20 octets (160 bits).

Regardons maintenant quelque chose de plus compliqué: le sigscript.  Nous allons regarder la première (et seule) entrée de la première transaction considérée.  Le scriptsig est bien plus long que le script de sortie: 139 octets:

48 30 45 02 21 00 CF 7B F3 A0 D4 E8 FC E0 71 2C 48 1F 20 A3 4D 26 6A DE CB 3A 8D 2B 69 95 D4 DD 
C2 AE CA EA F9 F3 02 20 6E 92 39 F1 36 B2 81 42 37 97 87 1A AE 7C 40 40 93 9F 4B 82 0E 9D 27 CF
76 42 FF 67 BA E8 C6 3D 01 41 04 86 79 12 72 F2 37 A7 C8 00 6F 54 AB 11 D8 26 B3 54 72 98 9F C3
3A 7D 02 4A 57 A9 3E 25 EB 7E D0 EA 9B D9 05 E7 CC 98 F4 5D 64 07 5A D0 EF 9D AD 73 8F 87 90 BE
83 F6 87 8B 95 67 0C 36 02 15 1D

Pouvons-nous comprendre sa structure ?  Si le défi est une simple transaction, le scriptsig doit prendre la forme:

<sig> <pubKey>

Voyons de plus près.   D'abord il faut pousser la signature sur la pile, et en suite, la clé publique.  "Pousser sur la pile" commence par un octet indiquant le nombre d'octets à pousser, donc dans ce cas 0x48 (ce qui est 72 octets).  Cela voudrait dire que la signature est (les 72 octets suivants...):

30 45 02 21 00 CF 7B F3 A0 D4 E8 FC E0 71 2C 48 1F 20 A3 4D 26 6A DE CB 3A 8D 2B 69 95 D4 DD C2 
AE CA EA F9 F3 02 20 6E 92 39 F1 36 B2 81 42 37 97 87 1A AE 7C 40 40 93 9F 4B 82 0E 9D 27 CF 76
42 FF 67 BA E8 C6 3D 01

Le prochain octet est 0x41 (donc 65).  Cela voudrait dire que maintenant, nous allons pousser 65 octets sur la pile (la clé publique)

04 86 79 12 72 F2 37 A7 C8 00 6F 54 AB 11 D8 26 B3 54 72 98 9F C3 3A 7D 02 4A 57 A9 3E 25 EB 7E 
D0 EA 9B D9 05 E7 CC 98 F4 5D 64 07 5A D0 EF 9D AD 73 8F 87 90 BE 83 F6 87 8B 95 67 0C 36 02 15
1D

Nous devons être sur le bon chemin, car le nombre d'octets est parfaitement utilisé, pas un de trop ou pas un qui manque.

La signature est la signature elliptique plus un octet qui est normalement 1 (comme c'est le cas ici).  Ce "1" indique le type de hachage.  Nous trouvons bien ce 0x01 à la fin de la signature (en gras).  La structure actuelle de la signature est relativement compliquée, car elle contient plusieurs éléments en format DER.  Nous discuterons de cela plus tard.

La clé publique consiste en deux mots de 32 octets, qui forment la paire (x,y) sur la courbe elliptique.  Nous nous attendons donc à une clé de 64 octets.  Pour des raisons obscures dans le système bitcoin, cette concaténation de deux mots de 32 octets est précédée par un octet supplémentaire: 0x04.  Effectivement, le premier octet de la partie "clé publique" est bien 0x04.  Il suit donc 32 octets pour la partie x (soulignée) et en suite, encore 32 octets pour la partie y.  La partie y n'est en fait pas vraiment nécessaire, car à un signe près, le x détermine le y.

Il est important de se rendre compte que pour qu'une entrée soit valable, c'est à dire, acceptée dans le consensus comme la succession d'une sortie quelque part (indiquée par le hash de la transaction et l'index de la sortie), il n'est pas suffisant de satisfaire le défi.  Il faut que ce soit la première fois dans la block chain que ce défi soit satisfait.  C'est toute la raison d'être de la block chain: éviter la double dépense!

Mais cela veut dire qu'une sortie doit être dépensée en une seule fois, pour toute sa valeur.

On aurait pu faire différemment, mais dans bitcoin, une sortie ne peut être utilisée qu'une seule fois, en entier.  Ainsi, si Jean a payé 50 bitcoin à Louis, et donc Louis possède la clé secrète qui peut fabriquer des signatures correctes pour la sortie de cette transaction (qui vaut donc 50 bitcoin), si Louis veut payer 0.05 bitcoin à Alice pour un café, il doit dépenser les 50 bitcoin en une seule fois, car il ne pourra utiliser cette sortie qu'une seule fois.  Ainsi, Louis va construire une transaction avec deux sorties: une qui vaudra 0.05 bitcoin, avec un défi qu'Alice pourra résoudre (c'est donc son paiement à Alice), et une autre sortie de 49.95 bitcoin dont il gardera lui-même la nouvelle clé secrète.

Un tel paiement à soi-même d'une sortie qui vaut plus que ce qu'on veut payer, est appelé un paiement-change.  Ça a l'air d'être une bonne idée, mais cela va compromettre totalement anonymisation de bitcoin.  Effectivement, jusqu'au paiement de Jean à Louis, seulement Jean et Louis connaissaient cette transaction de 50 bitcoin.  Mais maintenant qu'Alice connaît Louis (car il vient d'acheter un café chez elle), et elle reçoit sa transaction, elle ne sait pas seulement que Louis vient de recevoir un virement de 50 bitcoin, mais en plus, elle connaît aussi l'adresse de change de Louis (c'est la deuxième adresse de la transaction).  Si en suite, Louis achète des boucles d'oreilles pour 30 bitcoin pour son amant, alors Alice sait que Louis vient de dépenser 30 bitcoin.  Suppose que le vendeur de boucles d'oreilles vient acheter un café chez Alice dans son bar à café, et qu'il paie Alice avec ces 30 bitcoins, alors Alice saura que c'est cette personne que Louis avait payé.  A fur et à mesure qu'Alice reçoit des paiements de gens qu'elle connaît, elle apprend de plus en plus sur les paiements que ces gens font entre eux.  Des connaissances partielles de certaines transactions dans le monde réel peuvent donc être exploités pour obtenir de l'information sur des transactions liés à ces personnes.  En combinant beaucoup de ces connaissances partielles, il devient presque possible de des-anonymiser l'essentiel des adresses bitcoin.  Anonymisation prônée de bitcoin est donc quasi-totalement cassée.

Les hash de transactions

Pour spécifier une sortie antérieure, une entrée indique le hash de la transaction en question.  Le hash de la transaction est une double application de SHA-256 à la transaction en entier, commençant par le numéro de version, incluant bien sûr les entrées et sorties, et finalement le lock time, exactement comme cela apparaît dans la block chain.  Par contre, le hash lui-même ne se trouve nulle part.  Ainsi, c'est la responsabilité du vérificateur, afin de trouver de quelle transaction il s'agit, de fabriquer un tableau contenant tous les hash de toutes les transactions de la block chain et leur place dans celle-ci.   Une fois un tel "dictionnaire" est mis en place, un hash donné indique vite où ce trouve la transaction en question (quel bloc, et quelle transaction dans le bloc).  Il aurait été, à première vue, plus simple d'indiquer le numéro du bloc et le numéro de transaction dans le bloc au lieu de ce hash, mais en faisant ceci, la transaction visée devient indépendante du bloc où elle va être enregistrée, ce qui a de multiples avantages.  Mais il faut donc se construire un dictionnaire de hashes de transactions, avant de pouvoir utiliser la block chain.

Les adresses bitcoin

En considérant de simples transactions, il y a un aspect du système bitcoin qui ressemble, à première vue, à un compte en banque, mais en fait cette ressemblance n'est que superficielle.  Cependant, la confusion arrive facilement et même certains régulateurs tombent dans le piège.  Soyons clair: il n'y a pas quelque chose comme un "compte bitcoin".  Quand quelqu'un veut transférer des bitcoins vers vous - parce que vous lui livrez des biens ou des services - alors vous devez lui fournir un défi que vous seulement pouvez relever C'est exactement ce que signifie une "adresse bitcoin": un défi que vous avez préparé et que seulement vous pouvez relever.

Il n'y a aucune raison pour laquelle une autre transaction vers vous aurait le même défi.  Effectivement, il est beaucoup plus sage d'utiliser un nouveau défi pour chaque transaction dans votre direction, bien que rien ne vous interdit d'utiliser le même défi.  Si vous utilisez toujours le même défi pour les transactions dans votre direction, alors ce défi commence à avoir des aires d'un "compte en banque".  Il est vrai que le nom du défi, à savoir "adresse bitcoin", aide beaucoup à établir la confusion dont nous parlons: l'adresse serait une sorte de "numéro de compte" où on envoie les bitcoins dans votre direction.Pour une simple transaction, le défi est de fournir une signature (avec une clé privé ECDSA) du message (la transaction modifiée), de telle façon que la clé publique correspondante produit le hash du défi en question.   Ceci est facile à faire quand vous avez une clé privé: à partir de cette clé, vous produisez la clé publique et donc aussi son hash, qui devient votre "adresse bitcoin", qui sera donc le défi.  Par contre, c'est cryptographiquement impossible de relever ce défi si vous n'étiez pas parti de la clé secrète, et c'est toute l'idée: celui qui fournit le défi est le seul à posséder les outils pour répondre au défi (et en faisant cela, de prouver que c'est bien lui le propriétaire des bitcoins).

Ainsi, la façon normale pour construire un défi que seulement vous pouvez relever, est:

  1. Il faut générer une paire de clés (secrète et publique) dans le groupe elliptique avec le générateur indiqué par bitcoin.  La clé publique consiste de deux mots de 32 octets.
  2. Il faut ajouter l'octet 0x04 au début
  3. Il faut calculer le hash SHA-256 de ce mot de 65 octets, ce qui donne un mot de 64 octets
  4. Il faut calculer le RIPEMD-160 de ce mot, ce qui donne l'adresse brute de 20 octets

C'est ce mot brute de 20 octets qui sera injecté dans le script de sortie dans la block chain. 

Seulement, pour transmettre une adresse à quelqu'un, on rajoute par convention quelques éléments:

  1. On ajoute au début un octet qui identifie le réseau.  Pour le réseau principal bitcoin, c'est 0x00.  Pour le réseau de test, c'est 0x6F.
  2. Prenez deux fois le SHA-256 de ce mot de 21 octets, et gardez les 4 premiers octets de ce résultat.  Ceci est la vérification d'erreur, qu'on ajoute à la fin des 21 octets, pour faire une chaîne de 25 octets.
  3. Il faut maintenant coder cette chaîne de 25 octets, comme un nombre, en base 58: c'est l'adresse bitcoin à distribuer.

Notez que pour pouvoir répondre au défi des 20 octets, il faut avoir la clé secrète d'origine.  Seulement, il n'y a rien qui vous empêche d'inventer une chaîne de 20 octets (et d'en faire même une adresse bitcoin à distribuer avec le 0x00 au début, et les 4 bons octets de vérification à la fin).  Si quelqu'un fait une transaction valide vers cette adresse (avec cette chaîne comme défi), alors ces bitcoin seront perdus à jamais, car personne ne connaît une clé secrète qui pourrait aller avec (car cette clé n'a jamais existé).  La seule façon de récupérer un jour ces bitcoin est en pouvant générer une nouvelle clé secrète qui génère le même défi - mais le jour où cela devient possible, le système bitcoin en entier devient caduc.  Notez que les bitcoin seront aussi irrémédiablement perdus si vous perdez votre copie de votre clé secrète.  Il y a déjà beaucoup de bitcoin perdus, mais on ne peut pas savoir lesquels, sauf si c'est vous qui avez fabriqué l'adresse et que vous savez que la clé n'existe pas, ou est perdue.

Il y a d'ailleurs quelque chose d'étrange dans la façon dont les adresses sont faites dans le système bitcoin.  On pourrait s'imaginer que la difficulté du système des clés est de l'ordre de 256 bits, car on utilise un groupe élliptique avec 256 bits (32 octets).  Seulement, le vrai défi se limite à 20 octets (160 bits), ce qui veut dire que la vraie difficulté est seulement 160 bits.  Effectivement, il doit y avoir 296 pairs de clés public/privé qui vont donner lieu exactement au même hash RIPEMD-160.  Chacune de ces pairs va pouvoir relever le défi.  Il est donc bizarre qu'il faut générer un système avec entropie et difficulté de 256 bits dans le système ECDSA, pour en suite, en gaspiller 96.  On aurait pu se limiter à 160 octets dès le départ, ce qui aurait utilisé moins de place (40 octets au lieu de 64 octets) dans le scriptsig.

The other point to notice is that there's something strange with the way this has been done in bitcoin.  One would think that the cryptographic difficulty of the public key system is of the order of 256 bits, given that one uses an elliptic curve with 256 bits (32 bytes).  But the fact that the only actual challenge is reduced to 20 bytes, means that the actual cryptographic difficulty is in fact only 160 bits.  Indeed, there are of the order of 296 different private/public key pairs that will result in exactly the same RIPEMD-160 hash.  Each of these different key pairs will be able to take up the challenge.  So it is kind of strange that one goes through the difficulty of using a 256 bit ECDSA system of which one has reduced the security by a factor of 296.  One could have used directly a curve with 160 bits.

Conclusion

En explorant la block chain, nous avons pu étudier et comprendre plusieurs aspects du système bitcoin.  Nous pouvons maintenant "lire" la block chain et comprendre ce que la plupart des octets y font (nous n'avons pas traité les scripts plus complexes, mais nous pouvons reconnaître les transactions simples, qui sont l'essentiel de la crypto monnaie, et nous serions capable de reconnaître un script plus compliqué, même si nous ne savons pas comment il fonctionne).  Nous comprenons aussi l'essentiel de transactions, qui forment la base d'une crypto monnaie.

Nous n'avons pas abordé l'autre partie du système bitcoin, qui est le protocole de communication pair-à-pair, et nous n'avons pas étudié tous les détails du système cryptographique de bitcoin (en particulier la cryptographie elliptique).  Sur le plan cryptographique, bitcoin utilise les primitives suivants:

  • La fonction de hashage SHA-256, pour les hash de transaction, la preuve de travail, le hash de l'entête de bloc, et la fabrication d'adresses bitcoin.  C'est aussi utilisé dans l'arbre de Merkle (nous ne l'avons pas étudié en détail).
  • La fonction de hashage RIPEMD-160, qui sert à calculer des adresses
  • Un groupe elliptique pour fabriquer les signatures de transaction que nous n'avons pas détaillé

En plus, dans le langage script de bitcoin, il a y accès à d'autres primitives qu'on pourrait utiliser dans des scripts complexes.

Un des problèmes majeurs découverts avec le système bitcoin est la centralisation du "minage" (c'est le proces de fournir une preuve de travail, pour générer un bloc et récupérer les nouveaux bitcoins).  Ce n'était absolument pas l'intention du départ (de Satoshi).  L'idée était que tout le monde, avec son PC, puisse miner des bitcoins, pour avoir une répartition du seignieurage le plus égalitaire possible.   Seulement, la "preuve de travail" dans bitcoin est trop simple: seulement l'entête du bloc joue un rôle.  L'ancienne partie de la chaîne n'entre qu'avec un hash fixe (l'avant-dernier bloc).  Ansi, il a été possible de fabriquer du matériel électronique spécifiquement pour faire du minage: les mineurs ASIC.   C'est tellement efficace, qu'aucun PC ne peut faire concurrence à un tel appareil, et leur existence a poussé la difficulté à des valeurs astronomiques.  D'un autre coté, comme un mineur ASIC nécessite un certain investissement, il y a des économies d'échelle dans le minage de bitcoin, et d'énormes "usines" de minage bitcoin ont vu le jour.  On peut en fait compter les grands mineurs sur les doigts.  Ainsi, une oligarchie de mineurs domine maintenant le paysage bitcoin, et ils peuvent, entre eux, décider sur le protocol futur de bitcoin.  Ce n'était pas l'idée.

Une autre difficulté est la suivante.  Etant donnée que tout bitcoin sur la block chain a une histoire de transactions menant vers sa création, et que cette histoire est publiquement visible, tous les bitcoins ne se valent pas.  On pourrait, un jour, décider, que des bitcoin qui sont passé par des transactions dont on sait qu'ils sont associés, à, par exemple, des marchants de drogue, ou par des Allemands, ne seront plus acceptés par les mineurs (un petit groupe oligarchique).  Nous avons vu que par construction d'un réseau de transactions dans le monde réel, nous pouvons "démasquer" la plupart des propriétaires de bitcoin, surtout à travers le méchanisme de change.  Chaque fois que vous payez quelqu'un dans le monde réel, votre identité "fuit" et pourra être liée a toutes vos transactions.