Die Blockchain in 9 Schritten – Teil 5: Erstellung eines Wallets
Mit diesem Teil verlassen wir die Blockchain und wenden uns langsam dem Krypto-Geld zu. Damit wir unser elektronisches Geld auch aufbewahren können benötigen wir eine passende Geldbörse oder auf Englisch ein Wallet. Selbstverständlich handelt es sich nicht um ein reales Portemonnaie aus Leder, sondern um eine Datei, welche erstaunliche Eigenschaften besitzt.
Das Besondere an diesem Wallet ist nämlich die Eigenschaft, dass die Geldbörse durch eine elektronische Signatur erzeugt und gleichzeitig damit geschützt wird. Der öffentliche Schlüssel („public key“) ist gleichzeitig die weltweit gültig „Kontonummer“ und der dazu gehörige private Schlüssel („private key“) dient der Zugriffsmöglichkeit. Um es in aller Deutlichkeit zu schreiben: ohne den privaten Schlüssel gibt es keinerlei Zugriffsmöglichkeit auf die Geldbörse oder kurz und knapp „weg ist weg“.
Damit wir die einzelnen Programmteile sauber strukturieren können landet der Quellcode für unsere Geldbörse wieder in einer eigenen Klasse „wallet“:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
package net.bplaced.javacrypto.blockchain.step5; /* * Diese Klasse gehört zu BlockChain.java * This class belongs to BlockChain.java */ import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.ECGenParameterSpec; public class Wallet { public PrivateKey privateKey; public PublicKey publicKey; public Wallet() { generateKeyPair(); } public void generateKeyPair() { try { // secp192r1 [NIST P-192, X9.62 prime192v1] (1.2.840.10045.3.1.1) // secp224k1 (1.3.132.0.32) // secp224r1 [NIST P-224] (1.3.132.0.33) // secp256k1 (1.3.132.0.10) // secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) KeyPairGenerator keypairGenerator = KeyPairGenerator.getInstance("EC", "SunEC"); ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp192r1"); //ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1"); keypairGenerator.initialize(ecSpec, new SecureRandom()); KeyPair keyPair = keypairGenerator.genKeyPair(); privateKey = keyPair.getPrivate(); publicKey = keyPair.getPublic(); } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchProviderException e) { throw new RuntimeException(e); } } } |
Die Bedienung geschieht über unsere ausgebaute Hauptklasse:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
package net.bplaced.javacrypto.blockchain.step5; /* * Herkunft/Origin: http://javacrypto.bplaced.net/ * Programmierer/Programmer: Michael Fehr * Copyright/Copyright: frei verwendbares Programm (Public Domain) * Copyright: This is free and unencumbered software released into the public domain. * Lizenztext/Licence: <http://unlicense.org> * getestet mit/tested with: Java Runtime Environment 8 Update 191 x64 * getestet mit/tested with: Java Runtime Environment 11.0.1 x64 * Datum/Date (dd.mm.jjjj): 29.05.2019 * Projekt/Project: Blockchain * Funktion: Schritt 5: Erstellung eines Wallets * Function: Step 5: creation of a wallet * * Sicherheitshinweis/Security notice * Die Programmroutinen dienen nur der Darstellung und haben keinen Anspruch auf eine korrekte Funktion, * insbesondere mit Blick auf die Sicherheit ! * Prüfen Sie die Sicherheit bevor das Programm in der echten Welt eingesetzt wird. * The program routines just show the function but please be aware of the security part - * check yourself before using in the real world ! * * Das Programm benötigt die nachfolgende Bibliothek: * The programm uses this external library: * jar-Datei: https://mvnrepository.com/artifact/com.google.code.gson/gson * * Das Projekt basiert auf dem nachfolgenden Artikel: * The project is based on this article: * https://medium.com/programmers-blockchain/create-simple-blockchain-java-tutorial-from-scratch-6eeed3cb03fa * https://medium.com/programmers-blockchain/creating-your-first-blockchain-with-java-part-2-transactions-2cdac335e0ce */ import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; public class BlockChain { public static ArrayList<Block> blockchain = new ArrayList<Block>(); public static int difficulty = 4; public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException { System.out.println("I05 BlockChain für Anfänger Stufe 05"); System.out.println("\nErzeuge ein Wallet"); Wallet wallet = new Wallet(); System.out.println("wallet privateKey:" + wallet.privateKey); System.out.println("wallet publicKey :" + wallet.publicKey); } public static void addBlock(Block newBlock) { newBlock.mineBlock(difficulty); blockchain.add(newBlock); } public static Boolean blockchainIsValid() { Block currentBlock; Block previousBlock; for (int i = 1; i < blockchain.size(); i++) { currentBlock = blockchain.get(i); previousBlock = blockchain.get(i - 1); if (!currentBlock.hash.equals(currentBlock.calculateHash())) { return false; } if (!previousBlock.hash.equals(currentBlock.previousHash)) { return false; } } return true; } public static String createDemonstationData(int number) { Date date = new Date(); return "Dataset:" + number + " " + new Timestamp(date.getTime()); } } |
In diesem Teil nutzen wir gar nicht den vorhandenen Code für die Blockchain, sondern konzentrieren uns ganz auf die Erstellung des Wallets. Da die beiden anderen Klassen unverändert sind, zeige ich Euch hier zuerst die kurze Ausgabe auf der Konsole und dahinter den Quellcode der beiden Klassen:
1 2 3 4 5 6 7 8 |
5 BlockChain für Anfänger Stufe 05 Erzeuge ein Wallet wallet privateKey:sun.security.ec.ECPrivateKeyImpl@2cd4 wallet publicKey :Sun EC public key, 192 bits public x coord: 87294081929586233431666512754659625323688232276291534555 public y coord: 3273931900638153797738526125483239284989885628695245333508 parameters: secp192r1 [NIST P-192, X9.62 prime192v1] (1.2.840.10045.3.1.1) |
Wir erzeugen ein elliptisches Kurvenpaar mit 192 Bit Schlüssellänge und nutzen dafür die Kurve SECP192R1 (was willkürlich durch uns geschieht, aber wir erstellen ja unser eigenes Krypto Geld).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package net.bplaced.javacrypto.blockchain.step5; /* * Diese Klasse gehört zu BlockChain.java * This class belongs to BlockChain.java */ import java.util.Date; public class Block { public String hash; public String previousHash; private long timeStamp; private String data; private int nonce; public Block(String previousHash, String data) { this.previousHash = previousHash; this.data = data; this.timeStamp = new Date().getTime(); this.hash = calculateHash(); } public String calculateHash() { String calculatedhash = StringUtil .generateSha256(previousHash + Long.toString(timeStamp) + Integer.toString(nonce) + data); return calculatedhash; } public void mineBlock(int difficulty) { String target = StringUtil.getDifficultyString(difficulty); while (!hash.substring(0, difficulty).equals(target)) { nonce++; hash = calculateHash(); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package net.bplaced.javacrypto.blockchain.step5; /* * Diese Klasse gehört zu BlockChain.java * This class belongs to BlockChain.java */ import java.security.MessageDigest; import com.google.gson.GsonBuilder; public class StringUtil { public static String generateSha256(String input) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hash = digest.digest(input.getBytes("UTF-8")); StringBuffer hexString = new StringBuffer(); for (int i = 0; i < hash.length; i++) { String hex = Integer.toHexString(0xff & hash[i]); if (hex.length() == 1) hexString.append('0'); hexString.append(hex); } return hexString.toString(); } catch (Exception e) { throw new RuntimeException(e); } } public static String getJson(Object o) { return new GsonBuilder().setPrettyPrinting().create().toJson(o); } public static String getDifficultyString(int difficulty) { return new String(new char[difficulty]).replace('\0', '0'); } } |
Weiter geht es mit Teil 6: I06 Nutzung von Transaktionen.
Alle Quellcodes zur Blockchain findet Ihr zum Download in meinem Github-Repository, welches Ihr über diesen Link erreicht: https://github.com/java-crypto/I-Blockchain. Alle Programme sind sowohl unter Java 8 als auch unter Java 11 lauffähig.
Die Lizenz zum obigen Beispiel findet Ihr auf der eigenen Lizenz-Seite.
Letzte Aktualisierung: 29.05.2019