Testen von Smart Contracts
Letzte Aktualisierung der Seite: 26. Februar 2026
Öffentliche Blockchains wie Ethereum sind unveränderlich, was es schwierig macht, den Code eines Smart Contracts nach der Bereitstellung zu ändern. Es gibt Muster für Vertragsaktualisierungen zur Durchführung „virtueller Upgrades“, aber diese sind schwer zu implementieren und erfordern sozialen Konsens. Darüber hinaus kann ein Upgrade einen Fehler nur beheben, nachdem er entdeckt wurde – wenn ein Angreifer die Schwachstelle zuerst entdeckt, ist Ihr Smart Contract dem Risiko eines Exploits ausgesetzt.
Aus diesen Gründen ist das Testen von Smart Contracts vor der Bereitstellung im Mainnet eine Mindestanforderung für die Sicherheit. Es gibt viele Techniken zum Testen von Verträgen und zur Bewertung der Code-Korrektheit; welche Sie wählen, hängt von Ihren Anforderungen ab. Dennoch ist eine Test-Suite, die aus verschiedenen Tools und Ansätzen besteht, ideal, um sowohl kleinere als auch größere Sicherheitslücken im Vertragscode zu finden.
Voraussetzungen
Diese Seite erklärt, wie man Smart Contracts testet, bevor man sie im Ethereum-Netzwerk bereitstellt. Es wird vorausgesetzt, dass Sie mit Smart Contracts vertraut sind.
Was ist das Testen von Smart Contracts?
Das Testen von Smart Contracts ist der Prozess der Überprüfung, ob der Code eines Smart Contracts wie erwartet funktioniert. Tests sind nützlich, um zu überprüfen, ob ein bestimmter Smart Contract die Anforderungen an Zuverlässigkeit, Benutzerfreundlichkeit und Sicherheit erfüllt.
Obwohl die Ansätze variieren, erfordern die meisten Testmethoden die Ausführung eines Smart Contracts mit einer kleinen Stichprobe der Daten, die er verarbeiten soll. Wenn der Vertrag korrekte Ergebnisse für die Beispieldaten liefert, wird davon ausgegangen, dass er ordnungsgemäß funktioniert. Die meisten Test-Tools bieten Ressourcen zum Schreiben und Ausführen von Testfällen (opens in a new tab), um zu überprüfen, ob die Ausführung eines Vertrags mit den erwarteten Ergebnissen übereinstimmt.
Warum ist es wichtig, Smart Contracts zu testen?
Da Smart Contracts oft hochwertige finanzielle Vermögenswerte verwalten, können kleinere Programmierfehler zu massiven Verlusten für Benutzer (opens in a new tab) führen und tun dies auch oft. Rigoroses Testen kann Ihnen jedoch helfen, Fehler und Probleme im Code eines Smart Contracts frühzeitig zu entdecken und zu beheben, bevor er im Mainnet gestartet wird.
Während es möglich ist, einen Vertrag zu aktualisieren, wenn ein Fehler entdeckt wird, sind Upgrades komplex und können bei unsachgemäßer Handhabung zu Fehlern führen (opens in a new tab). Die Aktualisierung eines Vertrags negiert zudem das Prinzip der Unveränderlichkeit und belastet die Benutzer mit zusätzlichen Vertrauensannahmen. Umgekehrt mindert ein umfassender Plan zum Testen Ihres Vertrags die Sicherheitsrisiken von Smart Contracts und reduziert die Notwendigkeit, nach der Bereitstellung komplexe Logik-Upgrades durchzuführen.
Methoden zum Testen von Smart Contracts
Methoden zum Testen von Ethereum-Smart-Contracts fallen in zwei breite Kategorien: automatisiertes Testen und manuelles Testen. Automatisiertes Testen und manuelles Testen bieten einzigartige Vorteile und Kompromisse, aber Sie können beide kombinieren, um einen robusten Plan zur Analyse Ihrer Verträge zu erstellen.
Automatisiertes Testen
Automatisiertes Testen verwendet Tools, die den Code eines Smart Contracts automatisch auf Ausführungsfehler überprüfen. Der Vorteil des automatisierten Testens liegt in der Verwendung von Skripten (opens in a new tab) zur Steuerung der Bewertung von Vertragsfunktionen. Skriptbasierte Tests können so geplant werden, dass sie wiederholt mit minimalem menschlichen Eingreifen ausgeführt werden, was automatisiertes Testen effizienter macht als manuelle Testansätze.
Automatisiertes Testen ist besonders nützlich, wenn Tests repetitiv und zeitaufwändig sind, manuell schwer durchzuführen sind, anfällig für menschliche Fehler sind oder die Bewertung kritischer Vertragsfunktionen beinhalten. Aber automatisierte Test-Tools können Nachteile haben – sie übersehen möglicherweise bestimmte Fehler und produzieren viele falsch positive Ergebnisse (opens in a new tab). Daher ist die Kombination von automatisiertem Testen mit manuellem Testen für Smart Contracts ideal.
Manuelles Testen
Manuelles Testen wird von Menschen unterstützt und beinhaltet die Ausführung jedes Testfalls in Ihrer Test-Suite nacheinander bei der Analyse der Korrektheit eines Smart Contracts. Dies unterscheidet sich vom automatisierten Testen, bei dem Sie gleichzeitig mehrere isolierte Tests für einen Vertrag ausführen und einen Bericht erhalten können, der alle fehlgeschlagenen und bestandenen Tests anzeigt.
Manuelles Testen kann von einer einzelnen Person durchgeführt werden, die einem schriftlichen Testplan folgt, der verschiedene Testszenarien abdeckt. Sie könnten auch mehrere Personen oder Gruppen über einen bestimmten Zeitraum im Rahmen des manuellen Testens mit einem Smart Contract interagieren lassen. Tester vergleichen das tatsächliche Verhalten des Vertrags mit dem erwarteten Verhalten und markieren jeden Unterschied als Fehler.
Effektives manuelles Testen erfordert erhebliche Ressourcen (Fähigkeiten, Zeit, Geld und Aufwand), und es ist möglich – aufgrund menschlicher Fehler –, bestimmte Fehler bei der Ausführung von Tests zu übersehen. Aber manuelles Testen kann auch vorteilhaft sein – zum Beispiel kann ein menschlicher Tester (z. B. ein Prüfer) Intuition nutzen, um Randfälle zu erkennen, die ein automatisiertes Test-Tool übersehen würde.
Automatisiertes Testen für Smart Contracts
Unit-Testing
Unit-Testing bewertet Vertragsfunktionen separat und überprüft, ob jede Komponente korrekt funktioniert. Gute Unit-Tests sollten einfach sein, schnell ausgeführt werden können und eine klare Vorstellung davon vermitteln, was schiefgelaufen ist, wenn Tests fehlschlagen.
Unit-Tests sind nützlich, um zu überprüfen, ob Funktionen erwartete Werte zurückgeben und ob der Vertragsspeicher nach der Funktionsausführung ordnungsgemäß aktualisiert wird. Darüber hinaus stellt die Ausführung von Unit-Tests nach Änderungen an der Codebasis eines Vertrags sicher, dass das Hinzufügen neuer Logik keine Fehler einführt. Im Folgenden finden Sie einige Richtlinien für die Ausführung effektiver Unit-Tests:
Richtlinien für das Unit-Testing von Smart Contracts
1. Verstehen Sie die Geschäftslogik und den Workflow Ihres Vertrags
Bevor Sie Unit-Tests schreiben, ist es hilfreich zu wissen, welche Funktionalitäten ein Smart Contract bietet und wie Benutzer auf diese Funktionen zugreifen und sie nutzen werden. Dies ist besonders nützlich für die Ausführung von Happy-Path-Tests (opens in a new tab), die bestimmen, ob Funktionen in einem Vertrag die korrekte Ausgabe für gültige Benutzereingaben zurückgeben. Wir erklären dieses Konzept anhand dieses (gekürzten) Beispiels eines Auktionsvertrags (opens in a new tab)
1constructor(2 uint biddingTime,3 address payable beneficiaryAddress4 ) {5 beneficiary = beneficiaryAddress;6 auctionEndTime = block.timestamp + biddingTime;7 }89function bid() external payable {1011 if (block.timestamp > auctionEndTime)12 revert AuctionAlreadyEnded();1314 if (msg.value <= highestBid)15 revert BidNotHighEnough(highestBid);1617 if (highestBid != 0) {18 pendingReturns[highestBidder] += highestBid;19 }20 highestBidder = msg.sender;21 highestBid = msg.value;22 emit HighestBidIncreased(msg.sender, msg.value);23 }2425 function withdraw() external returns (bool) {26 uint amount = pendingReturns[msg.sender];27 if (amount > 0) {28 pendingReturns[msg.sender] = 0;2930 if (!payable(msg.sender).send(amount)) {31 pendingReturns[msg.sender] = amount;32 return false;33 }34 }35 return true;36 }3738function auctionEnd() external {39 if (block.timestamp < auctionEndTime)40 revert AuctionNotYetEnded();41 if (ended)42 revert AuctionEndAlreadyCalled();4344 ended = true;45 emit AuctionEnded(highestBidder, highestBid);4647 beneficiary.transfer(highestBid);48 }49}Alle anzeigenDies ist ein einfacher Auktionsvertrag, der darauf ausgelegt ist, Gebote während der Bietzeit zu empfangen. Wenn das highestBid steigt, erhält der vorherige Höchstbietende sein Geld zurück; sobald die Bietzeit abgelaufen ist, ruft der beneficiary den Vertrag auf, um sein Geld zu erhalten.
Unit-Tests für einen solchen Vertrag würden verschiedene Funktionen abdecken, die ein Benutzer bei der Interaktion mit dem Vertrag aufrufen könnte. Ein Beispiel wäre ein Unit-Test, der überprüft, ob ein Benutzer ein Gebot abgeben kann, während die Auktion läuft (d. h. Aufrufe von bid() sind erfolgreich), oder einer, der überprüft, ob ein Benutzer ein höheres Gebot als das aktuelle highestBid abgeben kann.
Das Verständnis des operativen Workflows eines Vertrags hilft auch beim Schreiben von Unit-Tests, die überprüfen, ob die Ausführung den Anforderungen entspricht. Zum Beispiel legt der Auktionsvertrag fest, dass Benutzer keine Gebote abgeben können, wenn die Auktion beendet ist (d. h. wenn auctionEndTime niedriger als block.timestamp ist). Daher könnte ein Entwickler einen Unit-Test ausführen, der überprüft, ob Aufrufe der Funktion bid() erfolgreich sind oder fehlschlagen, wenn die Auktion vorbei ist (d. h. wenn auctionEndTime > block.timestamp).
2. Bewerten Sie alle Annahmen im Zusammenhang mit der Vertragsausführung
Es ist wichtig, alle Annahmen über die Ausführung eines Vertrags zu dokumentieren und Unit-Tests zu schreiben, um die Gültigkeit dieser Annahmen zu überprüfen. Abgesehen vom Schutz vor unerwarteter Ausführung zwingt Sie das Testen von Zusicherungen (Assertions) dazu, über Operationen nachzudenken, die das Sicherheitsmodell eines Smart Contracts brechen könnten. Ein nützlicher Tipp ist, über „Happy-User-Tests“ hinauszugehen und negative Tests zu schreiben, die überprüfen, ob eine Funktion bei falschen Eingaben fehlschlägt.
Viele Unit-Testing-Frameworks ermöglichen es Ihnen, Zusicherungen zu erstellen – einfache Aussagen, die angeben, was ein Vertrag tun kann und was nicht – und Tests auszuführen, um zu sehen, ob diese Zusicherungen bei der Ausführung Bestand haben. Ein Entwickler, der an dem zuvor beschriebenen Auktionsvertrag arbeitet, könnte vor der Ausführung negativer Tests die folgenden Zusicherungen über dessen Verhalten machen:
-
Benutzer können keine Gebote abgeben, wenn die Auktion beendet ist oder noch nicht begonnen hat.
-
Der Auktionsvertrag wird rückgängig gemacht (reverts), wenn ein Gebot unter dem akzeptablen Schwellenwert liegt.
-
Benutzern, die den Zuschlag nicht erhalten, werden ihre Gelder gutgeschrieben.
Hinweis: Eine weitere Möglichkeit, Annahmen zu testen, besteht darin, Tests zu schreiben, die Funktionsmodifikatoren (opens in a new tab) in einem Vertrag auslösen, insbesondere require-, assert- und if…else-Anweisungen.
3. Messen Sie die Codeabdeckung
Codeabdeckung (opens in a new tab) (Code Coverage) ist eine Testmetrik, die die Anzahl der Zweige, Zeilen und Anweisungen in Ihrem Code verfolgt, die während der Tests ausgeführt werden. Tests sollten eine gute Codeabdeckung aufweisen, um das Risiko ungetesteter Schwachstellen zu minimieren. Ohne ausreichende Abdeckung könnten Sie fälschlicherweise annehmen, dass Ihr Vertrag sicher ist, weil alle Tests bestanden wurden, während in ungetesteten Codepfaden weiterhin Schwachstellen existieren. Die Aufzeichnung einer hohen Codeabdeckung gibt jedoch die Gewissheit, dass alle Anweisungen/Funktionen in einem Smart Contract ausreichend auf Korrektheit getestet wurden.
4. Verwenden Sie gut entwickelte Test-Frameworks
Die Qualität der Tools, die zur Ausführung von Unit-Tests für Ihre Smart Contracts verwendet werden, ist entscheidend. Ein ideales Test-Framework ist eines, das regelmäßig gewartet wird, nützliche Funktionen bietet (z. B. Protokollierungs- und Berichtsfunktionen) und von anderen Entwicklern ausgiebig genutzt und geprüft wurde.
Unit-Testing-Frameworks für Solidity-Smart-Contracts gibt es in verschiedenen Sprachen (hauptsächlich JavaScript, Python und Rust). In einigen der folgenden Leitfäden finden Sie Informationen darüber, wie Sie mit der Ausführung von Unit-Tests mit verschiedenen Test-Frameworks beginnen können:
- Ausführen von Unit-Tests mit Brownie (opens in a new tab)
- Ausführen von Unit-Tests mit Foundry (opens in a new tab)
- Ausführen von Unit-Tests mit Waffle (opens in a new tab)
- Ausführen von Unit-Tests mit Remix (opens in a new tab)
- Ausführen von Unit-Tests mit Ape (opens in a new tab)
- Ausführen von Unit-Tests mit Hardhat (opens in a new tab)
- Ausführen von Unit-Tests mit Wake (opens in a new tab)
Integrationstests
Während Unit-Testing Vertragsfunktionen isoliert debuggt, bewerten Integrationstests die Komponenten eines Smart Contracts als Ganzes. Integrationstests können Probleme erkennen, die sich aus vertragsübergreifenden Aufrufen oder Interaktionen zwischen verschiedenen Funktionen im selben Smart Contract ergeben. Zum Beispiel können Integrationstests helfen zu überprüfen, ob Dinge wie Vererbung (opens in a new tab) und Dependency Injection ordnungsgemäß funktionieren.
Integrationstests sind nützlich, wenn Ihr Vertrag eine modulare Architektur annimmt oder während der Ausführung mit anderen Verträgen auf der Blockchain (onchain) interagiert. Eine Möglichkeit, Integrationstests durchzuführen, besteht darin, einen der Blockchain auf einer bestimmten Höhe zu erstellen (mit einem Tool wie Forge (opens in a new tab) oder Hardhat (opens in a new tab)) und Interaktionen zwischen Ihrem Vertrag und bereitgestellten Verträgen zu simulieren.
Die geforkte Blockchain verhält sich ähnlich wie das Mainnet und verfügt über Konten mit zugehörigen Zuständen und Salden. Sie fungiert jedoch nur als isolierte lokale Entwicklungsumgebung (Sandbox), was bedeutet, dass Sie beispielsweise keine echten ETH für Transaktionen benötigen und Ihre Änderungen das echte Ethereum-Protokoll nicht beeinflussen.
Eigenschaftsbasiertes Testen
Eigenschaftsbasiertes Testen ist der Prozess der Überprüfung, ob ein Smart Contract eine bestimmte definierte Eigenschaft erfüllt. Eigenschaften behaupten Fakten über das Verhalten eines Vertrags, von denen erwartet wird, dass sie in verschiedenen Szenarien wahr bleiben – ein Beispiel für eine Smart-Contract-Eigenschaft könnte sein: „Arithmetische Operationen im Vertrag führen niemals zu einem Überlauf oder Unterlauf.“
Statische Analyse und dynamische Analyse sind zwei gängige Techniken zur Ausführung von eigenschaftsbasiertem Testen, und beide können überprüfen, ob der Code für ein Programm (in diesem Fall ein Smart Contract) eine vordefinierte Eigenschaft erfüllt. Einige Tools für eigenschaftsbasiertes Testen verfügen über vordefinierte Regeln zu erwarteten Vertragseigenschaften und überprüfen den Code anhand dieser Regeln, während andere es Ihnen ermöglichen, benutzerdefinierte Eigenschaften für einen Smart Contract zu erstellen.
Statische Analyse
Ein statischer Analysator nimmt den Quellcode eines Smart Contracts als Eingabe und gibt Ergebnisse aus, die erklären, ob ein Vertrag eine Eigenschaft erfüllt oder nicht. Im Gegensatz zur dynamischen Analyse beinhaltet die statische Analyse nicht die Ausführung eines Vertrags, um ihn auf Korrektheit zu analysieren. Die statische Analyse argumentiert stattdessen über alle möglichen Pfade, die ein Smart Contract während der Ausführung nehmen könnte (d. h. durch Untersuchung der Struktur des Quellcodes, um zu bestimmen, was dies für den Betrieb des Vertrags zur Laufzeit bedeuten würde).
Linting (opens in a new tab) und statisches Testen (opens in a new tab) sind gängige Methoden zur Durchführung statischer Analysen von Verträgen. Beide erfordern die Analyse von Low-Level-Darstellungen der Ausführung eines Vertrags, wie z. B. abstrakte Syntaxbäume (opens in a new tab) und Kontrollflussgraphen (opens in a new tab), die vom Compiler ausgegeben werden.
In den meisten Fällen ist die statische Analyse nützlich, um Sicherheitsprobleme wie die Verwendung unsicherer Konstrukte, Syntaxfehler oder Verstöße gegen Codierungsstandards im Code eines Vertrags zu erkennen. Es ist jedoch bekannt, dass statische Analysatoren im Allgemeinen unzuverlässig bei der Erkennung tieferer Schwachstellen sind und übermäßig viele falsch positive Ergebnisse produzieren können.
Dynamische Analyse
Die dynamische Analyse generiert symbolische Eingaben (z. B. bei der symbolischen Ausführung (opens in a new tab)) oder konkrete Eingaben (z. B. beim Fuzzing (opens in a new tab)) für die Funktionen eines Smart Contracts, um zu sehen, ob Ausführungsspuren bestimmte Eigenschaften verletzen. Diese Form des eigenschaftsbasierten Testens unterscheidet sich von Unit-Tests dadurch, dass Testfälle mehrere Szenarien abdecken und ein Programm die Generierung von Testfällen übernimmt.
Fuzzing (opens in a new tab) ist ein Beispiel für eine dynamische Analysetechnik zur Überprüfung beliebiger Eigenschaften in Smart Contracts. Ein Fuzzer ruft Funktionen in einem Zielvertrag mit zufälligen oder fehlerhaften Variationen eines definierten Eingabewerts auf. Wenn der Smart Contract in einen Fehlerzustand übergeht (z. B. einen, bei dem eine Zusicherung fehlschlägt), wird das Problem markiert und Eingaben, die die Ausführung in Richtung des anfälligen Pfads treiben, werden in einem Bericht ausgegeben.
Fuzzing ist nützlich zur Bewertung des Eingabevalidierungsmechanismus eines Smart Contracts, da eine unsachgemäße Handhabung unerwarteter Eingaben zu einer unbeabsichtigten Ausführung führen und gefährliche Auswirkungen haben kann. Diese Form des eigenschaftsbasierten Testens kann aus vielen Gründen ideal sein:
-
Das Schreiben von Testfällen zur Abdeckung vieler Szenarien ist schwierig. Ein Eigenschaftstest erfordert nur, dass Sie ein Verhalten und einen Datenbereich definieren, mit dem das Verhalten getestet werden soll – das Programm generiert automatisch Testfälle basierend auf der definierten Eigenschaft.
-
Ihre Test-Suite deckt möglicherweise nicht alle möglichen Pfade innerhalb des Programms ausreichend ab. Selbst bei 100 % Abdeckung ist es möglich, Randfälle zu übersehen.
-
Unit-Tests beweisen, dass ein Vertrag für Beispieldaten korrekt ausgeführt wird, aber ob der Vertrag für Eingaben außerhalb der Stichprobe korrekt ausgeführt wird, bleibt unbekannt. Eigenschaftstests führen einen Zielvertrag mit mehreren Variationen eines bestimmten Eingabewerts aus, um Ausführungsspuren zu finden, die Fehler bei Zusicherungen verursachen. Somit bietet ein Eigenschaftstest mehr Garantien dafür, dass ein Vertrag für eine breite Klasse von Eingabedaten korrekt ausgeführt wird.
Richtlinien für die Ausführung von eigenschaftsbasiertem Testen für Smart Contracts
Die Ausführung von eigenschaftsbasiertem Testen beginnt typischerweise mit der Definition einer Eigenschaft (z. B. Fehlen von Integer-Überläufen (opens in a new tab)) oder einer Sammlung von Eigenschaften, die Sie in einem Smart Contract überprüfen möchten. Möglicherweise müssen Sie auch einen Wertebereich definieren, innerhalb dessen das Programm Daten für Transaktionseingaben generieren kann, wenn Sie Eigenschaftstests schreiben.
Sobald es richtig konfiguriert ist, führt das Tool für Eigenschaftstests die Funktionen Ihres Smart Contracts mit zufällig generierten Eingaben aus. Wenn es Verletzungen von Zusicherungen gibt, sollten Sie einen Bericht mit konkreten Eingabedaten erhalten, die die zu bewertende Eigenschaft verletzen. In einigen der folgenden Leitfäden erfahren Sie, wie Sie mit der Ausführung von eigenschaftsbasiertem Testen mit verschiedenen Tools beginnen können:
- Statische Analyse von Smart Contracts mit Slither (opens in a new tab)
- Statische Analyse von Smart Contracts mit Wake (opens in a new tab)
- Eigenschaftsbasiertes Testen mit Brownie (opens in a new tab)
- Fuzzing von Verträgen mit Foundry (opens in a new tab)
- Fuzzing von Verträgen mit Echidna (opens in a new tab)
- Fuzzing von Verträgen mit Wake (opens in a new tab)
- Symbolische Ausführung von Smart Contracts mit Manticore (opens in a new tab)
- Symbolische Ausführung von Smart Contracts mit Mythril (opens in a new tab)
Manuelles Testen für Smart Contracts
Das manuelle Testen von Smart Contracts erfolgt oft später im Entwicklungszyklus nach der Ausführung automatisierter Tests. Diese Form des Testens bewertet den Smart Contract als ein vollständig integriertes Produkt, um zu sehen, ob er wie in den technischen Anforderungen spezifiziert funktioniert.
Testen von Verträgen auf einer lokalen Blockchain
Während automatisiertes Testen in einer lokalen Entwicklungsumgebung nützliche Debugging-Informationen liefern kann, möchten Sie wissen, wie sich Ihr Smart Contract in einer Produktionsumgebung verhält. Die Bereitstellung auf der Haupt-Ethereum-Chain verursacht jedoch Gasgebühren – ganz zu schweigen davon, dass Sie oder Ihre Benutzer echtes Geld verlieren können, wenn Ihr Smart Contract noch Fehler aufweist.
Das Testen Ihres Vertrags auf einer lokalen Blockchain (auch bekannt als Entwicklungsnetzwerk) ist eine empfohlene Alternative zum Testen im Mainnet. Eine lokale Blockchain ist eine Kopie der Ethereum-Blockchain, die lokal auf Ihrem Computer läuft und das Verhalten der Ausführungsebene von Ethereum simuliert. Als solches können Sie Transaktionen programmieren, um mit einem Vertrag zu interagieren, ohne erheblichen Mehraufwand zu verursachen.
Die Ausführung von Verträgen auf einer lokalen Blockchain könnte als eine Form des manuellen Integrationstests nützlich sein. Smart Contracts sind hochgradig zusammensetzbar, was es Ihnen ermöglicht, sie in bestehende Protokolle zu integrieren – aber Sie müssen dennoch sicherstellen, dass solch komplexe Interaktionen auf der Blockchain (onchain) die korrekten Ergebnisse liefern.
Mehr über Entwicklungsnetzwerke.
Testen von Verträgen in Testnets
Ein Testnetzwerk oder Testnet funktioniert genau wie das Ethereum-Mainnet, außer dass es Ether (ETH) ohne realen Wert verwendet. Die Bereitstellung Ihres Vertrags in einem Testnet bedeutet, dass jeder damit interagieren kann (z. B. über das Frontend der Dapp), ohne Gelder zu gefährden.
Diese Form des manuellen Testens ist nützlich zur Bewertung des End-to-End-Ablaufs Ihrer Anwendung aus der Sicht eines Benutzers. Hier können Beta-Tester auch Probeläufe durchführen und Probleme mit der Geschäftslogik und der allgemeinen Funktionalität des Vertrags melden.
Die Bereitstellung in einem Testnet nach dem Testen auf einer lokalen Blockchain ist ideal, da ersteres dem Verhalten der Ethereum Virtual Machine näher kommt. Daher ist es für viele Ethereum-native Projekte üblich, Dapps in Testnets bereitzustellen, um den Betrieb eines Smart Contracts unter realen Bedingungen zu bewerten.
Testen vs. formale Verifikation
Während das Testen hilft zu bestätigen, dass ein Vertrag die erwarteten Ergebnisse für einige Dateneingaben zurückgibt, kann es dies nicht schlüssig für Eingaben beweisen, die während der Tests nicht verwendet wurden. Das Testen eines Smart Contracts kann daher keine „funktionale Korrektheit“ garantieren (d. h. es kann nicht zeigen, dass sich ein Programm für alle Sätze von Eingabewerten wie erforderlich verhält).
Die formale Verifikation ist ein Ansatz zur Bewertung der Korrektheit von Software, indem überprüft wird, ob ein formales Modell des Programms mit der formalen Spezifikation übereinstimmt. Ein formales Modell ist eine abstrakte mathematische Darstellung eines Programms, während eine formale Spezifikation die Eigenschaften eines Programms definiert (d. h. logische Zusicherungen über die Ausführung des Programms).
Da Eigenschaften in mathematischen Begriffen geschrieben sind, wird es möglich zu überprüfen, ob ein formales (mathematisches) Modell des Systems eine Spezifikation unter Verwendung logischer Schlussfolgerungsregeln erfüllt. Daher wird gesagt, dass formale Verifikations-Tools einen „mathematischen Beweis“ für die Korrektheit eines Systems liefern.
Im Gegensatz zum Testen kann die formale Verifikation verwendet werden, um zu überprüfen, ob die Ausführung eines Smart Contracts eine formale Spezifikation für alle Ausführungen erfüllt (d. h. er hat keine Fehler), ohne ihn mit Beispieldaten ausführen zu müssen. Dies reduziert nicht nur die Zeit, die für die Ausführung von Dutzenden von Unit-Tests aufgewendet wird, sondern ist auch effektiver beim Aufspüren versteckter Schwachstellen. Allerdings liegen formale Verifikationstechniken auf einem Spektrum, abhängig von ihrer Schwierigkeit bei der Implementierung und ihrer Nützlichkeit.
Mehr über formale Verifikation für Smart Contracts.
Testen vs. Audits und Bug-Bounties
Wie bereits erwähnt, kann rigoroses Testen selten die Abwesenheit von Fehlern in einem Vertrag garantieren; formale Verifikationsansätze können stärkere Zusicherungen der Korrektheit bieten, sind aber derzeit schwierig zu verwenden und verursachen erhebliche Kosten.
Dennoch können Sie die Wahrscheinlichkeit, Vertragsschwachstellen zu finden, weiter erhöhen, indem Sie eine unabhängige Codeüberprüfung durchführen lassen. Smart-Contract-Audits (opens in a new tab) und Bug-Bounties (opens in a new tab) sind zwei Möglichkeiten, andere dazu zu bringen, Ihre Verträge zu analysieren.
Audits werden von Prüfern durchgeführt, die Erfahrung darin haben, Fälle von Sicherheitslücken und schlechten Entwicklungspraktiken in Smart Contracts zu finden. Ein Audit umfasst in der Regel Tests (und möglicherweise formale Verifikation) sowie eine manuelle Überprüfung der gesamten Codebasis.
Umgekehrt beinhaltet ein Bug-Bounty-Programm in der Regel das Anbieten einer finanziellen Belohnung für eine Person (allgemein als White-Hat-Hacker (opens in a new tab) bezeichnet), die eine Schwachstelle in einem Smart Contract entdeckt und sie den Entwicklern offenlegt. Bug-Bounties ähneln Audits, da sie beinhalten, andere zu bitten, bei der Suche nach Fehlern in Smart Contracts zu helfen.
Der Hauptunterschied besteht darin, dass Bug-Bounty-Programme der breiteren Entwickler-/Hacker-Community offenstehen und eine breite Klasse von ethischen Hackern und unabhängigen Sicherheitsexperten mit einzigartigen Fähigkeiten und Erfahrungen anziehen. Dies kann ein Vorteil gegenüber Smart-Contract-Audits sein, die sich hauptsächlich auf Teams stützen, die möglicherweise über begrenzte oder enge Fachkenntnisse verfügen.
Test-Tools und Bibliotheken
Unit-Testing-Tools
-
solidity-coverage (opens in a new tab) – Codeabdeckungs-Tool für in Solidity geschriebene Smart Contracts.
-
Waffle (opens in a new tab) – Framework für fortgeschrittene Smart-Contract-Entwicklung und -Tests (basierend auf ethers.js).
-
Remix Tests (opens in a new tab) – Tool zum Testen von Solidity-Smart-Contracts. Funktioniert unter dem Remix-IDE-Plugin „Solidity Unit Testing“, das zum Schreiben und Ausführen von Testfällen für einen Vertrag verwendet wird.
-
OpenZeppelin Test Helpers (opens in a new tab) – Zusicherungsbibliothek (Assertion Library) für das Testen von Ethereum-Smart-Contracts. Stellen Sie sicher, dass sich Ihre Verträge wie erwartet verhalten!
-
Brownie Unit-Testing-Framework (opens in a new tab) – Brownie nutzt Pytest, ein funktionsreiches Test-Framework, mit dem Sie kleine Tests mit minimalem Code schreiben können, das gut für große Projekte skaliert und hochgradig erweiterbar ist.
-
Foundry Tests (opens in a new tab) – Foundry bietet Forge, ein schnelles und flexibles Ethereum-Test-Framework, das in der Lage ist, einfache Unit-Tests, Gasoptimierungsprüfungen und Vertrags-Fuzzing auszuführen.
-
Hardhat Tests (opens in a new tab) – Framework zum Testen von Smart Contracts basierend auf ethers.js, Mocha und Chai.
-
ApeWorx (opens in a new tab) – Python-basiertes Entwicklungs- und Test-Framework für Smart Contracts, das auf die Ethereum Virtual Machine abzielt.
-
Wake (opens in a new tab) – Python-basiertes Framework für Unit-Testing und Fuzzing mit starken Debugging-Funktionen und Unterstützung für Cross-Chain-Tests, das pytest und Anvil für beste Benutzererfahrung und Leistung nutzt.
Tools für eigenschaftsbasiertes Testen
Tools für statische Analyse
-
Slither (opens in a new tab) – Python-basiertes Framework zur statischen Analyse von Solidity zum Finden von Schwachstellen, zur Verbesserung des Codeverständnisses und zum Schreiben benutzerdefinierter Analysen für Smart Contracts.
-
Ethlint (opens in a new tab) – Linter zur Durchsetzung von Stil- und Sicherheits-Best-Practices für die Programmiersprache Solidity für Smart Contracts.
-
Cyfrin Aderyn (opens in a new tab) – Rust-basierter statischer Analysator, der speziell für die Sicherheit und Entwicklung von Web3-Smart-Contracts entwickelt wurde.
-
Wake (opens in a new tab) – Python-basiertes Framework zur statischen Analyse mit Detektoren für Schwachstellen und Codequalität, Druckern zum Extrahieren nützlicher Informationen aus Code und Unterstützung für das Schreiben benutzerdefinierter Submodule.
-
Slippy (opens in a new tab) – Ein einfacher und leistungsstarker Linter für Solidity.
Tools für dynamische Analyse
-
Echidna (opens in a new tab) – Schneller Vertrags-Fuzzer zur Erkennung von Schwachstellen in Smart Contracts durch eigenschaftsbasiertes Testen.
-
Diligence Fuzzing (opens in a new tab) – Automatisiertes Fuzzing-Tool, das nützlich ist, um Eigenschaftsverletzungen im Smart-Contract-Code zu erkennen.
-
Manticore (opens in a new tab) – Framework zur dynamischen symbolischen Ausführung zur Analyse von EVM-Bytecode.
-
Mythril (opens in a new tab) – EVM-Bytecode-Bewertungstool zur Erkennung von Vertragsschwachstellen mithilfe von Taint-Analyse, concolic Analyse und Kontrollflussprüfung.
-
Diligence Scribble (opens in a new tab) – Scribble ist eine Spezifikationssprache und ein Laufzeit-Verifikations-Tool, mit dem Sie Smart Contracts mit Eigenschaften annotieren können, die es Ihnen ermöglichen, die Verträge automatisch mit Tools wie Diligence Fuzzing oder MythX zu testen.
Verwandte Tutorials
- Ein Überblick und Vergleich verschiedener Testprodukte _
- Wie man Echidna verwendet, um Smart Contracts zu testen
- Wie man Manticore verwendet, um Fehler in Smart Contracts zu finden
- Wie man Slither verwendet, um Fehler in Smart Contracts zu finden
- Wie man Solidity-Verträge für Tests mockt
- Wie man Unit-Tests in Solidity mit Foundry ausführt (opens in a new tab)
Weiterführende Literatur
- Ein ausführlicher Leitfaden zum Testen von Ethereum-Smart-Contracts (opens in a new tab)
- Wie man Ethereum-Smart-Contracts testet (opens in a new tab)
- MolochDAOs Unit-Testing-Leitfaden für Entwickler (opens in a new tab)
- Wie man Smart Contracts wie ein Rockstar testet (opens in a new tab)
Tutorials: Testen von Smart Contracts auf Ethereum
- Wie man eine Dapp in einem lokalen Multi-Client-Testnet entwickelt und testet – Anleitung zur Bereitstellung eines Smart Contracts in einem lokalen Testnet und zur Durchführung von Tests.
- Wie man Solidity-Smart-Contracts für Tests mockt – Fortgeschrittenes Tutorial zur Verwendung von Mock-Daten und zur Implementierung von Unit-Testing.
- Wie man Echidna verwendet, um Smart Contracts zu testen – Fortgeschrittene Ansätze für Fuzzing und das Testen von Smart Contracts.