Test et vérification formelle pour la sécurité des contrats intelligents Web3

Test et vérification formelle pour la sécurité des contrats intelligents Web3

Tests et vérification formelle pour la sécurité des contrats intelligents Web3 PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Temps de lecture: 9 minutes

Imaginez faire du parachutisme. Avant de sauter de l'avion, vous vérifierez cent fois votre parachute, n'est-ce pas ? Les vérifications et les tests font partie intégrante de la sécurité ; pensez à toute chose liée à la sécurité. Il y aurait probablement un mécanisme de test suivant par la suite, qu'il s'agisse de l'installation d'une vidéosurveillance ou de la vérification de l'encre du stylo avant un examen écrit à l'école, nous suivons tous des mesures de sécurité. Plus le risque est élevé, plus nous testons les choses. Et quand on parle de contrats intelligents, le risque est ÉNORME. Vous ne pouvez pas être négligent en matière de sécurité des contrats intelligents.

1. La sécurité est toujours nécessaire.

Vous pouvez bien sûr verrouiller la porte deux ou trois fois n'a pas d'importance. Pouvez-vous être sûr que votre maison ne peut pas être cambriolée pendant votre absence ? Vous ne pouvez pas parce que vous ne savez pas ce que le voleur pourrait faire pour entrer par effraction dans la maison - il en va de même pour toutes les mesures de sécurité que nous prenons. Il n'existe pas de méthode totalement sûre qui garantira la sécurité. Pourtant, l'action que nous prenons augmente rapidement nos chances d'être en sécurité, ce qui est le jeu. Nous voulons augmenter les chances d'être en sécurité en employant différentes mesures.

Le monde du Web3 n'est pas différent. Il n'existe aucune méthode sûre pour vous sauver, mais le fait d'avoir des auditeurs expérimentés de QuillAudits peut augmenter considérablement les chances que votre protocole soit sécurisé et garantira votre sécurité à jour. Dans web3, il existe deux mécanismes importants qui vous aident à comprendre votre niveau de sécurité en effectuant quelques tests sur votre protocole :-

  1. Test de contrat intelligent
  2. Vérification formelle des contrats intelligents

Découvrons-les en détail et apprenons comment ils nous aident à connaître les points faibles ou les vulnérabilités de nos contrats.

2. Test de contrat intelligent

Un développeur expérimenté peut expliquer le travail à une machine avec du code. Pourtant, parfois, la machine ne décrit pas le mécanisme exact que le développeur avait en tête en raison d'un défaut ou d'une erreur logique dans le code. Le test est le processus qui aide à identifier où notre code échoue et ce qui peut être fait pour le faire correspondre à l'action que nous avons besoin qu'il exécute.

Tests de contrats intelligents est une phase du cycle de développement au cours de laquelle nous effectuons une analyse détaillée de nos contrats et essayons de savoir où et pourquoi notre code échoue. Presque tous les contrats intelligents passent par cette phase. Il existe deux façons de tester les contrats intelligents. Explorons-les.

2.1 Automatisé

Comme son nom l'indique, cette méthode de test des contrats intelligents est utilisée pour effectuer des tests scénarisés. Il s'agit d'un logiciel automatisé qui exécute des tests répétés pour détecter les vulnérabilités et les défauts des contrats intelligents. Ces outils de test automatisés peuvent être configurés avec des données de test et des résultats attendus. Ensuite, le résultat réel est comparé aux résultats attendus pour vérifier si le contrat fonctionne correctement. Les tests automatisés peuvent être classés en trois catégories.

2.1.1. Tests fonctionnels

Supposons que vous écriviez un programme pour prendre deux nombres, a et b, puis renvoyiez l'addition des deux nombres. Donc, pour vérifier ce programme, vous donnez 2 et 8 et alimentez le résultat attendu à 10. Maintenant, lorsque le programme s'exécute, il devrait également renvoyer 10. Si c'est le cas, alors cela fonctionne bien, et notre code est correct, mais s'il pas, alors il y a une erreur avec notre code. 

Les tests fonctionnels nécessitent de comprendre comment votre contrat doit se comporter dans certaines conditions. Nous pouvons le tester en exécutant un calcul avec des valeurs sélectionnées et en comparant la sortie renvoyée. Les tests fonctionnels ont trois classes : -

  1. Tests unitaires: - Il s'agit de tester l'exactitude des composants individuels du contrat intelligent. Il est assertif ou nécessite des déclarations sur des variables.
  1. Intégration textesng : – Celles-ci traitent du test de plusieurs composants individuels ensemble. Les tests d'intégration sont un niveau supérieur dans la hiérarchie que les tests unitaires. Cela nous aide à déterminer les erreurs résultant de l'interaction de différentes fonctions, qui peuvent faire partie d'autres contrats intelligents.
  1. Système Textesng : – C'est le plus élevé de la hiérarchie. En cela, nous testons l'ensemble du contrat comme un système entièrement intégré pour voir s'il fonctionne selon nos besoins. Cela se fait du point de vue de l'utilisateur, et la meilleure façon de le faire est de le déployer sur des réseaux de test.

2.1.2. Analyse statique

L'analyse statique peut être effectuée sans même exécuter le programme. Cela implique l'analyse du code source ou du bytecode du contrat intelligent avant son exécution. Donnant ainsi son nom, l'analyse statique peut aboutir à la détection de certaines vulnérabilités courantes.

2.1.3. Analyse dynamique

Contrairement à l'analyse statique, l'analyse dynamique est effectuée pendant l'exécution des contrats intelligents pour identifier les problèmes dans le code. Les analyseurs de code dynamiques observent l'état d'exécution du contrat et génèrent un rapport détaillé des vulnérabilités et des violations de propriété. Le fuzzing relève de l'analyse DYnamique. Le fuzzing alimente une entrée incorrecte ou malveillante pour provoquer l'exécution de code involontaire.

Manuel 2.2

Comme son nom l'indique, cette méthode de test de contrat intelligent implique une interaction régulière avec un développeur humain. Les audits de code, où les développeurs parcourent des lignes de codes, relèvent du mode manuel de test de contrat intelligent.

Le mode manuel nécessite beaucoup de temps, de compétences, d'argent et d'efforts. Pourtant, le résultat en vaut souvent la peine car, grâce à cela, nous identifions des vulnérabilités qui peuvent passer inaperçues lors des tests automatiques. Il existe deux types essentiels de tests manuels : -

2.2.1 Audits de code : - 

La meilleure façon de tester si votre mesure de sécurité fonctionne correctement est d'essayer de la casser. Par exemple, si vous voulez vérifier si votre serrure de voiture fonctionne correctement, essayez de la casser. Maintenant, vous pouvez demander qu'un voleur de voiture expérimenté puisse facilement entrer par effraction dans ma voiture. Je ne peux pas, alors la solution est d'embaucher quelqu'un qui sait cambrioler pour qu'il puisse vous guider !

 Oui, je parle de QuillAudits. Nous sommes une équipe d'auditeurs qualifiés qui peuvent vous guider. Les audits de code nécessitent un état d'esprit d'attaquant pour trouver toutes les vulnérabilités possibles dans le code source. Un audit de code est une évaluation détaillée du code d'un contrat intelligent pour découvrir les vulnérabilités et les défauts potentiels.

2.2.2 Prime de bogue : -

Si vous pensez qu'il pourrait y avoir des failles de sécurité dans votre code source (qui le sont pour la plupart) et que vous ne les trouvez pas, vous pouvez sous-traiter ce travail à des indépendants en créant un système de récompense. C'est plus comme annoncer une récompense pour quiconque peut pirater votre contrat intelligent. Ce faisant, vous découvrez la vulnérabilité présente dans votre contrat intelligent afin de mieux le protéger et d'éviter les pertes à vos utilisateurs.

3. Vérification formelle des contrats intelligents

La vérification formelle est le processus d'évaluation de l'exactitude d'un contrat basé sur des spécifications formelles. Cela signifie qu'une vérification formelle évalue si le code fait ce qui est prévu. La vérification formelle utilise des méthodes formelles pour spécifier, concevoir et vérifier les programmes.

3.1 Quelle est la spécification formelle ?

Dans le contexte des contrats intelligents, les spécifications formelles font référence aux propriétés qui doivent rester les mêmes dans toutes les circonstances possibles. Ce sont des propriétés « invariantes » car elles ne peuvent pas changer et représentent des assertions logiques sur l'exécution du contrat.

La spécification formelle est un ensemble d'énoncés écrits en langage formel. Les spécifications couvrent différentes propriétés et décrivent comment les propriétés du contrat doivent se comporter dans d'autres circonstances. Les spécifications formelles sont essentielles car si les contrats n'ont pas de variables invariantes ou si les propriétés changent pendant l'exécution, cela peut conduire à une éventuelle exploitation de la propriété, ce qui peut entraîner une perte énorme.

Cela peut nous aider à déterminer si un contrat intelligent répond aux spécifications ou a des comportements inattendus. La vérification formelle comporte trois composants : une spécification, un modèle et un moteur de vérification.

3.1.1 Spécification

Une spécification est une description claire, sans ambiguïté et complète des exigences d'un contrat intelligent. Il doit décrire ce que le contrat est censé faire et ce qu'il n'est pas censé faire. Voici un exemple de spécification pour un contrat simple et intelligent qui ajoute deux nombres :

// Specification: Adds two numbers
// Inputs: a, b (uint)
// Outputs: the sum of a and b (uint) function add(uint a, uint b) public view returns (uint) {
// Implementation details are not relevant to the specification
// …
}

Modèle 3.1.2

Un modèle représente formellement le contrat intelligent qui peut être utilisé pour raisonner sur son comportement. Un modèle populaire de contrats intelligents est le langage de programmation Solidity. Voici un exemple de modèle pour la fonction d'ajout décrite ci-dessus :

// Model: Adds two numbers
// Inputs: a, b (uint)
// Outputs: the sum of a and b (uint) function add(uint a, uint b) public view returns (uint) {
return a + b;
}

3.1.3 Moteur de vérification

Un moteur de vérification est un outil qui permet d'analyser un modèle et de vérifier son exactitude par rapport à une spécification donnée. Il existe plusieurs moteurs de vérification disponibles pour les contrats intelligents, notamment :

Mythril : un outil d'exécution symbolique open-source capable de détecter un large éventail de vulnérabilités de sécurité dans les contrats intelligents Solidity.

Remix IDE : un environnement de développement intégré qui comprend un outil de vérification formel qui peut vérifier l'exactitude des contrats intelligents.

Prouveur de certificat : un outil commercial qui peut vérifier l'exactitude des contrats intelligents à l'aide d'un raisonnement mathématique automatisé. Voici un exemple de la façon dont la vérification formelle peut être utilisée pour vérifier l'exactitude d'un contrat intelligent à l'aide du prouveur Certora :

pragma solidity 0.7.6; // Model: Adds two numbers
// Inputs: a, b (uint)
// Outputs: the sum of a and b (uint)
function add(uint a, uint b) public pure returns (uint) {
return a + b;
} // Model: Adds two numbers
// Inputs: a, b (uint)
// Outputs: the sum of a and b (uint) function add(uint a, uint b) public pure returns (uint) {
return a + b;
} // Specification: Adds two numbers
// Inputs: a, b (uint)
// Outputs: the sum of a and b (uint) function test_add(uint a, uint b) public pure returns (bool) {
uint expected = a + b;
uint actual = add(a, b);
return expected == actual;
} // Verification: Verify the correctness of the add function contract TestAdd {
function test_add(uint a, uint b) public view returns (bool) {
return CertoraProver.verify(test_add, a, b);
}
}

Dans l'exemple ci-dessus, nous définissons un contrat intelligent Solidity qui inclut un modèle de la fonction d'ajout, une spécification pour la fonction et un moteur de vérification (Certora Prover) qui peut vérifier l'exactitude de la fonction. Nous définissons également une fonction de test (test_add) qui peut être utilisée pour vérifier l'exactitude de la fonction.

3.2 Test VS Vérification formelle

Comme nous en avons discuté, le test renvoie le résultat attendu pour certains robots de données d'entrée qui lui manquent, car nous ne pouvons pas dire sur les données sur lesquelles il n'a pas été testé. Il est pratiquement impossible de le vérifier sur toutes les entrées possibles. Ainsi, nous ne sommes pas sûrs de son « exactitude fonctionnelle ». C'est là qu'intervient la vérification formelle. Les méthodes de vérification formelle utilisent des techniques mathématiques rigoureuses pour spécifier et vérifier les logiciels ou les contrats intelligents.

3.3 Techniques de vérification formelle

La vérification formelle a un large éventail de techniques pour améliorer sécurité des contrats intelligents. Dans cette partie du blog, nous en explorerons quelques-uns individuellement.

3.3.1 Vérification du modèle

Comme nous avons discuté de ce qu'est une spécification formelle, nous vérifions le contrat intelligent par rapport à sa spécification dans cette technique de vérification formelle. Ces contrats intelligents sont représentés comme des systèmes de transition d'état et les propriétés sont définies à l'aide d'une logique temporelle. 

Cette technique est principalement utilisée pour évaluer les propriétés temporelles qui décrivent le comportement des contrats intelligents dans le temps. Propriété de contrôle d'accès (appel administrateur auto-destruction) peut être écrit sous forme de logique formelle. Ensuite, l'algorithme de vérification de modèle peut vérifier si le contrat satisfait à cette vérification formelle.

La vérification de modèle utilise une technique appelée exploration de l'espace d'état, qui consiste essentiellement à essayer tous les états possibles dans lesquels notre contrat intelligent peut se trouver, puis à vérifier si l'un d'entre eux entraîne une violation de propriété. Cependant, cela peut conduire à une infinité d'états; par conséquent, les vérificateurs de modèles s'appuient sur des techniques d'abstraction pour rendre possible une analyse efficace des contrats intelligents.

3.3.2 Démonstration de théorème

La démonstration de théorèmes concerne le raisonnement mathématique sur l'exactitude des programmes. Il s'agit de créer une impression logique du système et des spécifications du contrat et de vérifier « l'équivalence logique » entre les déclarations. L'équivalence logique est une relation mathématique qui dit que l'énoncé A est vrai si et seulement si l'énoncé B est vrai.

Comme nous l'avons appris dans la technique de vérification de modèle, nous modélisons les contrats comme des systèmes de transition avec des états finis. La démonstration de théorèmes peut gérer l'analyse de systèmes à états infinis. Cependant, un démonstrateur de théorème automatisé ne peut pas toujours savoir si un problème logique est décidable ; ainsi, une assistance humaine est souvent nécessaire pour guider le prouveur de théorèmes dans la dérivation des preuves d'exactitude.

4. Conclusion

Les tests et la vérification formelle font tous deux partie intégrante du développement de contrats intelligents. Ce sont les méthodes utilisées pour sécuriser les contrats intelligents et aider à préparer les contrats pour le déploiement. Mais comme vous le savez, la sécurité ne suffit jamais. De nombreux contrats intelligents étaient piratés simplement parce qu'il n'y avait pas de tests appropriés. Aujourd'hui plus que jamais, la communauté Web3 a besoin de protocoles plus sécurisés. 

Chez QuillAudits, nous avons pour mission de vous aider à protéger vos protocoles. Avec notre équipe compétente et expérimentée, nous veillons à ce qu'aucune vulnérabilité ne passe inaperçue. Visitez notre site Web et sécurisez votre projet Web3 !

28 Vues

Horodatage:

Plus de Quillhasch