Chaque token, chaque collection NFT, chaque marché de prêt et chaque bridge sur Ethereum est un smart contract : du bytecode stocké à une adresse et exécuté par chaque nœud exactement tel qu’il a été écrit. Un explorateur de smart contracts Ethereum est la partie d’un explorateur de blocs qui retransforme ce bytecode en quelque chose d’inspectable. Il affiche le code source si l’auteur l’a publié, vous permet d’appeler des fonctions sans écrire une ligne de code, liste les événements émis par le contrat et vous dit qui l’a déployé.
Nul besoin d’être développeur Solidity pour en tirer profit. Savoir ce que « vérifié » veut vraiment dire, comment repérer un proxy et où trouver les clés d’administration suffit à écarter toute une catégorie de risques. Ce guide parcourt la page d’un contrat onglet par onglet, puis se termine par une routine en cinq étapes. Pour les contrôles propres aux tokens, comme la concentration des détenteurs ou les honeypots, consultez notre guide de l’explorateur de tokens, qui complète celui-ci.
Ce que signifie « code source vérifié » sur Etherscan, Sourcify et Blockscout
Une adresse de contrat ne stocke que du bytecode. N’importe qui peut prétendre qu’un fichier Solidity donné l’a produit ; la vérification est la manière dont un explorateur contrôle cette affirmation. L’auteur soumet les fichiers source, la version du compilateur, les réglages de l’optimiseur et les arguments du constructeur. L’explorateur compile le tout et compare le résultat au bytecode on-chain. S’ils correspondent, le code source est publié à côté du contrat avec une coche verte.
Etherscan distingue l’Exact Match, où le code et les arguments du constructeur fournis par l’auteur reproduisent le contrat déployé, du Similar Match, qu’Etherscan applique automatiquement lorsque le bytecode d’un nouveau contrat correspond à celui d’un contrat déjà vérifié. Les similar matches sont pratiques pour les clones déployés par une factory, mais ils ignorent les arguments du constructeur, qui peuvent pourtant changer le comportement d’un contrat. Quand les enjeux sont élevés, préférez un exact match.
Sourcify, un service de vérification open source incubé à l’origine au sein de l’Ethereum Foundation, s’appuie sur le fichier de métadonnées que le compilateur Solidity intègre sous forme de hash à la fin du bytecode. Il nomme désormais les deux résultats possibles exact match et match ; vous croiserez encore les anciens noms « full » et « partial » dans de nombreux outils. Un exact match signifie que tout, commentaires et chemins de fichiers compris, est identique à l’octet près. Un match signifie que le code exécutable est identique mais que les métadonnées diffèrent. Les deux prouvent la logique ; le changement de nom a eu lieu parce que « partial » laissait croire qu’un contrat n’était pas vérifié. Blockscout prend en charge ses propres méthodes de vérification (source aplatie, standard JSON input, plugins Hardhat et Foundry) et s’intègre à Sourcify, si bien qu’un contrat vérifié sur Sourcify peut aussi apparaître comme vérifié sur Blockscout. Notre avis sur Blockscout détaille ce point.
Utiliser les onglets Read Contract et Write Contract
Une fois un contrat vérifié, l’explorateur connaît son ABI et génère deux formulaires. Read Contract liste toutes les fonctions view et pure. Les appeler est gratuit, ne demande aucun wallet et renvoie la valeur on-chain actuelle : le totalSupply() d’un token, le owner() d’un coffre, ou si un protocole est en paused(). C’est le moyen le plus rapide de répondre à des questions factuelles sur un contrat sans faire confiance au tableau de bord de qui que ce soit.
Write Contract liste les fonctions qui modifient l’état. L’explorateur vous demande de connecter un wallet, insère les paramètres dans une vraie transaction et la transmet à votre wallet pour signature. C’est réellement utile quand le site d’un projet est en panne et que vous devez retirer vos fonds, ou quand vous voulez révoquer une autorisation sans passer par un site tiers. C’est aussi là que les erreurs arrivent : les montants sont exprimés dans la plus petite unité du token, donc 1 USDC s’écrit 1000000 et 1 WETH 1000000000000000000. Pour les non-développeurs, l’onglet Write sert davantage à lire qu’à cliquer : la liste des fonctions qui modifient l’état vous dit ce que le propriétaire et les utilisateurs peuvent faire.
L’ABI et les sélecteurs de fonctions, en termes simples
L’ABI (application binary interface) est une description JSON des fonctions et des événements d’un contrat : noms, types des paramètres et types de retour. Les explorateurs s’en servent pour décoder les transactions. Quand vous envoyez une transaction à un contrat, ses données d’entrée commencent par un sélecteur de fonction de quatre octets, soit les quatre premiers octets du hash keccak-256 de la signature de la fonction. Tout ce qui suit le sélecteur correspond aux arguments, chacun complété à 32 octets.
// Trois fonctions ERC-20 et leurs sélecteurs de 4 octets
function transfer(address to, uint256 amount) external returns (bool); // 0xa9059cbb
function approve(address spender, uint256 amount) external returns (bool); // 0x095ea7b3
function balanceOf(address account) external view returns (uint256); // 0x70a08231
// sélecteur = 4 premiers octets de keccak256("transfer(address,uint256)")
// calldata d'un transfert :
// 0xa9059cbb
// 000000000000000000000000<adresse du destinataire, 20 octets>
// <montant sous forme d'entier non signé de 32 octets>
Voilà pourquoi un explorateur peut étiqueter comme transfer la transaction d’un contrat non vérifié : il reconnaît 0xa9059cbb grâce aux bases de données publiques de signatures, même sans l’ABI du contrat. Cela explique aussi une ruse de phishing. Les sélecteurs ne font que quatre octets, si bien que des attaquants peuvent fabriquer des fonctions aux noms absurdes qui entrent en collision avec des sélecteurs familiers, ou baptiser une fonction malveillante claimRewards. Les noms décodés sont des indices ; le code source vérifié est la vérité. Notre guide de l’explorateur de transactions montre comment décoder les données d’entrée d’une vraie transaction.
Proxies : EIP-1967, UUPS et l’adresse d’implémentation
Un contrat ne peut pas être modifié après son déploiement. Les systèmes évolutifs se scindent donc en deux : un petit proxy, qui détient l’état et l’adresse avec laquelle les utilisateurs interagissent, et un contrat d’implémentation (la logique), qui contient le code. Le proxy transmet chaque appel via delegatecall. Mettre à jour le système revient à faire pointer le proxy vers une nouvelle implémentation. USDC en est un bon exemple réel : 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 est un proxy, et la logique du token réside dans un contrat d’implémentation distinct que Circle peut remplacer.
L’EIP-1967 a standardisé l’emplacement où les proxies stockent ce pointeur : l’adresse d’implémentation se trouve dans le slot de stockage 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, et l’admin dans 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103. Comme ces slots sont fixes, les explorateurs peuvent détecter les proxies et afficher des onglets « Read as Proxy » et « Write as Proxy » qui utilisent l’ABI de l’implémentation. Dans un transparent proxy, la fonction de mise à jour vit dans le proxy et seul un admin peut l’appeler. Dans un proxy UUPS (issu de l’ERC-1822), la fonction de mise à jour vit dans l’implémentation elle-même : le proxy reste léger, mais une implémentation boguée peut bloquer définitivement les mises à jour. Les beacon proxies, enfin, font pointer de nombreux proxies vers un même beacon qui désigne l’implémentation.
Pour votre contrôle de sécurité, retenez l’essentiel : quand vous lisez un proxy, vous ne lisez pas le code qui s’exécute. Cliquez jusqu’à l’implémentation, vérifiez qu’elle est vérifiée, puis cherchez qui peut appeler la mise à jour. Celui qui contrôle cette clé contrôle chaque token du contrat.
Événements, logs et bytecode
Les contrats émettent des événements pour consigner ce qui s’est passé : Transfer, Approval, OwnershipTransferred, Upgraded, Paused. Chaque événement devient un log dans le reçu de la transaction, avec jusqu’à quatre topics indexés et un champ de données. L’onglet Events de la page d’un contrat est un fil chronologique de ces logs, et pour la sécurité, c’est une mine d’or. Un événement Upgraded il y a deux jours, un nouveau RoleGranted au profit d’une adresse inconnue ou un OwnershipTransferred vers un wallet tout neuf : voilà exactement le type de changements qui précèdent les incidents.
L’onglet bytecode affiche le code déployé brut. Pour un contrat non vérifié, c’est tout ce dont vous disposez. Des outils peuvent le décompiler en pseudo-code approximatif, et nos choix open source comme Otterscan et d’autres explorateurs auto-hébergés peuvent le tracer sur votre propre nœud. Depuis la mise à jour Pectra de mai 2025, il existe un autre cas à savoir reconnaître : une adresse de wallet ordinaire dont le code, très court, commence par 0xef0100 suivi d’une adresse correspond à une délégation EIP-7702, ce qui signifie que ce compte exécute actuellement le code d’un autre contrat. Les explorateurs modernes l’étiquettent, et il mérite le même examen que n’importe quel contrat.
Créateur du contrat et transaction de création
Chaque page de contrat indique qui l’a créé et dans quelle transaction. Cette simple ligne répond à un nombre surprenant de questions. A-t-il été déployé par le déployeur connu de l’équipe, ou par une adresse alimentée depuis une plateforme d’échange une heure plus tôt ? A-t-il été créé directement ou par une factory, comme les pools Uniswap ou les wallets Safe ? Quels arguments ont été passés au constructeur ? Cliquer sur le créateur montre aussi ce que cette adresse a déployé d’autre ; un historique de tokens abandonnés relève du schéma, pas de la coïncidence. Notre guide de l’explorateur d’adresses explique comment dresser rapidement le profil d’un wallet.