Ri 02/2018: Zurück in die Zukunft.

Ri 02/2018: Navigation
Ri 02/2018: Beitrag
Ethereum Smart Contracts:
Eine technische Einführung
Joachim Spalink*
Im folgenden Beitrag soll beleuchtet werden, welche Bedeutung sog. Smart Contracts bei Ethereum haben und wie Smart Contracts technisch gesehen funktionieren. Dabei geht es schwerpunktmäßig um die entwicklerseitige Betrachtung von Smart Contracts.[1] Wie sich zeigen wird, ist ein Smart Contract geschriebener Code[2], der z.B. Bezahlvorgänge automatisieren kann. Es handelt sich also – entgegen der Benamung – zunächst nicht um juristische Konstruktionen, sondern lediglich um einen Algorithmus[3], der bestimmte Wirkungen hervorbringt. Dabei sind Smart Contracts insbesondere für und bei Ethereum, einer der momentan wichtigsten Blockchain-Implementierungen, von entscheidender Bedeutung. Die nachfolgenden Ausführungen konzentrieren sich daher auf Ethereum Smart Contracts.
___STEADY_PAYWALL___I. Ethereum – ein kurzer geschichtlicher Überblick
Ethereum wurde am 25. Januar 2015 öffentlich vorgestellt. Vorausgegangen war die Veröffentlichung des Whitepapers[4] „Ethereum: A Next Generation Smart Contract & Decentralized Application Platform“ von Vitalik Buterin im Dezember 2013[5]. Im April 2014 wurde von Gavin Wood, einem Mitbegründer des Projekts, das Ethereum Yellowpaper[6] veröffentlicht, das die formale Spezifikation von Ethereum enthält.[7] Es folgten Implementierungen und Tests, bis das Netzwerk im Juli 2015 gestartet wurde, genannt Ethereum Frontier. Dieses Grundgerüst wurde im März 2016 durch Homestead ersetzt, was die Nutzung von Ethereum sicherer machte. Im nächsten Schritt, der sogenannten Phase Metropolis, sollten insbesondere Anwendungen für Endverbraucher enstehen.[8] In einer sich daran anschließenden Phase namens Serenity[9] soll dann der Konsensalgorithmus[10] von Proof of Work[11] auf Proof of Stake[12] (als „Casper“ bezeichnet) umgestellt werden.[13]
II. Smart Contracts als wesentlicher Bestandteil von Ethereum
Die Ausführungsumgebung von Ethereum ist standardmäßig „leblos“, was bedeutet, dass der Zustand aller Objekte in der Datenbank Blockchain gleich bleibt. Objekte können andere Nutzerkonten oder Smart Contracts sein, sie alle werden durch eine Adresse identifiziert. Erst dann, wenn ein Nutzer eine Transaktion[14] sendet, werden Zustände verändert. Je nach Ziel der Transaktion kann dies ein anderer „Account“ oder ein Smart Contract sein. Ist das Ziel ein anderer „Account“, so wird eine bestimmte Menge der Kryptowährung Ether transferiert. Ist das Ziel ein Smart Contract, wird dieser aktiviert und ausgeführt.[15] Smart Contracts sind nicht dauerhaft aktiv, wie gerne der Eindruck vermittelt wird.
1. Wie funktioniert ein Smart Contract auf der Plattform Ethereum?
SmartContracts werden bei Ethereum auf der sogenannten Ethereum Virtual Machine (EVM) ausgeführt. Die virtuelle Maschine verfügt über eine Stack-basierte[16] Architektur, die jedoch keiner standardmäßigen von Neumann-Architektur[17] entspricht. Der Code wird statt in einem allgemeinen verfügbaren Speicher in einem virtuellen ROM gespeichert. Bevor der Smart Contract auf der EVM laufen kann, muss er zu Bytecode kompiliert werden.[18] Außerdem findet vor der Ausführung einer Transaktion eine Überprüfung auf Validität[19] statt, dazu zählt beispielweise, ob genug Ether zur Ausführung vorhanden ist. Wird der Bytecode ausgeführt, geht die Maschine den Array[20] an Bytecode durch und führt die Operationen durch.[21]
Im Folgenden wird näher dargestellt, wie genau ein Smart Contract aufgebaut ist und woraus sich seine Wirkungsweise ergibt.
2. Der Smart Contract als Klasse
Der Smart Contract auf Ethereum ist zunächst eine sogenannte Klasse. Das beschreibt in der objektorientierten Programmierung[22] eine Bündelung von Daten und Funktionen. Man kann sich dies analog zu einem Gegenstand des täglichen Lebens vorstellen, wie z.B. einem Auto: Das Auto hat statische Eigenschaften (z.B. einen bestimmten Motor, eine bestimmte Farbe). Es verfügt aber auch über Möglichkeiten, seinen Zustand zu verändern (z.B. zu fahren) oder mit anderen Dingen zu kommunizieren (z.B. über ein Navigationssystem).
Wird von einer Klasse, die eine abstrakte Beschreibung darstellt, eine sogenannte Instanz erstellt, werden hier die spezifischen Eigenschaften in sogenannten Variablen der Klasse festgehalten (z.B. die spezifische Farbe eines einzelnen Autos, also die Instanz der Klasse „Auto“).
Über sogenannte Funktionen können Aktionen durchgeführt werden.
Bei der Klasse gibt es auch noch sogenannte Bezeichner zur Bestimmung der Sichtbarkeit, dies bedeutet, dass manche Daten und Funktionen von außen sichtbar sind bzw. nur für interne Zwecke zu verwenden sind.
Konstruktoren sind Funktionen, die genauso wie die Klasse genannt werden und beim Erstellen einer Instanz ausgeführt werden. Sie können dafür verwendet werden, um Variablen der Instanz zu setzen oder bestimmte Vorgänge bei der Erstellung auszuführen.
3. Die wesentlichen Bestandteile der Klasse „contract“ auf Ethereum
Smart Contracts auf Ethereum können beispielweise mit der Programmiersprache Solidity[23] geschrieben werden. Dabei besteht eine hohe Vergleichbarkeit zu üblichen Klassen in der objektorientierten Programmierung. Listing 1 zeigt einen Beispielscode für eine Klasse (letztlich schon einen kleinen Smart Contract) in Solidity, Listing 2 zeigt den äquivalenten Code in der (sehr verbreiteten) Programmiersprache Java.
In diesem Beispiel wird eine Zahl an eine bestimmte Stelle innerhalb der Klasse geschrieben. Diese Zahl kann dann auch von anderen gelesen werden. Der Name der Klasse lautet „SimpleStorage“, sie besitzt eine Variable namens „storedData“ vom Typ „uint“, das sind ganze Zahlen >=0. Die Funktion set(uint x) setzt die Variable „storedData“ auf den übergebenen Wert und ist öffentlich durch den die Sichtbarkeit hervorrufenden Bezeichner „public“. Das Keyword „view“ in der Methodensignatur der get() Methode bedeutet, dass der Wert nicht verändert werden kann, diese Methode gibt einfach nur die Variable (also die gesetzte Zahl) in „storedData“ zurück. Eine weitere Möglichkeit (die in dem Beispiel nicht verwendet wird) ist der Gebrauch von Funktions-Modifikatoren. Damit kann das Verhalten von Funktionen beeinflusst werden, zum Beispiel durch automatisches Prüfen einer Bedingung vor Ausführen der Funktion. Modifikatoren können vererbt[24] sowie überschrieben werden.
Um mit einem Smart Contract etwas zu veräußern (wie etwa „Anteile“ bei einem ICO oder in dem nachfolgenden Beispiel virtuelle Katzen) werden meist Tokens verwendet, welche ebenfalls einen Smart Contract darstellen können. Es gibt unterschiedliche Arten von Tokens. Die größten Unterschiede (tokentypes) bestehen zwischen fungible tokens (ERC20-Standard)[25] und non-fungible tokens (ERC721-Standard)[26]. Tokens nach dem ERC721-Standard sind einzigartig, nicht untereinander tauschbar und nicht teilbar. Dagegen erinnern ERC20-Tokens an eine Währung; ein Token kann mit einem Token desselben Typs getauscht werden wie der Euro, er hat den gleichen Wert wie ein anderer ERC20-Token (also z.B. ein anderer Ether). Des Weiteren kann ein fungible token auch in kleinere Einheiten aufgeteilt werden, wie etwa der Euro in Cent.
Mit dem Smart Contract lässt sich zum einen über eine Website interagieren, zum anderen kann aber auch ein eigener client[27] verwendet werden, z.B. basierend auf Javascript web3.js.[28] Hier finden sich Funktionen, um mit der Adresse des Smart Contracts die Schnittstellendefinition[29] abzufragen und daraufhin Methoden auf diesen Smart Contract aufzurufen. Bei jeder Interaktion mit Ethereum wird eine Transaktionsgebühr (in Ether) fällig. Diese ist abhängig von der Komplexität des Smart Contracts und davon, wie schnell die Miner sich darum kümmern sollen, dass die Transaktion in die Blockchain eingefügt wird. Die Miner widmen sich zuerst Transaktionen mit einer hohen Transaktionsgebühr, da dies lukrativer ist. Zudem benötigt jede Transaktion, wie ein Auto, Treibstoff, sog. „Gas“ (Einheit: „Gwei“). Die Smart Contracts werden in der EVM ausgeführt, würden jedoch unter Umständen nie stoppen.[30] Wenn für den Abschluss einer Transaktion nicht ausreichend Gas mitgesendet wird, führt die EVM den Code nicht vollständig aus, die Ausführung kommt zum Stehen und die Transaktion wird nicht in die Blockchain geschrieben.
III. Beispiel für einen Smart Contract auf Ethereum
Ein ganz simpler Smart Contract ist in Listing 3 zu sehen. Er findet sich auch offiziell auf der Ethereum-Seite[31]. Der Smart Contract erstellt und verwaltet einen Token mit dem Namen MyToken. Bei der Erstellung dieses Tokens auf der Ethereum-Blockchain wird dem Ersteller des Contracts die gesamte Menge an Tokens zugewiesen, was in der Funktion „MyToken“ geschieht. Sollen Tokens an andere Adressen[32] gesendet werden, geschieht dies über die „transfer“-Funktion. Die ersten Tokens gehen immer von der Adresse des Smart Contract-Erstellers aus zu anderen, von ihm bestimmten Adressen. Sobald die Inhaber anderer Adressen über Tokens verfügen können, können mit diesen sie auch handeln, solange die Prüfungen in der „transfer“-Funktion dies zulassen. Geprüft wird in diesem Fall, ob der Sender genügend Tokens besitzt, welche versendet werden sollen und ob es zu keinem Überlauf[33] kommt, wenn die gesendeten Tokens dem Empfänger gutgeschrieben werden. Ein Überlauf ist denkbar, wenn die Datentypen nur einen begrenzten Bereich von Zahlen repräsentieren können. Als ein umfangreicheres Beispiel für Smart Contracts können die CryptoKitties[34] herangezogen werden. Letztlich handelt es sich um ein Spiel, bei dem man „digital cats“ züchten und sammeln kann. Jede der virtuellen Katzen ist einzigartig und auf der Blockchain gespeichert. Da die Smart Contracts öffentlich und auf der Ethereum-Blockchain einsehbar sind, kann sich auch jedermann jede der CryptoKitties anschauen. Dazu kann beispielweise etherchain.org, etherscan.io oder ein anderes Browsing-Tool verwendet werden.
Eine CryptoKitty besteht aus einem Kern-Smart Contract (0x06012c8cf97bead5deae237070f9587f8e7a266d) und mehreren weiteren Smart Contracts, in welche möglichst viel Funktionalität ausgelagert wurde, da das Ändern und Austauschen eines Smart Contracts mit sehr viel Aufwand verbunden ist. Der Kern-Smart Contract enthält dann die Adressen zu den anderen Smart Contracts, die weitere Funktionalität zur Verfügung stellen.
Besieht man sich die Smart Contracts, so wird deutlich, dass die „Katzen“ letztlich ERC721-Tokens sind; alle 15 Minuten wird über einen Zeitraum von einem Jahr eine Generation CryptoKitties erzeugt (totalSupply). Die verschiedenen CryptoKitties-Smart Contracts verfügen über Funktionen, die das Paaren, Erzeugen, Verkaufen und Versenden der virtuellen Katzen regeln. So existiert ein Smart Contract für eine Auktion (0xb1690c08e213a35ed9bab7b318de14420fb57d8c), soweit über die Website eine dieser Katzen zum Verkauf angeboten werden soll. Dieser Smart Contract stellt Funktionen zum Erstellen einer Auktion sowie zum Bieten bei einer Auktion bereit und beschreibt Events[35], bei erstellten und erfolgreich beendeten Auktionen, um Basisfunktionalitäten abzudecken. Bei Interaktionen mit dem Auktions-Smart Contract behalten die Ersteller des Auktions-Smart Contract einen Teil der Kryptowährung Ether ein, in der der „Kaufpreis“ und die Transaktionsgebühr zu entrichten sind.
IV. Fazit: Smart Contracts sind keine Verträge
Dieser kleine Einblick in Aufbau und Funktionen von Smart Contracts sollte entwicklerseitig aufzeigen:
Smart Contracts sind keine Verträge, sondern lediglich in Programmiersprache geschriebene Algorithmen,[36] die sich ausführen lassen. Insofern können beispielsweise Bezahlvorgänge ohne Online-Girokonto bei einer Bank elektronisch ausgeführt werden und im Rahmen eines Vertragsverhältnisses zusätzliche Bedeutung erlangen. Auch die Übertragung einer CryptoKitty im Rahmen einer Auktion gegen eine bestimmte Menge Ether erfolgt im Rahmen eines echten juristischen Vertrags. Smart Contracts können sich auch teilweise selbst ausführen; letztlich hängt dies aber von der Programmierung im Einzelnen ab.
A
A
* Joachim Spalink ist Softwareentwickler bei der Cetonis GmbH in Stuttgart.
[1] Ethereum Development Tutorial, https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial (zuletzt abgerufen am 27. Mai 2018).
[2] Otto, Ri 2017, 24 (26).
[3] Otto, Ri 2017, 24 (25).
[4] Das sog. Whitepaper gibt einen Überblick über die Leistungen und Funktionen. https://github.com/ethereum/wiki/wiki/White-Paper (zuletzt abgerufen am 27. Mai 2018).
[5] https://web.archive.org/web/20131219030753/http://vitalik.ca/ethereum.html (zuletzt abgerufen am 27. Mai 2018)
[6] Das sog. Yellowpaper ist nur ein Folgepapier zum Whitepaper, Wood, Dr. G., „Ethereum: A Secure Decentralised Gerealised Transaction Ledger“, http://gavwood.com/Paper.pdf (zuletzt abgerufen am 27. Mai 2018).
[7] Ebd.
[8] Als Beispiele werden hier z.B. einfache Interfaces für Nicht-Techniker genannt.
[9] https://blog.ethereum.org/2015/03/03/ethereum-launch-process/ (zuletzt abgerufen am 27. Mai 2018)
[10] Konsensalgorithmus ist ein Verfahren, um zu einer Einigung innerhalb eines Netzwerks zu kommen, vgl. Otto, Ri 2017, 5 (10).
[11] Vgl. Otto, Ri 2017, 5 (10).
[12] Vgl. Otto, Ri 2017, 5 (10), Ethereum Development Tutorial, https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ (zuletzt abgerufen am 27. Mai 2018).
[13] Buterin, V., “A Prehistory of the Ethereum Protocol”, https://vitalik.ca/2017-09-15-prehistory.html (zuletzt abgerufen am 27. Mai 2018).
[14] Vgl. zum Begriff: Otto, Ri 2017, 5 (7).
[15] Ethereum Development Tutorial, https://github.com/ethereum/wiki/wiki/Ethereum-Development-Tutorial (zuletzt abgerufen am 27. Mai 2018).
[16] Stack-basiert bedeutet: die Anweisungen befinden sich in einer Art Stapel und werden nacheinander ausgeführt.
[17] Bei der von-Neumann-Architektur sind die Komponenten des Rechners über einen sog. Bus verbunden. Im Speicher liegen sowohl der Programmcode als auch die Daten.
[18] Vgl. Otto, Ri 2017, 24 (30).
[19] Validität meint hier keine Bestätigung inhaltlicher Wahrheit, sondern lediglich die Bestätigung der Einhaltung systemischer Anforderungen. Zum Mining-Prozess siehe Otto, Ri 2017, 5 (10).
[20] Array ist eine Datenstruktur vergleichbar mit einer Liste.
[21] Dameron, M., „An Ethereum Technical Specification“, 11. Mai 2018,https://github.com/chronaeon/beigepaper/blob/master/beigepaper.pdf.
[22] Objektorientierte Programmierung bedeutet, dass die Strukturen der Software an der Wirklichkeit ausgerichtet werden. Einzelne Objekte kommunizieren miteinander über deren Methoden.
[23] „Introduction to Smart Contracts“, https://solidity.readthedocs.io/en/v0.4.24/introduction-to-smart-contracts.html (zuletzt abgerufen am 27. Mai 2018).
[24] Dies meint hier: es gibt eine Basisklasse mit diesen Modifikatoren analog zu beispielweise einer Basisklasse Fahrzeug, in welcher nur allgemeine Funktionen vorhanden sind. PKW und LKW als „Unterklassen“ erben Methoden, welche jedes Fahrzeug aufweist (z.B. „Fahren“), spezielle Methoden werden nur für den LKW oder PKW in den entsprechenden Klassen implementiert.
[25] https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md (zuletzt abgerufen am 27. Mai 2018).
[26] https://github.com/ethereum/eips/issues/721 (zuletzt abgerufen am 27. Mai 2018).
[27] Ein Client ist eine Software, mit der auf Schnittstellen zugegriffen werden kann.
[28] Ethereum JavaScript API, https://github.com/ethereum/web3.js (zuletzt abgerufen am 27. Mai 2018).
[29] Schnittstellendefinition ist eine Beschreibung einer Schnittstelle. Über Schnittstellen kommunizieren Programme untereinander.
[30] Vgl. Otto, Ri 2017, 5 (10); 24 (32).
[31] https://ethereum.org/token (zuletzt abgerufen am 27. Mai 2018).
[32] Vgl. Otto, Ri 2017, 24 (30, 31).
[33] Überlauf meint: Der maximale Bereich wird überschritten, den ein Datentyp darstellen kann. Der Datentyp startet dann wieder am Anfang und macht mit dem Rest weiter; analog zu einem Autotacho, der überläuft und wieder bei 0 beginnt.
[34] https://www.cryptokitties.co/ (zuletzt abgerufen am 27. Mai 2018).
[35] Events sind sozusagen Signale auf die reagiert werden kann.
[36] I.e. ein „Computerprogramm“, Otto, Ri 2017, 24 (25).
Titelbild: © ApricotBrandy via Adobe Stock, #159088614