
La préhistoire du protocole Ethereum : un réveil progressif depuis le néant
TechFlow SélectionTechFlow Sélection

La préhistoire du protocole Ethereum : un réveil progressif depuis le néant
Le présent article vise à retracer l'évolution du protocole Ethereum depuis ses débuts jusqu'à sa publication.
Article rédigé le 14 septembre 2017
Note de la rédaction : Cet article est un récit par Vitalik du développement du protocole Ethereum, racontant l'histoire de sa conception, de sa première publication et de ses itérations successives.
Bien que les idées sous-jacentes au protocole Ethereum soient aujourd'hui globalement stabilisées depuis deux ans, la vision actuelle d'Ethereum n'est pas apparue du jour au lendemain. Après le lancement de la blockchain Ethereum, son protocole a connu une série d'évolutions majeures et de décisions cruciales.
Cet article vise à retracer l'évolution du protocole Ethereum depuis ses débuts jusqu'à sa sortie initiale. Les importants travaux réalisés par Geth, cppethereum, pyethereum et EthereumJ dans l'implémentation du protocole, ainsi que l'histoire des applications et de l'écosystème commercial autour d'Ethereum, ne seront pas abordés ici.
De même, l'historique de la recherche sur Casper et le sharding ne sera pas traité non plus. Sans aucun doute, nous pourrions écrire bien d'autres articles sur les nombreuses idées proposées — puis abandonnées — par Vlad, Gavin, moi-même et d'autres, telles que les preuves de preuve de travail, les chaînes multi-tours, l'hypercube, les shadow chains (prédécesseurs possibles des Plasma), les fibres de chaîne ou encore les différentes versions de Casper, ainsi que les réflexions en constante évolution de Vlad sur les incitations aux participants au sein des protocoles de consensus. L'histoire derrière ces idées est elle-même si complexe qu'elle mériterait un article à part entière. Pour cette raison, elles resteront provisoirement hors sujet.
Commençons donc par la toute première version. Celle-ci deviendra finalement Ethereum, mais à l'époque, elle n'avait même pas encore ce nom. En octobre 2013, lors d'un voyage en Israël, j'ai passé beaucoup de temps avec l'équipe de Mastercoin, allant jusqu'à leur suggérer d'ajouter certaines fonctionnalités. Après avoir longuement réfléchi à leur projet, j'ai envoyé à l'équipe une proposition visant à rendre leur protocole plus généraliste, capable de prendre en charge davantage de types de contrats sans nécessiter l'ajout d'une fonctionnalité complexe et volumineuse :
https://web.archive.org/web/20150627031414/http://vbuterin.com/ultimatescripting.html
Il convient de noter que cette version diffère fortement de la vision ultérieure d'Ethereum : elle se concentre exclusivement sur la technologie que Mastercoin cherchait alors à développer, à savoir les contrats bilatéraux. Dans ce type de contrat, deux parties A et B versent conjointement des fonds, puis peuvent retirer ces fonds selon une formule prédéfinie (par exemple, « si X se produit, tout va à A ; sinon, tout va à B »). Le langage de script utilisé n'est pas Turing-complet.
L'équipe de Mastercoin a été impressionnée, mais n'a pas souhaité abandonner son projet pour suivre cette direction. Quant à moi, je devenais de plus en plus convaincu que c'était pourtant la bonne voie. C'est ainsi qu'environ en décembre, une deuxième version a vu le jour :
https://web.archive.org/web/20131219030753/http://vitalik.ca/ethereum.html
Dans cette version, on observe une refonte importante, dont une grande partie m'est venue lors d'une longue marche à San Francisco en novembre. À ce moment-là, j'ai pris conscience du potentiel pleinement universel des contrats intelligents. Plutôt que d'utiliser un simple langage de script pour décrire une relation bilatérale, le contrat lui-même devenait un compte autonome, capable de détenir, envoyer et recevoir des actifs, et même de maintenir un stockage permanent (appelé alors « mémoire », tandis que la seule « mémoire » temporaire était constituée de 256 registres). Le langage passait d'une machine virtuelle basée sur une pile à une machine basée sur des registres, plus conforme à mes préférences. Je n'y voyais guère d'inconvénient, hormis une complexité accrue.
Le mot « ether » signifie littéralement « éther » (c’est-à-dire le carburant, équivalent au gas). Après chaque étape de calcul, le solde du contrat appelé par une transaction est diminué d'une certaine quantité. Si les fonds du contrat sont épuisés, l'exécution s'arrête. Notez que ce mécanisme impliquant que le destinataire paie signifie que le contrat doit exiger du destinataire un paiement. Si ce paiement n'est pas effectué, l'exécution est immédiatement interrompue. Cette version du protocole incluait une limite de 16 étapes gratuites d'exécution, permettant ainsi au contrat de rejeter les transactions non rémunérées.
Jusqu'alors, le protocole Ethereum avait été entièrement conçu par moi seul. Mais à partir de ce moment, de nouveaux acteurs ont commencé à rejoindre le projet. Sur le plan protocolaire, la contribution la plus marquante fut celle de Gavin, qui a entamé la discussion avec moi via un message privé sur about.me en décembre 2013.
Jeffrey Wilcke, principal développeur du client Go (alors appelé « ethereal »), m'a également contacté à la même période et a commencé à coder. Bien que ses contributions aient surtout concerné le développement des clients plutôt que la recherche protocolaire.
Les premières contributions de Gavin furent doubles. Premièrement, vous remarquerez peut-être que dans la conception initiale, le modèle d'appel de contrat était asynchrone : bien qu'un contrat A puisse créer une transaction interne vers un contrat B (« transaction interne » est le jargon Ethereum ; à l'origine, cela s'appelait simplement « transaction », puis « appel de message » ou « appel »), l'exécution de cette transaction interne ne commençait qu'après la fin complète de la première transaction. Cela signifiait qu'une transaction ne pouvait pas utiliser les appels internes pour récupérer des informations depuis un autre contrat ; pour cela, il fallait utiliser l'opcode EXTRO (semblable à SLOAD, qui lit le stockage d'un autre contrat), mais cet opcode fut par la suite supprimé grâce au soutien de Gavin et d'autres.
En implémentant ma spécification initiale, Gavin a naturellement implémenté les transactions internes de façon synchrone, sans même réaliser la divergence d'intention — c’est-à-dire que dans son implémentation, lorsqu'un contrat en appelle un autre, la transaction interne s'exécute immédiatement. Une fois cette exécution terminée, la machine virtuelle revient au contrat initiateur et poursuit avec l'opcode suivant. Cette approche semblait meilleure aux yeux de Gavin comme aux miens, et nous avons décidé de l'intégrer au protocole.
Deuxièmement, une discussion entre Gavin et moi (survenue lors d'une promenade à San Francisco, dont les détails précis se sont perdus dans le flot de l'histoire, bien qu'ils puissent subsister quelque part dans les archives profondes de la NSA) a conduit à une refonte du modèle de frais de transaction, passant d'un paiement par le contrat à un paiement par l'expéditeur, et introduisant l'architecture du carburant (gas). Plutôt que de consommer de l'ether à chaque étape de calcul, dans cette nouvelle version, l'initiateur d'une transaction paie des frais et reçoit une certaine quantité de carburant (une sorte de compteur d'étapes de calcul). Le nombre d'étapes autorisées dépend alors de la limite de carburant. Si une transaction épuise tout son carburant, celui-ci est perdu, mais toute l'exécution est annulée. Cela semblait être la solution la plus sûre, car elle supprimait tous les risques d'attaques par exécution partielle auxquels les contrats étaient auparavant exposés. À la fin de l'exécution, tout carburant non utilisé est remboursé.
Gavin a profondément influencé, de manière subtile, la vision d'Ethereum : en passant d'une plateforme dédiée aux monnaies programmables — où des contrats basés sur la blockchain peuvent détenir des actifs numériques et les transférer selon des règles prédéfinies — à une plateforme de calcul universelle. Ce changement s'est manifesté par des nuances dans l'accent mis sur certains aspects et dans la terminologie, puis s'est renforcé avec notre insistance croissante sur l'intégration de Web3 (considérant Ethereum comme une composante d'un ensemble de technologies décentralisées, aux côtés du protocole Whisper et du protocole Swarm, figure 1).

Au début de l'année 2014, nous avons apporté quelques modifications supplémentaires, inspirées par d'autres. Suite à une suggestion d'Andrew Miller et d'autres, nous sommes revenus à une architecture basée sur une pile (figure 2).

Charles Hoskinson nous a suggéré de passer du SHA256 de Bitcoin au SHA3 plus récent (ou plus précisément, keccak256). Après un certain débat, nous avons décidé, en concertation avec Gavin, Andrew et d'autres, de limiter la taille des valeurs dans la pile à 32 octets. L'autre option — les entiers illimités — restait envisageable, mais posait un problème : il était difficile d'estimer précisément combien de carburant coûteraient des opérations comme l'addition ou la multiplication.
Début janvier 2014, notre premier algorithme de minage envisagé s'appelait Dagger (Poignard) :
https://github.com/ethereum/wiki/blob/master/Dagger.md
Dagger tire son nom du graphe acyclique orienté (Directed Acyclic Graph, DAG), une structure mathématique utilisée dans l'algorithme. L'idée était que tous les N blocs, un nouveau DAG serait généré de manière pseudo-aléatoire à partir d'une graine. Ce DAG reposerait sur un ensemble de nœuds occupant plusieurs milliards d'octets en mémoire. Toutefois, produire une valeur individuelle dans ce DAG ne nécessiterait que le calcul de quelques milliers d'entrées. Un calcul Dagger consistait à extraire plusieurs valeurs à des positions arbitraires dans ce jeu de données, puis à les hacher ensemble. Il existait donc une méthode rapide (si les données sont déjà en mémoire) et une méthode lente mais peu gourmande en mémoire (recalculer chaque valeur à partir du DAG).
L'objectif de cet algorithme était d'avoir des propriétés similaires aux algorithmes populaires de l'époque comme Scrypt, en étant limité par la mémoire, tout en restant amical pour les clients légers. Les mineurs utiliseraient la méthode rapide, donc leur minage serait limité par la bande passante mémoire (théoriquement, la mémoire grand public est déjà suffisamment optimisée pour que les ASIC peinent à l'améliorer davantage), tandis que les clients légers pourraient utiliser la méthode lente et peu gourmande. La première méthode prendrait quelques microsecondes, la seconde quelques millisecondes, ce qui reste faisable pour les clients légers.
À partir de là, l'algorithme a évolué à plusieurs reprises au fil du développement d'Ethereum. L'idée suivante fut la preuve de travail adaptative. Dans ce schéma, la preuve de travail consisterait à exécuter des contrats Ethereum choisis aléatoirement, avec un mécanisme astucieux contre les ASIC : si des ASIC étaient développés, les mineurs concurrents auraient alors intérêt à créer et publier des contrats que ces ASIC exécuteraient mal. Aucun ASIC ne pourrait exceller dans le calcul universel, car cela reviendrait à construire un simple processeur. Nous pourrions ainsi exploiter ces incitations adversariales pour obtenir une preuve de travail équivalente à un calcul universel.
Pour une raison simple, cette idée a finalement échoué : l'attaque à long terme. Un attaquant pourrait reconstruire une chaîne depuis le bloc 1 en ne remplissant celle-ci qu'avec des contrats simples. Or, l'attaquant pourrait concevoir du matériel spécialisé pour ces contrats simples, permettant à sa chaîne de rattraper rapidement la chaîne principale. Retour à la case départ.
L'algorithme suivant s'appelait « Random Circuit » (Circuit Aléatoire), dont une description détaillée figure dans un document Google. Cette idée était née de Vlad Zamfir et moi-même, analysée par Matthew Wampler-Doty et d'autres. Elle visait à simuler un calcul universel dans le minage via l'exécution de circuits générés pseudo-aléatoirement. Cette fois, rien ne prouvait formellement l'impossibilité d'une telle approche. Mais les experts en matériel informatique que nous avons consultés en 2014 étaient très pessimistes. Matthew Wampler-Doty a proposé une preuve de travail basée sur des solutions SAT, mais elle fut aussi rejetée.
Finalement, après plusieurs détours, nous sommes arrivés à l'algorithme Dagger Hashimoto, parfois appelé Dashimoto. Celui-ci reprenait de nombreuses idées de Hashimoto, un mécanisme de preuve de travail proposé par Thaddeus Dryja, pionnier du concept de « preuve de travail limitée par les E/S ». Là, la vitesse de minage dépendait moins du nombre de hachages par seconde que du volume de mégaoctets accessibles en RAM par seconde. Dagger Hashimoto combinait cette idée avec le jeu de données généré par le DAG du Dagger, amical pour les clients légers. Après de multiples ajustements par moi-même, Matthew, Tim et d'autres, ces concepts se sont cristallisés dans l'algorithme que nous appelons aujourd'hui « Ethash ».
À l'été 2014, le protocole était devenu assez stable, excepté la preuve de travail qui ne devait atteindre Ethash qu'au début 2015. Sa spécification semi-officielle fut publiée sous la forme du « Livre Jaune » de Gavin.
En août 2014, j'ai conçu et introduit le mécanisme des oncles (uncle blocks), permettant à la blockchain Ethereum d'avoir des blocs plus fréquents et une capacité de traitement accrue, tout en réduisant les risques de centralisation. Ce mécanisme est présenté dans PoC6.
Après discussion avec l'équipe de BitShares, nous avons envisagé d'utiliser le tas (heap) comme structure de données de premier ordre — mais nous n'avons pas eu le temps de l'implémenter, et les audits de sécurité et attaques DoS ultérieurs nous ont montré que sa mise en œuvre sécurisée était bien plus difficile qu'anticipée.
En septembre, Gavin et moi avons planifié deux changements majeurs au protocole. D'abord, outre l'arbre d'état et l'arbre des transactions, chaque bloc inclurait désormais un arbre de réceptions. Cet arbre contiendrait les hachages des journaux créés par chaque transaction et les racines d'état intermédiaires. Ces journaux permettraient aux transactions de produire des sorties stockées dans la blockchain, accessibles aux clients légers, mais indisponibles pour les calculs futurs d'état. Cette approche permettrait aux applications décentralisées d'interroger facilement des événements comme les transferts de jetons, achats, ordres boursiers créés ou appariés, ou enchères en cours.
Nous avons envisagé d'autres idées, comme extraire un arbre de Merkle de la trajectoire complète d'exécution d'une transaction, afin de permettre des preuves arbitraires. Mais après compromis entre simplicité et exhaustivité, nous avons opté pour les journaux.
Deuxièmement, l'idée des précompilés. Les précompilés résolvaient le problème de rendre disponibles dans la EVM des calculs cryptographiques complexes sans supporter les coûts liés à la EVM. Nous avons aussi exploré des idées ambitieuses sur les « contrats natifs » : si les mineurs disposaient d'une implémentation plus efficace pour certains contrats, ils voteraient pour baisser leur coût en carburant. Ainsi, les contrats rapidement exécutés par la majorité des mineurs auraient naturellement un prix inférieur. Toutes ces idées ont été rejetées, car nous n'avons pas trouvé de moyen suffisamment sûr sur le plan cryptographico-économique. Un attaquant pourrait créer un contrat exécutant une opération cryptographique avec une porte dérobée, distribuer cette porte à ses amis, exécuter le contrat plus vite, voter pour réduire le carburant et lancer une attaque DoS. Nous avons donc choisi une approche moins ambitieuse : intégrer directement un petit nombre de précompilés dans le protocole pour des opérations courantes comme les hachages et signatures.
Gavin a aussi été une figure clé dans la promotion de l'abstraction protocolaire : rendre modulaires divers éléments du protocole — soldes en ether, algorithmes de signature des transactions, nonce, etc. — en les transformant en contrats au sein du protocole lui-même. L'objectif théorique final étant que tout le protocole Ethereum puisse être décrit comme une série d'appels de fonctions vers une machine virtuelle dotée d'un état initial spécifique. Nous n'avons pas eu le temps d'intégrer toutes ces idées dans la version initiale Frontier, mais elles devaient progressivement être adoptées via des changements comme ceux de « Constantinople », les contrats Casper et les spécifications de sharding.
Tout cela a été implémenté dans PoC7. Après PoC7, le protocole n'a plus subi de grands changements, seulement quelques ajustements mineurs mais parfois importants. Ces détails seraient publiés après audit de sécurité.
Début 2015, Jutta Steiner et d'autres ont organisé des audits de sécurité préliminaires, incluant des audits logiciels et académiques. Les audits logiciels portaient principalement sur les implémentations C++ et Go dirigées respectivement par Gavin et Jeff. Mon implémentation Pyethereum a aussi fait l'objet d'un audit rapide. Parmi les audits académiques, l'un a été mené par Ittay Eyal (connu pour la « minage égoïste »), l'autre par Andrew Miller et d'autres membres de Least Authority. L'audit d'Eyal a conduit à un léger changement protocolaire : la difficulté totale de la chaîne n'inclurait plus les blocs oncles. L'audit de Least Authority s'est concentré sur les contrats intelligents, l'économie du carburant et les arbres de Patricia. Il a entraîné plusieurs modifications, notamment l'utilisation de sha3(addr) et sha3(key) comme clés dans les arbres, plutôt que les adresses et clés directes, rendant les attaques de pire cas plus difficiles.
Un autre sujet important discuté fut le mécanisme de vote sur la limite de carburant. À l'époque, nous étions inquiets du manque de progrès sur le débat concernant la taille des blocs Bitcoin, et souhaitions concevoir Ethereum de manière flexible, ajustable dans le temps selon les besoins. Mais la question restait : quelle est la meilleure limite ? Initialement, je proposais une limite dynamique fixée à 1,5 fois la moyenne mobile exponentielle de l'utilisation réelle du carburant. À long terme, les blocs seraient ainsi remplis à environ 2/3. Mais Andrew a démontré que cette limite pouvait être manipulée : les mineurs désirant augmenter la limite n'avaient qu'à inclure dans leurs blocs des transactions consommant beaucoup de carburant mais peu de temps processeur, créant ainsi des blocs pleins sans coût élevé. En fin de compte, ce mécanisme revenait essentiellement à laisser les mineurs voter sur la limite de carburant.
N'ayant pas trouvé de meilleure stratégie, Andrew a recommandé que les mineurs votent explicitement sur la limite, avec comme stratégie par défaut 1,5 fois la moyenne mobile exponentielle. La raison ? Nous n'avions pas encore trouvé la bonne méthode pour fixer une limite maximale, et le risque d'échec d'une méthode précise semblait bien supérieur au risque d'abus par les mineurs. Autant donc simplifier : laissons les mineurs voter, acceptons les risques d'une limite trop haute ou trop basse, et bénéficions en retour de la flexibilité et de la capacité des mineurs à ajuster rapidement la limite selon les besoins.
Après un mini hackathon avec Gavin et Jeff, PoC9 a été lancé en mars, destiné à être la dernière version de preuve de concept. Nous avons ensuite exécuté un réseau test baptisé « Olympic » pendant quatre mois, utilisant le protocole prévu pour le réseau principal. Parallèlement, nous avons établi le plan à long terme d'Ethereum. Vinay Gupta a rédigé un article, « The Ethereum Release Process », décrivant les quatre phases du développement du réseau principal, donnant naissance aux noms désormais célèbres : « Frontier », « Homestead », « Metropolis » et « Serenity ».
Le réseau test « Olympic » a fonctionné pendant quatre mois. Pendant les deux premiers mois, nous avons découvert de nombreux bogues dans diverses implémentations, ainsi que des échecs de consensus. Vers juin, le réseau s'est considérablement stabilisé. En juillet, nous avons décidé de figer le code ; le 30 juillet, le réseau principal Ethereum a été officiellement lancé.
Bienvenue dans la communauté officielle TechFlow
Groupe Telegram :https://t.me/TechFlowDaily
Compte Twitter officiel :https://x.com/TechFlowPost
Compte Twitter anglais :https://x.com/BlockFlow_News














