Qu’est-ce que l’EVM ?
L’Ethereum Virtual Machine (EVM), la machine virtuelle Ethereum, est un ensemble de règles communes pour exécuter des contrats intelligents. Les nœuds Ethereum implémentent ces règles dans leur propre logiciel, calculent à partir des mêmes transactions et du même état initial, et obtiennent ainsi un résultat que d’autres nœuds peuvent recontrôler.
L’EVM n’est pas un serveur physique particulier, ni l’application unique qu’un développeur voit sur son ordinateur. Elle ressemble davantage à une notice de calcul précise : quelles opérations de base le code peut exécuter, où les données sont placées, combien de ressources de calcul chaque opération consomme, et comment l’état de la blockchain est mis à jour en cas de succès ou d’échec de l’exécution.
Du code source au bytecode exécutable
Les développeurs écrivent généralement leurs contrats dans un langage de haut niveau comme Solidity. Le code source lisible par un humain doit être converti par un compilateur en bytecode exécutable par l’EVM, c’est-à-dire une suite d’instructions machine disposées selon un format fixe.
Lors du déploiement d’un contrat, la transaction de création contient le code servant à le générer. Après une exécution réussie, le réseau établit une adresse pour le contrat et conserve le bytecode à exécuter lors des appels ultérieurs. Le code d’exécution d’un contrat déployé n’est pas la même représentation que les fichiers sources du développeur : un code source publié doit donc encore être recoupé avec le bytecode en chaîne avant de pouvoir affirmer que les deux correspondent.
La version et les réglages du compilateur peuvent influer sur le bytecode final. Deux fichiers sources d’apparence proche peuvent produire des résultats différents ; voir le même nom de contrat remplace encore moins la vérification du réseau et de l’adresse du contrat.
L’appel fournit au contrat ses données d’exécution
Lorsqu’un utilisateur appelle un contrat, il envoie à l’adresse du contrat une transaction porteuse de données. Ces données indiquent généralement quelle fonction appeler et joignent les paramètres dans un format convenu. Un contrat peut aussi appeler un autre contrat pendant l’exécution, en transmettant plus loin des valeurs ou des données.
L’EVM part de l’état actuel de la blockchain, lit l’appelant, la cible, la valeur éventuellement joint, les données d’entrée et les informations que le bloc courant autorise à utiliser, puis exécute instruction par instruction le bytecode du contrat ciblé. Chaque instruction modifie, selon les règles, les données temporaires de ce calcul, ou demande à lire ou écrire l’état persistant du contrat.
Un contrat ne se lance pas de lui-même simplement parce qu’une échéance est arrivée. Il faut qu’une transaction ou l’appel d’un autre contrat forme un point d’entrée d’exécution ; une « exécution automatique » affichée sur une page web exige généralement encore qu’un service externe soumette une transaction lorsque les conditions sont remplies.
Les opcodes sont les actions de base du bytecode
Le bytecode EVM est composé d’opcodes successifs. Un opcode peut se comprendre comme la plus petite action que la machine virtuelle reconnaît : par exemple faire de l’arithmétique, comparer des valeurs, lire des données d’appel, lire ou écrire le stockage, et appeler d’autres contrats.
Les différents opcodes ont des règles définies d’entrée, de sortie et de consommation de gas. Un nœud n’a pas besoin de comprendre les noms métier d’un contrat : exécuter dans l’ordre des opcodes suffit à contrôler si le résultat fourni par un autre nœud est conforme au protocole.
Une seule ligne d’un langage de haut niveau peut être compilée en plusieurs opcodes. Inversement, regarder un opcode isolé ne permet pas de saisir une intention métier complète ; l’examen d’un contrat suppose donc généralement de combiner code source, réglages de compilation, données d’appel et adresse de déploiement réelle.
Données temporaires et état persistant
Les données employées pendant l’exécution ne sont pas toutes inscrites durablement dans la blockchain. Il convient d’abord de distinguer trois emplacements :
- les données d’appel sont l’entrée en lecture seule apportée par cet appel ;
- la mémoire est un espace de travail temporaire utilisé pendant cette exécution et n’est pas conservée après ;
- le stockage appartient à un contrat précis et, une fois écrit avec succès, devient une partie de l’état de la blockchain que des appels ultérieurs pourront lire.
L’EVM emploie en outre une structure de calcul temporaire du type dernier entré, premier sorti, appelée pile. Les opcodes prennent des valeurs au sommet de la pile et y replacent le résultat après calcul. Un lecteur non spécialiste n’a pas à suivre chaque étape à la main, mais doit savoir qu’« un changement en mémoire » et « le stockage du contrat a changé » ne sont pas la même chose.
Écrire dans le stockage persistant consomme généralement plus de gas qu’un simple calcul temporaire. Supprimer ou modifier le stockage est également encadré par les règles du protocole : l’état en chaîne n’est pas un fichier local qu’un programme ordinaire pourrait écraser à volonté.
Les changements d’état doivent pouvoir être recalculés
Les transactions d’un même bloc ont un ordre déterminé. En partant du même état d’avant-bloc et en exécutant dans l’ordre les mêmes transactions, les nœuds devraient obtenir le même état d’après-bloc ; sinon, ils ne peuvent pas s’accorder sur un registre commun.
Un contrat EVM ne peut donc pas, lors de l’exécution, accéder directement à n’importe quelle page web, à l’heure d’un appareil ou au résultat aléatoire d’un serveur. Lorsqu’un prix, une donnée météorologique ou une autre information hors chaîne est nécessaire, un participant externe doit d’abord amener cette donnée en chaîne sous forme de transaction. L’EVM peut contrôler comment le code utilise cette entrée, mais ne peut pas prouver automatiquement que le fait hors chaîne correspondant soit véridique.
Les informations fournies par le bloc, comme l’heure ou le numéro de bloc, proviennent aussi de l’environnement d’exécution défini par le protocole. Les développeurs peuvent les lire selon les règles, mais ne doivent pas prendre ces valeurs pour une horloge externe précise ou une source secrète d’aléatoire échappant au processus de proposition de blocs.
Le gas limite la charge de travail de chaque exécution
Chaque opération de l’EVM consomme une certaine quantité de gas. Le gas est une unité de mesure du travail de calcul et de stockage, pas un token distinct ; sur le réseau principal Ethereum, les frais d’exécution réels sont généralement payés avec l’actif natif du réseau, ETH.
L’expéditeur d’une transaction fixe le gas maximal que celle-ci peut consommer. À l’exécution, l’EVM cumule le gas selon les opérations réellement effectuées ; si le gas restant ne suffit pas à accomplir l’étape suivante, l’exécution échoue par épuisement du gas.
Le gas empêche des boucles infinies ou des appels anormalement complexes d’occuper sans coût les ressources de calcul de tous les nœuds. Il implique aussi qu’une même fonction puisse consommer des quantités différentes selon l’entrée, l’état courant et le chemin d’exécution. Une transaction d’un montant élevé n’exécute pas nécessairement plus de code qu’une transaction d’un faible montant.
Succès, annulation et échec
Un contrat peut se terminer normalement en renvoyant des données, s’annuler volontairement, ou échouer en raison d’une opération invalide, d’un épuisement du gas ou d’une autre cause. En cas d’échec, les modifications d’état non encore validées sur ce chemin d’appel sont annulées selon les règles, mais les ressources de calcul déjà consommées par la transaction peuvent tout de même engendrer des frais.
Une transaction peut déclencher plusieurs niveaux d’appels de contrats. Si un appel interne échoue, le contrat externe peut, selon son code, choisir de continuer à traiter le résultat renvoyé, ou faire annuler toute la transaction. « Une étape interne a échoué » et « la transaction a finalement échoué » doivent donc être appréciés en tenant compte des résultats d’appel.
Une annulation d’état ne supprime pas non plus le fait qu’une transaction a été incluse dans un bloc. Un explorateur de blocs peut afficher une transaction échouée et le gas consommé ; seules les modifications d’état attendues du contrat n’ont pas pris effet.
Lire des résultats et soumettre des transactions
Un portefeuille ou une application peut faire simuler localement par un nœud une requête en lecture seule et en renvoyer immédiatement le résultat. Ce type de lecture ne fait pas l’objet d’un nouveau consensus de l’ensemble du réseau et ne modifie pas l’état en chaîne ; il n’exige généralement pas que l’utilisateur signe et paie des frais en chaîne.
Une opération devant changer l’état doit en revanche former une transaction, être signée par un compte et diffusée, puis être exécutée conjointement par les nœuds une fois entrée dans un bloc. Une simulation avant soumission peut aider à repérer des échecs évidents, mais le résultat final peut encore dépendre de l’ordonnancement des transactions, des changements d’état, des réglages de gas et du réseau sélectionné.
Une interface d’application affichant « succès prévu » n’équivaut donc pas à une transaction déjà confirmée. Le résultat réel en chaîne exige de consulter, sur le bon réseau, l’état de la transaction, le résultat d’exécution et l’état du contrat.
L’EVM et Ethereum ne sont pas le même concept
L’EVM ne décrit qu’une partie des règles d’exécution des contrats intelligents et de transition d’état. Ethereum comprend aussi les formats de comptes et de transactions, la propagation des blocs, le consensus par preuve d’enjeu, la communication réseau et d’autres composants du protocole.
D’autres blockchains peuvent également implémenter l’EVM ou un environnement d’exécution très proche, afin de réutiliser outils de contrats et bytecode. On les appelle généralement réseaux compatibles EVM, mais elles conservent un historique de blocs, des dispositions de validation, un actif de frais et une frontière de sécurité qui leur sont propres.
Ainsi, « pouvoir exécuter des contrats EVM » n’indique pas qu’il s’agit d’Ethereum, et ne garantit pas que la même adresse héberge le même code sur des réseaux différents. Pour utiliser une application sur plusieurs réseaux, il faut encore vérifier le réseau et son numéro de réseau, l’adresse du contrat et le bytecode réel.
L’exécution commune n’équivaut pas à la sûreté d’un contrat
Les règles déterministes de l’EVM permettent aux nœuds de recontrôler si un contrat s’est exécuté conformément à son code, mais pas de juger si ce code correspond au résultat métier réellement voulu par l’utilisateur. Des droits erronés, un contrat externe rappelant de façon répétée avant la fin d’une opération précédente, des problèmes d’entrée de prix, un contrôle de mise à niveau ou une interface trompeuse peuvent chacun faire qu’une transaction pleinement conforme aux règles de l’EVM produise une conséquence imprévue.
Une compilation réussie, une exécution réussie en chaîne ou un code source publié ne remplacent pas davantage, chacun de leur côté, un audit de sécurité. Juger un contrat précis exige de combiner le bytecode déployé, l’état d’initialisation, les droits d’administration, les dépendances externes et le chemin d’appel réel.
FAQ
L’EVM est-elle un serveur cloud ?
Non. C’est un ensemble de règles d’exécution implémentées conjointement par les logiciels de nœuds, qui ne correspond à aucune machine fixe particulière.
Le code Solidity est-il exécuté directement par l’EVM ?
Généralement non. Le code source Solidity est d’abord converti par un compilateur en bytecode EVM, et les nœuds exécutent le bytecode déployé.
Lire un contrat exige-t-il toujours de payer des frais de gas ?
Une requête locale en lecture seule ne forme généralement pas de transaction en chaîne et n’engendre donc pas directement de frais en chaîne. Si la lecture fait partie de l’exécution d’une autre transaction inscrite en chaîne, les opérations correspondantes comptent tout de même dans le gas de cette transaction.
L’EVM peut-elle lire directement des données d’internet ?
Non. Les données externes doivent être amenées en chaîne par un participant ou un service au moyen d’une transaction ; l’EVM ne peut que traiter, selon les règles, une entrée déjà fournie.
La compatibilité EVM signifie-t-elle qu’un contrat migre sans modification ?
Rien ne le garantit. Degré de compatibilité, version de protocole, opcodes disponibles, règles de frais, contrats système et dépendances externes peuvent différer : une vérification et des tests sur le réseau cible restent nécessaires.
Concepts associés
Poursuis avec Ethereum, contrat intelligent, frais de gas et blockchain, ou reviens au glossaire des cryptomonnaies.
Sources
- Ethereum.org : Ethereum Virtual Machine — l’EVM, les transitions d’état, l’environnement d’exécution, la pile, la mémoire et le stockage.
- Ethereum.org : structure d’un contrat intelligent — code source, compilation, code déployé et structure des appels de contrats.
- Ethereum.org : opcodes de l’EVM — opcodes, paramètres et règles de gas.
- Ethereum.org : gas et frais — mesure du gas, plafond de gas, frais d’exécution et conséquence d’un épuisement du gas.




