Techblog

EVMuncher: Anti-Patterns in Smart Contracts finden

Von Jacek Varky
12. Dezember 2019

In diesem Artikel stelle ich EVMuncher vor. EVMuncher ist ein Open-Source-Tool, das Smart Contracts auf nicht-optimierten Code untersucht. Es zeigt, wieviel Gas dadurch verschwendet werden. Um zu verstehen wie EVMuncher funktioniert, erkläre ich zunächst folgende Punkte:

  • Wie funktioniert ein Smart Contract im Detail?
  • Welche Rolle spielt Gas?
  • Was ist ein Anti-Pattern?

Anschließend beschreibe ich, wie EVMuncher arbeitet.

Wie funktioniert ein Smart Contract?

Tutorials zum Thema Smart Contract schreiben gibt es viele. Jeder kann sich solch ein Tutorial durchlesen und danach einen einfach Smart Contract schreiben. Was aber hinter den Kulissen passiert, wird in den meisten Tutorials nicht beschrieben. Um die Funktionsweise von EVMuncher zu verstehen, ist dieses Wissen notwendig.

Einen Smart Contract schreibt man in der Regel in einer Hochsprache für Smart Contracts. Damit ist sie in Komplexität und Abstraktion von der Maschinensprache deutlich entfernt. Das bedeutet auch, dass die geschriebenen Befehle von der auszuführenden Maschine erst mal nicht verstanden werden; sie müssen erst von einem Compiler in die jeweilige Maschinensprache umgesetzt werden. Im Fall der Ethereum Blockchain ist die auszuführende Maschine die Ethereum Virtual Machine, kurz EVM.

Schauen wir uns ein Beispiel an.

Auf der linken Seite sehen wir den Solidity Code für einen einfach Smart Contract. Auf der rechten Seite sieht man den gleichen Smart Contract in Maschinensprache. Jede der Zahlen stellt entweder einen Befehl oder ein Datum dar. Genau mit dieser Darstellung arbeitet die EVM.

Wenn jetzt die get()-Funktion des Smart Contracts ausgeführt wird, geht die EVM durch das Kauderwelsch an Zahlen, springt an die Stelle, wo die get()-Funktion in Maschinensprache beschrieben wird, und führt den entsprechenden Code aus. Den gesamten Befehlssatz der EVM findet man im Yellow Paper (Link).

Stack-based Architektur

Um zu verstehen wie die EVM die Befehle abarbeitet, müssen wir die Architektur der EVM verstehen.

Die EVM basiert auf einer Stack-based Architektur: Hier werden alle Daten, die bei einem Befehl benötigt werden, vom Stack gepoppt, verarbeitet und das Ergebnis wird wieder auf den Stack gepusht. Ein Beispiel zeige ich in der folgenden Abbildung.

Hier wird zuerst der Wert 5 und danach der Wert 2 auf den Stack gepusht. Im nächsten Schritt wird der add-Befehl ausgeführt. Dafür werden die zuvor gepushten Werte vom Stack gepoppt, addiert und das Ergebnis, hier die 7, wieder auf den Stack gepusht.

Was ist Gas?

Jeder Befehl, der von der EVM ausgeführt wird, kostet etwas. Möchte man zum Beispiel den add-Befehl ausführen, muss man drei Einheiten an den Miner bezahlen. Diese Einheiten werden in der Ethereum Blockchain als Gas bezeichnet.

Wenn ein Anwender einen Smart Contract ausführen möchte, muss dieser genügend Gas mitgeben, damit die Miner den Smart Contract ausführen können und den neuen Status des Smart Contracts in der Blockchain speichern. Gibt der Anwender zu wenig Gas mit, ist die EVM nicht in der Lage, den gesamten Code auszuführen; sie bricht ab und der Smart Contract wird auf den alten Zustand zurückgesetzt.

Was ist ein Anti-Pattern?

Anti-Patterns beschreiben in der Softwareentwicklung Lösungsansätze mit schlechtem Programmierstil.

Anti-Patterns sind jedoch nicht auf den Programmierstil beschränkt, es gibt sie auch in der Übersetzung von Hochsprachen zu Maschinensprachen.

Antipattern       Pattern
  add                   pop
  pop                   pop

Auf der linken Seite ist ein Anti-Pattern, auf der rechten Seite sieht man das passende Pattern. Beim Anti-Pattern wird der add-Befehl verwendet. Der Befehl nimmt die obersten beiden Werte vom Stack, addiert diese Werte und pusht das Ergebnis auf dem Stack. Sobald der add-Befehl ausgeführt wurde, wird der pop-Befehl ausgeführt, welches den obersten Wert vom Stack entfernt. Das bedeutet, dass das Ergebnis des add-Befehls verworfen wird. Wir stellen fest, dass bei der Kombination aus add und pop am Ende zwei Werte vom Stack entfernt werden. Genauso gut können wir zwei pop-Befehle verwenden.

Da der add-Befehl drei Gas kostet und pop zwei Gas, können wir mit dem Pattern ein Gas im Vergleich zum Anti-Pattern einsparen. Solche Einsparungen deckt unser Tool EVMuncher auf.

Funktion von EVMuncher

EVMuncher analysiert den Maschinencode eines Smart Contracts auf Anti-Patterns. Die Anti-Pattern identifizierte Chen in dem Paper ‚Towards Saving Money in Using Smart Contracts ‘ (hier online bei IEEE nach Login). Er implementierte 24 Anti-Pattern in einem Tool mit dem Namen GasReducer. Dieses Tool steht jedoch nicht zur Verfügung. Wir haben uns dafür entschieden, selbst ein Tool zu schreiben und Open Source zu stellen: So enstand EVMuncher.

Smart-Contract-Entwickler können unter evmuncher.maibornwolff.de eine Smart-Contract-Adresse eingeben, EVMuncher holt sich den Maschinencode des Smart Contracts von der Ethereum Blockchain. Dieser Maschinencode wird dann auf Anti-Pattern analysiert. Am Ende der Analyse zeigt das Tool dem Anwender die Anzahl der verschwendeten Gas an.

Gas-schonend programmieren

Bei jeder Ausführung eines Smart Contracts wird Gas an den Miner bezahlt. Schaut man sich den Wechselkurs von Gas zu Euro oder Dollar an, wirkt das wie vernachlässigbare Summen. Dennoch hat die Ethereum-Blockchain den Anspruch, in Zukunft viel mehr Transaktionen zu verarbeiten und das Rückgrat des Web zu sein. Bei Millionen von Transkation und Smart-Contract-Ausführungen täglich summiert sich die Menge an verschwendetem Gas. Deswegen wollen wir mit dem Tool die Entwickler dazu animieren, ressourcenschonend zu arbeiten und sparsam mit dem Einsatz der Anwender umzugehen.

Neuen Kommentar schreiben

Public Comment form

  • Zulässige HTML-Tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd><p><h1><h2><h3>

Plain text

  • Keine HTML-Tags erlaubt.
  • Internet- und E-Mail-Adressen werden automatisch umgewandelt.
  • HTML - Zeilenumbrüche und Absätze werden automatisch erzeugt.

ME Landing Page Question