Capitalisation boursière: $3.8892T 0.810%
Volume(24h): $178.4653B 36.330%
Indice de peur et de cupidité:

67 - Avidité

  • Capitalisation boursière: $3.8892T 0.810%
  • Volume(24h): $178.4653B 36.330%
  • Indice de peur et de cupidité:
  • Capitalisation boursière: $3.8892T 0.810%
Cryptos
Les sujets
Cryptospedia
Nouvelles
Cryptosopique
Vidéos
Top Cryptospedia

Choisir la langue

Choisir la langue

Sélectionnez la devise

Cryptos
Les sujets
Cryptospedia
Nouvelles
Cryptosopique
Vidéos

Comment éviter la réentrance dans la solidité?

La réentrance dans la solidité se produit lorsqu'un appel externe permet à un contrat malveillant d'exécuter récursivement la même fonction, potentiellement de drainage des fonds ou de l'état de corruption.

Jul 20, 2025 at 08:49 am

Comprendre la réentrance dans la solidité

La réentrance est une vulnérabilité de sécurité essentielle dans les contrats intelligents de Solidity qui se produisent lorsqu'une fonction fait un appel externe à un contrat non fiable avant de terminer ses modifications de l'état interne. Cela permet au contrat externe de rappeler récursivement dans la fonction d'origine, de vider potentiellement des fonds ou de corrompre la logique du contrat.

Le tristement célèbre hack DAO en 2016 a été un excellent exemple de la façon dont la réentrance peut être exploitée. L'attaquant a utilisé une fonction de secours malveillante pour déclencher à plusieurs reprises un retrait avant que le contrat ne mette à jour son solde, entraînant la perte de millions d'éther.

Pour éviter de telles vulnérabilités, les développeurs doivent mettre en œuvre les meilleures pratiques et les modèles de conception qui sécurisent les appels externes et garantir que les modifications de l'État se produisent avant toute interaction externe.

Utiliser le modèle de vérification des effets d'interactions

L'un des moyens les plus efficaces de prévenir la réentrance consiste à suivre le modèle de vérification des effets-interactions . Ce modèle garantit que toutes les modifications de l'état interne sont apportées avant que des appels externes ne soient exécutés.

  • Vérification : valider les entrées et conditions.
  • Effets : Mettez à jour les variables d'état du contrat.
  • Interactions : appelez des contrats externes ou envoyez de l'éther.

En adhérant à cet ordre, vous vous assurez que même si une tentative de réentrance se produit, l'état interne a déjà été mis à jour, empêchant l'accès à deux dépenses ou non autorisé .

Par exemple, considérez une fonction de retrait simple:

 function withdraw(uint amount) public { require(balances[msg.sender] >= amount); balances[msg.sender] -= amount; (bool success, ) = msg.sender.call{value: amount}(''); require(success);

}

Dans ce cas, le solde est mis à jour avant l'appel externe, ce qui le rend sécuritaire de la réentrance .

Implémenter les serrures mutex

Une autre méthode efficace pour empêcher la réentrance consiste à utiliser un verrou de mutex , qui est une variable d'état qui empêche la réentrance pendant l'exécution.

Un exemple simple consiste à utiliser un drapeau booléen pour bloquer la réintégration:

 bool private locked; Fonction se retirer (montant uint) public {

require(!locked); locked = true; require(balances[msg.sender] >= amount); balances[msg.sender] -= amount; (bool success, ) = msg.sender.call{value: amount}(''); require(success); locked = false;

}

Cela garantit que la fonction ne peut pas être rentrée pendant qu'elle s'exécute toujours , bloquant efficacement les appels récursifs. Cependant, les développeurs doivent être prudents pour ne pas créer de blocages ou un comportement inattendu lors de l'utilisation de mutexes.

Utilisez ReentricyGuard d'Openzeppelin

Au lieu de mettre en œuvre manuellement la logique Mutex, les développeurs peuvent utiliser le contrat de RenturcoryGuard fourni par Openzeppelin , qui propose une solution sécurisée et testée.

Pour utiliser ReentricancyGuard:

  • Importer le contrat: import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
  • Hériter de celui-ci dans votre contrat: contract MyContract is ReentrancyGuard
  • Appliquer le modificateur nonReentrant aux fonctions sensibles à la réentrance.
 pragma solidity ^0.8.0; import '@ openzeppelin / contracts / security / reentricancyguard.sol';

contrat sécurisé avec Drawal est ReentricyGuard {

mapping(address => uint) public balances; function deposit() external payable { balances[msg.sender] += msg.value; } function withdraw(uint amount) external nonReentrant { require(balances[msg.sender] >= amount, 'Insufficient balance'); balances[msg.sender] -= amount; (bool success, ) = msg.sender.call{value: amount}(''); require(success, 'Transfer failed'); }

}

Cette approche résume la complexité de la manipulation de mutex et réduit le risque d'introduire des bogues , ce qui en fait une méthode préférée pour de nombreux développeurs.

Évitez les appels bruts et utilisez le transfert en toute sécurité

Dans Solidity, l'utilisation address.call{value: ...}('') est plus flexible que transfer() ou send() , mais il supprime également la limite de gaz , la rendant vulnérable à la réentrance.

  • transfer() et send() ne transmettre que 2300 gaz , ce qui est insuffisant pour toute exécution significative, empêchant ainsi la réentrance .
  • Cependant, call() transmet tous les gaz disponibles , permettant aux attaquants d' exécuter une logique malveillante complexe pendant les fonctions de secours ou de réception.

Pour atténuer ceci:

  • Préférez transfer() ou send() pour des transferts d'éther simples.
  • Si l'utilisation call() est nécessaire, assurez-vous que les modifications d'état se produisent avant l'appel et que les gardes de réentrance sont en place.

FAQ: des questions fréquemment posées

Q: Qu'est-ce qu'une attaque de réentrance dans la solidité?

R: Une attaque de réentrance se produit lorsqu'un contrat externe rappelle la fonction d'appel avant de terminer l'exécution, conduisant souvent à des retraits de fonds non autorisés ou à la corruption de l'État .

Q: Puis-je empêcher la réentrance sans utiliser d'Openzeppelin RentarnancyGuard?

R: Oui, en mettant en œuvre manuellement le modèle de contrôle-effets-effets ou en utilisant un serrure Mutex pour bloquer la réentrance pendant l'exécution de la fonction.

Q: Est-il sûr d'utiliser l'adresse.transfer () dans les versions de solidité moderne?

R: Bien que transfer() limite le gaz et empêche la réentrance, il peut échouer de manière inattendue si le contrat de bénéficiaire est à court de gaz. Il est toujours considéré comme plus sûr que call() pour des transferts simples.

Q: Tous les appels externes dans la solidité sont-ils vulnérables à la réentrance?

R: Pas tous, mais tout appel externe à un contrat contrôlé par l'utilisateur peut être un vecteur potentiel. La vulnérabilité survient lorsque les changements d'état suivent l'appel externe, pas l'appel lui-même.

Clause de non-responsabilité:info@kdj.com

Les informations fournies ne constituent pas des conseils commerciaux. kdj.com n’assume aucune responsabilité pour les investissements effectués sur la base des informations fournies dans cet article. Les crypto-monnaies sont très volatiles et il est fortement recommandé d’investir avec prudence après une recherche approfondie!

Si vous pensez que le contenu utilisé sur ce site Web porte atteinte à vos droits d’auteur, veuillez nous contacter immédiatement (info@kdj.com) et nous le supprimerons dans les plus brefs délais.

Connaissances connexes

Voir tous les articles

User not found or password invalid

Your input is correct