Was kommt nach der Blockchain? Teil 2: Praktische Beispiele


23.01.2019 von

https://www.iteratec.de/fileadmin/Bilder/News/iteratec_logo.png https://www.iteratec.de/fileadmin/Bilder/News/iteratec_logo.png iteratec GmbH

In diese Blogserie geben wir einen tieferen Einblick zum Thema IOTA und Hashgraph und die dahinter liegenden Konzepte:

  • IOTA – Einführung
  • IOTA – Praktische Beispiele
  • Hashgraph – Einführung
  • Hedera Hashgraph – Praktische Beispiele

Nachdem wir im ersten Teil der Blogserie einen groben Überblick zu IOTA und der Basistechnologie gegeben haben, zeigen wir im zweiten Teil einige Umsetzungsbeispiele basierend auf der angebotenen JAVA-Client-Bibliothek unter Verwendung des IOTA Devnet.

Für das bessere Verständnis erläutern wir einzelne grundlegende Begriffe etwas detaillierter.

Seed

Ein Seed ist der Ausgangspunkt von allem.

Für die Erstellung eines Accounts und von Adressen ist ein Seed notwendig. Dieser Seed sollte aus mindestens 81 Tryts bestehen und bildet den Zugangsschlüssel zu einem Konto. Diesen sollte man also auch niemals aus den Händen geben, da er wie eine Geldbörse ist.

Wer sich nun die Frage gestellt hat: Was sind Tryts?

IOTA setzt anstatt des Binärsystems auf das Ternärsystem (Dreiersytem). Dies führt zu einem eigenen Alphabet, das aus 27 Zeichen besteht: 26 Großbuchstaben (A-Z) und der 9.

Ein Trit (trinary digit) kann dabei drei Zustände annehmen 31 (-1,0,1). Drei Trits ergeben dabei ein Tryt also 33=27, was damit der Anzahl der oben genanten Zeichen im Alphabet entspricht. Mit einem Tryt kann also ein Zeichen im Alphabet dargestellt werden.

Zum besseren Verständnis soll im folgenden Beispiel das Wort HOLD in Trytes umgewandelt werden, um es in Tangle zu schreiben.

Als Ergebnis der Umwandlung ergibt sich aus dem Wort HOLD RBYBNBVB in Trytes. Für den aus 81 Trytes bestehenden Seed ergeben sich damit 2781 Kombinationen.

Erstellen eines Seed

Für die Erstellung eines Seed gibt es verschiedene Möglichkeiten. Das nachfolgende Beispiel zeigt die Erstellung mithilfe des Mac Terminals:

cat /dev/urandom |LC_ALL=C tr -dc 'A-Z9' | fold -w 81 | head -n 1

Als Ergebnis erhält man einen Seed, der aus 81 Zeichen (trytes) besteht (der Seed ist hier nicht vollständig dargestellt):

OUTBHZFNSCEPBFUVMUBCRZGCWLOKLSOAOHHDNPMRLPMIQADCNJOUYDYRIJW9PBXEX9T...

Private Key und Adressen

Ein Seed ist der Ausgangspunkt für das Generieren des Private Key und des Public Key, der die Adresse repräsentiert. Der gesamte Prozess ist in Abbildung 1 visualisiert.

Der Private Key wird von einem Sub-Seed-Schlüsselindex abgeleitet. Auf Basis dieses Schlüssels wird schließlich die Adresse generiert. Dabei kann die Generierung für drei unterschiedliche Signatur-Security-Level erfolgen. Der Unterschied liegt in der Schlüssellänge (81 Trytes, 162 Trytes, 243 Trytes).

Für das Security-Level 2 wird aus dem Seed und dem Index ein Hash abgeleitet. Dieser besteht aus 2 x 27 Segmenten mit je einem 81 Trytes langen Hashwert. (81 x 27= 2187 Trytes). Daraus ergibt sich eine Schlüssellänge für den Private Key von 2 x 2187 = 4374 Trytes. Für die Key-Fragmente wird wiederum aus den beiden Blöcken des Private Key ein 81 Trytes langer Hashwert gebildet. Aus diesen beiden Blöcken wird dann wieder ein 81 Trytes langer Hash ermittelt, der die Adresse ist. Für das Security-Level 1 wird nur jeweils ein Block und für das Level 3 werden drei Blöcke verwendet.

Erzeugen von Adressen

Die Methode zur Erzeugung der Adressen spiegelt das vorgestellte Konzept zur Adresserzeugung vollständig wider. Dies zeigen auch die entsprechenden Aufrufparameter.

Mit der nachfolgenden Methode werde neue noch nicht verwendete Adressen erzeugt.

GetNewAddressResponse res = iotaAPIClient.generateNewAddresses(seed, securityLevel, checksum, index, amount);

Als Ergebnis der Methode erhalten wir zum Beispiel für die verschiedenen Security-Level folgende Adressen (s. Tabelle 1). Die grauen Zeichen bilden dabei die Checksummen. Bei der Ausführung der Methode mit checksum = false fehlen die letzten 9 Zeichen.

Transaktionen

Non-Value-Transaktionen

Basierend auf dem beschriebenen Prozess einer Transaktion (siehe Teil 1) erfolgt zunächst die Erzeugung der Transaktion (Transfer-Daten).

...
Transfer transaction = new Transfer(address, value, message, tag); transfers.add(transaction);
...

Hier werden die notwendigen Daten der Transaktion, wie die Adresse und die Nachricht erfasst. Der Value bleibt in diesem Fall Null.

Im zweiten Schritt erfolgt der Transfer. Bei der Methode sendTransfer handelt es sich um einen erweiterten API-Aufruf, der die im Kap. 1.4 Transaktionen beschrieben einzelnen Schritte zusammenfasst.

...
SendTransferResponse str = iotaAPIClient.sendTransfer(seed, security, depth, minWeightMagnitude, transfers, inputs, remainderAddress, validateInputs, validateInputAddresses, tips);
...

Wichtige Parameter, die hier gefüllt sein müssen sind:

Alle anderen Werte können Null oder leer sein.
Nach dem Senden der Transaktion bekommt man die folgende Response:

hash=X9DQMGHHNSOJBHSVSHSWERSHZXIQIXHQCPTLMLRXKXTYKZOSPYWXQBAMSMMMBCLJWUQWW9ZXG9YTZ9999
signatureFrag-ments=ODGASCTCJDXCRCTCSBSCGADBGAVAWAYAXBRBOBGAQAGAJDPC9DIDTCGADBGAVAWAUAGAQD9999999999999999999999999999999999999999999…999
address=WBNEWLOFVMDCYLAJWVWXOLRCVRCBWVORV9GVCDHZVPXORYMKWYSPVXAQSQKRCBFNYDOCEDGZ9FGFDMMDW
value=0
obsoleteTag=QRTASPAM99999999999999NHE99
timestamp=1542901673
currentIndex=0
lastIndex=0
bundle=IIP9URQVIJTDQSGFFKVXLLUAVBZSACSYFLLDOHLTACXCKECZFRDSTAFSECELQGGQ9VTQEWEN9OJDLLNYX
trunkTransac-tion=VNOWRP9JHCIQFKLELZXSRVMTKOSGJERMRDTDGZ9ZNOLEXIOVWBMWXJOGWXSIWAHPHIMHLUFJSSBCNT999
branchTransac-tion=NJIINZRTBDBQZJKUKQQVFQSJCBPAXVGREKEIFEEXCZSYTX9MMDSBKFUIBJYEKDZUFSYEPRZNKCVEII999
nonce=IMJSIIWFQANIOIBVXT9N9LRNDBW
persistence=<null>
attachmentTimestamp=1542901674831
tag=JOTASPAM99999999999999NHE99
attachmentTimestampLowerBound=0
attachmentTimestampUpperBound=3812798742493

Im signatureFragments befindet sich die eigentliche Nachricht als Trytes String. Im Devnet Tangle Explorer kann man sich die Nachricht dann als Text oder JSON anzeigen lassen.

Die beiden Transaktionen, die von unserer Transaktion validiert wurden, findet man als trunkTransaction und branchTransaction. Mithilfe des Devnet Tangle Explorer kann man diesen Zusammenhang sehr gut visualisieren. Hier ist auch die Transaktion zu finden, die unsere Transaktion validiert hat.

Value-Transaktionen

Bei einer Value-Transaktion werden nun IOTAs, genannt Token, von einem Besitzer zu einem anderen transferiert.

Voraussetzung ist, dass ich einen zweiten Seed mit einer Adresse anlege, um eine entsprechende Überweisung zu tätigen. Weiterhin ist es notwendig, einen Token zu erhalten. Dafür wird ein Service angeboten, der für das Devnet entsprechende Token ausgibt.

Einen Token erhält man, indem man eine generierte Adresse auf der Seite https://faucet.devnet.iota.org eingibt. Den Erhalt kann man anschließend wieder im Devnet Tangle Explorer prüfen. Die Abbildung zeigt nun eine Balance von 1.000i.

Ein ganz wesentlicher Unterschied zur Non-Value-Transaktion ist die Notwendigkeit, dem Transfer die inputs mitzugeben. Dabei handelt es sich um die Transaktionen die Guthaben besitzen, von dem transferiert werden soll.

Folgendes Beispiel soll das Ganze etwas anschaulicher machen.

Wir möchten von Person A zu Person B einen Transfer von 1i durchführen.

PersonA

AdressePersonA = FQIYHISQQ9EOOUOZEVLTIBENFCXLDSTRHQINBERHPUTBSCKSJYZBEA9CFNKIJQCWOCXICHSXSWDBEQZFC9VCBDKIAD

Balance / Guthaben = 2.000i

PersonB

AdressePersonB = WBNEWLOFVMDCYLAJWVWXOLRCVRCBWVORV9GVCDHZVPXORYMKWYSPVXAQSQKRCBFNYDOCEDGZ9FGFDMMDW9JSTBIMSX

Balance / Guthaben = 1.000i

Die nachfolgenden Methoden sind in der gegebenen Reihenfolge auszuführen:

1. Transfer definieren für Person A überweist Person B 2i

Transfer transaction = new Transfer(address, value, message, tag); transfers.add(transaction);

Für address ist die Empfängeradresse, also die Adresse Person B und der value ist 2 Die Einträge für message, tag kann man beliebig setzen.

2. Jetzt muss man das Guthaben von Person A ermitteln, von dem „abgebucht“ werden soll.

GetBalancesAndFormatResponse res = iotaAPIClient.getInputs(seed, security, 0, 1, 1);inputs= res.getInputs();

Dazu muss der seed von Person A verwendet werden. Es wird über alle Adressen des entsprechenden Security Levels gesucht. Das Ergebnis wird dann als inputs in die sendTransfer Methode übergeben.

3. Transfer auslösen

SendTransferResponse str = iotaAPIClient.sendTransfer(seed, security, depth, minWeightMagnitude, transfers, inputs, remainderAddress, validateInputs, validateInputAddresses, tips);

Nach der Ausführung des Transfers erhält man in der Response ein Bundle an Transaktionen, die für die Ausführung des Transfers notwendig waren.

Im Tangle Explorer findet man das Bundle über die BundleID.

bundle=EBLGCSDFULIAVILWUUBWAOOXWBHHIIDXEHIIZQITWVLHJZLXGKJ9ONFCLREDEJXOVVHXANPEJOCKICQKY

In Abbildung 5 kann man nun sowohl die Input- als auch die Output-Transaktionen sehen.

Von hier kann man sich dann die einzelnen Transaktionen des Bundles detaillierter anschauen. Die erste Transaktion (Index 0) zeigt, dass Person B 2i erhalten hat. Hier ist als Adresse die „Empfänger-Adresse“ von Person B eingetragen.

Wenn Person B die Transaktionen für seine Adresse nun betrachtet, dann sieht sie, dass das Guthaben nun 1002i beträgt.

Die drei weiteren Transaktionen betreffen die Adresse von Person A und finden sich dort wieder. Hier sehen wir im ersten Eintrag das entfernte „alte“ Guthaben und in der dritten Zeile das „neue“ Guthaben. Zeile zwei ist die Transaktion mit dem zweiten Teil der Signatur.

Im dritten der Blogserie widmen wir uns der verteilten Ledger-Technologie Hashgraph.

Diesen Artikel bewerten
 
 
 
 
 
 
 
0 Bewertungen (0 %)
Bewerten
 
 
 
 
 
 
1
5
0