5. Smart Contracts mit Ethereum¶
5.1. Einführung¶
Eine Blockchain ist eine dezentrale und transparente digitale Datenbank, die eine chronologische Aufzeichnung von Transaktionen oder Ereignissen enthält. Im Wesentlich handelt es sich um eine Kette von Datenblöcken, die miteinander verknüpft sind.
Die Funktionsweise einer Blockchain basiert auf folgenden Kernkonzepten:
Dezentralisierung: Eine Blockchain ist dezentralisiert, was bedeutet, dass sie auf einem Netzwerk von Computern (Knoten) existiert, die über das Internet verbunden ist. Dabei speichert jeder Knoten eine vollständige Kopie der Blockchain und validiert die Transaktionen unabhängig. Es gibt also keinen zentralen Server, der die Kontrolle über die Blockchain hat.
Kryptographie: Die in einer Blockchain enthaltenen Daten werden mithilfe kryptographischer Algorithmen gesichert. Jeder Block enthält einen Hash-Wert, der den Inhalt des Vorgängers und die darin enthaltene Transaktion eindeutig repräsentiert.
Konsensmechanismus: Um neue Blöcke der Blockchain hinzuzufügen und Transaktionen zu bestätigen, verwenden Blockchains einen Konsensmechanismus. Dieser ermöglicht es den Knoten im Netzwerk, sich auf einen Zustand der Blockchain zu einigen und sicherzustellen, dass alle Teilnehmer die gleiche Version der Blockchain haben. Beispiele für Konsensmechanismen sind der Proof-of-Work (PoW) in Bitcoin und der Proof-of-Stake (PoS) in Ethereum.
Transaktionen: In einer Blockchain werden die Transaktionen in Blöcken gesammelt und chronologisch hinzugefügt. Eine Transaktion kann den Transfer von Geld, Daten oder die Ausführung eines Smart Contracts beinhalten.
Der Prozess der Validierung und Hinzufügen neuer Blöcke wird dabei auch als „Mining“ bezeichnet. Dieser Prozess kann je nach Konsensmechanismus variieren, beinhaltet jedoch im Allgemeinen das Lösen eines rechenintensiven Problems oder das Bereitstellen von Sicherheiten, um einen neuen Block zu erstellen.
Eine Kryptowährung wie Bitcoin ist hierbei nur einer von vielen Anwendungsmöglichkeiten der Blockchain. Wir wollen heute besonders auf die Anwendung als Smart Contract eingehen.
5.2. Ethereum und Smart Contracts¶
5.2.1. Ethereum¶
Für das Arbeiten mit Smart Contracts ist the Ethereum-Blockchain sehr gut geeignet. Sie ist eine öffentliche, dezentrale und verteilte Datenbank, die auf dem oben beschriebenen Prinzip basiert. Sie wurde 2015 von Vitalik Buterin entwickelt und funktionierte nach dem Proof-of-Work Prinzip. Um den Energieverbrauch um 99% zu senken, wurde seit August 2022 der Konsensmechanismus auf Proof-of-Stake umgestellt. Im Zentrum der Ethereum-Blockchain steht das Konzept der Smart Contracts. Bitcoins Scripting-Begrenzungen, welche eine eingeschränkte Unterstützung für Smart Contracts bieten, dienten als ursprüngliche Motivation für Ethereum. D.h. Bitcoin bietet nur eine begrenzte Untersützung für Smart Contracts, da die Scriptsprache nicht „Turing complete“ ist. So können bestimmte Programme nur auf der Ethereum-Blockchain programmiert werden. In den Scripten gibt es zwei grundlegende Funktionen, zum einen das Lesen von der Blockchain, zum anderen das Schreiben in die Blockchain. Das Lesen kann von jedem, jederzeit kostenlos durchgeführt werden. Für das Schreiben wird eine Transaktionsgebühr erhoben. Transaktionen werden mit Gas bezahlt. Gasgebühren werden mit Etheriums Eigenwährung Ether gezahlt. Da Ethereum das Konzept eines Gas-Limits implementiert, können keine Transaktionen ausgeführt werden, die mehr Gas als das Gas-Limit benötigen. Aufgrund dessen wird die Ethereum Virtual Machine (EVM) „quasi-Turing complete“ genannt.
5.2.2. Smart Contracts¶
Ein Smart Contract definiert ein Programm, welches Nutzern ermöglicht, miteinander gemäß einer bestimmten Reihe vordefinierter Regeln zu interagieren. Hier entfällt jedoch die Notwendigkeit eines Dritten, der diese Regeln durchsetzt, da die Transaktionen direkt und transparent auf der Blockchain durchgeführt werden. Nach dem Aktivieren sind Smart Contracts selbstausführende Verträge, die basierend auf vordefinierten Events oder Bedingungen agieren. Die Smart Contracts auf Ethereum sind in der Programmiersprache Solidity geschrieben.
Schritte des Smart Contracts:
Der Smart Contract-Code wird in Solidity geschrieben und kompiliert, um Bytecode zu erzeugen, der auf der EVM ausgeführt werden kann.
Der kompilierte Smart Contract-Code wird dann auf der Ethereum-Blockchain bereitgestellt, indem eine Transaktion erstellt wird, die den Smart Contract enthält.
Die Transaktion wird von den Ethereum-Minern validiert und in einen Block auf der Blockchain aufgenommen.
Sobald der Smart Contract auf der Blockchain verfügbar ist, kann er durch Aufrufe bestimmter Funktionen aktiviert und ausgeführt werden.
Die Ausführung des Smart Contracts erfolgt in der EVM, die den Code interpretiert und die entsprechenden Aktionen ausführt. Dies kann den Transfer von Vermögenswerten, die Aktualisierung von Zuständen oder das Auslösen von Ereignissen umfassen.
Die Ergebnisse der Smart Contract-Ausführung werden auf der Blockchain gespeichert und können von allen Teilnehmern eingesehen werden.
5.3. Vorbereitungen¶
5.3.1. Truffle¶
Einrichtung von Truffle:
Truffle (https://trufflesuite.com/truffle/) ist ein Framework und eine Entwicklungsumgebung für die Erstellung von dezentralen Anwendungen und Smart Contracts auf der Ethereum-Plattform. Es bietet eine Reihe von Tools, die Entwicklern dabei helfen, effizienter und produktiver mit Ethereum zu arbeiten. Hierzu gehören z.B. Projektverwaltung, Smart-Contract-Entwicklung und automatisierte Tests.
Installation mit npm:
npm install -g truffle
Neues Projekt initialisieren:
truffle init
In der Datei truffle-config.js können nun weitere Konfigurationen, wie Netzwerkdaten und Compilerversionen angegeben werden.
Einrichtung von Truffle Box:
Truffle bietet auch einige vordefinierte Boxen für Standardanwendungen, um eine gewissen Grundstrucktur vorzugeben. Wir nutzen in unserem Fall die „React Truffle Box“ für eine simple Webanwendung, die ihre Daten aus einem Smart Contract bezieht.
React Truffle Box initialisieren:
truffle unbox react
5.3.2. Ganache¶
Einrichtung von Ganache:
Ganache (https://trufflesuite.com/ganache/) ist ein Tool, um eine simulierte Blockchain aufzubauen. Ganache gibt es als Anwendung mit GUI und als Konsolenanwendung.
Installation Ganache-CLI mit npm:
npm install -g ganache
Installation Ganache-GUI:
Installationspaket je nach Betriebssystem von der Webseite herunterladen und installieren.
Neue Blockchain initialisieren:
Hierzu die Ganache Anwendung öffnen und per Quickstart eine Ethereum Blockchain erstellen:
Anschließen sieht man die Accounts Seite von Ganache mit 10 Wallet Adressen, die jeweils 100 ETH Guthaben besitzen:
5.3.3. MetaMask¶
Einrichtung von Metamask:
Für die Nutzung unserer Smart Contract Anwendung benötigen wir einen Web3 kompatiblen Browser oder eine Erweiterung für einen normalen Browser. In unserem Fall nutzen wir die Browser-Erweiterung MetaMask. MetaMask ist eine Krypto-Wallet, die alle Arten von Ethereum-basierten Token unterstützt. MetaMask kann als reguläre Krypto-Wallet dienen, aber ihre wahre Stärke liegt in der nahtlosen Anbindung an Smart Contracts und dezentralisierte Anwendungen.
Installation Metamask:
Metamask Erweiterung je nach Browser von https://metamask.io/ herunterladen oder direkt aus dem Erweiterungs-Store beziehen.
Metamask mit unserer Ganache Blockchain verbinden:
https://docs.metamask.io/wallet/get-started/run-development-network/
Um Metamask für unsere Anwendung nutzen zu können, muss Metamask mit unserem Ganache Blockchain Netzwerk verbunden sein. Alle Daten hierzu finden wir in der Ganache Anwendung.
Neues Netzwerk hinzufügen:
Daten aus Ganache eintragen:
Account aus Ganache per Private Key importieren:
5.4. Versuchsdurchführung¶
5.4.1. Smart-Contract¶
Wir wollen unseren Smart-Contract auf der Blockchain deployen und mit diesem über unsere React-Webanwendung interagieren.
Smart Contract bereitstellen:
Unser Smart Contract hat nur die simple Aufgabe einen Integer Wert über zwei Funktionen lesbar und schreibbar zu machen.
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
contract SimpleStorage {
uint256 value;
function read() public view returns (uint256) {
return value;
}
function write(uint256 newValue) public {
value = newValue;
}
}
Um den Smart Contract auf unserer Blockchain zu deployen, müssen wir folgendes Kommando ausführen. Das „migrate“ Kommando führt alle Migrationen unter dem Ordner „migrations“ aus und stellt diese auf dem in der truffle-config.js konfigurierten Netzwerk „development“ bereit.
truffle migrate --network development
Wir erhalten folgende Ausgabe:
Starting migrations...
======================
> Network name: 'development'
> Network id: 5777
> Block gas limit: 6721975 (0x6691b7)
1_deploy_simple_storage.js
==========================
Replacing 'SimpleStorage'
-------------------------
> transaction hash: 0x771fc309e293f7079b1e16b964120e8fd601572417df16b9c12f2118c04a753a
> Blocks: 0 Seconds: 0
> contract address: 0x77c4277D811afeAAB0Bf75Bb3890d011a252D459
> block number: 1
> block timestamp: 1684995377
> account: 0x48531cfC9c201D9D6fC04f74a4dc6FA82876c32B
> balance: 99.999575921125
> gas used: 125653 (0x1ead5)
> gas price: 3.375 gwei
> value sent: 0 ETH
> total cost: 0.000424078875 ETH
> Saving artifacts
-------------------------------------
> Total cost: 0.000424078875 ETH
Summary
=======
> Total deployments: 1
> Final cost: 0.000424078875 ETH
Hier sehen wir alle Informationen, die unseren Smart Contract betreffen.
Smart Contract Schnittstelle:
Zu jedem Smart Contract gibt es ein Application Binary Interface (ABI), ähnlich zum Prinzip der API bei klassischen Webanwendungen. Diese ABI würd über eine json Datei beschrieben. Diese json Datei wird beim Bereitstellen des Smart-Contract erstellt und in unserem Fall direkt im Source Ordner unserer Webanwendung abgelegt, da wir diese dort später benötigen. Der Pfad wurde wieder in der truffle-config.js definiert.
Um auf die Schnittstelle zuzugreifen nutzen wir die JavaScript Bibliothek „web3.js“ (https://web3js.org/).
5.4.2. Webanwendung¶
Webanwendung starten:
Unsere Webanwendung läuft nicht in auf der Blockchain, sondern wir klassisch auf einem Webserver bereitgestellt.
Die Webanwendung starten wir folgendermaßen:
npm start
Die Anwendung ist nun unter http://localhost:8080/ erreichbar.
Webanwendung öffnen:
Beim ersten Öffnen werden wir direkt von MetaMask unterbrochen, um unser Wallet auszuwählen, mit dem wir mit dem Smart Contract interagieren wollen:
Der relevante Code für die Verbindung des Smart Contract mit unserem Wallet befindet sich in der EthProvider.jsx:
const init = useCallback(
async artifact => {
if (artifact) {
//Web3.givenProvider wird von Browser gesetzt oder es wird der localhost als Fallback genutzt
const web3 = new Web3(Web3.givenProvider || "ws://localhost:7545");
//Account von Browser anfragen. Hierdurch öffnet sich das MetaMask Fenster
const accounts = await web3.eth.requestAccounts();
const networkID = await web3.eth.net.getId();
const { abi } = artifact;
let address, contract;
try {
address = artifact.networks[networkID].address;
//Smart Contract mit ABI und Adresse initialisieren
contract = new web3.eth.Contract(abi, address);
} catch (err) {
console.error(err);
}
dispatch({
type: actions.init,
data: { artifact, web3, accounts, networkID, contract }
});
}
}, []);
useEffect(() => {
const tryInit = async () => {
try {
//Initialisierung mit der ABI json unseres Contracts
const artifact = require("../../contracts/SimpleStorage.json");
init(artifact);
} catch (err) {
console.error(err);
}
};
tryInit();
}, [init]);
Sobald wir verbunden sind, sehen wir die Webanwendung, welche zunächst einen kurzen Überblick über Einrichtungsschritte zu Truffle und Ganache gibt und uns weiter unten die Möglichkeit bietet, mit unserem Smart Contract zu interagieren.
Smart Contract lesen und schreiben:
Das „contract“ Object bietet uns hier alle in der ABI definierten Methoden
Über den Button „read()“ können wir den Aktuellen Wert aus unserem Contract lesen. Hierzu rufen wir die „read()“ Methode auf und geben noch unseren Account als Absender der Anfrage an.
const read = async () => {
const value = await contract.methods.read().call({ from: accounts[0] });
setValue(value);
};
Über den Button „write(uint)“ können wir den eingegeben Wert in unseren Contract schreiben. Hierzu rufen wir die „read()“ Methode mit unserem eingegeben Wert auf und geben noch unseren Account als Absender der Anfrage an.
const write = async e => {
...
const newValue = parseInt(inputValue);
await contract.methods.write(newValue).send({ from: accounts[0] });
};
Da die „write()“ Methode eine neue Transaktion auf der Blockchain erstellt, erhalten wir hier eine Meldung von Metamask, um diese Transaktion zu bestätigen.
Hier erhalten wir alle Informationen zu unserer Transaktion, wie die Daten der Transaktion und ihre Kosten.
Um die Transaktion auszuführen müssen wir diese Bestätigen. Anschleßen können wir per „read()“ den neuen Wert lesen.
5.4.3. Blockchain¶
Transaktionen:
Jede schreibende Operation erstellt eine Transaktion auf der Blockchain. Folgene Transaktion haben wir bis jetzt durch unseren Versuch ausgeführt:
Die Contract Creation Transaktion enhält alle Informationen über underen Smart Contract.
Die zweite Transaktion wurde durch den „write(123)“ Aufruf erstellt:
Smart-Contract:
Außerdem sehen wir unseren Smart-Contract:
5.5. Fazit¶
Vorteile von Smart Contracts:
Automatisierung: Es ist kein „Zwischenhändler“ nötig, was die Anfälligkeit für menschliche Fehler reduziert, und den Prozess beschleunigt
Sicherheit: Durch die globale Bestätigung aller Knotenpunkte, ist ein Transaktionsfehler so gut wie ausgeschlossen
Effizienz und Kostenersparnis: Ohne manuelle Eingriffe erspart man sich Transaktionskosten
Nachteile von Smart Contracts:
Komplexität: Die Erstellung und Implementierung von Smart Contracts erfordert technisches Know-how und Erfahrung in Blockchain-Entwicklung.
Unveränderlichkeit: Die Unveränderlichkeit von Smart Contracts kann sowohl ein Vorteil als auch ein Nachteil sein. Wenn einmal ein Smart Contract bereitgestellt ist, können seine Bedingungen nicht geändert werden, es sei denn, es ist eine Upgrade-Funktionalität im Vertrag selbst vorgesehen.
Mangel an Flexibilität: Smart Contracts sind in der Regel präzise und deterministisch. Sie reagieren nicht gut auf unvorhersehbare Ereignisse oder komplexe Situationen, die menschliches Ermessen erfordern.
5.6. Literaturangaben¶
Informationen:
How Ethereum Works: The History of Ethereum: https://medium.com/certik/how-ethereum-works-the-history-of-ethereum-abcc0b770315
Solidity Doc: https://docs.soliditylang.org/en/v0.8.20/
Truffle: https://trufflesuite.com/truffle/
Ganache: https://trufflesuite.com/ganache/
Bilder:
Blockchain erklärt: https://muenchen.digital/blog/explainit-blockchain-erklaert/