Les meilleures pratiques pour écrire des contrats optimisés

Table of contents
- Le contrat qui coûtait (trop) cher
- L’EVM ne pardonne pas
- Les bonnes pratiques comme super pouvoir
- 🛠️ 1. Préfère constant et immutable quand c’est possible
- 📦 2. Optimise le storage layout pour packer les variables
- ⛓️ 3. Utilise des mappings plutôt que des tableaux dynamiques
- 📊 4. External > Public (quand il n’y a pas d’appel interne)
- 🔁 5. Réduis l’usage des boucles ou segmente-les
- 📈 6. Minimise les appels à d’autres contrats
- 🧪 7. Teste, profile et mesure avec des outils adaptés
- 🔒 8. Évite les redondances dans les vérifications de sécurité
- 🧠 9. Préfère les événements aux écritures inutiles
- 🔁 10. Refactorise les calculs redondants
- l’optimisation est une habitude

Le contrat qui coûtait (trop) cher
Imagine ceci : tu as bossé des semaines sur ton smart contract.
Tu es fier du code, le déploiement se passe bien, et… BAM 💥 la première interaction coûte 80$ de gas à un utilisateur.
Résultat ? Il ragequit, ton DApp est trop chère à utiliser, et tu viens de perdre un early adopter.
Tu creuses un peu, et tu te rends compte que des petits détails des public
inutiles, des boucles mal placées, du storage
mal rangé ont transformé ton chef-d’œuvre en aspirateur à ETH.
L’EVM ne pardonne pas
Sur Ethereum, chaque ligne, chaque action, chaque variable a un prix.
Et ce prix, c’est le gas.
Un smart contract mal optimisé, c’est comme une application mobile codée sans réfléchir à la batterie ou aux données mobiles.
Ça marche… jusqu’à ce que ça devienne inutilisable.
Les frais de gas ne sont pas juste un détail technique :
ils sont au cœur de l’expérience utilisateur, de la scalabilité, de ta crédibilité.
Les bonnes pratiques comme super pouvoir
La bonne nouvelle ?
Tu peux éviter tout ça. Et ce n’est pas sorcier.
Dans cet article, on passe en revue les meilleures pratiques pour écrire des contrats propres, économiques et puissants.
Pas pour faire joli. Mais pour :
Réduire les coûts à l’usage
Gagner la confiance des utilisateurs et des auditeurs
Être prêt pour le mainnet dès demain
Prêt à écrire des smart contracts que même Vitalik approuverait ?
C’est parti. 👇
🛠️ 1. Préfère constant
et immutable
quand c’est possible
Chaque fois que tu déclares une variable qui ne change jamais ou change une seule fois au déploiement, indique-le.
uint256 public constant MAX_SUPPLY = 10000;
address public immutable owner;
constructor() {
owner = msg.sender;
}
Pourquoi c’est mieux :
constant
etimmutable
sont stockés dans le bytecode, pas dans le storageZéro coût de lecture = moins de gas
Plus facile à auditer : tu rends ton contrat plus prévisible
📦 2. Optimise le storage layout pour packer les variables
L’EVM stocke les variables par slot de 32 bytes.
Les variables plus petites que 32 bytes peuvent être regroupées dans un même slot, si elles sont déclarées consécutivement.
// Mauvais
uint256 a;
bool b;
uint256 c;
// Mieux
uint256 a;
uint256 c;
bool b; // placé en dernier pour ne pas casser le packing
Bénéfice : jusqu’à 50% de gas économisé sur les écritures complexes.
⛓️ 3. Utilise des mappings plutôt que des tableaux dynamiques
Les tableaux dynamiques (uint[]
, address[]
) sont pratiques mais peu efficaces.
Ils nécessitent souvent des boucles (coûteuses) pour lire ou modifier les données.
solidityCopierModifier// Inefficace
address[] public whitelist;
// Préférable
mapping(address => bool) public isWhitelisted;
Les mapping
permettent des accès directs en O(1), sans boucle, donc moins chers en gas.
📊 4. External > Public (quand il n’y a pas d’appel interne)
Utilise external
pour les fonctions appelées uniquement de l’extérieur.
Elles consomment moins de gas car les arguments ne sont pas copiés en mémoire, mais lus directement depuis les calldata.
// Moins optimisé
function mint(uint256 amount) public { ... }
// Plus optimisé
function mint(uint256 amount) external { ... }
⚠️ Si une fonction est appelée en interne, garde-la en public
.
🔁 5. Réduis l’usage des boucles ou segmente-les
Chaque itération dans une boucle coûte du gas.
Pire : une boucle trop longue peut faire échouer la transaction (out of gas).
Évite les for
ou while
sur des tableaux non bornés.
Bonnes pratiques :
Découpe les tâches en plusieurs transactions (
batch
oupagination
)Évite les
loop + write
, surtout dans lestorage
Privilégie les patterns comme pull over push
📈 6. Minimise les appels à d’autres contrats
Chaque appel externe (call
, delegatecall
, ou interaction avec un autre contrat) a un coût élevé, en gas et en complexité.
Pourquoi les éviter ou les minimiser :
Risque de
reentrancy
Moins de contrôle sur la consommation de gas
Difficulté de test unitaire
Optimisations possibles :
Réduis les appels on-chain
Préfère les calculs off-chain avec preuve (ex : hash + signature, Merkle proof…)
🧪 7. Teste, profile et mesure avec des outils adaptés
Un contrat peut sembler optimisé, mais seul un test réel avec des mesures de gas te le confirmera.
Outils recommandés :
eth-gas-reporter
→ Affiche le coût des fonctions dans les testsTenderly → Debug visuel et estimation du gas
Foundry → Rapide et excellent pour benchmarker
🔒 8. Évite les redondances dans les vérifications de sécurité
Beaucoup de devs multiplient les require()
pour se rassurer.
Mais chaque require()
a un coût.
Optimisation :
- Regroupe les conditions :
require(x > 0 && y > 0, "Invalid input");
- Évite les vérifications identiques dans plusieurs fonctions : crée un modificateur réutilisable
modifier onlyAdmin() {
require(msg.sender == admin, "Not admin");
_;
}
🧠 9. Préfère les événements aux écritures inutiles
Tu veux notifier une action sans que ça coûte une écriture en storage ?
Utilise des event
:
event Transfer(address indexed from, address indexed to, uint256 amount);
function send(address to, uint256 amount) public {
// business logic
emit Transfer(msg.sender, to, amount);
}
Avantage : les logs sont hors storage, donc beaucoup moins chers
Et très utiles pour les indexeurs comme TheGraph.
🔁 10. Refactorise les calculs redondants
function expensive() public {
uint256 total = balances[msg.sender] + bonuses[msg.sender];
doSomething(total);
doAnotherThing(total);
}
Plutôt que recalculer plusieurs fois, calcule une seule fois en mémoire, et réutilise.
l’optimisation est une habitude
Optimiser tes contrats, ce n’est pas une tâche de dernière minute à faire avant le déploiement.
C’est une discipline, une façon de penser, une hygiène de code.
Les meilleures pratiques sont là pour :
Te faire gagner du temps
Éviter les pièges de gas
Rendre ton projet crédible auprès de ta communauté et des auditeurs
Adopte ces réflexes dès maintenant. Refactore. Teste. Profile. Et répète.
💡 Un contrat optimisé, c’est un contrat qui vit longtemps et coûte moins cher à tous.
Subscribe to my newsletter
Read articles from Daniel Kambale directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Daniel Kambale
Daniel Kambale
Hello! I’m Daniel, a Web3 developer specializing in Solidity and smart contract development. My journey in the blockchain space is driven by a vision of a fully decentralized world, where technology empowers individuals and transforms industries. As a Web3 ambassador , I’m committed to fostering growth and innovation in this space, helping to shape a future that values transparency and security. Fluent in both English and French, I enjoy connecting with diverse communities and sharing my insights across languages. This is why you’ll find some of my articles in French, while others are in Swahili, as I believe knowledge should be accessible to all. I use my Hashnode blog to document my learning process, explore decentralized solutions, and share practical tutorials on Web3 development. Whether it's diving deep into Solidity, discussing the latest in blockchain, or exploring new tools, I’m passionate about contributing to a decentralized future and connecting with others who share this vision. Let’s build the future together!