
L'idéal de Web3 selon Gavin : l'histoire de l'évolution des contrats intelligents et des machines virtuelles de Polkadot
TechFlow SélectionTechFlow Sélection

L'idéal de Web3 selon Gavin : l'histoire de l'évolution des contrats intelligents et des machines virtuelles de Polkadot
La vision de Gavin est de construire un tout nouveau monde internet décentralisé.
Auteur : Guozi
Polkadot, un projet blockchain historique, est bien connu des professionnels du secteur Web3, même s'ils n'ont jamais utilisé ses produits.

Récemment, Polkadot a fait beaucoup parler de lui. La nouvelle architecture JAM a suscité un grand intérêt, et la démonstration par son fondateur d'un jeu DOOM a révélé une nouvelle perspective pour Polkadot, éveillant en moi un vif intérêt d'étude. Le projet Polkadot étant vaste — incluant notamment la chaîne Polkadot, le cadre de développement Substrate, les chaînes relais et parachains — je me concentrerai ici, dans les limites de cet article, sur la couche d'exécution, plus précisément la machine virtuelle, afin d'en présenter l'historique, l'état actuel et les informations associées.
Prélude
Lorsque Ethereum a été créé, Gavin Wood, attiré par ce projet, y a rejoint l'équipe de développement. À cette époque, Ethereum n'était encore qu'un cadre préliminaire, mais grâce à Gavin, il a pu prendre forme techniquement. Voici quelques-unes de ses contributions majeures :
(1) Réalisation de la preuve de concept PoC-1 d'Ethereum ; (2) Développement quasi exclusif de la première version cliente en C++ d'Ethereum ; (3) Rédaction du Yellow Paper, spécification technique d'Ethereum ; (4) Création du langage haut niveau Solidity destiné au développement de contrats intelligents.
Pour en savoir plus sur cette période, vous pouvez lire « Tout connecter : Ethereum et la future finance numérique ». L'histoire légendaire de Gavin Wood est également facilement trouvable en ligne, nous n'y reviendrons donc pas.
Concentrons-nous maintenant sur Solidity et la EVM. Voici d’abord un exemple simple de code Solidity, un compteur :
pragma solidity ^0.8.3; contract Counter { uint public count; function get() public view returns (uint) { return count; } function inc() public { count += 1; } function dec() public { count -= 1; } }
Cet exemple déclare une variable d'état count, que l'on peut assimiler à un emplacement unique dans une base de données. Des fonctions permettent d'interroger ou de modifier cette valeur. Ici, le contrat définit trois fonctions : inc, dec et get, pour modifier ou récupérer la valeur de la variable.
Après compilation via le compilateur Solidity solc, on obtient un bytecode (voir ci-dessous). Une fois déployé sur un nœud via JSON-RPC, la couche d'exécution atteint d'abord un consensus avant de transmettre l'instruction à la EVM pour exécution.
6080604052348015600e575f80fd5b506101d98061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c806306661abd1461004e578063371303c01461006c5780636d4ce63c14610076578063b3bcfa8214610094575b5f80fd5b61005661009e565b60405161006391906100f7565b60405180910390f35b6100746100a3565b005b61007e6100bd565b60405161008b91906100f7565b60405180910390f35b61009c6100c5565b005b5f5481565b60015f808282546100b4919061013d565b92505081905550565b5f8054905090565b60015f808282546100d69190610170565b92505081905550565b5f819050919050565b6100f1816100df565b82525050565b5f60208201905061010a5f8301846100e8565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610147826100df565b9150610152836100df565b925082820190508082111561016a57610169610110565b5b92915050565b5f61017a826100df565b9150610185836100df565b925082820390508181111561019d5761019c610110565b5b9291505056fea26469706673582212207b7edaa91dc37b9d0c1ea9627c0d65eb34996a5e3791fb8c6a42ddf0571ca98164736f6c634300081a0033
Examinons maintenant ce bytecode sous forme d'instructions assembleur :
PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D9 DUP1 PUSH2 0x1C PUSH0 CODECOPY PUSH0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0xF JUMPI PUSH0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4A JUMPI PUSH0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6661ABD EQ PUSH2 0x4E JUMPI DUP1 PUSH4 0x371303C0 EQ PUSH2 0x6C JUMPI DUP1 PUSH4 0x6D4CE63C EQ PUSH2 0x76 JUMPI DUP1 PUSH4 0xB3BCFA82 EQ PUSH2 0x94 JUMPI JUMPDEST PUSH0 DUP1 REVERT JUMPDEST PUSH2 0x56 PUSH2 0x9E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x63 SWAP2 SWAP1 PUSH2 0xF7 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x74 PUSH2 0xA3 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x7E PUSH2 0xBD JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x8B SWAP2 SWAP1 PUSH2 0xF7 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x9C PUSH2 0xC5 JUMP JUMPDEST STOP JUMPDEST PUSH0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH0 DUP1 DUP3 DUP3 SLOAD PUSH2 0xB4 SWAP2 SWAP1 PUSH2 0x13D JUMP JUMPDEST SWAP3 POP POP DUP2 SWAP1 SSTORE POP JUMP JUMPDEST PUSH0 DUP1 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x1 PUSH0 DUP1 DUP3 DUP3 SLOAD PUSH2 0xD6 SWAP2 SWAP1 PUSH2 0x170 JUMP JUMPDEST SWAP3 POP POP DUP2 SWAP1 SSTORE POP JUMP JUMPDEST PUSH0 DUP2 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0xF1 DUP2 PUSH2 0xDF JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x10A PUSH0 DUP4 ADD DUP5 PUSH2 0xE8 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH0 REVERT JUMPDEST PUSH0 PUSH2 0x147 DUP3 PUSH2 0xDF JUMP JUMPDEST SWAP2 POP PUSH2 0x152 DUP4 PUSH2 0xDF JUMP JUMPDEST SWAP3 POP DUP3 DUP3 ADD SWAP1 POP DUP1 DUP3 GT ISZERO PUSH2 0x16A JUMPI PUSH2 0x169 PUSH2 0x110 JUMP JUMPDEST JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH0 PUSH2 0x17A DUP3 PUSH2 0xDF JUMP JUMPDEST SWAP2 POP PUSH2 0x185 DUP4 PUSH2 0xDF JUMP JUMPDEST SWAP3 POP DUP3 DUP3 SUB SWAP1 POP DUP2 DUP2 GT ISZERO PUSH2 0x19D JUMPI PUSH2 0x19C PUSH2 0x110 JUMP JUMPDEST JUMPDEST SWAP3 SWAP2 POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH28 0x7EDAA91DC37B9D0C1EA9627C0D65EB34996A5E3791FB8C6A42DDF057 SHR 0xA9 DUP2 PUSH5 0x736F6C6343 STOP ADDMOD BYTE STOP CALLER
De point de vue des principes de compilation, voici le flux d’exécution : Code source Solidity → Analyseur lexical → Analyseur syntaxique → Compilation → Bytecode → Machine virtuelle → Interprétation et exécution
Oui, cela ne représente qu’un nouveau langage de programmation dans l’industrie informatique, mais à l’époque, c’était une avancée remarquable. Deux ans après son entrée dans le projet Ethereum, celui-ci a vu le jour comme prévu. Si Vitalik Buterin a donné corps à Ethereum, Gavin Wood lui a insufflé son âme. Bitcoin est un système de paiement électronique, tandis qu’Ethereum a rendu la blockchain programmable. Avec son slogan « Ordinateur mondial », tout a changé.
Web 3.0
Toujours en tant que cofondateur et CTO d’Ethereum, Gavin a publié le 17 avril 2014, sur son blog « Insights into a Modern World », un article intitulé DApps: What Web 3.0 Looks Like[1], exposant pleinement sa vision de l’ère Web3.0 et les quatre composants qui la définissent. L’influence du concept Web3.0 est aujourd’hui évidente. Non seulement Gavin excelle techniquement, mais il possède aussi une vision prospective. Pour davantage d’informations historiques et débats autour du Web3, voir l’article Wikipédia Web3[2]. L’entrepreneur et investisseur américain Nova Spivack[3] propose d’étendre la définition du Web3.0 aux grandes tendances technologiques actuelles vers une nouvelle phase de maturité. Extrait :
• Ubiquitous connectivity : Prolifération des réseaux à large bande, accès mobile à Internet (ex. tablettes).
• Network computing : Modèle commercial « SaaS », interopérabilité des services web, calcul distribué, grille informatique et calcul utilitaire (aussi appelé « cloud computing »).
• Open technologies : API et protocoles ouverts, formats de données ouverts, logiciels libres et données ouvertes (Creative Commons, licences open data).
• Open identity : OpenID, réputation ouverte, identités transversales et profils personnels.
• Smart networks : Technologies du web sémantique comme RDF, OWL, SWRL, SPARQL, plateformes d’applications sémantiques et stockage basé sur des déclarations.
• Distributed databases : Base de données mondiale (« World Wide Database »), mise en œuvre via le web sémantique.
• Intelligent applications : Traitement du langage naturel, apprentissage automatique, raisonnement machine, agents autonomes.

Fin 2015, Gavin quitte Ethereum.
Il fonde ensuite Parity Technologies et développe un client Ethereum écrit en Rust, dominant rapidement le marché des portefeuilles Ethereum. Les raisons de son départ restent inconnues, mais une chose est sûre : la vision de Gavin est de construire un nouveau monde internet décentralisé.
« Ethereum était pour moi une expérience, un prototype visant à valider la faisabilité technique. C’était aussi mon école. Je suis diplômé, et je veux explorer d'autres horizons. »
« Ce que j’ai appris de plus important chez Ethereum, ce n’est pas la technique (un groupe de recherche gère déjà les détails techniques), mais plutôt l’expérience sociale. La gouvernance en fait partie. Je pense qu’améliorer les capacités d’un système via la gouvernance est crucial. C’est une caractéristique révolutionnaire, justement absente chez Ethereum. »
Pendant son passage chez Ethereum, Gavin était un praticien, pas un concepteur. Mais il méditait déjà sur une nouvelle innovation.
Naissance de Polkadot
Un an plus tard, Gavin résout enfin la question qui le hantait depuis longtemps, et publie en 2016 le livre blanc de Polkadot. Beaucoup savent que Polkadot vise non seulement à résoudre les problèmes de scalabilité, mais aussi à permettre la communication entre blockchains indépendantes, soit l’interopérabilité. Mais ce que vous devez surtout retenir sur Polkadot, c’est : le sharding. Car poussé à l’extrême, le sharding devient fondamentalement Polkadot.
Les propos originaux du fondateur de Polkadot, Gavin, illustrent parfaitement ce point :
« La logique de conception de Polkadot ne partait pas directement de l’interopérabilité. Nous attendions la sortie du sharding d’Ethereum. Mais il n’est jamais arrivé, et n’est toujours pas là. J’ai donc décidé de créer un "Ethereum" plus scalable, poussant le concept de sharding à un degré extrême : pourquoi garder des shards ? Autant concevoir des chaînes indépendantes. Ensuite, ces chaînes peuvent échanger des informations, communiquant finalement via une couche de consensus partagée. »
Mais comment comprendre le sharding ? Parlons d’abord de la situation d’Ethereum. Depuis toujours, les performances d’Ethereum sont un talon d’Achille. En 2018, le jeu CryptoKitties a provoqué une congestion sévère, rallongeant considérablement les délais de transaction et faisant exploser les frais. C’est comme une banque avec un seul guichet lent : quand trop de clients arrivent, la file d’attente s’allonge.
Mais si la banque avait plusieurs guichets traitant simultanément les demandes, la file disparaîtrait. Voilà la logique de base du sharding : diviser les nœuds du réseau en zones distinctes appelées "shards", répartissant ainsi les transactions entre différents shards, ce qui améliore massivement l’efficacité.
Dans Polkadot, chaque shard porte la logique centrale, autorisant les transactions parallèles et l’échange de données, reliant finalement plusieurs blockchains en un seul réseau.
Polkadot ne se contente pas d’égaler, voire de surpasser, la vision d’Ethereum 2.0. Son originalité tient à ceci : dans Polkadot, il peut y avoir plusieurs instances d’Ethereum. Ce n’est plus une simple blockchain. « Polkadot veut offrir une plateforme véritablement ouverte et libre pour toutes sortes d’innovations sociales. »
C’est l’idéal du Web3, l’idéal de Polkadot, et l’idéal de Gavin.
Polkadot 1.0
La chaîne-relais de Polkadot ne supporte pas nativement les contrats intelligents, mais les parachains[4] qui y sont connectées peuvent définir librement leurs règles de transition d’état, leur permettant ainsi d’offrir des fonctionnalités de contrat intelligent. Contrairement aux autres écosystèmes, dans Polkadot, parachains et contrats intelligents se situent à des niveaux différents de la pile : les contrats intelligents s’exécutent au-dessus des parachains. Ces dernières sont généralement décrites comme des blockchains de couche 1 — avec la différence qu’elles n’ont pas à construire leur propre sécurité et peuvent être mises à niveau et interopérer.
Polkadot offre une grande flexibilité aux développeurs pour créer des contrats intelligents, supportant à la fois les contrats Solidity exécutés par la EVM (machine virtuelle Ethereum), et les contrats basés sur Wasm utilisant ink! :
Contrats compatibles EVM
L’écosystème Polkadot prend en charge la machine virtuelle Ethereum (EVM) grâce à l’outil Frontier[5]. Celui-ci permet aux blockchains basées sur Substrate d’exécuter nativement des contrats intelligents Ethereum, et d’interagir sans friction avec l’écosystème Ethereum via des interfaces API/RPC compatibles. Les contrats sont écrits en Solidity ou Vyper. La EVM est largement standardisée, notamment sur des parachains Polkadot telles qu’Astar, Moonbeam ou Acala. Cette compatibilité permet de déployer des contrats sur plusieurs réseaux avec peu ou pas de modification, profitant ainsi d’un écosystème de développement mature et étendu.
Par exemple : Astar[6], plateforme clé de contrats intelligents sur Polkadot, adopte une approche multi-machine virtuelle, supportant simultanément les contrats EVM et WebAssembly (Wasm). Ce double support VM permet aux développeurs de choisir leur environnement de programmation favori tout en conservant une compatibilité totale avec Ethereum. Le runtime[7] de la plateforme est construit sur Substrate avec FRAME, combinant des composants clés du Polkadot-SDK et des modules personnalisés pour ses fonctionnalités uniques.

Ces chaînes utilisent souvent des modules de contrat existants, ajoutant parfois des innovations. Par exemple : Phala[8] : utilise le module de contrat dans un environnement d’exécution confidentiel (TEE) pour des contrats intelligents privés et interopérables. Aleph Zero[9] : utilise des pallets de contrat dans un environnement à connaissances zéro. t3rn[10] : utilise le module de contrat comme brique de base pour l’exécution multichaîne de contrats intelligents. Pour plus d’exemples comme Aster, Moonbeam, Acala, consulter la documentation officielle : Contrats sur parachains[11]
Contrats Wasm (ink!) :
Polkadot fournit via le framework FRAME un module Contracts[12], utilisant WebAssembly comme environnement d’exécution pour les contrats. Théoriquement, tout langage compilable en Wasm peut être utilisé, mais pour des raisons d’optimisation et de commodité, Parity a spécifiquement développé ink![13].
Avant d’aborder ink!, clarifions d’abord Substrate[14] et son module de contrat (pallet-contracts). Substrate est un framework pour construire des blockchains, qu’elles soient autonomes ou connectées à Kusama[15] ou Polkadot[16], autrement dit des parachains.
Substrate contient de nombreux modules, appelés « pallets » dans sa terminologie. Il inclut un ensemble de pallets répondant aux besoins courants d’une blockchain moderne : staking, jetons fongibles, jetons non fongibles, gouvernance, etc.
Substrate inclut aussi un module pour les contrats intelligents, appelé pallet Contracts. Si vous développez une parachain Substrate, vous pouvez facilement ajouter des contrats intelligents en intégrant ce pallet. Ce module agit comme environnement d’exécution, prenant un fichier WebAssembly en entrée. Les contrats doivent donc être compilés vers l’architecture cible WebAssembly (Wasm).
Où intervient ink! ? ink! est un langage de programmation, plus précisément un langage spécifique intégré (eDSL) basé sur le populaire langage Rust. Cela signifie que vous pouvez utiliser toute la syntaxe Rust classique, enrichie de détails supplémentaires adaptés au monde des contrats intelligents. Le module Contracts reçoit ces contrats ink! et les exécute de manière sécurisée. En résumé :
Avec ink!, vous pouvez écrire des contrats intelligents en Rust pour des blockchains construites avec Substrate et incluant le pallet Contracts.
ink! ne crée pas un nouveau langage, mais utilise du Rust standard avec un format de contrat explicite et des attributs spéciaux #[ink(...)]. Ces macros attributs indiquent à ink! quelles parties du contrat Rust représentent quoi, permettant finalement à ink! d’accomplir toute la magie nécessaire pour produire un bytecode Wasm compatible avec le SDK Polkadot. Puisque les contrats ink! sont compilés en Wasm, ils bénéficient d’une haute vitesse d’exécution, d’indépendance de plateforme et d’une sécurité renforcée via sandboxing.
Voyons un exemple simple de contrat ink!. Ce contrat stocke une valeur booléenne. Après création, celle-ci est initialisée à true. Il expose deux fonctions : une pour lire la valeur (fn get()), une autre pour la basculer (fn flip()).
#[ink::contract] mod flipper { #[ink(storage)] pub struct Flipper { value: bool, } impl Flipper { #[ink(constructor)] pub fn new(init_value: bool) -> Self { Self { value: init_value } } #[ink(message)] pub fn flip(&mut self) { self.value = !self.value; } #[ink(message)] pub fn get(&self) -> bool { self.value } }}
Similaire aux fonctionnalités offertes par Solidity : Storage, Message, Errors, Event, etc. Pour les développeurs de contrats, cela signifie qu’ils peuvent utiliser ink!, mais aussi d’autres langages : le compilateur Solang[17] pour Solidity ou ask![18] pour AssemblyScript (voir ci-dessous)
import { env, Pack } from "ask-lang";import { FlipEvent, Flipper } from "./storage";@contractexport class Contract { _data: Pack<Flipper>; constructor() { this._data = instantiate<Pack<Flipper>>(new Flipper(false)); } get data(): Flipper { return this.data.unwrap(); } set data(data: Flipper) { this._data = new Pack(data); } @constructor() default(flag: bool): void { this.data.flag = flag; } @message({ mutates: true }) flip(): void { this.data.flag = !this.data.flag; let event = new FlipEvent(this.data.flag); // @ts-ignore env().emitEvent(event); } @message() get(): bool { return this.data.flag; }}
Ajouter un nouveau langage n’est pas difficile. Il suffit d’avoir un compilateur pour WebAssembly, puis d’implémenter l’API du pallet Contracts.
Actuellement, cette API contient environ 15-20 fonctions couvrant tous les besoins d’un contrat intelligent : accès au stockage, fonctions cryptographiques, informations d’environnement (numéro de bloc), accès à des fonctions pour obtenir des nombres aléatoires ou terminer un contrat, etc. Toutes ne doivent pas être implémentées dans le langage — ink! « Hello, World! » n’a besoin que de six fonctions API. Le schéma suivant illustre cette relation :

Par rapport à la EVM, choisir ink! et le pallet Contracts présente de nombreux avantages. Résumons-en quelques-uns détaillés dans cet article :
• ink! est simplement du Rust — vous pouvez utiliser tous les outils Rust classiques : clippy, crates.io[19], IDE, etc.
• Rust est un langage issu de nombreuses années de recherche linguistique, sûr et rapide. Il incorpore aussi les enseignements tirés des anciens langages de contrats (comme Solidity), intégrés dès la conception d’ink!. Des comportements par défaut plus rationnels ont été choisis, comme désactiver les overflows par défaut ou rendre les fonctions privées par défaut.
• Rust est un langage impressionnant, élu langue de programmation préférée sur StackOverflow pendant sept années consécutives (source[20]).
• Si vous êtes une entreprise cherchant à recruter des développeurs de contrats intelligents, vous pouvez puiser dans l’écosystème Rust, bien plus vaste que le créneau restreint des développeurs Solidity.
• ink! est natif Substrate, utilisant des primitives similaires, dont le même système de types.
• Le chemin de migration d’un contrat vers une parachain est très clair. Comme ink! et Substrate sont tous deux en Rust, les développeurs peuvent réutiliser une grande partie du code, des tests, ainsi que du code frontend et client.
• WebAssembly est une norme industrielle, constamment améliorée par de grandes entreprises comme Google, Apple, Microsoft, Mozilla et Facebook.
• WebAssembly élargit la gamme de langages disponibles pour les développeurs de contrats intelligents : Rust, C/C++, C#, Typescript, Haxe, Kotlin, etc. Vous pouvez ainsi utiliser le langage que vous maîtrisez. Cette conception est plus prospective qu’un couplage étroit entre langage et architecture d’exécution.
Pour en savoir plus, consultez What is Parity's ink!?[21]
Polkadot 2.0 / JAM
Le 28 février, Gavin Wood a présenté publiquement lors du JAM Tour à Shanghai un jeu DOOM exécuté sur JAM ! Un moment historique pour l’industrie blockchain. JAM transforme la blockchain non plus en simple réseau, mais en une plateforme de supercalculateur puissante, capable d’exécuter des logiciels conventionnels comme DOOM, avec forte puissance de calcul et faible latence.

Mettant de côté les autres aspects, concentrons-nous sur la machine virtuelle. Après avoir lu les derniers jours le code source de PolkaVM, je confirme que cela est bel et bien réel. Le point clé est que PolkaVM dispose d’un Host exécutant une VM, fournissant des interfaces exportées, sur laquelle tourne une version RISC-V du jeu Doom en tant que guest.
Code source ici :
https://github.com/paritytech/polkavm/tree/master/examples/doom
Examinons les principaux composants de cette nouvelle solution de contrat intelligent :
Revive Pallet
Le pallet Revive[22] permet au runtime de déployer et exécuter des contrats intelligents PolkaVM. Il s’agit d’une branche fortement modifiée de pallet_contracts. Ces contrats peuvent être écrits dans n’importe quel langage compilable en RISC-V. Actuellement, seuls Solidity (via revive[23]) et Rust (voir exemples Rust dans le dossier fixtures) sont officiellement supportés.
Compatibilité au niveau du langage avec Ethereum : les contrats peuvent être écrits en Solidity, et interagir avec des nœuds via JSON RPC Ethereum et des portefeuilles comme MetaMask. En interne, les contrats sont recompilés depuis YUL vers RISC-V pour s’exécuter sur PolkaVM au lieu de la EVM. Pour simplifier, une version personnalisée de REMIX[24] en frontend web permet de compiler les contrats en RISC-V et de les déployer sur Westend Asset Hub Parachain[25].
Revive
Revive[26] est le nom global du projet de compilateur « Solidity to PolkaVM », comprenant plusieurs composants (frontend YUL, exécutable resolc, etc.). resolc est le nom du binaire frontal à entrée unique, utilisant transparentement tous les composants revive pour générer l’artefact du contrat compilé. Il compile des contrats Solidity en code RISC-V exécutable par PolkaVM, permettant ainsi l’exécution de contrats Solidity sur Polkadot.
Un compilateur est nécessaire. Son principe : utiliser le compilateur solc d’origine, puis recompiler sa sortie intermédiaire (YUL) en RISC-V. LLVM[27], un framework de compilateur populaire et puissant, sert de backend, assumant la charge lourde de l’optimisation et de la génération de code RISC-V. revive se charge principalement de convertir l’IR YUL généré par solc en IR LLVM.

Cette méthode trouve un bon équilibre entre compatibilité élevée avec Ethereum, performance correcte des contrats et effort d’ingénierie réalisable. Comparé à la création complète d’un compilateur Solidity, la tâche est nettement plus petite. Cette approche permet de supporter tous les cas particuliers et bizarreries de Solidity et de ses multiples versions.
PolkaVM
PolkaVM[28] est une machine virtuelle utilisateur universelle basée sur RISC-V. C’est le changement le plus marquant face aux technologies concurrentes. Au lieu de la EVM, une nouvelle machine virtuelle personnalisée exécute les contrats. Actuellement, un interpréteur PolkaVM est intégré au runtime. De futures mises à jour introduiront un JIT PolkaVM complet exécuté côté client.

• Sécurité par défaut et sandboxing. Le code exécuté dans la VM doit s’exécuter dans un processus isolé, sans accès au système hôte, même en cas d’attaquant disposant d’une exécution de code à distance complète dans la VM.
• Haute vitesse d’exécution. Les performances doivent être comparables aux meilleurs VM WebAssembly, au moins du même ordre de grandeur.
• Rapidité de compilation, garantissant O(n) pour une compilation unique. Le chargement de nouveau code dans la VM doit être quasi instantané.
• Faible occupation mémoire. La surcharge mémoire de chaque instance concurrente de la VM ne doit pas dépasser 128 Ko.
• Fichiers binaires compacts. Les programmes compilés pour cette VM doivent occuper le moins d’espace possible.
• Pas de gaspillage d’espace d’adressage virtuel. La VM ne doit pas pré-allouer des Go d’espace d’adressage virtuel pour le sandboxing.
• Entièrement déterministe. Étant donné les mêmes entrées et le même code, l’exécution doit toujours produire exactement le même résultat.
• Mesure de gas asynchrone haute performance. La mesure de gas doit être peu coûteuse, déterministe et raisonnablement précise.
• Simplicité. Un programmeur devrait pouvoir écrire un interpréteur entièrement compatible en moins d’une semaine.
• Sémantique opérationnelle versionnée. Toute modification future de la sémantique observable par les programmes clients sera versionnée et explicitement activée.
• Normalisation. Une spécification complète doit exister, décrivant la sémantique opérationnelle observable par les clients.
• Multiplateforme. Sur systèmes non supportés, la VM s’exécutera en mode interprété.
• Dépendances externes minimales. La VM doit être largement autonome, compiler rapidement et résister aux attaques de la chaîne d’approvisionnement.
• Outils intégrés pour débogage et profilage.
Deux différences fondamentales avec la EVM :
• Machine à registres - La EVM est une machine à pile, où les paramètres de fonction passent par une pile infinie. PolkaVM, basé sur RISC-V, est une machine à registres, passant les paramètres via un ensemble fini de registres. Cela rend la traduction vers le matériel sous-jacent plus efficace. Le nombre de registres a été soigneusement choisi, inférieur à celui notoirement limité de x86-64. Cette limitation permet de ramener le problème NP-difficile d’allocation de registres à un simple mappage 1:1, clé du temps de compilation rapide de PolkaVM.
• Longueur de mot réduite - La EVM utilise des mots de 256 bits. Chaque opération arithmétique doit manipuler ces grands nombres, ralentissant considérablement les calculs car ils doivent être divisés en multiples instructions natives. PolkaVM utilise des mots de 64 bits, nativement supportés par le matériel. Lors de la conversion d’un contrat Solidity via YUL (#Revive), les opérations 256 bits sont encore utilisées car YUL est trop bas niveau pour convertir automatiquement les types entiers. Mais il est tout à fait possible d’écrire des contrats dans un autre langage et de les appeler depuis Solidity. Imaginez un système où la logique métier est en Solidity, mais les composants critiques sont en langage plus rapide, comme Python utilisant des modules C pour les tâches intensives.
Résumé
Langages de programmation pour contrats intelligents
Le nombre de langages de contrats intelligents augmente chaque année. Choisir le premier peut être difficile, surtout pour les débutants. Le choix dépend principalement de l’écosystème visé, bien que certains langages conviennent à plusieurs plateformes. Chaque langage a ses forces et faiblesses, que nous ne détaillerons pas ici.
Pourquoi tant de langages de contrats ? Je vois plusieurs raisons : 1) les langages existants ne satisfont pas certaines caractéristiques propres à la chaîne ; 2) meilleure performance, sécurité, coût ; 3) préférences personnelles :)
Je n’ai aucun parti pris sur les langages de contrat. Voici quelques extraits représentant différentes opinions, utiles tant pour les utilisateurs que pour les concepteurs de langages ou de machines virtuelles.
• Pourquoi ne pas utiliser Solidity ? Solidity est un pionnier admiré, mais il souffre de nombreux travers hérités de la EVM. Il manque des fonctionnalités courantes attendues par les programmeurs, son système de types est peu expressif, et son écosystème d’outils n’est pas unifié. Avec Sway, nous permettons de concevoir des contrats intelligents avec une suite complète d’outils modernes. Vous obtenez un langage complet, avec génériques, types algébriques et polymorphisme basé sur des traits. Vous avez aussi une chaîne d’outils intégrée, unifiée et facile à utiliser, incluant serveur LSP pour complétion, formateur, générateur de documentation, et tout ce qu’il faut pour exécuter et déployer vos contrats, facilitant ainsi votre travail. Notre système de types expressif vous aide à détecter les erreurs sémantiques, nous fournissons de bons paramètres par défaut, et effectuons une analyse statique poussée (vérifications obligatoires, effets, interactions) vous permettant d’écrire du code sûr et correct dès la compilation via java.lang.Integer.pattern.
via https://docs.fuel.network/docs/sway/
• Pourquoi ne pas utiliser Rust ? Bien que Rust soit un excellent langage de programmation système (Sway lui-même est écrit en Rust), il n’est pas adapté au développement de contrats intelligents. Rust excelle grâce à ses abstractions sans coût et à son modèle de mémoire complexe de gestion des emprunts, permettant des performances impressionnantes au runtime pour des programmes complexes sans ramasse-miettes. Sur blockchain, le coût d’exécution et de déploiement est une ressource rare. Utilisation mémoire faible, temps d’exécution court. La gestion complexe de la mémoire devient alors souvent trop coûteuse, et le vérificateur d’emprunt de Rust devient un fardeau sans bénéfice. Les langages de programmation généraux ne conviennent généralement pas à cet environnement, car leur conception suppose une exécution dans un contexte de calcul général. Sway cherche à offrir aux développeurs de contrats tous les autres avantages de Rust — système de types moderne, méthodes sûres, bons paramètres par défaut — via une syntaxe familière et des fonctionnalités adaptées aux besoins spécifiques de la blockchain.
via https://docs.fuel.network/docs/sway/
• Le code Clarity est interprété et exécuté exactement comme écrit. Solidity et d’autres langages sont compilés en bytecode avant d’être envoyés sur la chaîne. Compiler un langage de contrat comporte deux dangers : d’abord, le compilateur ajoute une couche de complexité. Une erreur dans le compilateur pourrait produire un bytecode différent du code source, introduisant potentiellement des vulnérabilités. Ensuite, le bytecode n’est pas lisible par l’humain, rendant difficile la vérification de ce que fait réellement un contrat intelligent. Posez-vous la question : signeriez-vous un contrat que vous ne pouvez pas lire ? Si la réponse est non, pourquoi serait-ce différent pour un contrat intelligent ? Avec Clarity, ce que vous voyez est ce que vous obtenez.
via https://docs.stacks.co/concepts/clarity#clarity-is-interpreted-not-compiled
Machine virtuelle et jeu d’instructions
De la JVM bien connue à la EVM, les machines virtuelles ont eu un essor heuristique dans le domaine blockchain. À ma connaissance, il existe des dizaines de VM différentes, chacune implémentée différemment. L’interpréteur, composant central, reste souvent le moyen d’exécution de base, notamment en dehors des techniques de compilation Just-In-Time (JIT) ou Ahead-Of-Time (AOT). L’interpréteur est responsable de l’analyse et de l’exécution du bytecode.
Exemple d’interpréteur
Voici un petit exemple illustrant un interpréteur fondamental, sans mécanisme d’optimisation.
use std::collections::VecDeque; #[derive(Debug, Clone, Copy)] enum OpCode {Push(i32), Add, Sub, Mul, Div, Print} struct Interpreter { stack: Vec<i32>, } impl Interpreter { fn new() -> Self { Interpreter { stack: Vec::new() } } fn run(&mut self, bytecode: VecDeque<OpCode>) { for op in bytecode { match op { OpCode::Push(value) => self.stack.push(value), OpCode::Add => self.binary_op(|a, b| a + b), OpCode::Sub => self.binary_op(|a, b| a - b), OpCode::Mul => self.binary\_op(|a, b| a * b), OpCode::Div => self.binary\_op(|a, b| a / b), OpCode::Print => { if let Some(value) = self.stack.last() { println!("{}", value); } } } } }fn binary_op(&mut self, op: fn(i32, i32) -> i32) { if self.stack.len() < 2 { panic!("Stack underflow!"); } let b = self.stack.pop().unwrap(); let a = self.stack.pop().unwrap(); self.stack.push(op(a, b)); }} fn main() { let bytecode = VecDeque::from(vec!\[ OpCode::Push(10), OpCode::Push(20), OpCode::Add, OpCode::Push(5), OpCode::Mul, OpCode::Print, ]); let mut interpreter = Interpreter::new(); interpreter.run(bytecode); }
Chaque instruction est constituée d’un opcode (code opération), éventuellement suivi de paramètres. L’interpréteur utilise une pile (stack) pour stocker les données de calcul, avec seulement 6 instructions.
Classification des jeux d’instructions
À partir de cet exemple, le nombre et l’extensibilité des instructions déterminent largement l’orientation d’une machine virtuelle. Selon mon analyse, les VM peuvent être classées selon leur jeu d’instructions en quatre catégories principales :
1. Jeu d’instructions maison comme EVM, entraînant de nombreux travaux redondants (conception du compilateur, jeu d’instructions…). Avant l’EIP-3855[29], EVM avait déjà 141 instructions, et continue d’en ajouter.
2. WASM, prêt à l’emploi, supportant plusieurs langages, mais relativement lourd. Le document Polkadot mentionne aussi ce point. Je pense que l’avantage de WASM réside dans son support natif multi-langage. Si une chaîne veut juste exécuter une logique simple, enregistrer brutalement l’état dans un slot de storage, c’est approprié. Développement rapide, intégration rapide. Mais son inconvénient est que ses instructions ne sont pas spécialement conçues pour la blockchain, et il est difficile de les adapter ou de les réduire (plus de 150 instructions[30]).
Citons aussi SVM de Solana, exécutant des instructions BPF, compilables depuis n’importe quel langage via bibliothèques dynamiques. Moins courant que WASM.
3. Basé sur RISC-V, comme PolkaVM et de nombreux zkVM actuels : ceno, eigen zkvm, jolt, mozak vm, nexus, o1vm, openvm, powdrVM, risc0, sp1, sphinx, etc. Je n’ai pas encore étudié tous, mais concernant PolkaVM et Nexus zkVM, ils implémentent une interprétation RISC-V universelle. La plupart des langages, après compilation via GCC ou LLVM, peuvent produire du code RISC-V, ouvrant ainsi la porte à un support multi-langage futur. L’ensemble de base RV32I compte 47 instructions, extensible, comparé aux 3000+ de x86, vraiment minimaliste.
4. Interprété, comme Clarity (Lisp) de Stacks, Lua d’AO, Typescript de Mina. En somme, si d’un côté EVM représente des instructions propriétaires, et de l’autre WASM symbolise l’ouverture, RISC-V apparaît comme un bon compromis pour un développement secondaire. D’abord, de nombreux compilateurs supportent déjà cet ensemble d’instructions, avec de nombreuses implémentations de référence. Ensuite, il est facile d’y ajouter des instructions personnalisées.
Supplément : Explorer l’avenir des contrats intelligents multichaînes
Avec la diversification de l’écosystème blockchain, de plus en plus de projets lancent leur propre langage de contrat intelligent pour des fonctionnalités uniques (Solidity, Move, Cairo, Sway, etc.). Cette innovation enrichit la pile technologique, mais crée aussi de nouveaux coûts d’apprentissage et des défis de compatibilité. Une question centrale émerge progressivement : Peut-on déployer sans friction des contrats Solidity matures sur de nouvelles blockchains ?
Pour y répondre, nous avons lancé conjointement avec plusieurs chercheurs passionnés par les technologies de compilation le projet de compilateur Hummanta. Ce projet vise à briser les barrières inter-chaînes, permettant la compilation croisée de langages de contrats intelligents, en supportant la conversion de Solidity, Move, Cairo, Sway vers divers environnements de machines virtuelles, notamment : EVM et nouvelles VM : PolkaVM, SolanaVM, MoveVM, FuelVM, etc.

État actuel du projet
Nous progressons selon trois axes :
1. Standardisation syntaxique et du jeu d’instructions : Recensement systématique des définitions syntaxiques des langages et des jeux d’instructions des VM, posant les bases de la compilation croisée.
2. Développement de la chaîne d’outils compilateur : Construction d’un parseur basé sur LALRPOP[31], utilisation de Cranelift[32]/LLVM pour la génération de code, supportant la transformation multi-langage vers multi-bytecode cible.
3. Expérience de développement intégrée : Développement de l’outil CLI Hummanta[33] (similaire à Cargo), offrant un support complet du processus de compilation à déploiement
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












