$$\rightleftharpoonup{xx}$$
$$\longleftharp{xx}$$,
$$\longrightharp{xx}$$,
Studieninputs
In dieser Studie wurden zwei Solidity-Smart-Contracts als Verifikationseingaben verwendet. Ersteres war ein Simple DAO-ähnlicher Vertrag, der als Fallstudie für die Wiederaufnahme genutzt wurde. Der zweite war ein ausgedünnter Ledger-/State-Transition-Vertrag, der darauf ausgelegt war, Vertragsebenen-Einschränkungen gegen Doppelausgaben zu testen. Der ursprüngliche Solidity-Quellcode diente als Eingabe für die in diesem Protokoll definierten Abstraktions- und Verifikationsprozesse. Der allgemeine Transformationsprozess, der für solche Verträge verwendet wird, ist in Abbildung 1 dargestellt, die die schrittweise Transformation des Solidity-Quellcodes in die FSM-, Event-B- und SMV-Modelle während der Verifikation zeigt.
Modellierungsgrenze
Formale Modellierung konzentriert sich auf die Steuerungsflusslogik von Smart Contracts, einschließlich Funktionsein- und -austrittsverhaltens, interner Ausführung und Vertragszustandsübergängen. Die Sichtbarkeit der Funktionen (öffentlich, extern, intern und privat) wurde zusammen mit dem entsprechenden Call-Stack-Verhalten dargestellt, das für die Re-Entrancy-Analyse relevant ist. Die Arten abstrakter Übergänge (Anruf, Senden, Übertragung) wurden als Operationen für den Transfer von Ethern behandelt.
Vertragsebene-Invarianten wurden definiert, um die Transaktionseinzigartigkeit zu gewährleisten und Doppelausgaben innerhalb der Abstraktionsgrenze zu vermeiden. Um die Anforderungen an die Validierungsauswahl und Blockintegrität darzustellen, wurde die Protokoll-Logik-Abstraktionsschicht anhand der Protokollzustandsübergänge sowohl von Proof of Work als auch von Proof of Stake definiert.
Die Abstraktionsgrenze umfasste keine Netzwerkschicht-Elemente, einschließlich der Planung der zuzusendenden Nachrichten und Verzögerungen durch eine Vielzahl von Hops, Fork-Auflösung, Netzwerkgegner mit byzantinischen Strategien, Ethereum-Virtual-Machine-Semantik und Gas-Semantik, die von Netzwerkknoten kontrolliert wird, Ausnahmepropagation, asynchrone Ausführungen, komplexes Rückfallverhalten und Netzwerk-Finalität. Daher gelten die Ergebnisse der Bestimmung der doppelten Ausgaben nur für Vertragsebene-Invarianten und stellen keine netzwerkebene Vereinbarung über die Endgültigkeit dar.
Werkzeuge und Konfiguration
Die Rodin-Plattform wurde verwendet, um das Event-B-Modell (Version 3.7.0) zu modellieren, zu verfeinern, Beweisverpflichtungen zu erstellen und auszuführen, was es den PP-, ML-, SMT- und Atelier-B-Beweisern ermöglichte, Beweise automatisch und interaktiv auszuführen. nuXmv Version 2.0.0 wurde auf den generierten SMV-Modellen im vollständigen CTL-Explorationsmodus ausgeführt, um CTL-Modellprüfungen durchzuführen.
Alle Verifikationsausführungen wurden in einer kontrollierten Rechenumgebung unter Verwendung von Ubuntu 22.04 LTS, OpenJDK 11 und Python 3.10.12 durchgeführt. Web3 (7.6.0), NetworkX (3.4.2), Matplotlib (3.8.0), Graphviz (0.20.3), NumPy (1.26.4) und Pandas (2.2.2) wurden zur Implementierung von Simulations- und Visualisierungselementen verwendet. Dieses Design garantierte, dass formale Verifikations- und Simulationsergebnisse unter denselben Ausführungsbedingungen reproduziert werden konnten.
Transformations-Workflow
Dieser Verifikationsprozess hatte vier Phasen. Soliditätsverträge wurden zunächst in eine Finite State Machine (FSM-SC)-Darstellung übersetzt. Das FSM-SC-Modell wurde anschließend in Event-B codiert, mit klar festgelegten Invarianten und Verfeinerungsgraden. Die FSM-SC-Abstraktion wurde in nuXmv in ein SMV-Modell übersetzt. Die Verifikationsergebnisse wurden als Statistiken zur Nachweispflichtentlastung und CTL-Modellprüfung angegeben, und Gegenbeispiele wurden als Fälle bereitgestellt.
FSM-Bau
Jeder Vertrag wurde als endliche Zustandsmaschine abstrahiert, definiert als:

Wobei:
S = Menge von Zuständen
S₀ = Anfangszustand
T = Übergangsrelation
V = Sichtbarkeitskartierung
G = Schutzprädikate
A = Aktionen/Zustandsupdates.
Algorithmus 1: FSM-Konstruktion aus Solidity
Eingabe: Soliditäts-Quellcode
Ausgabe: FSM-SC
1) Den abstrakten Syntaxbaum des Solidity-Vertrags analysieren.
2) Erstelle den Anfangszustand S₀ aus der Konstruktordefinition.
3) Für jede Soliditätsfunktion f wird ein eigener Kontrollzustand S_f erstellt und die Sichtbarkeit V(f) ∈ {öffentlich, extern, intern, privat} erfasst.
4) Für jede Aussage innerhalb der Funktion f leiten Sie einen Übergang t ab, indem Sie Guard-Prädikate aus Regore/Assert-Bedingungen und Aktionen aus Zustandsvariablen-Updates extrahieren.
5) Übergang t zu T hinzufügen.
6) Erstelle explizite Übergangstypen für Ether-Transferoperationen (Aufruf, Senden, Übertragung), interne und externe Aufrufe, Delegiertenaufruf, Selbstzerstörung, tx.origin-Nutzung, bedingte Verzweigungen und Schleifenkonstruktionen.
7) FSM-SC = (S, S₀, T, V, G, A) zurückgeben.
Und jede Soliditätsfunktion ist mit einem anderen FSM-Steuerzustand verbunden. Für das Verständnis von Schwachstellen wurden schwachstellenrelevante Ausführungsflüsse, z. B. solche Flows mit externen Aufrufen gefolgt von Balance-Updates, explizit in geordnete Übergänge abstrahiert. Abbildung 2 zeigt ein Beispiel für ein FSM-SC-Diagramm für den SimpleDAO-ähnlichen Vertrag und zeigt, wie Eintrittszustände, externe Aufrufübergänge und Zustandsaktualisierungssequenzen während dieser Konstruktionsphase abstrahiert wurden.
Kodierung von FSM in Event-B
Der FSM-Übergang wurde als Event-B-Konstrukte dargestellt. Alle Übergänge entsprechen Ereignissen von Ereignis B, einschließlich bestimmter Wachen und Aktionen.
Algorithmus 2: FSM-zu-Event-B-Codierung
Eingang: FSM-SC
Ausgabe: Event-B-Maschine und Kontext
1) Definieren Sie STATE_SET und FUNKTION im Vertragskontext.
2) Variablen deklarieren, die den FSM-Kontrollzustand und den Vertragsniveau-Zustand repräsentieren.
3) Jeden FSM-Steuerzustand s ∈ S mit current_state ∈ STATE_SET darstellen.
4) Für jeden Übergang (s → s′, g, a) erstellen Sie ein Ereignis-B-Ereignis E_t mit:
5) WOBEI current_state = s ∧ g
6) DANN current_state := s′ ∥ anwenden(a)
7) Sichtbarkeitsbeschränkungen kodieren mit Guards, die von V(f) abgeleitet sind.
8) Invarianten inv1–inv9 definieren, um Sicherheits- und Konsistenzeigenschaften zu erfassen.
9) INITIALISIERUNG definieren, indem S₀ und Standardwerte zugewiesen werden.
Die Menge der Zustände, der aktuelle Zustand, die Funktionssichtbarkeit, der Aufrufstapel, der Transaktionszeitstempel, der Ether-Transferstatus, die Delegiertenaufruf-Flagge, die Selbstzerstörungsflagge und die Verifikationsbedingung sind einige der Variablen, die im Event-B-Modell erfasst werden. Die Invarianten (inv1-inv9) und die Aktionen der Initialisierungen (akt1-akt6) entsprechen denen der formalen Spezifikation. Abbildung 3 zeigt außerdem grafisch, wie die Schlüsselereignisse, die für Schwachstellen relevant sind, insbesondere re-entrancy-bezogene Übergänge, in der Event-B-Codierung verwaltet werden. Diese Abbildung erklärt, wie die strukturellen Muster des in Abbildung 2 gezeigten FSM-SC-Modells in verifizierbare Event-B-Ereignisse abgebildet werden.
Verfeinerungsstrategie
Es wurden zwei Stufen der Verfeinerung umgesetzt. Hochstufige Vertragskontrollfluss- und Kerninvarianten wurden auf abstrakter Ebene dargestellt. Das verfeinerte Niveau fügte vertragsspezifische Einschränkungen hinzu, darunter Call-Stack-Beschränkungen, Sichtbarkeitsbeschränkungen und Bedingungen zur Verhinderung von Wiedereintritt.
Algorithmus 3: Verfeinerung und Nachweis-Verpflichtung-Entlastung
Eingabe: Abstrakte Maschine und verfeinerte Maschine
Ausgabe: Erfüllte Beweisverpflichtungen und Statistiken
1) Erzeugung von Beweisverpflichtungen für die abstrakte Maschine in Rodin.
2) Ausführen aktivierter automatischer Prüfer und Aufzeichnen der Entladungsergebnisse.
3) Verfeinerungsnachweisverpflichtungen für die verfeinerte Maschine zu erstellen.
4) Automatische Beweise auf Verfeinerungsverpflichtungen anzuwenden.
5) Erfüllung der verbleibenden Verpflichtungen, wenn nötig, interaktiv.
6) Exportnachweisstatistiken und Statusberichte.
Die Beweisberichterstattung umfasste die Anzahl der Invarianten, Verfeinerungsstufen, erzeugte Beweispflichten, automatische Entladungsrate, interaktive Entladungsrate und endgültige Entladungsrate.
CTL-Eigenschaftsspezifikation und Modellprüfung
Die FSM-SC-Abstraktion wurde in ein SMV-Modell für zeitliche Verzweigungsverifikation in nuXmv übersetzt.
Algorithmus 4: FSM-zu-SMV- und CTL-Prüfung
Ausgabe: PASS/FAIL-Verifikationsergebnis und Gegenbeispiel-Traces (falls vorhanden)
1. Erfassen Sie die FSM-Steuerzustände als aufgezählten SMV-Variablenzustand.
2. Wandeln Sie FSM-Übergänge in bewachte Next(State)-Assignments um.
3. Halte Flaggen für schwachstellenrelevante Bedingungen, wie externe Anrufe und Balance-Updates.
4. CTL-Eigenschaften in nuXmv kodieren und Modellprüfungen durchführen.
5. Wenn eine Eigenschaft fehlschlägt, erzeugen Sie Gegenbeispiel-Spuren, die FSM-Übergangssequenzen repräsentieren.
CTL-Prüfungen umfassten Anforderungen an Wiedereinweisungsanordnungen, die Finalisierung von Zustandsupdates nach Übertragungsoperationen, die Begrenzung uneingeschränkter rekursiver Eingriffe in kritische Abschnitte und die Vermeidung von Deadlocks.
Sicherheitseigenschaften überprüft
Der Simple DAO-ähnliche Vertrag, der Re-Entrancy verhindert, wurde bestätigt, indem eine sichere Reihenfolge zwischen externen Aufrufen und Zustandsupdates über Invarianten und CTL-Constraints sichergestellt wurde. Wo erlaubt, überprüften diese Wächter Zugangskontrollbeschränkungen und stellten sicher, dass unautorisierte Übergänge durch Invarianten eingeschränkt wurden. Das reduzierte Hauptbuchmodell überprüfte die Invarianten der Transaktionseinzigartigkeit und der Konsistenz des Hauptbuchs auf Präventionsebene innerhalb des Vertrags.
Berichtete Ausgaben
Der Ergebnisbereich liefert Berichte zu FSM-Strukturmetriken, Event-B-Modellmetriken und Statistiken für den Nachweis der Verpflichtung und CTL-Verifikation. Die Ergebnisse des formalen Beweises und der CTL-Modellüberprüfung werden separat dargelegt, um den Nachweis von Korrektheitsgarantien durch Invarianten und den Nachweis einer Zeitverifikation mittels zeitlicher Verifikation zu unterscheiden.