Une déclaration d’événement Solidity définit un format nommé permettant d’enregistrer des arguments. Un log est un enregistrement particulier produit par le mécanisme de journalisation de la machine virtuelle Ethereum, ou EVM. Comprendre la différence entre logs et événements Ethereum suppose de distinguer cette définition d’une émission précise, puis les octets enregistrés de l’interprétation qu’on leur attribue.
Cette distinction devient utile lorsqu’un explorateur affiche un nom d’événement lisible à côté de topics et de données hexadécimales. Le nom, les champs décodés et l’enregistrement brut répondent à des questions différentes. Pour interpréter cet affichage, il faut disposer du schéma de l’événement et du contexte pertinent.
1. La déclaration d’événement définit le format
Les événements Solidity constituent une abstraction du mécanisme de journalisation de l’EVM. Émettre un événement entraîne l’enregistrement de ses arguments dans la structure de logs de la transaction. Une déclaration décrit ce qui peut être émis ; elle ne prouve pas qu’une émission particulière a eu lieu. La documentation Solidity sur les contrats explique cette relation et les informations nécessaires pour interpréter les données d’un événement.
Par exemple, une déclaration peut nommer un événement Reading et lui attribuer deux arguments de type entier non signé. Cela définit un format dans le programme hypothétique. Pour parler d’une occurrence précise, il faudrait disposer d’un enregistrement effectivement émis.
2. Lire séparément l’émetteur, les topics et les données
Trois éléments structurent le log :
- L’émetteur : le champ
addressindique l’adresse à l’origine du log. - Les topics : un tableau contenant de zéro à quatre entrées de 32 octets chacune.
- Les données : selon l’encodage des événements Solidity, le champ
datacontient les arguments non indexés, encodés selon l’ABI.
Le champ de l’émetteur répond à une question de provenance. Sa seule présence ne suffit pas à identifier l’expéditeur de la transaction ou un destinataire économique. Attribuer ces rôles demanderait un contexte supplémentaire.
La documentation JSON-RPC d’Ethereum définit ces champs et présente un exemple de log produit par l’EVM, puis inclus dans un reçu de transaction. Cet exemple montre où un log peut apparaître ; il ne démontre pas que chaque transaction en produit un. Le reçu rassemble les informations relatives à la transaction, tandis que le log constitue ici l’élément particulier à interpréter.
Pour comprendre le rôle des logiciels qui fournissent ces informations par RPC, consultez notre présentation des nœuds et clients Ethereum.
3. Les topics suivent les règles d’encodage de l’événement
Pour un événement non anonyme respectant la convention ABI de Solidity, topics[0] contient le hachage Keccak du nom de l’événement et de la liste des types canoniques de ses paramètres. Pour un événement nommé Reading comportant deux paramètres uint256, le texte de cette signature est Reading(uint256,uint256). Les noms des paramètres et le marqueur indexed n’entrent pas dans cette formule.
Les événements anonymes omettent ce topic de signature. Il ne faut donc pas considérer automatiquement le premier topic comme un identifiant d’événement sans déterminer quelle convention s’applique.
Un argument uint256 indexé est représenté directement dans son topic par une valeur ABI de 32 octets. Cette règle ne s’étend pas à tous les types. Les tableaux indexés, y compris ceux de taille fixe, les chaînes, le type dynamique bytes et les structures utilisent plutôt le hachage Keccak d’un encodage particulier. Il faut notamment distinguer bytes des types d’octets de taille fixe.
Comme l’explique la spécification ABI de Solidity, cette représentation hachée permet de rechercher une valeur candidate connue. En revanche, elle ne permet pas à une application de décoder une valeur d’origine inconnue à partir de ce seul topic. Des informations obtenues séparément peuvent aider, mais elles constituent alors des éléments supplémentaires.
4. L’ABI fournit le contexte de décodage
Un décodage correct exige de connaître les types de l’événement, les paramètres indexés et son caractère anonyme ou non. Une ABI, ou un schéma équivalent, fournit ce contexte. Le log brut ne conserve pas une description complète du type de l’événement à côté des valeurs.
Cette distinction compte même lorsqu’un outil affiche des noms de champs plausibles. Le schéma fourni indique à l’outil comment interpréter les octets. On en déduit qu’un décodage réussi selon ce schéma ne vérifie pas, à lui seul, que celui-ci correspond bien à l’enregistrement examiné : les données enregistrées et les informations de type fournies séparément restent deux éléments distincts.
La correspondance d’une signature a une autre limite : Solidity précise qu’un événement anonyme peut imiter le topic de signature d’un autre événement. On en déduit qu’un topic correspondant ne suffit pas à authentifier la déclaration supposée. Cela ne signifie pas que l’adresse émettrice a été falsifiée ; la provenance et l’interprétation des topics restent des questions séparées.
5. Décoder prudemment un exemple hypothétique
Exemple entièrement hypothétique : supposons qu’un contrat inventé émette un événement non anonyme déclaré ainsi : event Reading(uint256 indexed sensor, uint256 value);, avec les arguments (7, 42). Supposons également que le log respecte l’encodage ABI Solidity de cette déclaration. Il s’agit d’un exercice pédagogique, pas d’une transaction observée.
À partir de ces hypothèses et des règles d’encodage documentées, on obtient l’interprétation suivante :
addressindique l’adresse du contrat émetteur supposé, laissée indéterminée dans cet exemple.topics[0]contient le hachage Keccak deReading(uint256,uint256).topics[1]encode l’argument indexésensor, dont la valeur est l’entier non signé 7.dataencode l’unique argument non indexévalue, dont la valeur est l’entier non signé 42.
Le placement des deux arguments est une déduction fondée sur la déclaration supposée : la signature occupe le premier topic, l’argument indexé occupe le suivant et l’argument non indexé figure dans les données.
L’encodage ABI standard des entiers non signés place les octets de poids fort en premier, selon l’ordre big-endian, et complète à gauche avec des octets nuls jusqu’à atteindre 32 octets. Le mot hypothétique représentant le capteur se termine donc par 07, et celui des données par 2a, représentation hexadécimale de 42. Les octets précédents sont nuls.
Que permet d’établir le nombre 42 ?
Selon le schéma supposé, il s’agit de la valeur décodée de l’argument. Aucune unité physique, unité monétaire ou opération de paiement n’a été définie. On en déduit que ce log hypothétique, pris isolément, ne permet pas d’établir qu’un paiement de 42 a eu lieu.
Cette limite ne signifie pas que les logs ne peuvent jamais contribuer à démontrer une activité économique. Une interprétation plus poussée demanderait d’examiner le comportement pertinent du contrat et le contexte d’exécution. Notre article sur la vérification d’une transaction Ethereum développe la distinction entre résultat d’exécution et résultat attendu. Ici, décoder un argument et prouver une conséquence économique restent deux étapes distinctes.
6. Une liste de contrôle pour lire un log
- Distinguer définition et occurrence. Examinez-vous une déclaration d’événement ou un enregistrement particulier ?
- Identifier l’émetteur. Lisez l’adresse comme l’origine du log, sans lui attribuer d’autres rôles.
- Établir le schéma. Relevez les types, les paramètres indexés et le caractère anonyme ou non.
- Vérifier l’interprétation des topics. Déterminez si un topic de signature est attendu et si les arguments sont représentés par des valeurs directes ou des hachages.
- Expliciter les hypothèses de décodage. Distinguez les octets bruts des noms de champs et des valeurs issus du schéma.
- Limiter la conclusion. Précisez ce que les éléments disponibles établissent et laissez ouvertes les questions d’unité ou de résultat non documentées.
Ces vérifications peuvent servir d’exercice de lecture à partir de documentation et d’exemples. L’attribution aux sources étaye l’explication technique ; elle ne certifie pas la sécurité d’un contrat particulier et ne prouve pas un résultat économique.
Article pédagogique préparé avec l’assistance d’une IA. Il explique l’interprétation des enregistrements et ne recommande ni transaction ni signature avec un portefeuille.