Hinter Bitcoin ist Ethereum die Kryptowährung mit dem höchsten Marktwert. Wenngleich wir heute noch auf _die_ Killer-App warten, das Meiste sind doch nur Coin-Börsen & Wallets, so ist Ethereum in der Hinsicht vielversprechend, als dass die Währung als „turing complete“ gilt, man kann also im Gegensatz zu Bitcoin dafür und damit „richtig programmieren“.
Mit der folgenden Anleitung bauen wir uns heute ein eigenes privates Ethereum-Netzwerk!
WARNUNG: die Durchführung des Tutorials geschieht auf eigene Gefahr. Ich übernehme keinerlei Garantie dass irgendwas funktioniert! Auch solltet ihr darauf achten, dass ihr eure eigenen Ethereum von diesen erstellten Ethereum getrennt aufbewahrt. Das Tutorial soll dazu dienen, a) für Ethereum zu programmieren und richtet sich an Entwickler, b) einen einfachen „smart contract“ aufzusetzen, sowie c) das wohl Wichtigste, zu verstehen, wie Ethereum funktioniert.
Los geht’s! 🙂
—
1. Vorbereitungen
Ihr braucht Zugang zu einem eigenen Server-Bereich und den geth („Go Ethereum Client“). In dieser Anleitung nehmen wir mal an, ihr betreibt einen Ubuntu-Server. Hier findet ihr die Anleitung für die geth-Installation unter Ubuntu: geth installieren. Ferner solltet ihr um minen zu können mindestens 2GB RAM bereitstellen.
Das private Netzwerk wird „gizmeodoteu“ genannt. Es ist aufrufbar unter der Fake-IP-Adresse 101.102.103.104.
Öffnet nun ein Konsolenfenster, loggt euch über SSH in Ubuntu ein und erstellt ein Arbeitsverzeichnis:
ssh root@101.102.103.104
mkdir gizmeodoteu
cd gizmeodoteu
mkdir data
mkdir source
2. Generierung des Genesis-Blocks
Der Genesis-Block ist der allererste Block jeder Blockchain und die Parameter sind in der Datei genesis.json definiert. Die Datei speichern wir ab unter /root/gizmeodoteu/genesis.json. Hier der Inhalt der Datei:
{
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc" : {
"0x0000000000000000000000000000000000000001": {"balance": "111111111"},
"0x0000000000000000000000000000000000000002": {"balance": "222222222"}
},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x00001",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000209",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00"
}
Hierbei steht chainId=1 für das Ethereum-Hauptnetzwerk. Daher ist es wichtig eine eigene chainId für euer privates Netzwerk zu nehmen, damit euer privates Netzwerk die Blockchain nicht mit der offiziellen verwechselt.
Zum Testen und für ein allgemein besseres Verständnis, setzen wir die Schwierigkeit auf einen niedrigen Wert. Auch sollte ein einzigartiger Wert für nonce gewählt werden. Über das Feld alloc werden Accounts mit Ether (die Ethereum-Währung) vorgefüllt.
Geht nun in euer Verzeichnis, wo ihr die genesis.json abgelegt habt und initialisiert den bootnode. Das ist der Knoten, mit welchem sich euer Client mit dem privaten Netzwerk verbinden und auch mit anderen Knoten kommunizieren kann:
cd /root/gizmeodoteu/data
geth --datadir=/root/gizmeodoteu/data init /root/gizmeodoteu/genesis.json
bootnode --genkey=boot.key
bootnode --nodekey=boot.key
3. Neuen Account erstellen und Kontostand prüfen
Öffnet ein neues Konsolenfenster und wechselt über SSH auf euren virtuellen Server:
ssh root@101.102.103.104
geth attach /root/gizmeodoteu/data/geth.ipc
> eth.accounts
Natürlich gibt es noch keine Adressen von Konten. Den ersten Account eröffnen wir nun. Ersetzt „meinPW“ mit einem starken Passwort, bewahrt dieses an einem sehr sicheren Ort auf. Ethereum vergibt nicht: ohne dieses Passwort werdet ihr niemals mehr Zugang zu eurem Account haben:
> personal.newAccount("meinPW")
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
Speichert eure Adresse gut ab, diese beginnt mit dem Präfix 0x. Auch gibt es noch keine Ether in diesem Account, dazu kommen wir noch. Natürlich ist das geminte Ether hier nur nützlich in eurem privaten Netzwerk.
4. Im privaten Netzwerk minen
Das Minen hier hat doppelten Zweck: Ether erzeugen um die Transaktion durch gas, eine Ethereum-Untereinheit, zu betreiben. Zudem führt das Minen eure Transaktionen in die Blockchain.
Öffnet ein neues Konsolenfenster und verbindet euch zu eurem privaten Server:
ssh root@101.102.103.104
geth --datadir=/root/gizmeodoteu/data --mine --minerthreads=1 --etherbase=0x...
Der Parameter etherbase hier spezifiziert die Zieladresse, wohin eure durch das Mining generierten Ether gesendet werden sollen. Hier steht eure Wallet-Adresse aus Schritt 3. Wenn ihr nun den Kontostand erneut checkt (siehe Schritt 3), solltet ihr eine große Zahl angezeigt bekommen. Gratulation! Ihr seid nun Ether-Milliardär!
Klar, diese generierten Ether sind nur wertvoll innerhalb eures privaten Netzwerks. Trotzdem geil! Ihr wisst nun, wie ihr für Ethereum entwickeln könnt und _das_ ist wirklich unbezahlbar.
5. Einen einfachen Vertrag kompilieren
Die offizielle Dokumentation zu Ethereum erwähnt nicht, dass das Kompilieren über solC nicht mehr via RPC möglich ist. Alle Tutorials, die darauf aufbauen, enden in einer Art Fass ohne Boden. Es gibt wohl 2 Wege Verträge zu kompilieren, es ist für das eigene Verständnis wichtig, beide mal versucht zu haben.
Als Erstes installiert ihr den Kommandozeilen-Compiler solC:
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install solc
Öffnet nun erneut ein Konsolenfenster, verbindet euch über SSH mit eurem Server und navigiert zum Verzeichnis, wo euer Quellcode abgelegt wird:
cd /root/gizmeodoteu/source
Speichert den folgenden „Begrüssungs“-Vertrag in /root/gizmeodoteu/greeter.sol:
contract mortal {
/* Variable "owner" vom Typ address definieren */
address owner;
/* diese Funktion wird bei Initialisierung ausgeführt und setzt den Besitzer des Vertrags */
function mortal() { owner = msg.sender; }
/* Funktion, um die Investionen des Vertrags wiederherzustellen */
function kill() { if (msg.sender == owner) selfdestruct(owner); }
}
contract greeter is mortal {
/* Variable "greeting" vom Typ string definieren */
string greeting;
/* das hier wird ausgeführt, wenn der Vertrag aufgerufen wird */
function greeter(string _greeting) public {
greeting = "Hallo, Welt!";
}
/* Hauptfunktion */
function greet() constant returns (string) {
return greeting;
}
}
Jetzt kompilieren wir den Vertrag mit solC:
solc --bin --abi -o /root/gizmeodoteu/source /root/gizmeodoteu/source/greeter.sol
Das Setzen von bin und abi sagen dem Compiler, dass „Ethereum Virtual Machine (EVM)“-Bytecode und eine Datei Application Binary Inferface (ABI) erstellt werden sollen. Mit -o legt man wie üblich ein Ausgabeverzeichnis fest, welches mit der zweiten Angabe des Verzeichnisses mit einer *.sol-Datei abgeschlossen wird.
Die Kompilierung hier erzeugt zwei Dateien:
– eine EVM-Datei, erkennbar an der Endung *.bin. Diese entspricht dem Vertrags-Bytecode, der vom webbasierten Compiler generiert wird; dieser ist einfacher zu verwenden und wird weiter unten vorgestellt.
– eine ABI-Datei, erkennbar an der Endung *.abi: stellt euch das application binary interface als eine Art Vorlage für den Vertrag vor. Das erleichtert die Kommunikation von euch und anderen mit dem Vertrag, sobald er sich in der Blockchain befindet.
Öffnet beide Dateien nun mit nano oder einem anderen Texteditor eurer Wahl. Indem ihr versteht, was darin steht, werdet ihr weniger Mühe damit haben eure Verträge zu veröffentlichen und mit ihnen zu interagieren.
Alternativ dazu könnt ihr auch den Online-Compiler benutzen. Durch einfaches Copy&Paste nimmt dieser euch die Arbeit ein bisschen ab. Jedoch sind beide Methoden gleichwertig.
Kopiert dazu einfach den Text aus greeter.sol von oben in den Online-Compiler. Wartet einen Moment und klickt dann auf den Link „Contract details…“. Der Inhalt des Felds Bytecode sollte mit dem aus der Datei greeter.bin übereinstimmen. Das Selbe gilt für das Feld Interface aus der Datei greeter.abi.
6. Einen „Begrüssungs“-Vertrag in eurem privaten Netzwerk veröffentlichen
Kopiert den Inhalt des Feldes Web3 deploy in den Online-Compiler. Fügt den Inhalt in einen Texteditor eures PCs und achtet auf die hervorgehobenen Bereiche:
var _greeting = 'gizmeoDOTeu rockt!';
var browser_ballot_sol_greeterContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"type":"constructor"}]);
var browser_ballot_sol_greeter = browser_ballot_sol_greeterContract.new(
_greeting,
{
from: web3.eth.accounts[0],
data: '0x6060604052341561000f57600080fd5b6040516103dd3803806103dd833981016040528080518201919050505b5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6040805190810160405280600d81526020017f48656c6c6f2c20576f726c642100000000000000000000000000000000000000815250600190805190602001906100b99291906100c1565b505b50610166565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061010257805160ff1916838001178555610130565b82800160010185558215610130579182015b8281111561012f578251825591602001919060010190610114565b5b50905061013d9190610141565b5090565b61016391905b8082111561015f576000816000905550600101610147565b5090565b90565b610268806101756000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b514610049578063cfae32171461005e575b600080fd5b341561005457600080fd5b61005c6100ed565b005b341561006957600080fd5b61007161017f565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b25780820151818401525b602081019050610096565b50505050905090810190601f1680156100df5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561017c576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b610187610228565b60018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561021d5780601f106101f25761010080835404028352916020019161021d565b820191906000526020600020905b81548152906001019060200180831161020057829003601f168201915b505050505090505b90565b6020604051908101604052806000815250905600a165627a7a7230582069d50e4318daa30d3f74bb817c3b0cb732c4ec6a493eb108266c548906c8b6d70029',
gas: '1000000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
Das oben abspeichern als myContract.js.
Bevor ihr fortfahrt prüfen, dass a) euer Kontostand nicht 0 ist und b) euer Account entsperrt ist. Ist der Kontostand zu niedrig oder der Account gesperrt, könnt ihr den Vertrag nicht veröffentlichen. Deshalb solltet ihr die obigen Schritte nochmals abarbeiten, um Ether zu minen und entsperrt dann euren Account wie folgt (ersetzt „meinPW“ mit eurem eigenen von oben):
Öffnet ein neues Konsolenfenster:
ssh root@101.102.103.104
geth attach /root/gizmeodoteu/data/geth.ipc
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
> personal.unlockAccount(eth.accounts[0], "meinPW")
Bitte nicht abschalten, denn es wird wichtig: auch hier gibt es kein Update der Dokumentation zu Ethereum, daher gibt es Verwirrungen, wie man Verträge kompiliert. Beachtet, dass die Funktion web3.eth.contract() ein Argument braucht. Das ist das selbe, wie die Datei greeter.abi, die wir mit dem solC erstellt haben. Das Feld data ist gleichbedeutend mit dem EVM-Bytecode der Datei greeter.bin. Der einzige Unterschied ist wieder das Präfix 0x.
Jetzt wird der Vertrag öffentlich gemacht:
loadScript(myContract.js)
Die Ausgabe sollte ungefähr so aussehen:
Contract mined! address: 0x4000737c8bd7bbe3dee190b6342ba1245f5452d1 transactionHash: 0x0a4c798467f9b40f2c4ec766657d0ec07c324659ea76fcc9c8ad28fc0a192319
Glückwunsch! Euer Vertrag „lebt“ und ist zu finden unter der Adresse 0x4000737c8bd7bbe3dee190b6342ba1245f5452d1 eurer privaten Blockchain.
Notiert euch diese, denn sowohl ihr oder auch andere werden diese brauchen, wenn ihr damit interagieren wollt.
Falls es nicht funktioniert hat: stellt sicher, dass ihr aktiv in einem anderen Fenster minet, damit die Transaktion in die Blockchain geführt werden kann.
7. Mit dem Vertrag interagieren
Auch hier gibt es noch keine Updates der offiziellen Ethereum-Doku. Die beschriebenen Funktionen werden schon nicht mehr benutzt. Startet erneut geth und versucht Folgendes:
> var abi = '[{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"type":"constructor"}]'
> var abi = JSON.parse(abi)
> var contract = web3.eth.contract(abi)
> var c = contract.at("0x4000737c8bd7bbe3dee190b6342ba1245f5452d1")
> c.greet()
Mit den ersten drei Eingaben legt ihr fest, wie der Vertrag laut ABI aussieht. Die Methode contract.at() braucht als Übergabeparameter die Adresse, wo euer Vertrag residiert. Ihr solltet nun die folgende Ausgabe sehen:
gizmeoDOTeu rockt!
Hinweis: geth bekommt Schnupfen, sobald eine eurer Eingaben illegale Zeichen beinhaltet, siehe:
“ (illegal) is not equal to " (legal)
und
‘ (illegal) is not equal to ' (legal)
9. Fazit
Wir haben nun mehr als nur kurz mal reingeschnuppert in Ethereum: wir haben ein eigenes (privates) Netzwerk aufgesetzt und sogar einen eigenen „smart contract“ kompiliert. Zudem haben wir Sackgassen der offiziellen Dokumentation vermieden. Wir haben ferner gesehen, wie man einen Vertrag veröffentlicht (deploy) und mit diesem interagiert.
Solltet ihr je Mist gebaut haben und müsst nochmals neu anfangen, startet „einfach“ euren Server neu und löscht eure Blockchain:
rm -R /root/gizmeodoteu/data/geth/chaindata
[via]
10. Ausblick
Die smart contracts sind, was Ethereum so stark macht. Durch diese Eigenschaft entfällt die Stelle des Vermittlers, Verträge werden dadurch fälschungssicher und günstig. Nicht nur Notare werden zukünftig dadurch überflüssig. smart contracts haben das Zeug dazu, ganze Institutionen, egal ob privat oder staatlich, zu ersetzen.
Ferner ist Ethereum „turing complete“: diese Eigenschaft besitzt das Bitcoin-Protokoll nicht. Dadurch kann man für Ethereum relativ leicht selbst Anwendungen entwickeln. Wer schonmal JavaScript programmiert hat, wird sich hier prima zurecht finden. Vielleicht hilft dieses Tutorial ja, mal mit einer anderen Anwendung an den Start zu gehen, als nur Wallets oder Coin-Börsen! 🙂
Falls euch das Tutorial gefallen hat, spendet mir doch ein paar Bitcoin! Die Adresse findet sich bei jedem Bitcoin-Button überall auf gizmeo.eu verstreut! Vielen Dank für die Aufmerksamkeit und happy hacking!