Passer au contenu principal

Dernière mise à jour de la page: 26 février 2026

Livre blanc d'Ethereum

Ce document d'introduction a été publié pour la première fois en 2014 par Vitalik Buterin, le fondateur d'Ethereum, avant le lancement du projet en 2015. Il convient de noter qu'Ethereum, comme nombre de projets open source gérés de façon communautaire, a évolué depuis sa création.

Même s'il date déjà de plusieurs années, nous conservons ce document car il constitue une référence utile et une représentation précise d'Ethereum et de la vision du projet. Pour en savoir plus sur les derniers développements d'Ethereum et sur la manière dont les modifications du protocole sont apportées, nous vous recommandons ce guide.

Les chercheurs et universitaires à la recherche d'une version historique ou canonique du livre blanc [de décembre 2014] devraient utiliser ce PDF.

Une plateforme de contrats intelligents et d'applications décentralisées de nouvelle génération

Le développement de Bitcoin par Satoshi Nakamoto en 2009 a souvent été salué comme une évolution radicale de la monnaie et de la devise, étant le premier exemple d'un actif numérique qui n'a simultanément aucune garantie ou « valeur intrinsèque (opens in a new tab) », et aucun émetteur ou contrôleur centralisé. L'attention est cependant en train de se porter sur un autre aspect (sans doute plus important) du Bitcoin : la technologie blockchain sous-jacente comme outil de consensus distribué. Les applications alternatives fréquemment citées de la technologie blockchain incluent l'utilisation d'actifs numériques sur la blockchain pour représenter des devises et des instruments financiers personnalisés (les « pièces colorées (opens in a new tab) »), la propriété d'un appareil physique sous-jacent (la « propriété intelligente (opens in a new tab) »), des actifs non fongibles tels que les noms de domaine (« Namecoin (opens in a new tab) »), ainsi que des applications plus complexes impliquant que des actifs numériques soient directement contrôlés par un morceau de code implémentant des règles arbitraires (les « contrats intelligents (opens in a new tab) ») ou même des « organisations autonomes décentralisées (opens in a new tab) » (DAO) basées sur la blockchain. Ce qu'Ethereum souhaite proposer, c'est une blockchain avec un véritable langage de programmation intégré, Turing-complet, pouvant être utilisé pour créer des « contrats » susceptibles d'encoder des fonctions de transition d'état arbitraires. Cela permettra aux utilisateurs de créer n'importe lequel des systèmes cités ci-dessus, ainsi que beaucoup d'autres que nous n'avons pas encore imaginés, le tout en quelques lignes de code.

Introduction à Bitcoin et aux concepts existants

Historique

Le concept de monnaie numérique décentralisée, ainsi que des applications alternatives comme les registres de propriété, font l'objet d'études depuis des décennies. Les protocoles anonymes de monnaie électronique des années 1980 et 1990, principalement fondés sur une primitive cryptographique appelée Chaumian Blinding (signature aveugle), ont fourni une monnaie à un niveau de confidentialité élevé, mais leurs protocoles sous-jacents ont largement échoué à se populariser en raison de leur dépendance à un intermédiaire centralisé. En 1998, le b-money (opens in a new tab) de Wei Dai a été la première proposition à introduire l'idée de créer de la monnaie en résolvant des énigmes informatiques ainsi que le consensus décentralisé, mais la proposition était peu détaillée sur la manière dont le consensus décentralisé pouvait réellement être mis en œuvre. En 2005, Hal Finney a présenté le concept de « preuves de travail réutilisables (opens in a new tab) », un système qui reprend les idées du b-money et les énigmes Hashcash d'Adam Back, difficiles à résoudre sur le plan informatique, pour créer un concept de cryptomonnaie, mais qui, une fois de plus, n'a pas atteint l'idéal en s'appuyant sur l'informatique de confiance comme backend. En 2009, une monnaie décentralisée fut implémentée pour la première fois par Satoshi Nakamoto, qui combinait des primitives reconnues utilisant la cryptographie asymétrique pour gérer la propriété, à un algorithme de consensus, le « proof-of-work », pour garder une trace des détenteurs de monnaie.

Le mécanisme de la preuve de travail a été une réelle avancée dans ce domaine, car il a permis de résoudre simultanément deux problèmes. Premièrement, cela a fourni un algorithme de consensus simple et efficace, permettant aux noeuds du réseau de s'accorder collectivement sur un ensemble de mises à jour canonique sur l'état du registre de Bitcoin. Deuxièmement, cela a fourni un mécanisme permettant de participer librement au consensus, résolvant le problème politique de décider qui peut influer sur le consensus, tout en empêchant simultanément les attaques Sybil. Il y parvient en substituant un obstacle formel à la participation, comme l'obligation d'être enregistré en tant qu'entité unique sur une liste donnée, par une barrière économique : le poids d'un seul nœud dans le processus de vote par consensus est directement proportionnel à la puissance de calcul que celui-ci apporte. Depuis, une approche alternative a été proposée, appelée preuve d'enjeu, qui calcule le poids d'un nœud comme étant proportionnel à ses avoirs en monnaie et non à ses ressources informatiques ; la discussion des mérites relatifs des deux approches dépasse le cadre de ce document, mais il convient de noter que les deux approches peuvent servir de colonne vertébrale à une cryptomonnaie.

Bitcoin en tant que système de transition d'états

Transition d'état d'Ethereum

D'un point de vue technique, le registre d'une cryptomonnaie telle que le Bitcoin peut être considéré comme un système de transition d'état dans lequel il existe un « état », représentant le statut de propriété de tous les bitcoins existants, et une « fonction de transition d'état », qui associe un état et une transaction, et en fait résulter un nouvel état. Dans un système bancaire standard, par exemple, l'état est un bilan, une transaction est une demande de transfert de X $ de A à B, et la fonction de transition d'état réduit la valeur du compte de A de X $ et augmente la valeur du compte de B de X $. Si le compte de A a moins de X $ au départ, la fonction de transition d'état renvoie une erreur. On peut donc formellement définir :

APPLY(S,TX) -> S' ou ERREUR

Dans le système bancaire défini ci-dessus :

APPLY({ Alice: $50, Marc: $50 },"send $20 from Alice to Marc") = { Alice: $30, Marc: $70 }

Mais :

APPLY({ Alice: $50, Marc: $50 },"send $70 from Alice to Marc") = ERROR

Dans Bitcoin, l'« état » est l'ensemble de toutes les unités de compte (techniquement, les sorties de transaction non dépensées, « unspent transaction outputs » ou UTXO) qui ont été minées, mais pas encore dépensées, chaque UTXO ayant une valeur nominale et un propriétaire (défini par une adresse de 20 octets qui est en fait une clé cryptographique publiquefn1). Une transaction comporte une ou plusieurs entrées, chacune contenant une référence à un UTXO existant et une signature cryptographique produite par la clé privée associée à l'adresse du propriétaire, ainsi qu'une ou plusieurs sorties, chacune comportant un nouvel UTXO à ajouter à l'état.

La fonction de transition d'états APPLY(S,TX) -> S' peut être définie grossièrement comme suit :

  1. Pour chaque entrée dans TX :

    • Si l'UTXO référencé n'est pas dans S, retourner une erreur.
    • Si la signature fournie ne correspond pas au propriétaire de l'UTXO, retourner une erreur.
  2. Si la somme des dénominations de tous les UTXO d'entrée est inférieure à la somme des dénominations de tous les UTXO de sortie, retourner une erreur.
  3. Retourner S avec tous les UTXO d'entrée supprimés et tous les UTXO de sortie ajoutés.

La première moitié de la première étape empêche les expéditeurs de transactions de dépenser des pièces qui n'existent pas, la seconde moitié de la première étape empêche les expéditeurs de transactions de dépenser les pièces d'autres personnes, et la deuxième étape assure la conservation de la valeur. Pour utiliser ceci pour le paiement, le protocole est le suivant. Supposons qu'Alice veuille envoyer 11,7 BTC à Bob. D'abord, Alice va chercher un ensemble d'UTXO disponibles qu'elle possède et qui totalisent au moins 11,7 BTC. En réalité, Alice ne pourra pas obtenir exactement 11,7 BTC ; disons que le plus petit montant qu'elle peut obtenir est 6+4+2=12. Elle crée alors une transaction avec ces trois entrées et deux sorties. La première sortie sera de 11,7 BTC avec l'adresse de Bob comme propriétaire, et la seconde sortie sera les 0,3 BTC restants de « monnaie », avec Alice elle-même comme propriétaire.

Minage

Blocs Ethereum

Si nous avions accès à un service centralisé digne de confiance, ce système serait trivial à mettre en œuvre ; il pourrait simplement être codé exactement comme décrit, en utilisant le disque dur d'un serveur centralisé pour suivre l'état. Cependant, avec Bitcoin, nous essayons de construire un système de monnaie décentralisé, nous devrons donc combiner le système de transition d'états avec un système de consensus afin de nous assurer que tout le monde est d'accord sur l'ordre des transactions. Le processus de consensus décentralisé de Bitcoin exige que les nœuds du réseau tentent continuellement de produire des paquets de transactions appelés « blocs ». Le réseau est conçu pour produire environ un bloc toutes les dix minutes, chaque bloc contenant un horodatage, un nonce, une référence au (c.-à-d. le hachage du) bloc précédent et une liste de toutes les transactions qui ont eu lieu depuis le bloc précédent. Au fil du temps, cela crée une « blockchain » persistante, en croissance constante, qui se met à jour en permanence pour représenter le dernier état du registre Bitcoin.

L'algorithme pour vérifier si un bloc est valide, exprimé dans ce paradigme, est le suivant :

  1. On vérifie que le bloc précédent référencé par le bloc existe et est valide.
  2. On vérifie que l'horodatage du bloc est supérieur à celui du précédent blocfn2 et qu'il n'excède pas 2 heures dans l'avenir.
  3. On vérifie que la preuve de travail du bloc est valide.
  4. Soit S[0] l'état à la fin du bloc précédent.
  5. Supposons que TX est la liste des transactions du bloc avec n transactions. Pour tout i dans 0...n-1, définissez S[i+1] = APPLY(S[i],TX[i]) Si une application renvoie une erreur, quittez et retournez faux.
  6. Retourner vrai, et enregistrer S[n] comme l'état à la fin de ce bloc.

Essentiellement, chaque transaction dans le bloc doit fournir une transition d'état valide depuis ce qui était l'état canonique avant l'exécution de la transaction vers un nouvel état. Notez que l'état n'est en aucun cas encodé dans le bloc ; il s'agit d'une pure abstraction qui doit être mémorisée par le nœud de validation et qui ne peut être calculée (de manière sécurisée) pour n'importe quel bloc qu'en partant de l'état de genèse et en appliquant séquentiellement chaque transaction dans chaque bloc. De plus, notez que l'ordre dans lequel le mineur inclut les transactions dans le bloc est important ; s'il y a deux transactions A et B dans un bloc telles que B dépense un UTXO créé par A, alors le bloc sera valide si A vient avant B mais pas autrement.

La seule condition de validité présente dans la liste ci-dessus qui ne se trouve pas dans d'autres systèmes est l'exigence de la « preuve de travail ». La condition précise est que le double hachage SHA256 de chaque bloc, traité comme un nombre de 256 bits, doit être inférieur à une cible ajustée dynamiquement, qui au moment de la rédaction de ce document est d'environ 2187. Le but est de rendre la création de blocs « difficile » d'un point de vue informatique, empêchant ainsi les attaquants Sybil de refaire toute la blockchain en leur faveur. SHA256 étant conçu comme une fonction pseudo-aléatoire complètement imprévisible, la seule façon de créer un bloc valide est de faire des essais et des corrections, en incrémentant le nonce de façon répétée pour voir si chaque nouveau hachage correspond.

À la cible actuelle d'environ 2187, le réseau doit faire en moyenne environ 269 tentatives avant qu'un bloc valide soit trouvé ; en général, la cible est recalibrée par le réseau tous les 2016 blocs pour qu'en moyenne un nouveau bloc soit produit par un nœud du réseau toutes les dix minutes. Afin de compenser le travail de calcul des mineurs, chacun d'entre eux est en droit d'inclure pour chaque bloc miné une transaction qui lui octroie 25 BTC sortant de nulle part. De plus, si une transaction a une dénomination totale plus élevée dans ses entrées que dans ses sorties, la différence va également au mineur en tant que « frais de transaction ». Incidemment, c'est aussi le seul mécanisme par lequel les BTC sont émis ; l'état de genèse ne contenait aucune pièce.

Afin de mieux comprendre le but du minage, examinons ce qui se passe en cas d'attaquant malveillant. La cryptographie sous-jacente de Bitcoin étant connue pour être sécurisée, l'attaquant ciblera la seule partie du système Bitcoin qui n'est pas protégée directement par la cryptographie : l'ordre des transactions. La stratégie de l'attaquant est donc simple :

  1. Envoyer 100 BTC à un commerçant en échange d'un produit (de préférence, un bien numérique à livraison rapide).
  2. Attendre la livraison du produit.
  3. Produire une autre transaction en s'envoyant 100 BTC à lui-même.
  4. Essayer de convaincre le réseau que la transaction qu'il s'est envoyée à lui-même est celle réalisée en premier.

Une fois l'étape (1) réalisée, un mineur inclura la transaction dans un bloc après quelques minutes. Par exemple, le bloc numéro 270000. Après environ une heure, cinq autres blocs auront été ajoutés à la chaîne après ce bloc, chacun de ces blocs pointant indirectement vers la transaction et la « confirmant » ainsi. À ce stade, le commerçant acceptera le paiement comme finalisé et livrera le produit ; comme nous supposons qu'il s'agit d'un bien numérique, la livraison est instantanée. Maintenant, l'attaquant crée une autre transaction s'envoyant les 100 BTC à lui-même. Si l'attaquant la diffuse simplement, la transaction ne sera pas traitée ; les mineurs essaieront d'exécuter APPLY(S,TX) et remarqueront que TX consomme un UTXO qui n'est plus dans l'état. Au lieu de cela, l'attaquant crée donc une « fourche » (une scission) dans la blockchain en commençant par miner une autre version du bloc 270000 pointant vers le même bloc parent 269999, mais contenant la nouvelle transaction à la place de l'ancienne. Parce que les données du bloc sont différentes, cela nécessite de refaire la preuve de travail. De plus, le hash de la nouvelle version du bloc 270000 de l'attaquant est différente, donc les blocs d'origine de 270001 à 270005 ne « pointent » pas vers lui. La chaîne d'origine et la nouvelle chaîne de l'attaquant sont donc bien complètement séparées. La règle étant que, dans le cas d'une fourche, c'est la plus longue blockchain qui est considérée comme la vraie, les mineurs légitimes travaillent donc sur la chaîne 270005 tandis que l'attaquant travaille seul sur la chaîne 270000. Pour que l'attaquant fasse de sa blockchain la plus longue, il devrait avoir plus de puissance de calcul que le reste du réseau combiné pour rattraper son retard (d'où l'« attaque des 51 % »).

Arbres de Merkle

SPV dans Bitcoin

À gauche : il suffit de présenter un petit nombre de nœuds dans un arbre de Merkle pour donner une preuve de la validité d'une branche.

À droite : toute tentative de modification d'une partie de l'arbre de Merkle entraînera une incohérence quelque part plus haut dans la chaîne.

Une caractéristique importante de l'évolutivité de Bitcoin est que le bloc est stocké dans une structure de données à plusieurs niveaux. Le « hachage » d'un bloc n'est en fait que le hachage de l'en-tête du bloc, un morceau de données d'environ 200 octets qui contient l'horodatage, le nonce, le hachage du bloc précédent et le hachage racine d'une structure de données appelée l'arbre de Merkle stockant toutes les transactions du bloc. Un arbre de Merkle est un type d'arbre binaire, composé d'un ensemble de nœuds avec un grand nombre de nœuds feuilles au bas de l'arbre contenant les données sous-jacentes, un ensemble de nœuds intermédiaires où chaque nœud est le hachage de ses deux enfants, et enfin un seul nœud racine, également formé à partir du hachage de ses deux enfants, représentant le « sommet » de l'arbre. Le but de l'arbre de Merkle est de permettre que les données d'un bloc soient livrées de manière fragmentée : un nœud peut télécharger uniquement l'en-tête d'un bloc d'une source, la petite partie de l'arbre qui le concerne d'une autre source, et être toujours assuré que toutes les données sont correctes. La raison pour laquelle cela fonctionne est que les hachages se propagent vers le haut : si un utilisateur malveillant tente d'échanger une fausse transaction au bas d'un arbre de Merkle, ce changement provoquera un changement dans le nœud au-dessus, puis un changement dans le nœud encore au-dessus, changeant finalement la racine de l'arbre et donc le hachage du bloc, ce qui amènera le protocole à l'enregistrer comme un bloc complètement différent (presque certainement avec une preuve de travail invalide).

Le protocole de l'arbre de Merkle est sans doute essentiel à la durabilité à long terme. Un « nœud complet » dans le réseau Bitcoin, qui stocke et traite l'intégralité de chaque bloc, occupe environ 15 Go d'espace disque sur le réseau Bitcoin en avril 2014, et croît de plus d'un gigaoctet par mois. Actuellement, c'est viable pour certains ordinateurs de bureau et non pour les téléphones, et plus tard, seules les entreprises et les amateurs pourront participer. Un protocole connu sous le nom de « vérification de paiement simplifiée » (SPV) permet l'existence d'une autre classe de nœuds, appelés « nœuds légers », qui téléchargent les en-têtes de bloc, vérifient la preuve de travail sur les en-têtes de bloc, puis ne téléchargent que les « branches » associées aux transactions qui les concernent. Cela permet aux nœuds légers de déterminer avec une forte garantie de sécurité quel est l'état de n'importe quelle transaction Bitcoin, ainsi que leur solde actuel, tout en ne téléchargeant qu'une très petite partie de l'ensemble de la blockchain.

Applications de blockchain alternatives

L'idée de reprendre le concept sous-jacent de la blockchain et de l'appliquer à d'autres concepts a également une longue histoire. En 2005, Nick Szabo a proposé le concept de « titres de propriété sécurisés avec autorité du propriétaire (opens in a new tab) », un document décrivant comment les « nouvelles avancées dans la technologie des bases de données répliquées » permettront un système basé sur la blockchain pour stocker un registre des propriétaires de terrains, créant un cadre élaboré incluant des concepts tels que la propriété par occupation, la prescription acquisitive et l'impôt foncier géorgien. Cependant, il n'existait malheureusement pas de système de base de données répliquée efficace à l'époque, et le protocole n'a donc jamais été mis en pratique. Après 2009, cependant, une fois le consensus décentralisé de Bitcoin développé, un certain nombre d'applications alternatives ont rapidement commencé à émerger.

  • Namecoin - créé en 2010, Namecoin (opens in a new tab) est mieux décrit comme une base de données d'enregistrement de noms décentralisée. Dans les protocoles décentralisés comme Tor, Bitcoin et BitMessage, il doit y avoir un moyen d'identifier les comptes pour que d'autres personnes puissent interagir avec eux, mais dans toutes les solutions existantes, le seul type d'identifiant disponible est un hachage pseudo-aléatoire comme 1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy. Idéalement, on souhaiterait avoir un compte avec un nom comme « george ». Cependant, le problème est que si une personne peut créer un compte nommé « george », quelqu'un d'autre peut utiliser le même processus afin d'enregistrer « george » pour lui-même et se faire passer pour lui. La seule solution est d'appliquer le paradigme du premier déposant, où le premier enregistrement réussit tandis que le second échoue, parfaitement adapté pour le protocole de consensus Bitcoin. Namecoin est l'implémentation la plus ancienne et la plus réussie d'un système d'enregistrement de noms reposant sur cette idée.
  • Pièces colorées - le but des pièces colorées (opens in a new tab) est de servir de protocole pour permettre aux gens de créer leurs propres monnaies numériques - ou, dans le cas trivial important d'une monnaie à une unité, des jetons numériques, sur la blockchain Bitcoin. Dans le protocole des pièces colorées, on « émet » une nouvelle monnaie en attribuant publiquement une couleur à un UTXO Bitcoin spécifique, et le protocole définit récursivement la couleur des autres UTXO pour qu'elle soit identique à celle des entrées dépensées par la transaction qui les crée (certaines règles spéciales s'appliquent dans le cas d'entrées de couleurs mélangées). Cela permet aux utilisateurs de conserver des portefeuilles ne contenant que des UTXO d'une couleur donnée et de les envoyer comme des Bitcoins normaux, en remontant l'historique de la blockchain pour déterminer la couleur de n'importe quel UTXO reçu.
  • Métacoins - l'idée derrière un métacoin est d'avoir un protocole qui vit au-dessus de Bitcoin, utilisant les transactions Bitcoin pour stocker les transactions de métacoins mais ayant une fonction de transition d'état différente, APPLY'. Parce que le protocole de métacoin ne peut pas empêcher les transactions de métacoins invalides d'apparaître dans la blockchain Bitcoin, une règle est ajoutée : si APPLY'(S,TX) renvoie une erreur, le protocole se rabat sur APPLY'(S,TX) = S. Cela facilite le mécanisme de création d'un protocole de cryptomonnaie arbitraire, qui comprend potentiellement des fonctionnalités avancées ne pouvant être implémentées à l'intérieur même de Bitcoin, mais avec un coût de développement très bas puisque les complexités du minage et du réseau sont déjà gérées par le protocole Bitcoin. Les metacoins ont été utilisés pour implémenter certains types de contrats financiers, d'enregistrements de nom et de bourses d'échange décentralisées.

Ainsi, en général, il existe deux approches pour construire un protocole de consensus : construire un réseau indépendant et construire un protocole au-dessus de Bitcoin. La première approche, bien que raisonnablement réussie dans le cas d'applications comme Namecoin, est difficile à mettre en œuvre ; chaque implémentation individuelle doit démarrer une blockchain indépendante, ainsi que construire et tester tout le code de transition d'état et de réseau nécessaire. De plus, nous prévoyons que l'ensemble des applications pour la technologie de consensus décentralisé suivra une distribution de loi de puissance où la grande majorité des applications serait trop petite pour justifier leur propre blockchain, et nous notons qu'il existe de grandes classes d'applications décentralisées, en particulier les organisations autonomes décentralisées, qui ont besoin d'interagir les unes avec les autres.

L'approche basée sur Bitcoin, d'un autre côté, a le défaut de ne pas hériter des fonctionnalités de vérification de paiement simplifiée de Bitcoin. La SPV fonctionne pour Bitcoin parce qu'elle peut utiliser la profondeur de la blockchain comme un proxy pour la validité ; à un certain moment, une fois que les ancêtres d'une transaction sont suffisamment anciens, on peut dire qu'ils faisaient légitimement partie de l'état. Les méta-protocoles basés sur la blockchain, d'autre part, ne peuvent pas forcer la blockchain à ne pas inclure des transactions qui ne sont pas valides dans le contexte de leurs propres protocoles. Par conséquent, une implémentation de méta-protocole SPV entièrement sécurisée devrait remonter jusqu'au début de la blockchain Bitcoin pour déterminer si certaines transactions sont valides ou non. Actuellement, toutes les implémentations « légères » de méta-protocoles basés sur Bitcoin reposent sur un serveur de confiance pour fournir les données, ce qui est sans doute un résultat très sous-optimal, surtout lorsque l'un des principaux objectifs d'une cryptomonnaie est d'éliminer le besoin de confiance.

Scriptage

Même sans aucune extension, le protocole Bitcoin facilite en fait une version faible du concept de « contrats intelligents ». Les UTXO dans Bitcoin peuvent être possédés non seulement par une clé publique, mais aussi par un script plus compliqué exprimé dans un langage de programmation simple basé sur une pile. Dans ce paradigme, une transaction dépensant cet UTXO doit fournir des données qui satisfont le script. En effet, même le mécanisme de base de la propriété de clé publique est implémenté via un script : le script prend une signature de courbe elliptique en entrée, la vérifie par rapport à la transaction et à l'adresse qui possède l'UTXO, et renvoie 1 si la vérification est réussie et 0 sinon. D'autres scripts plus compliqués existent pour divers cas d'utilisation supplémentaires. Par exemple, on peut construire un script qui requiert des signatures de deux des trois clés privées données pour valider (« multisig »), une configuration utile pour les comptes d'entreprise, les comptes d'épargne sécurisés et certaines situations de dépôt fiduciaire pour commerçants. Les scripts peuvent également être utilisés pour payer des primes pour des solutions à des problèmes de calcul, et on peut même construire un script qui dit quelque chose comme « cet UTXO Bitcoin est à vous si vous pouvez fournir une preuve SPV que vous m'avez envoyé une transaction Dogecoin de cette dénomination », permettant essentiellement un échange décentralisé entre cryptomonnaies.

Cependant, le langage de script tel qu'implémenté dans Bitcoin a plusieurs limitations importantes :

  • Manque de Turing-complétude - c'est-à-dire que, bien qu'il y ait un grand sous-ensemble de calculs que le langage de script de Bitcoin prend en charge, il ne prend pas en charge la quasi-totalité. La principale catégorie manquante est celle des boucles. Cela évite les boucles infinies lors de la vérification d'une transaction. Théoriquement, c'est un obstacle surmontable pour les programmeurs de scripts, car toute boucle peut être simulée en répétant simplement plusieurs fois le code sous-jacent avec une instruction « if » (si), mais cela conduit à des scripts qui sont très volumineux. Par exemple, l'implémentation d'un algorithme de signature à courbe elliptique alternatif pourrait nécessiter 256 itérations de multiplications, chacune incluse individuellement dans le code.
  • Aveuglement à la valeur - il n'y a aucun moyen pour un script UTXO de fournir un contrôle fin sur le montant qui peut être retiré. Un cas d'utilisation très intéressant d'un contrat d'oracle serait un contrat de couverture dans lequel A et B investiraient 1000 $ de BTC. Au bout de 30 jours, le script enverrait 1000 $ de BTC à A et le reste à B. Un oracle serait nécessaire pour déterminer la valeur du BTC en USD, mais il s'agirait néanmoins d'une énorme amélioration en termes de confiance et d'infrastructure requise par rapport aux solutions totalement centralisées actuellement disponibles. Cependant, comme les UTXO sont tout ou rien, la seule façon d'y parvenir est par un hack très inefficace consistant à avoir de nombreux UTXO de dénominations variables (par ex., un UTXO de 2k pour chaque k jusqu'à 30) et de laisser l'oracle choisir quel UTXO envoyer à A et lequel à B.
  • Manque d'état - les UTXO peuvent être soit dépensés, soit non dépensés ; il n'y a aucune possibilité pour des contrats ou des scripts à plusieurs étapes qui conserveraient un autre état interne au-delà de cela. Il est donc difficile de réaliser des contrats d'options multi-étapes, des offres d'échange décentralisées ou des protocoles d'engagement cryptographiques à deux étapes (nécessaires pour les primes de calcul sécurisées). Cela signifie que les UTXO ne peuvent être utilisés que pour construire des contrats simples à usage unique, et non des contrats dynamiques plus complexes comme les organisations décentralisées, ce qui rend aussi l'implémentation des méta-protocoles plus compliquée. L'état binaire combiné au défaut de valeur rend impossible une autre application importante : les limites de retrait.
  • Aveuglement à la blockchain - les UTXO sont aveugles aux données de la blockchain telles que le nonce, l'horodatage et le hachage du bloc précédent. Cela limite considérablement les applications de jeux d'argent, et plusieurs autres catégories, en privant le langage de script d'une source d'aléatoire potentiellement précieuse.

Ainsi, nous voyons trois approches pour construire des applications avancées au-dessus de la cryptomonnaie : construire une nouvelle blockchain, utiliser le scriptage au-dessus de Bitcoin, et construire un méta-protocole au-dessus de Bitcoin. Construire une nouvelle blockchain permet une liberté illimitée dans la construction d'un ensemble de fonctionnalités, mais au prix du temps de développement, de l'effort de démarrage et de la sécurité. L'utilisation du scriptage est facile à mettre en œuvre et à standardiser, mais ses capacités sont très limitées, et les méta-protocoles, bien que faciles, souffrent de défauts d'évolutivité. Avec Ethereum, nous avons l'intention de construire un cadre alternatif qui offre des gains encore plus importants en termes de facilité de développement ainsi que des propriétés de client léger encore plus fortes, tout en permettant aux applications de partager un environnement économique et la sécurité de la blockchain.

Ethereum

L'intention d'Ethereum est de créer un protocole alternatif pour construire des applications décentralisées, offrant un ensemble de compromis différent qui, nous le pensons, sera très utile pour une grande classe d'applications décentralisées, avec un accent particulier sur les situations où le temps de développement rapide, la sécurité pour les applications petites et rarement utilisées, et la capacité de différentes applications à interagir très efficacement, sont importants. Ethereum y parvient en construisant ce qui est essentiellement la couche fondamentale abstraite ultime : une blockchain avec un langage de programmation Turing-complet intégré, permettant à quiconque d'écrire des contrats intelligents et des applications décentralisées où ils peuvent créer leurs propres règles arbitraires pour la propriété, les formats de transaction et les fonctions de transition d'état. Une version dépouillée de Namecoin peut être écrite en deux lignes de code, et d'autres protocoles comme les monnaies et les systèmes de réputation peuvent être construits en moins de vingt lignes. Les contrats intelligents, des « boîtes » cryptographiques qui contiennent de la valeur et ne la déverrouillent que si certaines conditions sont remplies, peuvent également être construits sur la plateforme, avec une puissance bien plus grande que celle offerte par le scriptage Bitcoin en raison des pouvoirs ajoutés de la Turing-complétude, de la connaissance de la valeur, de la connaissance de la blockchain et de l'état.

Comptes Ethereum

Dans Ethereum, l'état est composé d'objets appelés « comptes », chaque compte ayant une adresse de 20 octets et les transitions d'état étant des transferts directs de valeur et d'informations entre les comptes. Un compte Ethereum comporte quatre champs :

  • Le nonce, un compteur utilisé pour s'assurer que chaque transaction ne peut être traitée qu'une seule fois
  • Le solde en ether actuel du compte
  • Le code du contrat du compte, s'il est présent
  • Le stockage du compte (vide par défaut)

L'« ether » est le principal cryptocarburant interne d'Ethereum. Il est utilisé pour payer les frais de transaction. En général, il existe deux types de comptes : les comptes externes, contrôlés par des clés privées, et les comptes de contrat, contrôlés par le code de leur contrat. Un compte externe n'a pas de code et il est possible d'envoyer des messages à partir de celui-ci en créant et en signant une transaction. Dans un compte de contrat, chaque fois que celui-ci reçoit un message, son code s'active, ce qui lui permet de lire et d'écrire dans la mémoire de stockage interne et, à son tour, d'envoyer d'autres messages ou de créer des contrats.

Notez que dans Ethereum, les « contrats » ne doivent pas être considérés comme quelque chose qui doit être « rempli » ni « respecté ». Il s'agit plutôt d'« agents autonomes », qui vivent à l'intérieur de l'environnement d'exécution Ethereum, exécutant toujours un morceau de code spécifique lorsqu'ils sont appelés par un message ou une transaction, et ayant un contrôle direct sur leur propre solde d'ether et leur propre magasin de clés/valeurs afin de garder une trace des variables persistantes.

Messages et Transactions

Dans Ethereum, le terme « transaction » désigne le paquet de données signées qui stocke un message à envoyer depuis un compte externe. Les transactions contiennent :

  • le destinataire du message ;
  • une signature identifiant l'expéditeur ;
  • le montant en ETH à transférer de l'expéditeur au destinataire ;
  • un champ de données facultatif ;
  • Une valeur STARTGAS, représentant le nombre maximal d'étapes de calcul que l'exécution de la transaction est autorisée à prendre
  • Une valeur GASPRICE, représentant les frais que l'expéditeur paie par étape de calcul

Les trois premiers champs sont des champs standards attendus dans toute cryptomonnaie. Le champ de données n'a pas de fonction par défaut, mais la machine virtuelle a un code d'opération qu'un contrat peut utiliser pour accéder aux données. Voilà un exemple de cas d'utilisation : si un contrat fonctionne comme un service d'enregistrement de domaine sur la blockchain, il voudra peut-être interpréter les données transférées comme contenant deux « champs », le premier étant un domaine à enregistrer, le second étant l'adresse IP à enregistrer. Le contrat lira ces valeurs à partir des données du message et les stockera de manière adéquate.

Les champs STARTGAS et GASPRICE sont cruciaux pour le modèle anti-déni de service d'Ethereum. Afin d'éviter les boucles infinies accidentelles ou hostiles, ou d'autres gaspillages de calcul dans le code, il est nécessaire que chaque transaction limite le nombre d'étapes de calcul dans l'exécution du code. L'unité fondamentale de calcul est le « gaz ». En général, une étape de calcul coûte 1 unité de gaz, mais certaines opérations coûtent plus cher, car elles sont plus gourmandes en calcul ou augmentent la quantité de données à stocker comme partie intégrante de l'état. Il existe aussi des frais de 5 unités de gaz pour chaque octet de données de transaction. Le but de ce système de frais est d'exiger d'un attaquant qu'il paie proportionnellement chaque ressource qu'il consomme, y compris le calcul, la bande passante et le stockage. Ainsi, toute transaction conduisant le réseau à consommer une plus grande quantité de l'une de ces ressources doit payer des frais de gaz à peu près proportionnels à cette augmentation.

Messages

Les contrats ont la capacité d'envoyer des "messages" à d'autres contrats. Les messages sont des objets virtuels qui ne sont jamais sérialisés et n'existent qu'au sein de l'environnement d'exécution d'Ethereum. Un message contient :

  • l'expéditeur du message (implicite) ;
  • le destinataire du message ;
  • le montant en ETH à transférer avec le message ;
  • un champ de données facultatif ;
  • Une valeur STARTGAS

En substance, un message est comme une transaction, sauf qu'il est émis par un contrat et non par un acteur externe. Un message est produit lorsqu'un contrat exécutant actuellement du code exécute l'opcode CALL, qui produit et exécute un message. Tout comme une transaction, un message provoque l'exécution du code du compte destinataire. Ainsi, les contrats peuvent interagir avec d'autres contrats exactement de la même façon que des acteur externes.

Notez que l'allocation de gaz assignée par une transaction ou un contrat concerne la totalité du gaz consommé par cette transaction et toutes les sous-exécutions. Par exemple, si un acteur externe A envoie une transaction à B avec 1 000 unités de gaz, que B consomme 600 unités de gaz avant d'envoyer un message à C, et que l’exécution interne de C consomme 300 unités de gaz avant le retour, B pourra encore consommer 100 unités de gaz avant d'être en panne sèche.

Fonction de transition d'état d'Ethereum

Transition d'état de l'ether

La fonction de transition d'état d'Ethereum, APPLY(S,TX) -> S' peut être définie comme suit :

  1. Vérifier si la transaction est bien formée (c.-à-d. a le bon nombre de valeurs), si la signature est valide et si le nonce correspond au nonce du compte de l'expéditeur. Sinon, une erreur est renvoyée.
  2. Calculer les frais de transaction comme STARTGAS * GASPRICE, et déterminer l'adresse d'envoi à partir de la signature. On déduit les frais du solde du compte de l'expéditeur et on incrémente son nonce. Si le solde est insuffisant, une erreur est renvoyée.
  3. Initialiser GAS = STARTGAS, et retirer une certaine quantité de gaz par octet pour payer les octets de la transaction.
  4. On transfère la valeur de la transaction du compte de l'expéditeur vers celui du destinataire. Si le compte destinataire n'existe pas encore, on le crée. Si le compte destinataire est un contrat, on exécute le code du contrat, soit jusqu'à la fin, soit jusqu'à ce que l'exécution soit à court de gaz.
  5. Si le transfert de valeur échoue parce que l'expéditeur n'a pas assez d'argent ou que l'exécution du code est en panne de gaz, on annule tous les changements d'état à l'exception du paiement des frais et on ajoute les frais au compte du mineur.
  6. Sinon, on rembourse les frais correspondant au gaz restant à l'expéditeur, et on envoie les frais correspondant au gaz consommé au mineur.

Par exemple, imaginons que le code du contrat soit :

if !self.storage[calldataload(0)]:
  self.storage[calldataload(0)] = calldataload(32)

Notez qu'en réalité, le code du contrat est écrit en code EVM de bas niveau. Pour plus de clarté, cet exemple est écrit en Serpent, un de nos langages de haut niveau qui peut être compilé en code EVM. Supposons que le stockage du contrat soit initialement vide, et qu'une transaction soit envoyée avec une valeur de 10 ethers, 2000 gaz, un prix de gaz de 0,001 ether, et 64 octets de données, où les octets 0-31 représentent le nombre 2 et les octets 32-63 représentent la chaîne CHARLIE. Dans ce cas, le processus de la fonction de transition d'état est le suivant :

  1. On vérifie que la transaction est valide et bien formée.
  2. On vérifie que l'expéditeur de la transaction dispose d'au moins 2 000 * 0,001 = 2 ETH. Si c'est le cas, on déduit 2 ETH de son compte.
  3. On initialise gaz = 2 000. En supposant que la transaction fasse 170 octets de long et que le coût par octet soit 5 UC, on soustrait 850, de sorte qu'il reste 1 150.
  4. On déduit 10 ETH supplémentaires du compte de l'expéditeur et on les ajoute à celui du contrat.
  5. On exécute le code. Dans ce cas, c'est simple : il vérifie si le stockage du contrat à l'index 2 est utilisé, remarque qu'il ne l'est pas, et définit donc le stockage à l'index 2 à la valeur CHARLIE. Supposons que cela consomme 187 unités de gaz, la quantité de gaz restante est alors de 1 150 - 187 = 963.
  6. On rend 963 * 0,001 = 0,963 ETH au compte de l'expéditeur, puis l'état résultant est renvoyé.

S'il n'y avait pas de contrat à la réception de la transaction, alors les frais de transaction totaux seraient simplement égaux au GASPRICE fourni multiplié par la longueur de la transaction en octets, et les données envoyées avec la transaction seraient non pertinentes.

Notez que les messages fonctionnent de la même façon que les transactions en terme d'invalidation : si l'exécution d'un message ne dispose pas d'assez de gaz, alors celle-ci, ainsi que toutes les autres exécutions qu'elle a déclenchées, reviennent à leur état initial, mais les exécutions parentes n'ont pas à être invalidées. Cela signifie qu'il est "sans danger" pour un contrat d'appeler un autre contrat, car si A appelle B avec le gaz G, alors l'exécution de A ne consommera jamais plus que le gaz G. Enfin, notez qu'il existe un opcode, CREATE, qui crée un contrat ; sa mécanique d'exécution est généralement similaire à CALL, à l'exception que la sortie de l'exécution détermine le code d'un contrat nouvellement créé.

Exécution du code

Dans les contrats Ethereum, le code est écrit dans un langage bytecode de bas niveau orienté pile, appelé « code de la machine virtuelle Ethereum » ou « code EVM ». Il se compose d'une série d'octets, où chaque octet représente une opération. En général, l'exécution du code est une boucle infinie qui consiste à effectuer de manière répétée l'opération au compteur de programme actuel (qui commence à zéro), puis à incrémenter le compteur de programme de un, jusqu'à ce que la fin du code soit atteinte ou qu'une erreur ou une instruction STOP ou RETURN soit détectée. Les opérations ont accès à trois types d'espace pour stocker des données :

  • La pile, un conteneur de type dernier entré, premier sorti (LIFO) sur lequel des valeurs peuvent être empilées et dépilées
  • Mémoire, un tableau d'octets extensible à l'infini
  • Le stockage à long terme du contrat, une banque de données clé/valeur. Contrairement à la pile et à la mémoire, qui sont réinitialisées après la fin du calcul, le stockage est conservé sur le long terme.

Le code peut aussi accéder à la valeur, à l'expéditeur et aux données du message reçu, ainsi qu'aux données d'en-tête du bloc. Il peut également renvoyer des données sous forme d'un tableau d'octets en sortie.

Le modèle d'exécution officiel du code EVM est étonnamment simple. Pendant que la machine virtuelle Ethereum est en cours d'exécution, son état de calcul complet peut être défini par le tuple (block_state, transaction, message, code, memory, stack, pc, gas), où block_state est l'état global contenant tous les comptes et incluant les soldes et le stockage. Au début de chaque tour d'exécution, l'instruction actuelle est trouvée en prenant le pc-ième octet de code (ou 0 si pc >= len(code)), et chaque instruction a sa propre définition sur la manière dont elle affecte le tuple. Par exemple, ADD dépile deux éléments de la pile et empile leur somme, réduit gas de 1 et incrémente pc de 1, et SSTORE dépile les deux premiers éléments de la pile et insère le deuxième élément dans le stockage du contrat à l'index spécifié par le premier élément. Bien qu'il existe de nombreuses façons d'optimiser l'exécution de la machine virtuelle Ethereum via la compilation à la volée, une implémentation de base d'Ethereum peut être réalisée en quelques centaines de lignes de code.

Blockchain et Minage

Diagramme d'application de bloc Ethereum

À bien des égards, la blockchain Ethereum est similaire à la blockchain Bitcoin, bien qu'elle présente certaines différences. Concernant l'architecture de la blockchain, la principale différence entre Ethereum et Bitcoin est que, contrairement à Bitcoin, les blocs d'Ethereum contiennent à la fois une copie de la liste des transactions et de l'état le plus récent. De plus, deux autres valeurs sont aussi stockés dans le bloc : le numéro de bloc et la difficulté. Dans Ethereum, l’algorithme de base de validation d'un bloc est le suivant :

  1. On vérifie que le précédent bloc référencé existe et est valide.
  2. On vérifie que l'horodatage du bloc est supérieur à celui du précédent bloc référencé et qu'il n'excède pas 15 minutes dans l'avenir.
  3. On vérifie que le numéro de bloc, la difficulté, la racine de transaction, la racine oncle et la limite de gaz (plusieurs concepts de bas niveau spécifiques à Ethereum) sont valides.
  4. On vérifie que la preuve de travail du bloc est valide.
  5. Soit S[0] l'état à la fin du bloc précédent.
  6. Soit TX la liste des transactions du bloc, avec n transactions. Pour tout i dans 0...n-1, définissez S[i+1] = APPLY(S[i],TX[i]). Si une application renvoie une erreur, ou si le gaz total consommé dans le bloc jusqu'à ce point dépasse le GASLIMIT, retourner une erreur.
  7. Soit S_FINAL égal à S[n], mais en ajoutant la récompense de bloc payée au mineur.
  8. Vérifier si la racine de l'arbre de Merkle de l'état S_FINAL est égale à la racine de l'état final fournie dans l'en-tête du bloc. Si c'est le cas, le bloc est valide. Sinon, il ne l'est pas.

L'approche peut sembler très inefficace à première vue, car elle nécessite de stocker l'état complet avec chaque bloc, mais en réalité, l'efficacité devrait être comparable à celle de Bitcoin. Cela vient du fait que l'état est stocké dans une structure en arbre, et qu'après chaque bloc, seule une petite partie de l'arbre doit être modifiée. Ainsi, en général, entre deux blocs adjacents, la grande majorité de l'arbre devrait être la même, et donc les données peuvent être stockées une fois et référencées deux fois à l'aide de pointeurs (c.-à-d. les hachages des sous-arbres). Un type particulier d'arbre, l'« arbre Patricia » est utilisé pour cela. Il s'agit d'un dérivé du concept d'arbre de Merkle qui permet d'insérer et de supprimer efficacement des nœuds, et pas seulement de les modifier. Par ailleurs, comme toutes les informations d'état font partie du dernier bloc, il n'est pas nécessaire de stocker tout l'historique de la blockchain. Cette stratégie, si elle pouvait être appliquée à Bitcoin, réduirait les besoins de stockage de 5 à 20 fois.

La question de savoir où le code d'un contrat est exécuté, en termes de matériel physique, est souvent posée. La réponse est simple : le processus d'exécution du code du contrat fait partie de la définition de la fonction de transition d'état, qui fait partie de l'algorithme de validation de bloc. Donc si une transaction est ajoutée au bloc B, l'exécution du code engendrée par cette transaction sera exécutée par tous les nœuds, maintenant et à l'avenir, qui téléchargent et valident le bloc B.

Applications

En général, il existe trois types d'applications sur Ethereum. La première catégorie est celle des applications financières, qui fournissent aux utilisateurs des moyens plus puissants de gérer et conclure des contrats en utilisant leur argent. Elle inclut les sous-monnaies, les produits financiers dérivés, les contrats de couverture, les portefeuilles d'épargne, les testaments, et même certaines catégories de contrats de travail. La deuxième catégorie est celle des applications semi-financières, où de l'argent entre en jeu, mais où il existe aussi un important aspect non monétaire. Un exemple parfait est celui des primes auto-appliquées pour des solutions à des problèmes de calcul. Enfin, il existe des applications comme le vote en ligne et la gouvernance décentralisée, qui n'ont aucun aspect financier.

Systèmes de jetons

Les systèmes de jetons (tokens) sur une blockchain ont de nombreuses applications allant des sous-monnaies représentant des actifs (comme les dollars US ou l'or) aux actions d'entreprise, en passant par les jetons individuels représentant des titres de propriété ou des coupons sécurisés infalsifiables, ou encore les jetons sans aucune valeur conventionnelle, utilisés comme mesures d'incitation sous la forme de points. Les systèmes de jetons sont étonnamment faciles à implémenter dans Ethereum. Le point essentiel à bien comprendre est que toute monnaie ou tout système de jetons est essentiellement une base de données proposant une seule opération : prendre X unités de A pour les donner à B, à condition que (1) A dispose d'au moins X unités avant la transaction et (2) que la transaction soit approuvée par A. Il suffit donc d'implémenter cette logique dans un contrat pour implémenter un système de jetons.

Le code de base d'une telle implémentation en Serpent ressemble à ceci :

def send(to, value):
  if self.storage[msg.sender] >= value:
    self.storage[msg.sender] = self.storage[msg.sender] - value
    self.storage[to] = self.storage[to] + value

Il s'agit fondamentalement d'une implémentation littérale de la fonction de transition d'état de « système bancaire » décrite précédemment dans ce document. Quelques lignes de code supplémentaires sont nécessaires pour spécifier l'étape initiale de distribution des unités monétaires et quelques autres cas particuliers, et idéalement une fonction sera ajoutée pour permettre à d'autres contrats d'obtenir le solde d'une adresse. C'est tout ce qu'il y a à faire ! En théorie, les systèmes de jetons basés sur Ethereum fonctionnant comme des sous-monnaies peuvent potentiellement présenter une autre caractéristique importante qui fait défaut aux méta-monnaies implémentées sur le Bitcoin en chaîne : la capacité de payer les frais de transaction directement dans cette monnaie. Pour mettre cela en œuvre, le contrat gère un solde en ETH grâce auquel il rembourse l'expéditeur du montant en ETH utilisé pour payer les frais, et rééquilibre son solde en collectant les unités monétaires internes qu'il prend en frais pour les revendre dans une vente aux enchères permanente. Les utilisateurs ont donc besoin « d'activer » leurs comptes avec de l'ether (ETH), mais une fois cela fait, ils peuvent réutiliser cette somme puisqu'elle est à chaque fois remboursée par le contrat.

Dérivés financiers et monnaies à valeur stable

Les produits financiers dérivés sont l'application la plus courante d'un « contrat intelligent » et l'une des plus simples à implémenter en programmation. La principale difficulté dans l'implémentation de contrats financiers est qu'ils nécessitent pour la plupart une référence à une cotation externe. Un contrat intelligent de couverture contre la volatilité de l'ETH (ou de toute autre cryptomonnaie) par rapport au dollar US serait, par exemple, une application très intéressante, mais cela impliquerait que le contrat connaisse le taux de change ETH/USD. La manière la plus simple de le faire est d'utiliser un contrat de « flux de données » maintenu par une partie spécifique (par ex., NASDAQ) conçu de manière à ce que cette partie ait la capacité de mettre à jour le contrat selon les besoins, et fournissant une interface qui permet à d'autres contrats d'envoyer un message à ce contrat et d'obtenir en retour une réponse qui fournit le prix.

Avec cet élément essentiel, le contrat de couverture ressemblerait à ceci :

  1. On attend que le tiers A fournisse 1 000 ETH.
  2. On attend que le tiers B fournisse 1 000 ETH.
  3. On enregistre la valeur en USD de 1 000 ETH dans l'espace de stockage du contrat, valeur calculée en interrogeant le contrat de flux de données. Appelons cette valeur $x.
  4. Après 30 jours, on autorise A ou B à « réactiver » le contrat afin d'envoyer l'équivalent de $x en ETH (calculé en interrogeant de nouveau le contrat de flux de données afin d'obtenir le nouveau taux) à A et le reste à B.

Ce type de contrat représenterait un beau potentiel dans le monde du cryptocommerce. Un des principaux problèmes souvent mentionné sur les cryptomonnaies, c'est leur volatilité : même si bon nombre d'utilisateurs et commerçants sont intéressés par la fiabilité et la facilité d'utilisation des actifs cryptographiques, il ne souhaitent pas risquer de perdre 23 % de leurs fonds en une seule journée. Jusqu'à présent, la solution la plus couramment proposée a été les actifs garantis par l'émetteur ; l'idée est qu'un émetteur crée une sous-monnaie dans laquelle il a le droit d'émettre et de révoquer des unités, et fournit une unité de la monnaie à quiconque lui fournit (hors ligne) une unité d'un actif sous-jacent spécifié (par ex., or, USD). L'émetteur promet ensuite de fournir une unité de l'actif sous-jacent à toute personne qui lui envoie une unité du crypto-actif. Ce mécanisme permet à n'importe quel actif non cryptographique d'être « transformé » en crypto-actif, si l'on peut faire confiance à l'émetteur.

Dans la pratique, néanmoins, les émetteurs ne sont pas toujours fiables, et dans certains cas l'infrastructure bancaire est trop fragile, ou trop hostile, pour permettre l'existence de tels services. Les produits financiers dérivés constituent une alternative. Ici, au lieu qu'un seul émetteur fournisse les fonds pour garantir un actif, c'est un marché décentralisé de spéculateurs, pariant que le prix d'un actif de référence cryptographique (par ex., ETH) augmentera, qui joue ce rôle. Contrairement aux émetteurs, les spéculateurs ne peuvent pas faire défaut, car le contrat de couverture conserve leurs fonds sous forme de dépôt fiduciaire. Notez que cette approche n'est pas totalement décentralisée, car une source de confiance est toujours nécessaire pour fournir le téléscripteur bien que l'amélioration soit massive en termes de réduction des besoins d'infrastructure (contrairement à un émetteur, la publication d'un taux de change ne nécessite aucun permis et peut être considérée comme de la liberté de parole) et des possibilités de fraude.

Systèmes d'identité et de réputation

La toute première cryptomonnaie alternative, Namecoin (opens in a new tab), a tenté d'utiliser une blockchain de type Bitcoin pour fournir un système d'enregistrement de noms, où les utilisateurs peuvent enregistrer leurs noms dans une base de données publique aux côtés d'autres données. Le principal cas d'utilisation cité est pour un système DNS (opens in a new tab), faisant correspondre des noms de domaine comme « bitcoin.org » (ou, dans le cas de Namecoin, « bitcoin.bit ») à une adresse IP. D'autres utilisations incluent l’authentification d'e-mails, et potentiellement des systèmes de réputation plus perfectionnés. Voilà un contrat élémentaire permettant de fournir un système d'enregistrement de noms similaire à celui de Namecoin sur Ethereum :

def register(name, value):
    if !self.storage[name]:
        self.storage[name] = value

Le contrat est très simple, il s’agit simplement d’une base de données au sein du réseau Ethereum qui peut être ajoutée, mais non modifiée ou supprimée. N'importe qui peut enregistrer un nom et une valeur, et cet enregistrement est inscrit pour toujours. Un contrat d'enregistrement de nom plus sophistiqué aura également une « clause de fonction » permettant à d'autres contrats de l'interroger, ainsi qu'un mécanisme pour le « propriétaire » (c.-à-d. le premier enregistreur) d'un nom de modifier les données ou de transférer la propriété. On peut même ajouter à cela une fonctionnalité de réputation et de réseau de confiance.

Stockage de fichiers décentralisé

Ces dernières années, plusieurs startups ont été créées dans le secteur du stockage de fichiers en ligne (la plus importante étant Dropbox). Dans le cadre d'un abonnement mensuel payant, elles proposent aux utilisateurs de stocker une copie de sauvegarde de leur disque dur, à laquelle ils peuvent accéder à leur convenance. Toutefois, le marché du stockage de fichiers en ligne reste à ce jour relativement inefficace. Un rapide survol des solutions existantes montre que dans la fourchette de 20 à 200 Go, où il n'existe ni offre gratuite ni offre professionnelle avec remises, le prix mensuel du stockage est supérieur à celui du disque dur lui-même. Les contrats Ethereum permettent le développement d'un écosystème de stockage de fichiers décentralisé, où chaque utilisateur peut recevoir de petites sommes d'argent en louant ses propres disques durs, l'espace inutilisé contribuant à réduire davantage le coût du stockage des fichiers.

La clé de voûte d'un tel système est ce que nous avons appelé le « contrat Dropbox décentralisé ». Ce contrat fonctionne de la façon suivante. Dans un premier temps, les données choisies sont divisées en blocs qui servent à construire un arbre de Merkle, chaque bloc étant chiffré pour assurer la confidentialité. Un contrat est ensuite créé avec une règle stipulant que tous les N blocs, le contrat choisira un index aléatoire de l'arbre de Merkle (en utilisant le hachage du bloc précédent, accessible depuis le code du contrat, comme source aléatoire) et donnera X ETH à la première entité qui fournira une transaction avec une preuve de propriété simplifiée similaire à une vérification du paiement du bloc situé à cet index spécifique dans l'arbre de Merkle. Lorsqu'un utilisateur veut retélécharger son fichier, il peut utiliser un protocole de canal de micropaiement (par ex., payer 1 szabo par 32 kilooctets) pour récupérer le fichier ; l'approche la plus efficace en termes de frais est que le payeur ne publie pas la transaction avant la fin, mais la remplace par une transaction légèrement plus lucrative avec le même nonce après chaque 32 kilooctets.

Une fonctionnalité importante du protocole est que, bien qu'on ait l'impression de faire confiance à plusieurs nœuds aléatoires pour ne pas perdre le fichier, on peut quasiment supprimer ce risque en divisant le fichier en plusieurs parties par partage secret et en surveillant les contrats pour vérifier que chaque partie est toujours présente sur un nœud. Si un contrat émet toujours des paiements, cela apporte la preuve cryptographique que quelqu'un stocke toujours le fichier.

Organisations autonomes décentralisées

Le concept général d'une « organisation autonome décentralisée » (DAO) est celui d'une entité virtuelle avec un certain nombre de membres ou d'actionnaires qui, peut-être à une majorité de 67 %, ont le droit de dépenser ses fonds et de modifier son code. Les membres vont collectivement décider de la façon dont les fonds doivent être alloués par l'organisation. Les méthodes pour allouer les fonds d'une DAO peuvent aller des primes aux salaires en passant par un mécanisme plus original, comme une monnaie interne, pour récompenser le travail. Ceci reproduit essentiellement les attributs juridiques d'une entreprise traditionnelle ou d'une association à but non lucratif, mais en utilisant uniquement la technologie cryptographique de la blockchain. Jusqu'à présent, une grande partie des discussions concernant les DAO tournait autour du modèle « capitaliste » d'une « société autonome décentralisée » (DAC), avec des actionnaires bénéficiaires de dividendes et des actions négociables. Une alternative, décrite comme une « communauté autonome décentralisée », attribuerait à tous les membres une part égale dans la prise de décision et exigerait un consensus de 67 % des membres pour ajouter ou supprimer un membre. L'exigence selon laquelle une personne ne peut avoir qu'une seule adhésion doit alors être appliquée collectivement par le groupe.

Une description générale de la façon de coder une DAO est fournie ci-après. La conception la plus simple est tout simplement un morceau de code qui se modifie lui-même et qui ne change que si les deux tiers des membres acceptent la modification. Bien que le code soit théoriquement immuable, on peut facilement contourner ceci et avoir une mutabilité de fait en disposant les morceaux de code dans des contrats séparés, et en stockant l'adresse des contrats à appeler dans un stockage modifiable. Dans une implémentation simple d'un tel contrat DAO, il y aurait donc trois types de transactions, identifiables par les données fournies dans la transaction :

  • [0,i,K,V] pour enregistrer une proposition avec l'index i afin de changer l'adresse à l'index de stockage K à la valeur V
  • [1,i] pour enregistrer un vote en faveur de la proposition i
  • [2,i] pour finaliser la proposition i si suffisamment de votes ont été effectués

Le contrat aurait alors des clauses pour chacun de ces types. Il conserverait un enregistrement de toutes les modifications de stockage ouvertes, ainsi qu'une liste de ceux qui ont voté pour. Il inclurait également une liste de tous les membres. Quand une modification de stockage atteint deux tiers de votes « pour » de la part des membres, une transaction de finalisation peut exécuter la modification. Un squelette plus sophistiqué aurait également une capacité de vote intégrée pour des fonctionnalités telles que l'envoi d'une transaction, l'ajout et la suppression de membres, et pourrait même prévoir une délégation de vote de style Démocratie Liquide (opens in a new tab) (c.-à-d. que n'importe qui peut désigner quelqu'un pour voter à sa place, et l'assignation est transitive, donc si A désigne B et B désigne C, alors C détermine le vote de A). Cette conception permettrait à la DAO de se développer organiquement en tant que communauté décentralisée, permettant éventuellement aux membres de déléguer la tâche de filtrage des membres à des spécialistes, bien que, contrairement au « système actuel », les spécialistes puissent facilement apparaître et disparaître au fil du temps, à mesure que les membres individuels de la communauté changent d'orientation.

L'entreprise décentralisée constitue un autre modèle, où n'importe quel compte peut avoir zéro ou plus d'actions, et où deux tiers des actions sont requises pour prendre une décision. Un modèle complet impliquerait une fonctionnalité de gestion d'actifs, la possibilité de faire une offre pour acheter ou vendre des actions, et la possibilité d'accepter les offres (de préférence avec un mécanisme de correspondance d'ordres à l'intérieur du contrat). Une délégation existerait également, à la manière d'une démocratie délégative, généralisant le concept de « conseil d'administration ».

Autres applications

1. Portefeuilles d'épargne. Imaginons qu'Alice souhaite conserver ses fonds en sécurité, mais craigne de perdre ou de se faire pirater sa clé privée. Elle place des ETH dans un contrat avec Marc, une banque, comme suit :

  • Alice seule ne peut retirer au maximum que 1 % des fonds chaque jour.
  • Marc seul ne peut retirer au maximum que 1% des fonds chaque jour, mais Alice a la possibilité de créer une transaction avec sa clé pour bloquer cette capacité.
  • Alice et Marc peuvent conjointement retirer n'importe quelle somme.

En principe, 1 % par jour suffit à Alice, mais si elle souhaite retirer davantage, elle peut demander de l'aide à Marc. Si la clé d'Alice est piratée, elle prévient Marc pour déplacer les fonds vers un nouveau contrat. Si elle perd sa clé, Marc finira par sortir les fonds du contrat. Si Marc s'avère être malveillant, Alice peut décider de révoquer son droit de retrait.

2. Assurance récolte. On peut facilement créer un contrat de produits financiers dérivés en utilisant un flux de données météo au lieu d'un indice de prix. Si un agriculteur normand achète un produit financier dérivé dont les paiements sont inversement proportionnels aux précipitations enregistrées en Normandie et qu'une sécheresse se produit, l'agriculteur recevra automatiquement de l'argent. S'il pleut suffisamment, l'agriculteur sera satisfait, car ses cultures se porteront bien. Cela peut être étendu aux assurances contre les catastrophes naturelles en général.

3. Flux de données décentralisé. Pour les contrats financiers sur différence, il pourrait être possible de décentraliser le flux de données via un protocole appelé « SchellingCoin (opens in a new tab) ». SchellingCoin fonctionne essentiellement comme suit : N parties saisissent toutes dans le système la valeur d'une donnée donnée (par ex., le prix ETH/USD), les valeurs sont triées, et toute personne se situant entre le 25e et le 75e percentile reçoit un jeton en récompense. Chacun a intérêt à donner la même réponse que tout le monde, et la seule valeur sur laquelle de nombreux acteurs peuvent être d'accord est celle évidente par défaut : la vraie valeur. Ceci crée un protocole décentralisé qui peut théoriquement fournir un certain nombre de valeurs, y compris le taux ETH/USD, la température à Berlin ou même le résultat d'un calcul particulier complexe.

4. Dépôt fiduciaire multisignature intelligent. Bitcoin permet des contrats de transactions multisignatures où, par exemple, trois des cinq clés données peuvent dépenser les fonds. Ethereum permet une plus grande granularité. Par exemple, 4 personnes sur 5 peuvent tout dépenser, 3 personnes sur 5 peuvent dépenser jusqu'à 10 % par jour et 2 personnes sur 5 peuvent dépenser jusqu'à 0,5 % par jour. En outre, la multisignature Ethereum est asynchrone : deux parties peuvent enregistrer leurs signatures sur la blockchain à différents moments, et la dernière signature enverra automatiquement la transaction.

5. Informatique dans le cloud. La technologie de l'EVM peut également être utilisée pour créer un environnement informatique vérifiable, permettant aux utilisateurs de demander à d'autres d'effectuer des calculs, puis éventuellement de réclamer des preuves que les calculs ont été effectués correctement à certains points de contrôle choisis au hasard. Cela permet la création d'un marché de l'informatique en nuage où tout utilisateur peut participer avec son ordinateur de bureau, son ordinateur portable ou son serveur spécialisé, et des vérifications ponctuelles ainsi que des dépôts de garantie peuvent être utilisés pour garantir que le système est digne de confiance (c.-à-d. que les nœuds ne peuvent pas tricher de manière rentable). Toutefois, un tel système ne convient pas à toutes les tâches. Par exemple, celles nécessitant un niveau de communication interprocessus élevé ne peuvent pas être effectuées facilement dans un cloud comportant de nombreux nœuds. Toutefois, d'autres tâches sont beaucoup plus faciles à paralléliser. Des projets comme SETI@home, folding@home et les algorithmes génétiques peuvent facilement être implémentés sur une telle plateforme.

6. Jeux d'argent et de hasard P2P. Un grand nombre de protocoles de jeu peer-to-peer, tels que le Cyberdice (opens in a new tab) de Frank Stajano et Richard Clayton, peuvent être implémentés sur la blockchain Ethereum. Le protocole le plus simple est en fait juste un contrat sur la différence du prochain hachage de bloc, et des protocoles plus avancés peuvent être construits à partir de là, créant des services de jeu d'argent et de hasard avec des frais proches de zéro, où il n'existe aucune possibilité de tricher.

7. Marchés prédictifs. Moyennant un oracle ou SchellingCoin, les marchés de prédiction sont également faciles à mettre en œuvre, et les marchés de prédiction ainsi que SchellingCoin pourraient s'avérer être la première application grand public de la futarchie (opens in a new tab) en tant que protocole de gouvernance pour les organisations décentralisées.

8. Places de marché décentralisées sur la chaîne, utilisant le système d'identité et de réputation comme base.

Divers et préoccupations

Implémentation modifiée de GHOST

Le protocole « Greedy Heaviest Observed Subtree » (GHOST) est une innovation introduite pour la première fois par Yonatan Sompolinsky et Aviv Zohar en décembre 2013 (opens in a new tab). La naissance de GHOST résulte du fait que les blockchains avec des temps de confirmation rapides souffrent d'une faible sécurité en raison d'un taux élevé de blocs caducs. Un certain temps étant nécessaire pour que les blocs se propagent à travers le réseau, si un mineur A mine un bloc et qu'un mineur B parvient à miner un autre bloc avant que le bloc du mineur A ne soit propagé à B, le bloc du mineur B est perdu et ne contribue pas à la sécurité du réseau. Par ailleurs, il existe un problème de centralisation : si le mineur A est un groupe de minage disposant de 30 % de la puissance de hachage du réseau (hashpower) et que B n'en a que 10 %, A risque de produire un bloc caduc 70 % du temps (puisque les autres 30 % du temps, A produit le dernier bloc et obtient donc immédiatement les données de minage). B risque de son côté de produire un bloc caduc 90 % du temps. Ainsi, si l'intervalle entre les blocs est assez court pour que le taux de blocs caducs soit élevé, A sera nettement plus efficace simplement en raison de sa taille. Ces deux effets combinés font que les blockchains produisant rapidement des blocs sont particulièrement susceptibles de générer un groupe de minage bénéficiant d'un pourcentage assez large de la puissance de hachage du réseau. Celui-ci aura alors, de fait, le contrôle du processus de minage.

Comme l'ont décrit Sompolinsky et Zohar, GHOST résout le premier problème de perte de sécurité du réseau en incluant les blocs caducs dans le calcul de la longueur de la chaîne. C'est-à-dire que non seulement le parent et les ancêtres d'un bloc, mais aussi les descendants caducs de l'ancêtre du bloc (dans le jargon Ethereum, les « oncles ») sont ajoutés au calcul permettant d'établir quel bloc a le plus grand nombre cumulé de preuves de travail. Pour résoudre le second problème, celui de la centralisation, il faut dépasser le protocole décrit par Sompolinsky et Zohar, et donner une récompense aux blocs caducs : un bloc caduc reçoit 87,5 % de sa récompense de base, et le neveu qui inclut le bloc caduc reçoit les 12,5 % restants. Les frais de transaction, quant à eux, ne sont pas distribués aux oncles.

Ethereum implémente une version simplifiée de GHOST qui ne descend que sur sept niveaux. Plus spécifiquement, elle est définie comme suit :

  • Un block doit spécifier un parent et 0 oncle ou plus.
  • Un oncle inclus dans un block B doit posséder les propriétés suivantes :
    • Il doit être un enfant direct de l'ancêtre de k-ième génération de B, où 2 <= k <= 7.
    • Il ne peut pas être un ancêtre de B.
    • Un oncle doit être un en-tête de bloc valide, mais il n'est pas nécessaire qu'il soit un bloc précédemment vérifié ni même valide.
    • Un oncle doit être différent de tous les oncles inclus dans les blocs précédents et de tous les autres oncles inclus dans le même bloc (inclusion non double).
  • Pour chaque oncle U dans le bloc B, le mineur de B obtient 3,125 % supplémentaires ajoutés à sa récompense coinbase et le mineur de U obtient 93,75 % d'une récompense standard coinbase.

Cette version limitée de GHOST, dont les oncles ne peuvent être inclus que jusqu'à 7 générations, a été utilisée pour deux raisons. Tout d'abord, une version illimitée de GHOST entraînerait trop de complications dans le calcul des oncles valides pour un bloc donné. Deuxièmement, une version illimitée de GHOST avec compensation tel qu'utilisée dans Ethereum supprime l'intérêt pour un mineur de miner sur la chaîne principale et non la chaîne d'un attaquant public.

Frais

Étant donné que chaque transaction publiée dans la blockchain impose au réseau son téléchargement à des fins de vérification, un mécanisme de régulation est nécessaire afin de prévenir tout abus, ce qui implique généralement des frais de transaction. Sur Bitcoin, l'approche par défaut consiste à avoir des frais de transactions volontaires, en s'appuyant sur les mineurs pour jouer le rôle de gardiens et implémenter des minimums variables. Cette approche a été reçue très favorablement par la communauté Bitcoin, car elle est basée sur le marché, et permet de déterminer le juste prix par rapport à l'offre et à la demande entre mineurs et expéditeurs de transactions. Ce raisonnement comporte néanmoins un problème : le traitement d'une transaction n'est pas un marché. Bien qu'il soit tentant de considérer la transaction comme un service rendu à l'expéditeur par le mineur, en réalité chaque transaction incluse par un mineur doit être traitée par tous les nœuds du réseau. La majorité du coût de traitement d'une transaction est donc prise en charge par des tiers et pas par le mineur qui décide ou non d'inclure la transaction. C'est pourquoi des problèmes de type « tragédie des biens communs » sont susceptibles de se produire.

Il s'avère cependant que lorsqu'on lui donne une hypothèse simplificatrice inexacte particulière, cette faille du mécanisme de marché s'annule comme par magie. L'argument est le suivant. Dans ce scénario imaginaire :

  1. Une transaction conduit à k opérations, offrant la récompense kR à tout mineur qui l'inclut, où R est défini par l'expéditeur et k et R sont (grossièrement) visibles par le mineur au préalable.
  2. Une opération a un coût de traitement de C pour tout nœud (c.-à-d. que tous les nœuds ont une efficacité égale)
  3. Il y a N nœuds de minage, chacun avec une puissance de traitement exactement égale (c.-à-d. 1/N du total)
  4. Il n'existe aucun nœud complet non minier.

Un mineur sera prêt à traiter une transaction si la récompense attendue est supérieure au coût. Ainsi, la récompense attendue est kR/N puisque le mineur a une chance de 1/N de traiter le bloc suivant, et le coût de traitement pour le mineur est simplement kC. Par conséquent, les mineurs incluront des transactions où kR/N > kC, ou R > NC. Notez que R est le frais par opération fourni par l'expéditeur, et est donc une borne inférieure du bénéfice que l'expéditeur tire de la transaction, et NC est le coût pour l'ensemble du réseau du traitement d'une opération. Les mineurs sont donc incités à n'inclure que les transactions pour lesquelles le bénéfice utilitaire total dépasse le coût.

Il existe cependant plusieurs écarts importants par rapport à ces hypothèses dans la réalité :

  1. Le mineur paie un coût plus élevé que les autres nœuds de vérification pour traiter la transaction, car le temps de vérification supplémentaire retarde la propagation du bloc et augmente le risque que le bloc devienne caduc.
  2. Il existe des nœuds complets non miniers.
  3. La répartition de la puissance de minage peut se révéler radicalement inégalitaire dans la pratique.
  4. Les spéculateurs, les ennemis politiques et les fous dont la fonction utilitaire inclut de causer du tort au réseau existent, et ils peuvent habilement configurer des contrats où leur coût est bien inférieur au coût payé par les autres nœuds de vérification.

(1) tend à inciter le mineur à inclure moins de transactions, et (2) augmente NC ; par conséquent, ces deux effets s'annulent au moins partiellement l'un l'autre.Comment ? (opens in a new tab) (3) et (4) sont le problème majeur ; pour les résoudre, nous instituons simplement un plafond flottant : aucun bloc ne peut avoir plus d'opérations que BLK_LIMIT_FACTOR fois la moyenne mobile exponentielle à long terme. Spécifiquement :

blk.oplimit = floor((blk.parent.oplimit \* (EMAFACTOR - 1) +
floor(parent.opcount \* BLK\_LIMIT\_FACTOR)) / EMA\_FACTOR)

BLK_LIMIT_FACTOR et EMA_FACTOR sont des constantes qui seront définies à 65536 et 1,5 pour le moment, mais seront probablement modifiées après une analyse plus approfondie.

Il existe un autre facteur qui dissuade les mineurs d'ajouter des blocs de grande taille dans Bitcoin : cela prend plus de temps de les propager et le risque qu'ils deviennent caducs est plus élevé. Dans Ethereum, les blocs consommant beaucoup de gaz peuvent également prendre plus de temps à se propager, à la fois car ils sont physiquement plus grands, mais aussi car ils requièrent plus de temps pour traiter les transitions d'état des transactions à valider. L'effet dissuasif associé aux délais est un facteur important chez Bitcoin, mais moindre chez Ethereum en raison du protocole GHOST, le recours à des limites de blocs réglementées offrant une base de référence plus stable.

Calcul et Turing-complétude

Il est important de noter que la machine virtuelle Ethereum est Turing-complète, ce qui signifie que le code de l'EVM peut coder tout calcul pouvant être effectué, y compris les boucles infinies. Le code EVM permet la création de boucles de deux façons. Premièrement, il y a une instruction JUMP qui permet au programme de revenir à un point précédent dans le code, et une instruction JUMPI pour faire des sauts conditionnels, permettant des déclarations comme while x < 27: x = x * 2. Ensuite, les contrats peuvent appeler d'autres contrats, ce qui permet potentiellement de créer des boucles par récursion. Cela conduit naturellement à la question suivante : les utilisateurs malveillants peuvent-ils arrêter les mineurs et les nœuds complets en les forçant à entrer dans une boucle infinie ? Cette question se pose en raison d'un problème informatique connu sous le nom de « problème de l'arrêt » : il n'existe généralement aucun moyen de savoir si un programme donné s'arrêtera un jour ou non.

Comme décrit dans la section sur la transition d'état, notre solution fonctionne en demandant à une transaction de fixer le nombre maximum d'étapes de calcul qu'elle est autorisée à effectuer. Si l'exécution prend plus de temps, le calcul est annulé, mais les frais sont néanmoins payés. Les messages fonctionnent de la même façon. Pour montrer la motivation derrière notre solution, considérons les exemples suivants :

  • Un attaquant crée un contrat qui exécute une boucle infinie, puis envoie une transaction activant cette boucle au mineur. Le mineur traitera la transaction en exécutant la boucle infinie et attendra qu'elle soit à court de gaz. Même si l'exécution tombe en panne sèche et s'arrête à mi-chemin, la transaction reste valide et le mineur continue à réclamer les frais à l'attaquant pour chaque étape de calcul.
  • Un attaquant crée une très longue boucle infinie dans l'intention de forcer le mineur à continuer de calculer pendant un temps si long qu'au moment où le calcul se terminera, quelques blocs supplémentaires seront sortis et il sera impossible pour le mineur d'inclure la transaction pour réclamer les frais. Cependant, l'attaquant devra soumettre une valeur pour STARTGAS limitant le nombre d'étapes de calcul que l'exécution peut prendre, de sorte que le mineur saura à l'avance que le calcul prendra un nombre d'étapes excessivement grand.
  • Un attaquant voit un contrat avec un code de la forme send(A,contract.storage[A]); contract.storage[A] = 0, et envoie une transaction avec juste assez de gaz pour exécuter la première étape mais pas la seconde (c.-à-d. effectuer un retrait mais ne pas laisser le solde diminuer). L'auteur du contrat n'a pas à se préoccuper de se protéger contre de telles attaques, car si l'exécution s'arrête à mi-chemin des modifications, celles-ci sont annulées.
  • Un contrat financier fonctionne en prenant la médiane de neuf flux de données exclusifs afin de minimiser le risque. Un attaquant prend le contrôle de l'un des flux de données, qui est conçu pour être modifiable via le mécanisme d'appel d'adresse variable décrit dans la section sur les DAO, et le convertit pour qu'il exécute une boucle infinie, essayant ainsi de forcer toute tentative de réclamation des fonds du contrat financier à tomber en panne de gaz. Le contrat financier peut toutefois fixer une limite de gaz sur le message pour éviter ce problème.

L'alternative à la Turing-complétude est la Turing-incomplétude, où JUMP et JUMPI n'existent pas et où une seule copie de chaque contrat est autorisée à exister dans la pile d'appels à un moment donné. Avec ce système, le système de frais décrit et les incertitudes entourant l'efficacité de notre solution pourraient disparaître, puisque le coût d'exécution d'un contrat serait limité au-dessus par sa taille. De plus, la Turing-incomplétude n'est même pas une limitation si importante. Parmi tous nos exemples de contrats conçus en interne, un seul nécessitait une boucle, et même celle-ci pouvait être supprimée en effectuant 26 répétitions d'un morceau de code d'une ligne. Étant donné les sérieuses implications de la Turing-complétude, et des bénéfices limités, pourquoi ne pas simplement utiliser un langage Turing-incomplet ? En réalité, la Turing-incomplétude est loin d'être une parfaite solution au problème. Pour comprendre pourquoi, il suffit de considérer les contrats suivants :

C0: call(C1); call(C1);
C1: call(C2); call(C2);
C2: call(C3); call(C3);
...
C49: call(C50); call(C50);
C50: (exécuter une étape d'un programme et enregistrer le changement dans le stockage)

Envoyez maintenant une transaction à A. Ainsi, en 51 transactions, nous avons un contrat qui effectue jusqu'à 250 étapes de calcul. Les mineurs pourraient essayer de détecter ces bombes logiques à l'avance en maintenant pour chaque contrat une valeur spécifiant le nombre maximum d'étapes de calcul autorisé, et en calculant cette valeur pour les contrats appelant d'autres contrats de manière récursive, mais cela nécessiterait que les mineurs interdisent les contrats qui créent d'autres contrats (puisque la création et l'exécution des 26 contrats ci-dessus pourraient facilement être regroupées en un seul contrat). Un autre point problématique est que le champ d'adresse d'un message est une variable, de sorte qu'en général, il n'est même pas possible de savoir à l'avance quels autres contrats un contrat donné va appeler. Au final, nous arrivons donc à une conclusion surprenante : la Turing-complétude est étonnamment facile à gérer, tout comme son absence est tout aussi étonnamment difficile à gérer, à moins que les mêmes contrôles soient en place. Mais dans ce cas, pourquoi ne pas laisser le protocole être Turing-complet ?

Monnaie et émission

Le réseau Ethereum comprend sa propre monnaie intégrée, l'ether (ETH), qui a pour double objectif de fournir une couche de liquidités primaire pour permettre un échange efficace entre différents types d'actifs numériques et, plus important encore, de fournir un mécanisme de paiement des frais de transaction. Pour des raisons pratiques et pour éviter toute polémique (voir le débat actuel sur les mBTC/uBTC/satoshi de Bitcoin), les dénominations seront pré-libellées :

  • 1 : wei
  • 1012 : szabo
  • 1015 : finney
  • 1018 : ether

Il s'agit d'une version étendue du concept de « dollars » et de « cents », ou de « BTC » et de « satoshi ». Dans un avenir proche, nous prévoyons que l'« ether » sera utilisé pour les transactions ordinaires, le « finney » pour les microtransactions, et le « szabo » et le « wei » pour les discussions techniques autour des frais et de la mise en œuvre du protocole. D'autres dénominations peuvent devenir utiles ultérieurement, mais ne doivent pas être incluses dans les clients à ce stade.

Le modèle d'émission sera le suivant :

  • L'ETH sera émis lors d'une vente de monnaie au prix de 1 000-2 000 ETH par BTC. Ce mécanisme est destiné à financer l'organisation Ethereum et à payer le développement qui a été utilisé avec succès par d'autres plateformes comme Mastercoin et NXT. Les premiers acheteurs bénéficieront de remises plus importantes. Les BTC reçus de la vente seront entièrement utilisés pour payer les salaires et les primes aux développeurs, et investis dans divers projets à but lucratif et non lucratif dans l'écosystème d'Ethereum et des cryptomonnaies.
  • 0,099 x le montant total vendu (60 102 216 ETH) sera alloué à l'organisation pour indemniser les premiers contributeurs et payer les dépenses désignées en ETH avant le bloc d'origine.
  • 0,099 x le montant total vendu sera conservé comme réserve à long terme.
  • 0,26 x le montant total vendu sera alloué aux mineurs chaque année indéfiniment après ce point.
GroupeAu lancementAprès 1 anAprès 5 ans
Unités monétaires1,198X1,458X2,498X
Acheteurs83,5 %68,6 %40,0 %
Réserve dépensée avant vente8,26 %6,79 %3,96 %
Réserve utilisée après vente8,26 %6,79 %3,96 %
Mineurs0 %17,8 %52,0 %

Taux de croissance de l'offre à long terme (en pourcentage)

Inflation d'Ethereum

Malgré l'émission linéaire de monnaie, tout comme pour le Bitcoin, le taux de croissance de l'offre tend néanmoins vers zéro au fil du temps.

Les deux principaux choix du modèle ci-dessus sont (1) l'existence et la taille d'un fonds de dotation et (2) l'existence d'une offre linéaire à la croissance permanente, par opposition à une offre plafonnée comme dans le cas du Bitcoin. La justification du fonds de dotation est la suivante. Si le fonds de dotation n'existait pas et que l'émission linéaire était réduite à 0,217 x pour obtenir le même taux d'inflation, la quantité totale d'ETH serait inférieure de 16,5 % et chaque unité aurait donc une valeur supérieure de 19,8 %. Par conséquent, à l'équilibre, 19,8 % d'ETH supplémentaires seraient achetés lors de la vente, de sorte que chaque unité aurait à nouveau exactement la même valeur qu'auparavant. L'organisation disposerait alors de 1,198 x plus de BTC, que l'on peut considérer comme divisés en deux tranches : les BTC initiaux et les 0,198 x supplémentaires. Par conséquent, cette situation est exactement équivalente à la dotation, mais avec une différence importante : l'organisation détient uniquement des BTC, et n'est donc pas incitée à soutenir la valeur de l'unité d'ether.

Le modèle de croissance linéaire permanente de l'offre réduit le risque de ce que certains considèrent comme une concentration excessive de la richesse en Bitcoins. Il offre aux individus vivant dans les époques actuelles et futures une chance équitable d'acquérir des unités monétaires, tout en maintenant une forte incitation à obtenir et conserver des ETH, car le « taux de croissance de l'offre » en pourcentage tend toujours vers zéro au fil du temps. Nous émettons également l'hypothèse que, comme des pièces sont toujours perdues au fil du temps en raison de la négligence, du décès, etc., et que la perte de pièces peut être modélisée comme un pourcentage de l'offre totale par an, l'offre totale de monnaie en circulation finira par se stabiliser à une valeur égale à l'émission annuelle divisée par le taux de perte (par ex., à un taux de perte de 1 %, une fois que l'offre atteint 26X, alors 0,26X sera miné et 0,26X perdu chaque année, créant un équilibre).

Notez qu'à l'avenir, il est probable qu'Ethereum passe à un modèle de preuve d'enjeu pour la sécurité, réduisant l'exigence d'émission à quelque chose entre zéro et 0,05 X par an. Dans le cas où l'organisation Ethereum perdrait son financement ou disparaîtrait pour toute autre raison, nous laissons ouvert un « contrat social » : quiconque a le droit de créer une future version candidate d'Ethereum, à la seule condition que la quantité d'ether soit au plus égale à 60102216 * (1.198 + 0.26 * n)n est le nombre d'années après le bloc de genèse. Les créateurs sont libres de vendre au public ou de céder d'une autre manière une partie ou la totalité de la différence entre l'expansion de l'offre induite par la preuve d'enjeu (PoS) et l'expansion maximale autorisée de l'offre pour payer le développement. Les mises à niveau candidates non conformes au contrat social peuvent, à juste titre, faire l'objet d'une fourche vers des versions conformes.

Centralisation du minage

L'algorithme de minage du Bitcoin fonctionne en demandant aux mineurs de calculer SHA256 des millions de fois sur des versions légèrement modifiées de l'en-tête du bloc, jusqu'à ce qu'un nœud finisse par proposer une version dont le hachage est inférieur à la cible (actuellement autour de 2192). Cependant, cet algorithme de minage est vulnérable à deux formes de centralisation. Pour commencer, l'écosystème de minage est désormais dominé par les circuits intégrés spécifiques aux applications (ASIC), des puces informatiques conçues pour la tâche spécifique du minage de Bitcoins, et donc des milliers de fois plus efficaces. Cela signifie que l'extraction de Bitcoins n'est plus une activité hautement décentralisée et égalitaire, puisqu'elle nécessite des millions de dollars de capital pour y participer efficacement. Deuxièmement, la plupart des mineurs de Bitcoins n'effectuent pas réellement la validation des blocs au niveau local. Ils s'appuient plutôt sur un groupe de minage centralisé pour fournir les en-têtes de bloc. Ce problème est sans doute le plus grave : à la rédaction de cet article, les trois principaux groupes de minage contrôlent indirectement environ 50 % de la puissance de traitement du réseau Bitcoin, même si cette situation est atténuée par le fait que les mineurs peuvent intégrer d'autres groupes de minage si l'un d'eux ou une coalition tentent une attaque de 51 %.

L'intention actuelle d'Ethereum est d'utiliser un algorithme de minage dans lequel les mineurs sont tenus d'extraire des données aléatoires de l'état, de calculer certaines transactions choisies au hasard dans les N derniers blocs de la blockchain et de renvoyer le hash du résultat. Ceci a deux avantages importants : Premièrement, les contrats Ethereum peuvent inclure n'importe quel type de calcul, donc un ASIC Ethereum serait essentiellement un ASIC pour le calcul général - c.-à-d. un meilleur CPU. Deuxièmement, le minage nécessite l'accès à l'ensemble de la blockchain, ce qui oblige les mineurs à la stocker dans son intégralité et d'être au moins capables de vérifier chaque transaction. Ceci supprime le besoin de groupes de minage centralisés. Bien que ceux-ci puissent toujours jouer le rôle légitime d'équilibrer le caractère aléatoire de la distribution des récompenses, cette fonction peut être tout aussi bien remplie par des groupes P2P sans contrôle central.

Ce modèle n'est pas testé, et des difficultés peuvent survenir en cours de route si l'on évite certaines optimisations astucieuses quand l'exécution du contrat est utilisée comme algorithme de minage. Toutefois, cet algorithme possède une fonctionnalité particulièrement intéressante qui permet à n'importe qui d'« empoisonner le puits » en introduisant dans la blockchain un grand nombre de contrats spécialement conçus pour contrecarrer certains ASIC. Des incitations économiques existent pour que les fabricants d'ASIC utilisent cette astuce pour s'attaquer mutuellement. La solution que nous développons est donc, en définitive, une solution humaine économique adaptative plutôt qu'une solution purement technique.

Évolutivité

La question de l'évolutivité est l'une des préoccupations les plus courantes concernant Ethereum. Comme Bitcoin, Ethereum présente le défaut que chaque transaction doit être traitée par chaque nœud du réseau. Pour Bitcoin, la taille actuelle de la blockchain est d'environ 15 Go et elle augmente d'environ 1 Mo par heure. Si le réseau Bitcoin devait traiter les 2 000 transactions par seconde de Visa, il croîtrait de 1 Mo toutes les trois secondes (1 Go par heure, 8 To par an). Ethereum est susceptible de subir un modèle de croissance similaire, aggravé par le fait qu'il y aura de nombreuses applications sur sa blockchain, et pas seulement une monnaie comme c'est le cas avec Bitcoin, mais amélioré par le fait que les nœuds complets Ethereum n'ont besoin de stocker que l'état de la blockchain et non son historique complet.

Avec une blockchain d'une telle taille, le risque de centralisation constitue un problème. Par exemple, si la taille de la blockchain atteint 100 To, le scénario probable serait que seul un très petit nombre de grandes entreprises exécuterait des nœuds complets, tous les utilisateurs réguliers utilisant des nœuds légers de vérification simplifiée de paiement (SPV). Dans une telle situation, il y a le risque que les nœuds complets se regroupent et s'accordent tous pour tricher d'une manière rentable (par ex., changer la récompense de bloc, s'attribuer des BTC). Les nœuds légers ne pourraient pas détecter cela tout de suite. Bien sûr, il existerait probablement au moins un nœud complet honnête, et après quelques heures, des informations sur la fraude seraient diffusées via des canaux comme Reddit. Mais à ce moment-là, il serait déjà trop tard : il incomberait aux utilisateurs ordinaires d'organiser une action pour mettre sur liste noire les blocs donnés. Cela poserait un problème de coordination massif et serait probablement infaisable à une échelle similaire à celle d'une attaque à 51 % réussie. Dans le cas de Bitcoin, c'est actuellement un problème, mais il existe une modification de la blockchain suggérée par Peter Todd (opens in a new tab) qui atténuera ce problème.

À court terme, Ethereum utilisera deux stratégies supplémentaires pour faire face à ce problème. Tout d'abord, en raison des algorithmes de minage basés sur la blockchain, chaque mineur sera obligé d'être un nœud complet, créant ainsi une limite inférieure du nombre de nœuds complets. Ensuite, nous inclurons surtout une racine d'arbre d'état intermédiaire dans la blockchain après le traitement de chaque transaction. Même si la validation des blocs est centralisée, tant qu'il existe un nœud vérificateur honnête, le problème de centralisation peut être contourné via un protocole de vérification. Si un mineur publie un bloc invalide, ce bloc doit être soit mal formaté, soit l'état S[n] est incorrect. Puisque S[0] est connu pour être correct, il doit y avoir un premier état S[i] qui est incorrect alors que S[i-1] est correct. Le nœud de vérification fournirait l'index i, ainsi qu'une « preuve d'invalidité » consistant en un sous-ensemble de nœuds de l'arbre Patricia nécessaires pour traiter APPLY(S[i-1],TX[i]) -> S[i]. Les nœuds pourraient utiliser ces nœuds pour exécuter cette partie du calcul, et voir que le S[i] généré ne correspond pas au S[i] fourni.

Une autre attaque, plus sophistiquée, impliquerait que des mineurs malveillants publient des blocs incomplets, de sorte que l'information complète n'existe même pas pour déterminer si les blocs sont valides ou non. La solution à ce problème est un protocole de défi-réponse : les nœuds vérificateurs émettent des « défis » sous la forme d'indices de transaction cible, et à la réception d'un nœud, un nœud léger traite le bloc comme non fiable jusqu'à ce qu'un autre nœud, que ce soit le mineur ou un autre vérificateur, fournisse un sous-ensemble de nœuds Patricia comme preuve de validité.

Conclusion

Le protocole Ethereum a été initialement conçu comme une version améliorée d'une cryptomonnaie, offrant des fonctionnalités avancées sur la blockchain telles que les dépôts fiduciaires, les limites de retrait, les contrats financiers, les marchés de jeux d'argent et de hasard, etc., via un langage de programmation très généraliste. Le protocole Ethereum ne « prend en charge » aucune de ces applications directement, mais l'existence d'un langage de programmation Turing-complet signifie que théoriquement, des contrats arbitraires peuvent être créés pour n'importe quel type de transaction ou d'application. Le plus intéressant dans Ethereum, c'est que son protocole va bien au-delà de la simple monnaie. Les protocoles autour du stockage de fichier décentralisé, des calculs décentralisés et des marchés prédictifs décentralisés, parmi des dizaines d'autres concepts du même ordre, ont le potentiel d'augmenter considérablement la productivité de l'industrie informatique, et de stimuler énormément d'autres protocoles P2P en y ajoutant pour la première fois une couche économique. Enfin, il existe aussi une gamme considérable d'applications n'ayant aucun rapport avec l'argent.

Le concept d'une fonction de transition d'état arbitraire telle qu'implémentée par le protocole Ethereum offre une plateforme au potentiel unique. Au lieu d'être un protocole fermé, à usage unique et destiné à une gamme spécifique d'applications dans les domaines du stockage de données, des jeux d'argent ou de la finance, Ethereum est ouvert par conception. Nous pensons qu'il est parfaitement adapté pour servir de couche de base à un très grand nombre de protocoles financiers et non financiers dans les années à venir.

Notes et lectures complémentaires

Notes

  1. Un lecteur averti peut remarquer qu'en réalité, une adresse Bitcoin est le hachage de la clé publique à courbe elliptique, et non la clé publique elle-même. Cependant, il est parfaitement légitime, dans la terminologie cryptographique, de faire référence au hachage de la clé publique comme à la clé publique elle-même. En effet, la cryptographie du Bitcoin peut être considérée comme un algorithme de signature numérique personnalisée, où la clé publique est constituée du hachage de la clé publique ECC, la signature est constituée de la clé publique ECC concaténée avec la signature ECC, et l'algorithme de vérification consiste à vérifier la clé publique ECC dans la signature par rapport au hachage de la clé publique ECC fourni comme clé publique, puis à vérifier la signature ECC par rapport à la clé publique ECC.
  2. Techniquement, la médiane des 11 blocs précédents.
  3. En interne, 2 et « CHARLIE » sont des nombresfn3, le dernier étant en représentation gros-boutiste une base 256. Les nombres peuvent être au minimum de 0 et au maximum de 2256-1.

En savoir plus

  1. Valeur intrinsèque (opens in a new tab)
  2. Propriété intelligente (opens in a new tab)
  3. Contrats intelligents (opens in a new tab)
  4. B-money (opens in a new tab)
  5. Preuves de travail réutilisables (opens in a new tab)
  6. Titres de propriété sécurisés avec autorité du propriétaire (opens in a new tab)
  7. Livre blanc de Bitcoin (opens in a new tab)
  8. Namecoin (opens in a new tab)
  9. Triangle de Zooko (opens in a new tab)
  10. Livre blanc des pièces colorées (opens in a new tab)
  11. Livre blanc de Mastercoin (opens in a new tab)
  12. Sociétés autonomes décentralisées, Bitcoin Magazine (opens in a new tab)
  13. Vérification de paiement simplifiée (opens in a new tab)
  14. Arbres de Merkle (opens in a new tab)
  15. Arbres Patricia (opens in a new tab)
  16. GHOST (opens in a new tab)
  17. StorJ et agents autonomes, Jeff Garzik (opens in a new tab)
  18. Mike Hearn sur la propriété intelligente au Turing Festival (opens in a new tab)
  19. RLP d'Ethereum
  20. Arbres de Merkle Patricia d'Ethereum
  21. Peter Todd sur les arbres de somme de Merkle (opens in a new tab)

Pour l'historique du livre blanc, voir ce wiki (opens in a new tab).

Comme de nombreux projets open source communautaires, Ethereum a évolué depuis sa création. Pour en savoir plus sur les derniers développements d'Ethereum et sur la manière dont les modifications du protocole sont apportées, nous vous recommandons ce guide.

Dernière mise à jour de la page : 26 février 2026

Cet article vous a été utile ?