Solidity | Programmiersprache von Ethereum

Solidity ist eine vertragsorientierte Programmiersprache für das Schreiben von intelligenten Verträgen. Sie wird für die Implementierung von Smart Contracts auf verschiedenen Blockchain-Plattformen verwendet und von einigen ehemaligen Ethereum-Mitarbeitern entwickelt – ursprünglich nur für die Blockchain-Plattform Ethereum. Später wurde die Programmiersprache auch auf anderen Blockchains eingesetzt.

 

solidity-logo Solidity | Programmiersprache von Ethereum
Logo von Solidity @wikipedia.org

 

Entwicklung der Ethereum Blockchain-Programmiersprache

Solidity wurde ursprünglich im August 2014 von Gavin Wood erdacht. Die Sprache wurde später vom Solidity-Team des Ethereum-Projekts unter der Leitung von Christian Reitwiessner entwickelt. Sie ist eine von vier Sprachen (die anderen sind Serpent, LLL, Viper (experimentell) und Mutan (veraltet), die speziell für die Ethereum Virtual Machine (EVM) konzipiert wurden und kommt gegenwärtig als Hauptsprache auf Ethereum sowie auf anderen privaten Blockchains zum Einsatz.

Nutzer können Solidity in ihrem Browser verwenden, ohne dass sie etwas herunterladen müssen. Diese Anwendung unterstützt nur die Kompilierung – wenn Anwender den Code ausführen oder in die Blockkette einbinden wollen, müssen sie einen Client wie AlethZero verwenden. Mit Solidity sind Entwickler in der Lage, Anwendungen zu schreiben, die eine selbstverstärkende Geschäftslogik implementieren, die in intelligenten Verträgen verankert ist und hinterlassen eine unwiderlegbare und verbindliche Aufzeichnung von Transaktionen.

 

Verifizierung bei Solidity

Tatsächlich handelt es sich um eine bewusst abgespeckte Programmiersprache mit einer Syntax, die der von ECMAScript (Javascript) sehr ähnlich ist. Programmierer arbeiten hier mit einem Stack-and-Memory-Modell mit einer 32-Byte-Befehlswortgröße, das EVM den Zugang zum Programm „Stack“ gewährt, welches wie ein Registerraum aufgebaut ist und in dem auch Speicheradressen aufgehoben werden können, um den Program Counter loop/jump (für sequentielle Programmsteuerung), einen erweiterbaren temporären „Speicher“ und einen permanenteren „Speicher“, der tatsächlich geschrieben wird, zu erstellen.

Diese Forderung nach Determinismus ist der Grund, warum Nutzer die „random()“-Funktion in der Solidity-Sprache nicht sehen werden. Wenn ein Block „abgebaut“ wird, werden die Smart-Contract-Implementierungen und Funktionsaufrufe innerhalb dieses Blocks (d.h. die, die innerhalb der letzten Blockdauer ausgeführt werden) auf dem Knoten ausgeführt, der den Block abbaut, und der neue Zustand ändert sich zu allen Speicherplätzen oder Transaktionen innerhalb dieses Smart Contract, die tatsächlich auf diesem Miner-Knoten stattfinden.

Dann wird der neue Block auf alle anderen Knoten übertragen und jeder Knoten versucht, den Block unabhängig zu verifizieren, was auch beinhaltet, dass er dieselben Zustandsänderungen an seiner lokalen Kopie der Blockkette durchführt. Der Prozess wird scheitern, wenn der Smart-Vertrag nicht-deterministisch agiert. Wenn die anderen Knoten nicht zu einem Konsens über den Zustand der Blockkette kommen können, nachdem der neue Block und seine Verträge ausgeführt wurden, könnte das Netzwerk buchstäblich zum Stillstand kommen. Aus diesem Grund müssen die Smart-Contracts (Verträge) von Ethereum (und Smart-Contracts im Allgemeinen in jedem Blockchainsystem) deterministisch sein: damit das Netz der Knotenpunkte immer den Konsens über die neuen Blöcke, die in den Block eintreffen, validieren und aufrechterhalten kann, um weiterlaufen zu können.

 

solidity-smart-contract-kryptowaehrung-620x394 Solidity | Programmiersprache von Ethereum
solidity Smart Contract für Kryptowährung @http://solidity.readthedocs.io

 

Kein Zugriff nach außen

Eine weitere Einschränkung, die Nutzer in EVM Smart-Contracts finden, ist die Unfähigkeit, auf Daten außerhalb des „Gedächtnisses“ und des „Speichers“ zuzugreifen (es ist nicht gewollt, dass der Smart-Contract die Festplatten der Knoten, auf denen er läuft, lesen oder löschen kann), und die Unfähigkeit, externe Ressourcen wie bei einer JQuery abzufragen.

Wenn Nutzer einen Smart-Contract aufrufen, der eine zustandsverändernde Arbeit oder Berechnung durchführt (jede Aktion außer dem einfachen Auslesen aus dem Speicher), entstehen für die Arbeit des Smart-Contracts Stromkosten und diese hängen mit der Menge an Rechenarbeit zusammen, die für die Ausführung der Funktion erforderlich ist. Es ist eine Art „micropayment for microcomputing„-System, bei dem man erwarten kann, dass man für eine bestimmte Menge an Strom für eine bestimmte Menge an Berechnungen bezahlt.

 

smart-contracts-ethereum-blockchain-620x329 Solidity | Programmiersprache von Ethereum
Smart Contracts über Ethereum Blockchain

 

Smart Contracts bei Solidity

Smart-Contracts haben eine eigene Adresse, von der aus sie Etherium empfangen und senden können. Intelligente Verträge können den „Anrufer“ der Funktion nachvollziehbar verfolgen, sodass festgestellt werden kann, ob eine seiner Funktionen von einem privilegierten „Eigentümer“- oder „Admin“-Konto aufgerufen wird und entsprechend administrativ handeln kann.

Anwender haben die Möglichkeit, Daten aus dem Ethereum-Blockchain zu lesen und auf Informationen über Transaktionen in älteren Blöcken zuzugreifen.

Aber sind Smart-Contracts in ihre eigene kleine deterministische Welt „eingesperrt“, nur in der Lage, die in der Ethereum-Blockkette selbst gespeicherten Daten zu kennen?

Überhaupt nicht! Hier kommen die „Orakel“ ins Spiel. Nutzer können einen Anruf zu einem Orakel (Was ist ein Oracel?) machen, das auf vertrauenswürdige Weise etwas über die Außenwelt erzählt und auf diese Daten im Rahmen des intelligenten Vertrags reagieren. Der springende Punkt dabei ist, dass, obwohl die realen Ereignisse selbst nicht deterministisch sind, das Orakel darauf vertrauen kann, dass es die Anfragen jedes einzelnen Knotens bezüglich des Geschehens immer deterministisch beantwortet, sodass alle Knoten dennoch zu einem Konsens kommen können.

 

 

Codebeispiel für Solidity

So funktioniert also das vertrauenswürdige Orakel in der Theorie. Ein „Orakel“ nimmt einige Daten auf, z.B. einen Tickerpreis-Feed über einen realen Aktienkurs, und zeichnet diese Daten in einem einfachen Orakel Smart-Vertrag auf:


function storeTickerData(bytes8 symbol, high, uint low, uint close)
onlyOrakel
returns(bool success)
{
# shop ticker data on-chain
tickerData[symbol][block.number] = [high,low,close]
# tickerData is a map of maps, string => uint => array[uint,uint,uint]
return true;
}


Aus dem kleinen Snippet des Codes oben ist ersichtlich, dass Nutzer eine ziemlich einfache Funktionsdeklarationssyntax haben und einige grundlegende Datentypen wie #uint‘ (unsigned integer) und #string‘ vorkommen. Anwender erkennen in den Dokumentationen, dass auch Variablentypen wie #adress‘ genutzt werden. Es gibt grundlegenden Arrays, Enums, Operatoren, Hash-Datenstrukturen, die als #Mappings‘ bezeichnet werden, und einige spezielle vordefinierte Einheiten und globale Variablen, die Dinge wie Blockhöhe, letzter Block-Zeitstempel und einige praktische SHA-Hash- und Adress-/Schlüsselmanipulationsfunktionen enthalten. Eine wichtige Eigenart von Solidity bei der Arbeit mit multidimensionalen Arrays: Die Indizierung erfolgt in „umgekehrter“ Reihenfolge von den meisten Sprachen nur während der Deklaration.