À des fins éducatives uniquement ; ne constitue ni un conseil en investissement ni une recommandation d’investissement. Les investissements peuvent entraîner des pertes.
Réponse directe
Les calldata sont la séquence immuable d’octets fournie en entrée d’une transaction Ethereum de premier niveau ou d’un appel interne. Un appel conventionnel de fonction Solidity commence par un sélecteur de 4-byte, suivi d’arguments encodés selon l’ABI. Les calldata ne sont toutefois pas autodescriptives : les mêmes octets peuvent avoir un sens différent selon le code d’exécution, l’implémentation du proxy ou le schéma. Les fonctions fallback, l’assemblage brut et les protocoles étrangers à Solidity ne sont pas tenus de suivre l’ABI conventionnelle des fonctions.
Un wallet doit donc afficher davantage qu’un nom de fonction potentiel. Une vérification sûre relie les octets à chainId, un bloc, from, to, le value natif, le codeHash d’exécution, l’implémentation active et une ABI fiable ; décode strictement chaque appel imbriqué ; distingue les calldata on-chain des signatures EIP-712 ; simule dans un état explicite ; puis rapproche le reçu et les modifications d’état effectives après l’inclusion.
La réalisation de cet examen ne prouve pas qu'un actif, une transaction ou un système est sûr.
Fonctionnement
- Fixez l’enveloppe de signature et le point d’observation :
chainId, numéro et hash du bloc,from,to,valuenatif, octets d’entrée, nonce et champs de frais. Conservez la source du wallet ou du RPC ; une charge décodée sur un autre réseau ou bloc ne représente pas la même affirmation. - Classez l’objet avant de le décoder. Une transaction, une demande de données typées EIP-712, un permit ERC-2612, une UserOperation ERC-4337 et un message personal-sign brut utilisent des domaines et schémas distincts ; ne les forcez pas tous à passer par l’ABI des transactions.
- Résolvez la cible au bloc fixé. Lisez le bytecode d’exécution et le
codeHash; identifiez le proxy, beacon ou l’implémentation le cas échéant ; consignez les slots d’implémentation et d’administration ; puis obtenez une ABI correspondant à cette version exacte du code. Un registre de sélecteurs fournit des candidats, pas une autorité. - Décodez strictement. Le sélecteur correspond aux premiers
4 bytesdu Keccak-256 de la signature canonique de la fonction, sans les types de retour. Les valeurs statiques occupent des mots de32-byte; les en-têtes dynamiques contiennent des offsets mesurés depuis le bloc d’arguments après le sélecteur. Rejetez les données tronquées, offsets hors limites, longueurs impossibles, padding invalide et octets finaux inexpliqués. - Développez récursivement les multicalls, calldata imbriquées et exécutions déléguées. Pour chaque appel enfant, énumérez la cible, la valeur native, le sélecteur, les arguments, le type d’appel et tout indicateur
allowFailure. Avecdelegatecall, le code de l’implémentation s’exécute dans le contexte d’adresse, de solde et de stockage de l’appelant, tout en conservantmsg.senderetmsg.value. - Établissez des registres distincts d’autorité et de valeur, puis simulez. Consignez destinataires, spenders, opérateurs NFT, unités brutes des jetons, décimales, échéances, limites de slippage et valeur native. Simulez avec le bloc, l’expéditeur et la valeur exacts, mais considérez le résultat comme un instantané conditionnel, car l’état, les prix, le temps, le code et l’ordre des transactions peuvent changer.
- Confirmez chaque champ important avant de signer. Après l’inclusion, examinez le statut du reçu, les logs, les traces disponibles et les variations de soldes, allowances et états d’opérateurs ; distinguez les échecs enfants interceptés du succès au premier niveau ; comptabilisez le gas même lors d’un revert ; attendez la finalité requise ; puis arrêtez-vous plutôt que de signer à nouveau sans comprendre l’échec.
Exemples détaillés
- Transfert ERC-20 statique.
transfer(address,uint256)utilise couramment le sélecteur0xa9059cbb. Un sélecteur et deux mots ABI représentent4 + 2 * 32 = 68 bytes. Un montant brut de1,500,000pour un jeton dont l’emploi de6 decimalsa été vérifié indépendamment s’affiche comme1.5 tokens. Les décimales sont des métadonnées externes du contrat, non encodées dans ces arguments, et le sélecteur seul n’identifie pas de manière unique le contrat ou la fonction. - Offset d’octets dynamiques. Pour
f(address,bytes)avec une charge de3-byte, l’en-tête de deux mots occupe64 bytes. L’offset dynamique vaut0x40, mesuré depuis le début du bloc d’arguments sans inclure le sélecteur. Sa partie finale contient un mot de longueur de32-byteet un mot de données complété à32-byte, portant les calldata totales à4 + 64 + 32 + 32 = 132 bytes. Considérer l’offset comme absolu depuis l’octet zéro décale la cible de quatre octets. - La valeur d’un lot dépend de l’implémentation. Un appel externe transporte
1.00 ETH; trois appels enfants décodés demandent explicitement0.20 ETH,0.30 ETHet0.10 ETH, soit0.60 ETH. Les0.40 ETHrestants peuvent être remboursés, conservés, transférés ou provoquer un revert selon le code du lot. Si le troisième appel échoue avecallowFailure=true, les appels antérieurs peuvent rester validés ; une implémentation atomique peut au contraire tout annuler. - Un permit n’est pas la calldata du relayer au moment de la signature. Un propriétaire disposant de
1,000 USDCsigne un permit ERC-2612 de300 USDCau nonce41. La signature seule ne modifie ni le solde ni l’allowance. Après sa soumission réussie par un relayer, le nonce passe à42et l’allowance à300; lorsque le spender utilise180, le solde est de820et l’allowance restante de120. Déconnecter le site ne révoque pas cette permission.
Risques
- Décoder avec le mauvais réseau, fork, block tag ou enveloppe de transaction.
- Signer pour un domaine, une adresse cible ou un destinataire usurpés.
- Considérer un sélecteur de
4-bytecomme unique malgré les collisions possibles. - Utiliser une ABI supposée, obsolète ou mal vérifiée.
- Faire confiance à une mention de source vérifiée sans la rapprocher du
codeHashactuel. - Manquer une mise à niveau de l’implémentation, du beacon ou de l’administrateur entre vérification et exécution.
- Ignorer une fonction de proxy dont le sélecteur entre en collision avec celui de l’implémentation.
- Oublier que
delegatecallécrit dans le contexte de stockage de l’appelant. - Accepter des offsets, longueurs, padding ou octets finaux dynamiques mal formés.
- Ne pas développer un lot imbriqué qui dissimule des cibles, valeurs ou permissions.
- Supposer l’atomicité alors que l’implémentation intercepte ou autorise les échecs enfants.
- Ignorer le
valuenatif de premier niveau parce que les arguments de jeton semblent inoffensifs. - Appliquer des décimales erronées ou supposer que les jetons fee-on-transfer et rebasing sont des ERC-20 standard.
- Accorder une allowance ERC-20 illimitée ou mal gérer la condition de concurrence lors de sa modification.
- Négliger la portée sur toute la collection de
setApprovalForAllpour les NFT. - Confondre des données typées EIP-712 ou un permit ERC-2612 avec les calldata d’une transaction.
- Omettre le nonce, l’échéance, le contrat de vérification, le domaine de réseau ou les limites de replay.
- Considérer une simulation comme stable malgré les changements d’oracle, de timestamp, d’état en attente, de MEV ou de code.
- Considérer le statut du reçu, les logs ou les traces du fournisseur comme une preuve exhaustive de l’état économique.
- Signer à nouveau à l’aveugle par une UI compromise ou ignorer les risques d’inclusion, de réorganisation et de finalité.
Idées reçues
- Un sélecteur de fonction identifie de manière unique ce que le contrat exécutera.
- Un résumé vérifié du frontend correspond exactement aux octets et à l’implémentation actuelle signés.
- Une transaction avec
value=0ne peut déplacer ni jetons, ni NFT, ni actifs délégués. - Une simulation ou un reçu réussis prouvent la sécurité et le résultat économique attendu.
- Déconnecter une dapp révoque les approbations, permits et permissions des opérateurs NFT.
Sujets connexes
Sources
- Contract ABI Specification - Solidity Documentation (consulté le : 2026-08-12)
- Introduction to Smart Contracts - Solidity Documentation (consulté le : 2026-08-12)
- Transactions - Ethereum.org (consulté le : 2026-08-12)
- ERC-20: Token Standard - Ethereum Improvement Proposals (consulté le : 2026-08-12)
- EIP-712: Typed structured data hashing and signing - Ethereum Improvement Proposals (consulté le : 2026-08-12)
- ERC-2612: Permit Extension for EIP-20 Signed Approvals - Ethereum Improvement Proposals (consulté le : 2026-08-12)
- ERC-721: Non-Fungible Token Standard - Ethereum Improvement Proposals (consulté le : 2026-08-12)
- ERC-1967: Proxy Storage Slots - Ethereum Improvement Proposals (consulté le : 2026-08-12)