Das nachfolgende Programm erzeugt insgesamt 11 Datenblöcke und damit ist eine Veränderung der Schwierigkeit („difficulty“) sehr gut zu bemerken. Wie im Basisartikel geschrieben solltet Ihr die „difficulty“ (zu finden in Zeile 41) nur schrittweise erhöhen, denn das Programm wird sehr schnell sehr langsam.
Hier ist der Programmcode der 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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
package net.bplaced.javacrypto.blockchain.step4; /* * 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 4: Mining eines Blockes * Function: Step 4: mining of a block * * 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 */ import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; public class BlockChainB { 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("I04b BlockChain für Anfänger Stufe 04"); int blockNumber; // genesis datensatz blockNumber = 1; System.out.println("\nGenesis Block " + blockNumber); addBlock(new Block("0", "Genesis Block")); // genesis block // daten der blockchain System.out.println("Anzahl Einträge in der blockchain:" + blockchain.size()); System.out.println("Inhalt der BlockChain:\n" + StringUtil.getJson(blockchain)); System.out.println("Ist die blockchain gültig:" + blockchainIsValid()); for (blockNumber = 2; blockNumber < 12; blockNumber++) { System.out.println("\nErgänze Block " + blockNumber); addBlock(new Block(blockchain.get(blockchain.size() - 1).hash, "Data " + blockNumber)); } // daten der blockchain System.out.println("Anzahl Einträge in der blockchain:" + blockchain.size()); System.out.println("Inhalt der BlockChain:\n" + StringUtil.getJson(blockchain)); System.out.println("Ist die blockchain gültig:" + blockchainIsValid()); } 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()); } } |
Die Konsole gibt diese Werte aus (Hinweis: ich habe die „difficulty“ auf „5“ erhöht, daher beginnen die Hashwerte mit 5 Nullen):
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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
I04b BlockChain für Anfänger Stufe 04 Genesis Block 1 Block Mined, Hash: 000001f0902dc8b71d5b8785038ddc8191ba2c044f53f52c134e75185ebc709b Anzahl Einträge in der blockchain:1 Inhalt der BlockChain: [ { "hash": "000001f0902dc8b71d5b8785038ddc8191ba2c044f53f52c134e75185ebc709b", "previousHash": "0", "timeStamp": 1559119487353, "data": "Genesis Block", "nonce": 628859 } ] Ist die blockchain gültig:true Ergänze Block 2 Block Mined, Hash: 00000078cdee6485196a9ddcf6ae7aa77323d18698406554152e2be47288246a Ergänze Block 3 Block Mined, Hash: 000002e3e1e2fb039968b430ca415acbca5c2893da246f929d8c19f9af825fca Ergänze Block 4 Block Mined, Hash: 00000f6878a65c09d1879afaf82463e2dd6b7b648b4819f15c012c7d07cfa661 Ergänze Block 5 Block Mined, Hash: 00000c547243f9ee77adcc4ea5ccb8e327fc8e11b95b08797eabd5b98beeb989 Ergänze Block 6 Block Mined, Hash: 000001d8e02fb8df5ba3524640ce98191d3adfcc235a0824683450dc3afe2903 Ergänze Block 7 Block Mined, Hash: 00000f15078e086669e0e80ecf6d1114ac17678357b93f2d1a51f4446b50e5ea Ergänze Block 8 Block Mined, Hash: 000000fb14a1baa6e9b8168c8f81eee4c298cd035bc5440eabe84110dc8ece38 Ergänze Block 9 Block Mined, Hash: 00000db045c5536f849601b8f2fc1df364e4edcf61b2380106c9a3c57c834a69 Ergänze Block 10 Block Mined, Hash: 00000af443d5436b9a57fbde183a8c0ad7fe87fcb522e6a4b10deabae4b28a92 Ergänze Block 11 Block Mined, Hash: 000006d195b37c50b00835683070c56866c0436362e2c7dcfa2dc00ef3d9eb88 Anzahl Einträge in der blockchain:11 Inhalt der BlockChain: [ { "hash": "000001f0902dc8b71d5b8785038ddc8191ba2c044f53f52c134e75185ebc709b", "previousHash": "0", "timeStamp": 1559119487353, "data": "Genesis Block", "nonce": 628859 }, { "hash": "00000078cdee6485196a9ddcf6ae7aa77323d18698406554152e2be47288246a", "previousHash": "000001f0902dc8b71d5b8785038ddc8191ba2c044f53f52c134e75185ebc709b", "timeStamp": 1559119488646, "data": "Data 2", "nonce": 2462979 }, { "hash": "000002e3e1e2fb039968b430ca415acbca5c2893da246f929d8c19f9af825fca", "previousHash": "00000078cdee6485196a9ddcf6ae7aa77323d18698406554152e2be47288246a", "timeStamp": 1559119493445, "data": "Data 3", "nonce": 1749478 }, { "hash": "00000f6878a65c09d1879afaf82463e2dd6b7b648b4819f15c012c7d07cfa661", "previousHash": "000002e3e1e2fb039968b430ca415acbca5c2893da246f929d8c19f9af825fca", "timeStamp": 1559119496855, "data": "Data 4", "nonce": 1394265 }, { "hash": "00000c547243f9ee77adcc4ea5ccb8e327fc8e11b95b08797eabd5b98beeb989", "previousHash": "00000f6878a65c09d1879afaf82463e2dd6b7b648b4819f15c012c7d07cfa661", "timeStamp": 1559119499563, "data": "Data 5", "nonce": 246007 }, { "hash": "000001d8e02fb8df5ba3524640ce98191d3adfcc235a0824683450dc3afe2903", "previousHash": "00000c547243f9ee77adcc4ea5ccb8e327fc8e11b95b08797eabd5b98beeb989", "timeStamp": 1559119500049, "data": "Data 6", "nonce": 1075139 }, { "hash": "00000f15078e086669e0e80ecf6d1114ac17678357b93f2d1a51f4446b50e5ea", "previousHash": "000001d8e02fb8df5ba3524640ce98191d3adfcc235a0824683450dc3afe2903", "timeStamp": 1559119502139, "data": "Data 7", "nonce": 2226944 }, { "hash": "000000fb14a1baa6e9b8168c8f81eee4c298cd035bc5440eabe84110dc8ece38", "previousHash": "00000f15078e086669e0e80ecf6d1114ac17678357b93f2d1a51f4446b50e5ea", "timeStamp": 1559119506452, "data": "Data 8", "nonce": 628789 }, { "hash": "00000db045c5536f849601b8f2fc1df364e4edcf61b2380106c9a3c57c834a69", "previousHash": "000000fb14a1baa6e9b8168c8f81eee4c298cd035bc5440eabe84110dc8ece38", "timeStamp": 1559119507670, "data": "Data 9", "nonce": 963696 }, { "hash": "00000af443d5436b9a57fbde183a8c0ad7fe87fcb522e6a4b10deabae4b28a92", "previousHash": "00000db045c5536f849601b8f2fc1df364e4edcf61b2380106c9a3c57c834a69", "timeStamp": 1559119509544, "data": "Data 10", "nonce": 3140095 }, { "hash": "000006d195b37c50b00835683070c56866c0436362e2c7dcfa2dc00ef3d9eb88", "previousHash": "00000af443d5436b9a57fbde183a8c0ad7fe87fcb522e6a4b10deabae4b28a92", "timeStamp": 1559119515655, "data": "Data 11", "nonce": 192946 } ] Ist die blockchain gültig:true |
Der Vollständigkeit halber folgen die beiden anderen Klassen:
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 |
package net.bplaced.javacrypto.blockchain.step4; /* * 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; // as number of milliseconds since 1/1/1970. 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); // Create a string with difficulty * "0" while (!hash.substring(0, difficulty).equals(target)) { nonce++; hash = calculateHash(); } System.out.println("Block Mined, Hash: " + hash); } } |
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.step4; /* * 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'); } } |
Zurück zum Teil 4: I04 Hash-Schwierigkeitsstufe erhöhen.
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