Weiter zum Hauptinhalt
Change page

Sicherheit von Smart Contracts

Seite zuletzt aktualisiert: 14. Februar 2026

Smart Contracts sind äußerst flexibel und in der Lage, große Mengen an Werten und Daten zu kontrollieren, während sie eine unveränderliche Logik auf der Grundlage von auf der Blockchain bereitgestelltem Code ausführen. So ist ein lebendiges Ökosystem aus vertrauenswürdigen und dezentralisierten Applikationen entstanden, das viele Vorteile gegenüber den alten Systemen bietet. Sie bieten auch eine Chance für Angreifer, die durch die Ausnutzung von Schwachstellen in Smart Contracts Profit machen wollen.

Öffentliche Blockchains wie Ethereum erschweren das Problem der Sicherung von Smart Contracts zusätzlich. Der Code eines bereitgestellten Vertrags kann normalerweise nicht geändert werden, um Sicherheitslücken zu schließen, während die aus Smart Contracts gestohlenen Vermögenswerte aufgrund der Unveränderlichkeit extrem schwer zu verfolgen und meistens nicht wiederherstellbar sind.

Obwohl die Zahlen variieren, wird geschätzt, dass der Gesamtbetrag des gestohlenen oder verlorenen Werts aufgrund von Sicherheitsmängeln in Smart Contracts weit über 1 Milliarde US-Dollar beträgt. Dazu gehören hochkarätige Vorfälle wie der DAO-Hackopens in a new tab (3,6 Mio. ETH gestohlen, was nach heutigen Preisen über 1 Mrd. USD wert ist), der Parity Multi-Sig-Wallet-Hackopens in a new tab (30 Mio. USD an Hacker verloren) und das Problem mit der eingefrorenen Parity-Walletopens in a new tab (über 300 Mio. USD in ETH für immer gesperrt).

Die oben genannten Probleme machen es für Entwickler zwingend erforderlich, in die Entwicklung sicherer, robuster und widerstandsfähiger Smart Contracts zu investieren. Die Sicherheit von Smart Contracts ist eine ernste Angelegenheit, die jeder Entwickler lernen sollte. In diesem Ratgeber werden Sicherheitsüberlegungen für Ethereum-Entwickler behandelt und Ressourcen zur Verbesserung der Smart Contract-Sicherheit vorgestellt.

Voraussetzungen

Stellen Sie sicher, dass Sie mit den Grundlagen der Smart-Contract-Entwicklung vertraut sind, bevor Sie sich mit der Sicherheit befassen.

Richtlinien für die Erstellung sicherer Ethereum-Smart-Contracts

1. Entwerfen Sie ordnungsgemäße Zugriffskontrollen

In Smart Contracts können Funktionen, die als public oder external markiert sind, von beliebigen extern verwalteten Konten (EOAs) oder Vertragskonten aufgerufen werden. Die Festlegung der öffentlichen Sichtbarkeit von Funktionen ist notwendig, wenn Sie möchten, dass andere Personen mit Ihrem Vertrag interagieren können. Funktionen, die als private gekennzeichnet sind, können jedoch nur von Funktionen innerhalb des Smart Contracts aufgerufen werden, nicht von externen Konten. Jedem Netzwerkteilnehmer Zugang zu Vertragsfunktionen zu gewähren, kann zu Problemen führen, insbesondere wenn dies bedeutet, dass jeder Nutzer sensible Operationen durchführen kann (z. B. das Minting neuer Token).

Um die unbefugte Nutzung von Smart Contract-Funktionen zu verhindern, müssen sichere Zugriffskontrollen implementiert werden. Die Zugriffskontrolle beschränkt die Möglichkeit, bestimmte Funktionen in einem Smart Contract zu nutzen, auf zugelassene Stellen, wie z. B. die für die Verwaltung des Vertrags zuständigen Konten. Das Ownable-Muster und die rollenbasierte Steuerung sind zwei nützliche Muster zur Implementierung der Zugriffskontrolle in Smart Contracts:

Ownable-Muster

Beim Ownable-Modell wird während der Vertragserstellung eine Adresse als „Eigentümer“ des Vertrags festgelegt. Geschützten Funktionen wird ein OnlyOwner-Modifikator zugewiesen, der sicherstellt, dass der Vertrag die Identität der aufrufenden Adresse authentifiziert, bevor die Funktion ausgeführt wird. Aufrufe geschützter Funktionen von anderen Adressen als der des Vertragseigentümers werden immer zurückgewiesen, um unerwünschte Zugriffe zu verhindern.

Rollenbasierte Zugriffskontrolle

Die Registrierung einer einzigen Adresse als Owner in einem Smart Contract birgt das Risiko der Zentralisierung und stellt einen Single Point of Failure dar. Wenn die Kontoschlüssel des Eigentümers gefährdet sind, können Angreifer den entsprechenden Vertrag angreifen. Aus diesem Grund kann die Verwendung eines rollenbasierten Zugriffskontrollmusters mit mehreren administrativen Konten eine bessere Option sein.

Bei der rollenbasierten Zugriffskontrolle wird der Zugriff auf sensible Funktionen auf eine Reihe von vertrauenswürdigen Teilnehmern verteilt. So kann beispielsweise ein Konto für das Minting von Token zuständig sein, während ein anderes Konto Upgrades durchführt oder den Vertrag pausiert. Durch diese dezentrale Zugriffskontrolle werden „einzelne Ausfallpunkte“ eliminiert und die Vertrauensvoraussetzungen für Benutzer reduziert.

Verwendung von Wallets mit Multi-Signature-Option

Ein weiterer Ansatz zur Implementierung einer sicheren Zugriffskontrolle ist die Verwendung eines Multi-Signatur-Kontos, um einen Vertrag zu verwalten. Im Gegensatz zu einem regulären EOA sind Multi-Signatur-Konten das Eigentum von mehreren Instanzen und erfordern Signaturen von einer Mindestanzahl von Konten, beispielsweise 3 von 5, um Transaktionen auszuführen.

Die Verwendung einer Mehrfachsignatur für die Zugriffskontrolle führt eine zusätzliche Sicherheitsebene ein, da Aktionen auf dem Zielvertrag die Zustimmung von mehreren Parteien erfordern. Dies ist besonders nützlich, wenn die Verwendung der Ownable-Funktion erforderlich ist, da es für einen Angreifer oder einen böswilligen Insider schwieriger ist, sensible Vertragsfunktionen für böswillige Zwecke zu manipulieren.

2. Verwenden Sie die Anweisungen require(), assert() und revert(), um Vertragsoperationen zu schützen

Wie bereits erwähnt, kann jeder Nutzer öffentliche Funktionen in Ihrem Smart Contract aufrufen, sobald dieser auf der Blockchain veröffentlicht wurde. Da Sie nicht im Voraus wissen können, wie externe Konten mit einem Vertrag interagieren werden, ist es ideal, interne Schutzmaßnahmen gegen problematische Funktionen zu implementieren, bevor Sie sie Veröffentlichen. Sie können korrektes Verhalten in Smart Contracts durch die Verwendung der Anweisungen require(), assert() und revert() erzwingen, um Ausnahmen auszulösen und Zustandsänderungen rückgängig zu machen, wenn die Ausführung bestimmte Anforderungen nicht erfüllt.

require(): require wird am Anfang von Funktionen definiert und stellt sicher, dass vordefinierte Bedingungen erfüllt sind, bevor die aufgerufene Funktion ausgeführt wird. Eine require-Anweisung kann verwendet werden, um Nutzereingaben zu validieren, Zustandsvariablen zu überprüfen oder die Identität des aufrufenden Kontos zu authentifizieren, bevor eine Funktion ausgeführt wird.

assert(): assert() wird verwendet, um interne Fehler zu erkennen und Verletzungen von „Invarianten“ in Ihrem Code zu überprüfen. Eine Invariante ist eine logische Behauptung über den Zustand eines Vertrags, die für alle Funktionsausführungen gelten soll. Ein Beispiel für eine Invariante ist das maximale Gesamtangebot oder der maximale Saldo eines Token-Vertrags. Die Verwendung von assert() stellt sicher, dass Ihr Vertrag niemals einen anfälligen Zustand erreicht, und falls doch, werden alle Änderungen an den Zustandsvariablen rückgängig gemacht.

revert(): revert() kann in einer if-else-Anweisung verwendet werden, die eine Ausnahme auslöst, wenn die erforderliche Bedingung nicht erfüllt ist. Der folgende Beispielvertrag verwendet revert(), um die Ausführung von Funktionen zu schützen:

1pragma solidity ^0.8.4;
2
3contract VendingMachine {
4 address owner;
5 error Unauthorized();
6 function buy(uint amount) public payable {
7 if (amount > msg.value / 2 ether)
8 revert("Nicht genügend Ether bereitgestellt.");
9 // Führen Sie den Kauf durch.
10 }
11 function withdraw() public {
12 if (msg.sender != owner)
13 revert Unauthorized();
14
15 payable(msg.sender).transfer(address(this).balance);
16 }
17}
Alles anzeigen

3. Testen Sie Smart Contracts und überprüfen Sie die Korrektheit des Codes

Die Unveränderlichkeit des Codes, der in der Ethereum Virtual Machine läuft, bedeutet, dass Smart Contracts in der Entwicklungsphase ein höheres Maß an Qualitätsbewertung erfordern. Wenn Sie Ihren Vertrag ausgiebig testen und auf unerwartete Ergebnisse achten, verbessern Sie die Sicherheit erheblich und schützen Ihre Nutzer auf lange Sicht.

Die übliche Methode besteht darin, kleine Unit-Tests mit Scheindaten zu schreiben, die der Vertrag von den Nutzern erhalten würde. Unit-Tests sind gut geeignet, um die Funktionalität bestimmter Funktionen zu testen und sicherzustellen, dass ein Smart Contract wie erwartet funktioniert.

Leider sind Unit-Tests für die Verbesserung der Sicherheit von Smart Contracts nur wenig effektiv, wenn sie nur isoliert angewendet werden. Ein Unit-Test kann beweisen, dass eine Funktion bei Mock-Daten korrekt ausgeführt wird, Unit-Tests sind jedoch nur so effektiv wie die Tests, die verfasst werden. Das macht es schwierig, unentdeckte Sonderfälle und Schwachstellen zu erkennen, die die Sicherheit Ihres Smart Contracts gefährden könnten.

Ein besserer Ansatz ist es, Unit-Tests mit eigenschaftsbasierten Tests zu kombinieren, die mittels statischer und dynamischer Analyse durchgeführt werden. Die statische Analyse stützt sich auf Low-Level-Darstellungen wie Kontrollflussgraphenopens in a new tab und abstrakte Syntaxbäumeopens in a new tab, um erreichbare Programmzustände und Ausführungspfade zu analysieren. In der Zwischenzeit führen dynamische Analysetechniken, wie z. B. Smart-Contract-Fuzzingopens in a new tab, Vertragscode mit zufälligen Eingabewerten aus, um Operationen zu erkennen, die Sicherheitseigenschaften verletzen.

Die formale Verifizierung ist eine weitere Technik zur Überprüfung der Sicherheitseigenschaften in Smart Contracts. Im Gegensatz zu regulären Tests kann die formale Verifizierung schlüssig beweisen, dass ein Smart Contract keine Fehler enthält. Dies wird erreicht, indem eine formale Spezifikation erstellt wird, die die gewünschten Sicherheitseigenschaften festhält, um dann zu gewährleisten, dass ein Formmodell des Vertrags mit dieser Spezifikation übereinstimmt.

4. Bitten Sie um eine unabhängige Überprüfung Ihres Codes

Nachdem Sie Ihren Vertrag getestet haben, sollten Sie andere bitten, den Quellcode auf Sicherheitsprobleme zu prüfen. Beim Testen werden nicht alle Schwachstellen in einem Smart Contract aufgedeckt, eine unabhängige Überprüfung erhöht jedoch die Wahrscheinlichkeit, dass Schwachstellen entdeckt werden.

Audits

Die Beauftragung eines Smart Contract-Audits ist eine Möglichkeit zur Durchführung einer unabhängigen Code-Überprüfung. Prüfer spielen eine wichtige Rolle, wenn es darum geht sicherzustellen, dass Smart Contracts sicher und frei von Qualitätsmängeln und Planungsfehlern sind.

Dennoch sollten Sie Audits nicht als Wunderwaffe betrachten. Smart Contract-Audits können nicht jeden Fehler aufspüren und sind hauptsächlich dazu gedacht, eine zusätzliche Runde von Überprüfungen durchzuführen, die dazu beitragen können, Probleme zu entdecken, die von den Entwicklern während der anfänglichen Entwicklung und Tests übersehen wurden. Sie sollten auch die Best Practices für die Zusammenarbeit mit Prüfern befolgen, z. B. den Code ordnungsgemäß dokumentieren und Inline-Kommentare hinzufügen, um den Nutzen eines Smart Contract-Audits zu maximieren.

Bug-Bounties

Die Einrichtung eines Prämienprogramms für das Aufdecken von Fehlern (Bug Bounty Program) ist ein weiterer Ansatz zur Durchführung externer Codeüberprüfungen. Ein Bug Bounty ist eine finanzielle Belohnung für Personen (in der Regel Whitehat-Hacker), die Schwachstellen in einer Applikation entdecken.

Wenn sie richtig eingesetzt werden, geben Bug Bounties den Mitgliedern der Hacker-Community einen Anreiz, Ihren Code auf kritische Fehler zu untersuchen. Ein Praxisbeispiel ist der „Infinite Money Bug“, der es einem Angreifer ermöglicht hätte, eine unbegrenzte Menge an Ether auf Optimismopens in a new tab zu erzeugen, einem Layer-2-Protokoll, das auf Ethereum läuft. Glücklicherweise entdeckte ein White-Hat-Hacker den Fehleropens in a new tab und benachrichtigte das Team, wodurch er eine hohe Prämie erhieltopens in a new tab.

Eine sinnvolle Strategie besteht darin, die Auszahlung eines Bug-Bounty-Programms im Verhältnis zur Höhe der auf dem Spiel stehenden Mittel festzulegen. Dieser Ansatz, der als „Scaling Bug Bountyopens in a new tab“ bezeichnet wird, bietet Einzelpersonen finanzielle Anreize, Schwachstellen verantwortungsvoll offenzulegen, anstatt sie auszunutzen.

5. Befolgen Sie bei der Entwicklung von Smart Contracts bewährte Praktiken

Die Verfügbarkeit von Audits und Bug Bounties entbindet Sie nicht von Ihrer Verantwortung, qualitativ hochwertigen Code zu schreiben. Die Sicherheit von Smart Contracts beginnt mit der Einhaltung geeigneter Planungs- und Entwicklungsprozesse:

  • Speichern Sie den gesamten Code in einem Versionskontrollsystem, z. B. Git

  • Nehmen Sie alle Codeänderungen über Pull Requests vor

  • Stellen Sie sicher, dass Pull-Requests mindestens einen unabhängigen Reviewer haben. Wenn Sie alleine an einem Projekt arbeiten, sollten Sie überlegen, ob Sie nicht andere Entwickler finden und mit diesen Code-Reviews austauschen

  • Verwenden Sie eine Entwicklungsumgebung zum Testen, Kompilieren und Bereitstellen von Smart Contracts

  • Führen Sie Ihren Code durch grundlegende Code-Analyse-Tools wie Cyfrin Aderynopens in a new tab, Mythril und Slither. Idealerweise sollten Sie dies tun, noch bevor eine Pull-Anfrage eingebunden wird, und die Unterschiede in der Ergebnisausgabe vergleichen

  • Stellen Sie sicher, dass Ihr Code ohne Fehler kompiliert wird und der Solidity-Compiler keine Warnungen ausgibt

  • Dokumentieren Sie Ihren Code ordnungsgemäß (mit NatSpecopens in a new tab) und beschreiben Sie Details zur Vertragsarchitektur in einer leicht verständlichen Sprache. Dies erleichtert es anderen, Ihren Code zu überprüfen und zu kontrollieren.

6. Implementieren Sie robuste Notfallwiederherstellungspläne

Die Entwicklung sicherer Zugriffskontrollen, die Implementierung von Funktionsmodifikatoren und andere Vorschläge können die Sicherheit von Smart Contracts verbessern, jedoch können sie die Möglichkeit böswilliger Angriffe nicht ausschließen. Der Aufbau sicherer Smart Contracts erfordert eine „Vorbereitung auf Fehler“ und einen Notfallplan, um wirksam auf Angriffe reagieren zu können. Ein angemessener Notfallwiederherstellungsplan umfasst einige oder alle der folgenden Komponenten:

Vertrags-Upgrades

Obwohl Ethereum Smart Contracts standardmäßig unveränderlich sind, ist es möglich, durch die Verwendung von Upgrade-Mustern einen gewissen Grad an Veränderbarkeit zu erreichen. Die Aktualisierung von Verträgen ist dann erforderlich, wenn ein kritischer Fehler Ihren alten Vertrag unbrauchbar macht und die Einführung einer neuen Logik die sinnvollste Option darstellt.

Die Mechanismen zur Aktualisierung von Verträgen funktionieren unterschiedlich, wobei jedoch das „Proxy-Muster“ einer der beliebtesten Ansätze für die Aktualisierung von Smart Contracts ist. Proxy-Musteropens in a new tab teilen den Zustand und die Logik einer Anwendung auf zwei Verträge auf. Der erste Vertrag (ein so genannter „Proxy-Vertrag“) speichert Zustandsvariablen (z. B. Benutzerguthaben), während der zweite Vertrag (ein so genannter „Logik-Vertrag“) den Code für die Ausführung von Vertragsfunktionen enthält.

Konten interagieren mit dem Proxy-Vertrag, der alle Funktionsaufrufe an den Logikvertrag mithilfe des Low-Level-Aufrufs delegatecall()opens in a new tab weiterleitet. Im Gegensatz zu einem regulären Nachrichtenaufruf stellt delegatecall() sicher, dass der an der Adresse des Logikvertrags ausgeführte Code im Kontext des aufrufenden Vertrags ausgeführt wird. Das bedeutet, dass der Logikvertrag immer in den Speicher des Proxys schreibt (anstatt in seinen eigenen Speicher) und die ursprünglichen Werte von msg.sender und msg.value erhalten bleiben.

Die Übertragung von Aufrufen an den Logikvertrag erfordert die Speicherung seiner Adresse im Speicher des Proxy-Vertrags. Um die Logik des Vertrags zu aktualisieren, muss daher nur ein anderer Logikvertrag eingesetzt und die neue Adresse im Proxy-Vertrag gespeichert werden. Da nachfolgende Aufrufe des Proxy-Vertrags automatisch an den neuen Logik-Vertrag weitergeleitet werden, hätten Sie den Vertrag „aktualisiert“, ohne den Code tatsächlich zu ändern.

Mehr zum Thema Vertrags-Upgrades.

Not-Stopps

Wie bereits erwähnt, können umfangreiche Prüfungen und Tests unmöglich alle Fehler in einem Smart Contract aufdecken. Wenn eine Schwachstelle in Ihrem Code nach der Veröffentlichung auftritt, ist es unmöglich, sie zu beheben, da Sie den Code, der unter der Vertragsadresse läuft, nicht ändern können. Außerdem kann die Implementierung von Upgrade-Mechanismen (z. B. Proxy-Muster) einige Zeit in Anspruch nehmen (sie erfordern oft die Zustimmung verschiedener Parteien), was den Angreifern nur mehr Zeit gibt, um mehr Schaden anzurichten.

Die einzige Möglichkeit besteht darin, eine „Not-Aus“-Funktion zu implementieren, die Aufrufe anfälliger Funktionen in einem Vertrag blockiert. Notausschalter bestehen in der Regel aus den folgenden Komponenten:

  1. Eine globale Boolesche Variable, die angibt, ob sich der Smart Contract in einem gestoppten Zustand befindet oder nicht. Diese Variable wird bei der Einrichtung des Vertrags auf false gesetzt, wechselt aber zu true, sobald der Vertrag angehalten wird.

  2. Funktionen, die bei ihrer Ausführung auf die boolesche Variable verweisen. Auf diese Funktionen kann zugegriffen werden, wenn der Smart Contract in Betrieb ist, und sie werden unzugänglich, wenn die Notausfunktion ausgelöst wird.

  3. Eine Entität, die Zugriff auf die Not-Stopp-Funktion hat, welche die boolesche Variable auf true setzt. Um böswillige Aktionen zu verhindern, kann der Aufruf dieser Funktion auf eine vertrauenswürdige Adresse (z. B. den Vertragsinhaber) beschränkt werden.

Sobald der Vertrag den Notausschalter aktiviert, sind bestimmte Funktionen nicht mehr aufrufbar. Dies wird erreicht, indem die ausgewählten Funktionen in einen Modifikator verpackt werden, der auf die globale Variable verweist. Nachfolgend finden Sie ein Beispielopens in a new tab, das eine Implementierung dieses Musters in Verträgen beschreibt:

1// Dieser Code wurde nicht professionell geprüft und gibt keine Zusicherungen bezüglich Sicherheit oder Korrektheit. Benutzung auf eigene Gefahr.
2
3contract EmergencyStop {
4
5 bool isStopped = false;
6
7 modifier stoppedInEmergency {
8 require(!isStopped);
9 _;
10 }
11
12 modifier onlyWhenStopped {
13 require(isStopped);
14 _;
15 }
16
17 modifier onlyAuthorized {
18 // Autorisierung von msg.sender hier prüfen
19 _;
20 }
21
22 function stopContract() public onlyAuthorized {
23 isStopped = true;
24 }
25
26 function resumeContract() public onlyAuthorized {
27 isStopped = false;
28 }
29
30 function deposit() public payable stoppedInEmergency {
31 // Einzahlungslogik hier
32 }
33
34 function emergencyWithdraw() public onlyWhenStopped {
35 // Notfall-Auszahlung hier
36 }
37}
Alles anzeigen

Dieses Beispiel zeigt die grundlegenden Merkmale von Notstopps:

  • isStopped ist ein Boolescher Wert, der zu Beginn false ergibt und true, wenn der Vertrag in den Notfallmodus wechselt.

  • Die Funktionsmodifikatoren onlyWhenStopped und stoppedInEmergency überprüfen die Variable isStopped. stoppedInEmergency wird verwendet, um Funktionen zu steuern, die unzugänglich sein sollten, wenn der Vertrag anfällig ist (z. B. deposit()). Aufrufe dieser Funktionen werden einfach zurückgewiesen.

onlyWhenStopped wird für Funktionen verwendet, die während eines Notfalls aufrufbar sein sollten (z. B. emergencyWithdraw()). Diese Funktionen können zur Lösung des Problems beitragen, weshalb sie nicht in der Liste der „eingeschränkten Funktionen“ aufgeführt sind.

Die Verwendung einer Notstopp-Funktion ist eine wirksame Notlösung für den Umgang mit schwerwiegenden Schwachstellen in Ihrem Smart Contract. Allerdings müssen die Nutzer darauf vertrauen können, dass die Entwickler sie nicht aus eigennützigen Gründen aktivieren. Zu diesem Zweck kann die Kontrolle über den Notstopp dezentralisiert werden, indem er entweder einem On-Chain-Abstimmungsmechanismus, einer Zeitsperre oder der Genehmigung durch eine Multisig-Wallet unterworfen wird.

Ereignisüberwachung

Ereignisseopens in a new tab ermöglichen es Ihnen, Aufrufe von Smart-Contract-Funktionen zu verfolgen und Änderungen an Zustandsvariablen zu überwachen. Ideal ist es, wenn Sie Ihren Smart Contract so programmieren, dass er immer dann ein Ereignis auslöst, wenn eine Partei eine sicherheitskritische Aktion durchführt (z. B. das Abheben von Guthaben).

Die Protokollierung von Ereignissen und deren Überwachung off-chain bietet Einblicke in Vertragsvorgänge und hilft, böswillige Handlungen schneller zu entdecken. Das bedeutet, dass Ihr Team schneller auf Hacks reagieren und Maßnahmen ergreifen kann, um die Auswirkungen auf die Benutzer zu minimieren, z. B. das Anhalten von Funktionen oder die Durchführung eines Upgrades.

Sie können sich auch für ein handelsübliches Überwachungsprogramm entscheiden, das automatisch Warnmeldungen weiterleitet, sobald jemand mit Ihren Verträgen interagiert. Mit diesen Tools können Sie benutzerdefinierte Warnmeldungen erstellen, die auf verschiedenen Auslösern basieren, z. B. dem Transaktionsvolumen, der Häufigkeit von Funktionsaufrufen oder den spezifischen Funktionen. Sie könnten zum Beispiel eine Warnung programmieren, die eingeht, wenn der in einer einzigen Transaktion abgehobene Betrag einen bestimmten Schwellenwert überschreitet.

7. Entwerfen Sie sichere Governance-Systeme

Vielleicht möchten Sie Ihre Anwendung dezentralisieren, indem Sie die Kontrolle über die wichtigsten Smart Contracts an Community-Mitglieder übergeben. In diesem Fall wird das Smart-Contract-System ein Governance-Modul enthalten - einen Mechanismus, der es den Mitgliedern der Gemeinschaft ermöglicht, administrative Aktionen über ein On-Chain-Governance-System zu genehmigen. So können die Token-Inhaber beispielsweise über einen Vorschlag abstimmen, einen Proxy-Vertrag auf eine neue Implementierung zu aktualisieren.

Eine dezentrale Verwaltung kann von Vorteil sein, insbesondere weil sie die Interessen von Entwicklern und Endnutzern in Einklang bringt. Dennoch können die Mechanismen zur Steuerung von Smart Contracts bei falscher Umsetzung neue Risiken mit sich bringen. Ein plausibles Szenario ist, dass ein Angreifer enorme Stimmkraft (gemessen an der Anzahl der gehaltenen Token) durch die Aufnahme eines Flash-Loans erlangt und einen bösartigen Vorschlag durchsetzt.

Eine Möglichkeit, Probleme im Zusammenhang mit der Onchain-Governance zu vermeiden, ist die Verwendung eines Timelocksopens in a new tab. Eine Zeitsperre verhindert, dass ein Smart Contract bestimmte Aktionen ausführt, bis eine bestimmte Zeitspanne verstrichen ist. Andere Strategien bestehen darin, jedem Token ein „Stimmgewicht“ zuzuweisen, das sich danach richtet, wie lange er gesperrt war, oder die Stimmkraft einer Adresse in einem historischen Zeitraum (z. B. 2-3 Blöcke in der Vergangenheit) anstelle des aktuellen Blocks zu messen. Beide Methoden reduzieren die Möglichkeit, schnell Stimmrecht anzuhäufen, um On-Chain-Abstimmungen zu beeinflussen.

Mehr über das Entwerfen sicherer Governance-Systemeopens in a new tab, verschiedene Abstimmungsmechanismen in DAOsopens in a new tab und die gängigen DAO-Angriffsvektoren, die DeFi nutzenopens in a new tab, finden Sie in den geteilten Links.

8. Reduzieren Sie die Komplexität im Code auf ein Minimum

Traditionelle Softwareentwickler sind mit dem KISS-Prinzip („Keep it simple, stupid“) vertraut, das davon abrät, unnötige Komplexität in das Softwaredesign einzubringen. Dies entspricht der seit langem vertretenen Auffassung, dass „komplexe Systeme auf komplexe Weise versagen“ und anfälliger für kostspielige Fehler sind.

Beim Schreiben von Smart Contracts ist es besonders wichtig, die Inhalte einfach zu halten, da Smart Contracts potenziell große Wertbeträge kontrollieren. Ein Tipp zur Vereinfachung beim Schreiben von Smart Contracts ist die Wiederverwendung bestehender Bibliotheken, wie z. B. OpenZeppelin Contractsopens in a new tab, wo immer dies möglich ist. Da diese Bibliotheken von den Entwicklern ausgiebig geprüft und getestet wurden, verringert sich durch ihre Verwendung die Wahrscheinlichkeit, dass durch das Schreiben neuer Funktionen von Grund auf Fehler eingeführt werden.

Ein weiterer allgemeiner Ratschlag lautet, kleine Funktionen zu schreiben und Verträge modulartig zu halten, indem die Logik auf mehrere Verträge aufgeteilt wird. Das Schreiben von einfacherem Code verringert nicht nur die Angriffsfläche in einem Smart Contract, sondern macht es auch einfacher, Rückschlüsse auf die Korrektheit des Gesamtsystems zu ziehen und mögliche Planungsfehler frühzeitig zu erkennen.

9. Schützen Sie sich vor häufigen Schwachstellen bei Smart Contracts

Reentrancy

Die EVM erlaubt keine Nebenläufigkeit, was bedeutet, dass zwei Verträge, die an einem Nachrichtenaufruf beteiligt sind, nicht gleichzeitig ausgeführt werden können. Ein externer Aufruf unterbricht die Ausführung und den Speicher des aufrufenden Vertrags, bis der Aufruf erwidert wird, woraufhin die Ausführung normal fortgesetzt wird. Dieser Prozess kann formell als Übertragung des Kontrollflussesopens in a new tab an einen anderen Vertrag beschrieben werden.

Die Übertragung des Kontrollflusses an nicht vertrauenswürdige Verträge ist zwar meist harmlos, kann aber Probleme verursachen, wie z. B. Wiederholungsangriffe. Ein Wiederholungsangriff liegt vor, wenn ein böswilliger Vertrag in einen gefährdeten Vertrag eingreift, bevor der ursprüngliche Funktionsaufruf abgeschlossen ist. Diese Art des Angriffs lässt sich am besten anhand eines Beispiels erklären.

Betrachten Sie einen einfachen Smart Contract („Opfer"), der es jedem ermöglicht, Ether einzuzahlen und abzuheben:

1// Dieser Vertrag ist anfällig. Nicht in der Produktion verwenden
2
3contract Victim {
4 mapping (address => uint256) public balances;
5
6 function deposit() external payable {
7 balances[msg.sender] += msg.value;
8 }
9
10 function withdraw() external {
11 uint256 amount = balances[msg.sender];
12 (bool success, ) = msg.sender.call.value(amount)("");
13 require(success);
14 balances[msg.sender] = 0;
15 }
16}
Alles anzeigen

Dieser Vertrag stellt eine withdraw()-Funktion zur Verfügung, die es Nutzern ermöglicht, zuvor in den Vertrag eingezahlte ETH abzuheben. Bei der Bearbeitung einer Abhebung führt der Vertrag die folgenden Vorgänge durch:

  1. Überprüft das ETH-Guthaben des Nutzers
  2. Sendet Guthaben an die anrufende Adresse
  3. Setzt das Guthaben auf 0 zurück und verhindert so weitere Abhebungen durch den Nutzer

Die withdraw()-Funktion im Victim-Vertrag folgt einem „Prüfungen-Interaktionen-Auswirkungen“-Muster. Sie prüft, ob die für die Ausführung notwendigen Bedingungen erfüllt sind (d. h. der Nutzer hat ein positives ETH-Guthaben) und führt die Interaktion durch, indem sie ETH an die Adresse des Aufrufers sendet, bevor sie die Auswirkungen der Transaktion anwendet (d. h. das Guthaben des Nutzers verringert).

Wenn withdraw() von einem extern verwalteten Konto (EOA) aufgerufen wird, wird die Funktion wie erwartet ausgeführt: msg.sender.call.value() sendet ETH an den Aufrufer. Wenn msg.sender jedoch ein Smart-Contract-Konto ist, das withdraw() aufruft, löst das Senden von Geldern mit msg.sender.call.value() auch die Ausführung von Code aus, der an dieser Adresse gespeichert ist.

Stellen Sie sich vor, dass dies der Code ist, der an der Vertragsadresse veröffentlicht wird:

1 contract Attacker {
2 function beginAttack() external payable {
3 Victim(victim_address).deposit.value(1 ether)();
4 Victim(victim_address).withdraw();
5 }
6
7 function() external payable {
8 if (gasleft() > 40000) {
9 Victim(victim_address).withdraw();
10 }
11 }
12}
Alles anzeigen

Dieser Vertrag ist darauf ausgelegt, drei Dinge zu tun:

  1. Eine Einzahlung von einem anderen Konto akzeptieren (wahrscheinlich von der EOA des Angreifers)
  2. 1 ETH in den Vertrag des Opfers einzahlen
  3. Die im Smart Contract gespeicherten 1 ETH abheben

Daran ist nichts auszusetzen, außer dass Attacker eine weitere Funktion hat, die withdraw() in Victim erneut aufruft, wenn das vom eingehenden msg.sender.call.value übrig gebliebene Gas mehr als 40.000 beträgt. Dies gibt Attacker die Möglichkeit, Victim erneut aufzurufen und mehr Geld abzuheben, bevor die erste Ausführung von withdraw abgeschlossen ist. Der Kreislauf sieht folgendermaßen aus:

1- EOA des Angreifers ruft `Attacker.beginAttack()` mit 1 ETH auf
2- `Attacker.beginAttack()` zahlt 1 ETH in `Victim` ein
3- `Attacker` ruft `withdraw()` in `Victim` auf
4- `Victim` prüft das Guthaben von `Attacker` (1 ETH)
5- `Victim` sendet 1 ETH an `Attacker` (was die Standardfunktion auslöst)
6- `Attacker` ruft `Victim.withdraw()` erneut auf (beachten Sie, dass `Victim` das Guthaben von `Attacker` aus der ersten Auszahlung noch nicht reduziert hat)
7- `Victim` prüft das Guthaben von `Attacker` (das immer noch 1 ETH beträgt, da die Auswirkungen des ersten Aufrufs noch nicht angewendet wurden)
8- `Victim` sendet 1 ETH an `Attacker` (was die Standardfunktion auslöst und `Attacker` erlaubt, die `withdraw`-Funktion erneut aufzurufen)
9- Der Prozess wiederholt sich, bis `Attacker` das Gas ausgeht. An diesem Punkt kehrt `msg.sender.call.value` zurück, ohne weitere Auszahlungen auszulösen
10- `Victim` wendet schließlich die Ergebnisse der ersten Transaktion (und der nachfolgenden) auf seinen Zustand an, so dass das Guthaben von `Attacker` auf 0 gesetzt wird
Alles anzeigen

Da das Guthaben des Aufrufers nicht auf 0 gesetzt wird, bevor die Funktion ausgeführt wurde, können nachfolgende Aufrufe erfolgreich sein und dem Aufrufer ermöglichen, sein Guthaben mehrmals abzuheben. Diese Art von Angriff kann genutzt werden, um die Gelder eines Smart Contracts zu entwenden, so wie es beim DAO-Hack von 2016opens in a new tab geschah. Reentrancy-Angriffe sind auch heute noch ein kritisches Problem für Smart Contracts, wie öffentliche Listen von Reentrancy-Exploitsopens in a new tab zeigen.

So verhindert man Wiederholungsangriffe

Ein Ansatz zum Umgang mit Reentrancy ist die Befolgung des Checks-Effects-Interactions-Mustersopens in a new tab. Dieses Modell ordnet die Ausführung von Funktionen so an, dass Code, der vor der Ausführung notwendige Überprüfungen durchführt, zuerst kommt, gefolgt von Code, der den Vertragsstatus manipuliert, und Code, der mit anderen Verträgen oder EOAs interagiert, als letztes erfolgt.

Das Prüfungen-Auswirkungen-Interaktionen-Muster wird in einer überarbeiteten Version des Victim-Vertrags verwendet, die unten gezeigt wird:

1contract NoLongerAVictim {
2 function withdraw() external {
3 uint256 amount = balances[msg.sender];
4 balances[msg.sender] = 0;
5 (bool success, ) = msg.sender.call.value(amount)("");
6 require(success);
7 }
8}

Dieser Vertrag führt eine Prüfung des Guthabens des Nutzers durch, wendet die Auswirkungen der withdraw()-Funktion an (indem das Guthaben des Nutzers auf 0 zurückgesetzt wird) und fährt dann mit der Interaktion fort (dem Senden von ETH an die Adresse des Nutzers). Auf diese Weise wird sichergestellt, dass der Vertrag seinen Speicher vor dem externen Aufruf aktualisiert und die Bedingung der Wiederverknüpfung, die den ersten Angriff ermöglichte, beseitigt. Der Attacker-Vertrag könnte immer noch NoLongerAVictim zurückrufen, aber da balances[msg.sender] auf 0 gesetzt wurde, werden zusätzliche Abhebungen einen Fehler auslösen.

Eine andere Möglichkeit ist die Verwendung einer gegenseitigen Ausschlusssperre (allgemein als „Mutex“ bezeichnet), die einen Teil des Vertragsstatus sperrt, bis ein Funktionsaufruf abgeschlossen ist. Dies wird durch eine boolesche Variable implementiert, die vor der Ausführung der Funktion auf true gesetzt wird und nach Abschluss des Aufrufs auf false zurückgesetzt wird. Wie im folgenden Beispiel zu sehen ist, schützt die Verwendung einer „Mutex“ eine Funktion vor wiederholten Aufrufen, während der ursprüngliche Aufruf noch in Bearbeitung ist, wodurch Wiederholungsangriffe effektiv verhindert werden.

1pragma solidity ^0.7.0;
2
3contract MutexPattern {
4 bool locked = false;
5 mapping(address => uint256) public balances;
6
7 modifier noReentrancy() {
8 require(!locked, "Wiedereintritt blockiert.");
9 locked = true;
10 _;
11 locked = false;
12 }
13 // Diese Funktion ist durch einen Mutex geschützt, so dass reentrante Aufrufe von innerhalb `msg.sender.call` `withdraw` nicht erneut aufrufen können.
14 // Die `return`-Anweisung wird zu `true` ausgewertet, wertet aber dennoch die `locked = false`-Anweisung im Modifikator aus
15 function withdraw(uint _amount) public payable noReentrancy returns(bool) {
16 require(balances[msg.sender] >= _amount, "Kein Guthaben zum Abheben.");
17
18 balances[msg.sender] -= _amount;
19 (bool success, ) = msg.sender.call{value: _amount}("");
20 require(success);
21
22 return true;
23 }
24}
Alles anzeigen

Sie können auch ein Pull-Paymentsopens in a new tab-System verwenden, bei dem Nutzer Gelder von den Smart Contracts abheben müssen, anstatt eines „Push-Payments“-Systems, das Gelder an Konten sendet. Dies verhindert die Möglichkeit, unbeabsichtigt Code an unbekannten Adressen auszulösen (und kann auch bestimmte Denial-of-Service-Angriffe verhindern).

Ganzzahl-Unterläufe und -Überläufe

Ein Integer-Überlauf tritt auf, wenn das Ergebnis einer arithmetischen Operation außerhalb des zulässigen Wertebereichs liegt, so dass es auf den niedrigsten darstellbaren Wert „überläuft“. Zum Beispiel kann ein uint8 nur Werte bis zu 2^8-1=255 speichern. Arithmetische Operationen, die zu Werten führen, die höher als 255 sind, führen zu einem Überlauf und setzen uint auf 0 zurück, ähnlich wie der Kilometerzähler eines Autos auf 0 zurückgesetzt wird, sobald er den maximalen Kilometerstand (999999) erreicht.

Ganzzahl-Unterläufe treten aus ähnlichen Gründen auf: die Ergebnisse einer arithmetischen Operation fallen unter den zulässigen Bereich. Angenommen, Sie versuchen, 0 in einem uint8 zu dekrementieren, würde das Ergebnis einfach auf den maximal darstellbaren Wert (255) überlaufen.

Sowohl Integer-Überläufe als auch -Unterläufe können zu unerwarteten Änderungen an den Zustandsvariablen eines Vertrags führen und eine ungeplante Ausführung zur Folge haben. Das folgende Beispiel zeigt, wie ein Angreifer einen arithmetischen Überlauf in einem Smart Contract ausnutzen kann, um eine ungültige Operation durchzuführen:

1pragma solidity ^0.7.6;
2
3// Dieser Vertrag soll als Zeit-Tresor dienen.
4// Nutzer können in diesen Vertrag einzahlen, aber für mindestens eine Woche nicht abheben.
5// Nutzer können die Wartezeit auch über die einwöchige Wartezeit hinaus verlängern.
6
7/*
81. TimeLock bereitstellen
92. Attack mit der Adresse von TimeLock bereitstellen
103. Attack.attack aufrufen und 1 Ether senden. Sie können Ihren Ether sofort abheben.
11
12Was ist passiert?
13Attack hat einen Überlauf bei TimeLock.lockTime verursacht und konnte vor Ablauf der einwöchigen Wartezeit abheben.
14*/
15
16contract TimeLock {
17 mapping(address => uint) public balances;
18 mapping(address => uint) public lockTime;
19
20 function deposit() external payable {
21 balances[msg.sender] += msg.value;
22 lockTime[msg.sender] = block.timestamp + 1 weeks;
23 }
24
25 function increaseLockTime(uint _secondsToIncrease) public {
26 lockTime[msg.sender] += _secondsToIncrease;
27 }
28
29 function withdraw() public {
30 require(balances[msg.sender] > 0, "Unzureichendes Guthaben");
31 require(block.timestamp > lockTime[msg.sender], "Sperrzeit nicht abgelaufen");
32
33 uint amount = balances[msg.sender];
34 balances[msg.sender] = 0;
35
36 (bool sent, ) = msg.sender.call{value: amount}("");
37 require(sent, "Senden von Ether fehlgeschlagen");
38 }
39}
40
41contract Attack {
42 TimeLock timeLock;
43
44 constructor(TimeLock _timeLock) {
45 timeLock = TimeLock(_timeLock);
46 }
47
48 fallback() external payable {}
49
50 function attack() public payable {
51 timeLock.deposit{value: msg.value}();
52 /*
53 wenn t = aktuelle Sperrzeit, dann müssen wir x so finden, dass
54 x + t = 2**256 = 0
55 also x = -t
56 2**256 = type(uint).max + 1
57 also x = type(uint).max + 1 - t
58 */
59 timeLock.increaseLockTime(
60 type(uint).max + 1 - timeLock.lockTime(address(this))
61 );
62 timeLock.withdraw();
63 }
64}
Alles anzeigen
Wie man Integer-Unterläufe und -Überläufe verhindert

Ab Version 0.8.0 weist der Solidity-Compiler Code zurück, der zu Integer-Unterläufen und -Überläufen führt. Verträge, die mit einer niedrigeren Compiler-Version kompiliert wurden, sollten jedoch entweder Prüfungen für Funktionen durchführen, die arithmetische Operationen beinhalten, oder eine Bibliothek (z. B. SafeMathopens in a new tab) verwenden, die auf Unter-/Überlauf prüft.

Orakel-Manipulation

Orakel beziehen Off-Chain-Informationen und senden sie On-Chain, damit Smart Contracts sie verwenden können. Mit Oracles können Sie Smart Contracts entwickeln, die mit Off-Chain-Systemen wie Kapitalmärkten zusammenarbeiten und dadurch ihre Anwendungsmöglichkeiten stark erweitern.

Aber wenn das Oracle manipuliert wird und falsche Daten auf die Blockchain sendet, werden Smart Contracts basierend auf falschen Eingaben ausgeführt, was Probleme verursachen kann. Dies ist die Grundlage des „Orakelproblems“, bei dem es darum geht sicherzustellen, dass die Informationen aus einem Blockchain-Orakel korrekt, aktuell und zeitnah sind.

Ein ähnliches Sicherheitsproblem ist die Nutzung eines On-Chain-Oracles, wie zum Beispiel einer dezentralen Börse, um den aktuellen Preis eines Assets zu ermitteln. Kreditplattformen in der Branche der dezentralen Finanzen (DeFi) tun dies oft, um den Wert der Sicherheiten eines Nutzers zu bestimmen und festzulegen, wie viel er sich leihen kann.

Die DEX-Preise sind häufig korrekt, was vor allem darauf zurückzuführen ist, dass Arbitrageure die Gleichheit auf den Märkten wiederherstellen. Die sind aber anfällig für Manipulationen, besonders wenn das On-Chain-Oracle die Assetpreise anhand von historischen Handelsmustern berechnet (was meistens der Fall ist).

So könnte ein Angreifer beispielsweise den Spotpreis eines Assets künstlich in die Höhe treiben, indem er einen Blitzkredit aufnimmt, kurz bevor er mit Ihrem Kreditvertrag interagiert. Die Abfrage der DEX nach dem Preis des Assets würde einen höheren als den normalen Wert ergeben (da die große „Kaufbestellung“ des Angreifers die Nachfrage nach dem Asset verzerrt), so dass er mehr Geld leihen kann, als er sollte. Solche „Flash-Darlehensangriffe“ wurden genutzt, um das Vertrauen in Preis-Orakel bei DeFi-Anwendungen auszunutzen, was Protokolle Millionen an verlorenen Guthaben gekostet hat.

So verhindert man Orakelmanipulation

Die Mindestanforderung zur Vermeidung von Orakel-Manipulationopens in a new tab ist die Verwendung eines dezentralen Orakel-Netzwerks, das Informationen aus mehreren Quellen abfragt, um Single Points of Failure zu vermeiden. In den meisten Fällen verfügen dezentrale Orakel über eingebaute kryptoökonomische Anreize, die die Nodes des Orakels dazu bringen, korrekte Informationen zu melden, was sie sicherer macht als zentralisierte Orakel.

Wenn Sie vorhaben, ein On-Chain-Oracle nach Assetpreisen zu befragen, sollten Sie eines in Erwägung ziehen, das einen zeitgewichteten Durchschnittspreis (TWAP) verwendet. Ein TWAP-Orakelopens in a new tab fragt den Preis eines Vermögenswerts zu zwei verschiedenen Zeitpunkten ab (die Sie ändern können) und berechnet den Kassakurs auf der Grundlage des erhaltenen Durchschnitts. Die Wahl längerer Zeiträume schützt Ihr Protokoll vor Preismanipulationen, da große Aufträge, die erst kürzlich ausgeführt wurden, keinen Einfluss auf die Preise der Assets haben können.

Ressourcen zur Smart-Contract-Sicherheit für Entwickler

Tools zur Analyse von Smart Contracts und zur Überprüfung der Code-Korrektheit

  • Test-Tools und -BibliothekenSammlung von branchenüblichen Tools und Bibliotheken zur Durchführung von Unit-Tests, statischer Analyse und dynamischer Analyse von Smart Contracts.

  • Tools zur formalen VerifizierungTools zur Überprüfung der funktionalen Korrektheit in Smart Contracts und zur Prüfung von Invarianten.

  • Smart-Contract-Auditing-DiensteListe von Organisationen, die Smart-Contract-Auditing-Dienste für Ethereum-Entwicklungsprojekte anbieten.

  • Bug-Bounty-PlattformenPlattformen zur Koordinierung von Bug-Bounties und zur Belohnung der verantwortungsvollen Offenlegung kritischer Schwachstellen in Smart Contracts.

  • Fork Checkeropens in a new tabEin kostenloses Online-Tool zur Überprüfung aller verfügbaren Informationen zu einem geforkten Vertrag.

  • ABI Encoderopens in a new tabEin kostenloser Online-Dienst zur Kodierung Ihrer Solidity-Vertragsfunktionen und Konstruktorargumente.

  • Aderynopens in a new tabStatischer Analysator für Solidity, der die abstrakten Syntaxbäume (AST) durchläuft, um vermutete Schwachstellen zu identifizieren und Probleme in einem leicht verständlichen Markdown-Format auszugeben.

Tools zur Überwachung von Smart Contracts

Tools für die sichere Verwaltung von Smart Contracts

  • Safeopens in a new tabEine auf Ethereum laufende Smart-Contract-Wallet, die eine Mindestanzahl von Personen zur Genehmigung einer Transaktion erfordert, bevor sie stattfinden kann (M-aus-N).

  • OpenZeppelin Contractsopens in a new tabVertragsbibliotheken zur Implementierung von Verwaltungsfunktionen, einschließlich Vertragseigentum, Upgrades, Zugriffskontrollen, Governance, Anhaltbarkeit und mehr.

Smart-Contract-Auditing-Dienste

  • ConsenSys Diligenceopens in a new tabEin Smart-Contract-Auditing-Dienst, der Projekte im gesamten Blockchain-Ökosystem dabei unterstützt sicherzustellen, dass ihre Protokolle startklar und zum Schutz der Nutzer ausgelegt sind.

  • CertiKopens in a new tabEin Blockchain-Sicherheitsunternehmen, das Pionierarbeit bei der Anwendung modernster formaler Verifizierungstechnologie auf Smart Contracts und Blockchain-Netzwerke leistet.

  • Trail of Bitsopens in a new tabEin Cybersicherheitsunternehmen, das Sicherheitsforschung mit einer Angreifermentalität kombiniert, um Risiken zu reduzieren und Code zu stärken.

  • PeckShieldopens in a new tabEin Blockchain-Sicherheitsunternehmen, das Produkte und Dienstleistungen für die Sicherheit, den Datenschutz und die Benutzerfreundlichkeit des gesamten Blockchain-Ökosystems anbietet.

  • QuantStampopens in a new tabEin Auditing-Dienst, der die allgemeine Einführung der Blockchain-Technologie durch Sicherheits- und Risikobewertungsdienste erleichtert.

  • OpenZeppelinopens in a new tabEin auf Smart-Contract-Sicherheit spezialisiertes Unternehmen, das Sicherheitsaudits für verteilte Systeme anbietet.

  • Runtime Verificationopens in a new tabEin Sicherheitsunternehmen, das sich auf die formale Modellierung und Verifizierung von Smart Contracts spezialisiert hat.

  • Hackenopens in a new tabEin Web3-Cybersicherheits-Auditor, der einen 360-Grad-Ansatz für die Blockchain-Sicherheit verfolgt.

  • Nethermindopens in a new tabSolidity- und Cairo-Auditing-Dienste, die die Integrität von Smart Contracts und die Sicherheit der Nutzer auf Ethereum und Starknet gewährleisten.

  • HashExopens in a new tabHashEx konzentriert sich auf die Prüfung von Blockchains und Smart Contracts, um die Sicherheit von Kryptowährungen zu gewährleisten, und bietet Dienstleistungen wie die Entwicklung von Smart Contracts, Penetrationstests und Blockchain-Beratung an.

  • Code4renaopens in a new tabEine wettbewerbsorientierte Audit-Plattform, die Anreize für Experten im Bereich Smart-Contract-Sicherheit schafft, Schwachstellen zu finden und dabei zu helfen, Web3 sicherer zu machen.

  • CodeHawksopens in a new tabEine Plattform für wettbewerbsorientierte Audits, die Wettbewerbe zum Auditing von Smart Contracts für Sicherheitsforscher veranstaltet.

  • Cyfrinopens in a new tabEin Kraftpaket für Web3-Sicherheit, das Krypto-Sicherheit durch Produkte und Smart-Contract-Auditing-Dienste fördert.

  • ImmuneBytesopens in a new tabEin Web3-Sicherheitsunternehmen, das Sicherheitsaudits für Blockchain-Systeme durch ein Team erfahrener Prüfer und erstklassiger Tools anbietet.

  • Oxorioopens in a new tabSmart-Contract-Audits und Blockchain-Sicherheitsdienste mit Expertise in EVM, Solidity, ZK, Cross-Chain-Technologie für Krypto-Unternehmen und DeFi-Projekte.

  • Inferenceopens in a new tabSicherheits-Audit-Unternehmen, spezialisiert auf Smart-Contract-Audits für EVM-basierte Blockchains. Dank der fachkundigen Prüfer werden potenzielle Probleme identifiziert und umsetzbare Lösungen vorgeschlagen, um diese Probleme vor der Bereitstellung zu beheben.

Bug-Bounty-Plattformen

  • Immunefiopens in a new tabEine Bug-Bounty-Plattform für Smart Contracts und DeFi-Projekte, auf der Sicherheitsforscher Code überprüfen, Schwachstellen aufdecken, bezahlt werden und Krypto sicherer machen.

  • HackerOneopens in a new tabEine Plattform zur Koordination von Schwachstellen und Bug-Bounties, die Unternehmen mit Penetrationstestern und Cybersicherheitsforschern verbindet.

  • HackenProofopens in a new tabEine Experten-Bug-Bounty-Plattform für Krypto-Projekte (DeFi, Smart Contracts, Wallets, CEX und mehr), auf der Sicherheitsprofis Triage-Dienste anbieten und Forscher für relevante, verifizierte Fehlerberichte bezahlt werden.

  • Sherlockopens in a new tabEin Underwriter in Web3 für die Sicherheit von Smart Contracts, bei dem Auszahlungen an Auditoren über Smart Contracts verwaltet werden, um sicherzustellen, dass relevante Fehler fair bezahlt werden.

  • CodeHawksopens in a new tabEine wettbewerbsorientierte Bug-Bounty-Plattform, auf der Auditoren an Sicherheitswettbewerben und -herausforderungen sowie (bald) an ihren eigenen privaten Audits teilnehmen.

Veröffentlichungen bekannter Schwachstellen und Exploits von Smart Contracts

Herausforderungen zum Erlernen der Smart-Contract-Sicherheit

Bewährte Praktiken zur Sicherung von Smart Contracts

Tutorials zur Sicherheit von Smart Contracts

War dieser Artikel hilfreich?