Die Blockchain in 9 Schritten – Teil 8: Der JavaCryptoCoin
Nun vollenden wir unsere Schritte zum JavaCryptoCoin und besprechen die übrigen 4 Klassen. Der erste Teil des Quellcodes wird in I07 Vorbereitung des JavaCryptoCoin besprochen. Eine kleine Warnung vorne weg – hier kommt noch eine Menge an Informationen!
Der folgende Sourcecode ist sehr kurz und knapp und enthält die Klasse „TransactionInput“. Die Grundlage unserer Währung ist, dass ein Zahlungseingang alle Geldmittel beinhaltet, die Ihr erhalten habt und noch zur Verfügung stehen. Zur Verfügung stehen Euch die noch nicht ausgegeben Gelder und auf Englisch „Unspend transactions“. Da dieser Begriff für die Programmierer zu lang ist, wird er mit dem Kürzel „UTXO“ abgekürzt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package net.bplaced.javacrypto.blockchain.step8; /* * Diese Klasse gehört zu JavaCryptoCoin.java * This class belongs to JavaCryptoCoin.java */ import java.io.Serializable; public class TransactionInput implements Serializable{ private static final long serialVersionUID = -6643746839251237698L; public String transactionOutputId; public TransactionOutput UTXO; public TransactionInput(String transactionOutputId) { this.transactionOutputId = transactionOutputId; } } |
Wenn es eine Eingangs-Klasse gibt, sollte es auch die umgekehrte Zahlungsausgangs-Klasse geben – hier ist der Sourcecode der „TransactionOutput-Klasse“.
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 |
package net.bplaced.javacrypto.blockchain.step8; /* * Diese Klasse gehört zu JavaCryptoCoin.java * This class belongs to JavaCryptoCoin.java */ import java.io.Serializable; import java.security.PublicKey; public class TransactionOutput implements Serializable{ private static final long serialVersionUID = 7902714355455361435L; public String id; public PublicKey recipient; public float value; public String parentTransactionId; public TransactionOutput(PublicKey recipient, float value, String parentTransactionId) { this.recipient = recipient; this.value = value; this.parentTransactionId = parentTransactionId; this.id = StringUtil .generateSha256(StringUtil.getStringFromKey(recipient) + Float.toString(value) + parentTransactionId); } public boolean isMine(PublicKey publicKey) { return (publicKey.equals(recipient)); } } |
Beide Klassen bilden das Fundament der übergeordneten und stark erweiterten Klasse „Transaction“. Die Methode „processTransaction“ ist das zentrale Element der Klasse, denn hier wird eine Zahlungstransaktion verarbeitet, ein Minimum-Betrag vorausgesetzt und die Zahlung abgelehnt, wenn nicht genügend Coins zur Verfügung stehen. Ebenfalls wird hier geprüft, ob die für die Zahlung genutzte elektronische Unterschrift richtig ist.
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 |
package net.bplaced.javacrypto.blockchain.step8; /* * Diese Klasse gehört zu JavaCryptoCoin.java * This class belongs to JavaCryptoCoin.java */ import java.io.Serializable; import java.security.*; import java.util.ArrayList; public class Transaction implements Serializable{ private static final long serialVersionUID = -3795222285878701219L; public String transactionId; public PublicKey sender; public PublicKey recipient; public float value; public byte[] signature; public boolean asReward = false; public ArrayList<TransactionInput> inputs = new ArrayList<>(); public ArrayList<TransactionOutput> outputs = new ArrayList<>(); private static int sequence = 0; public Transaction(PublicKey from, PublicKey to, float value, ArrayList<TransactionInput> inputs) { this.sender = from; this.recipient = to; this.value = value; this.inputs = inputs; } public boolean processTransaction() { if (verifySignature() == false) { System.out.println("# Transaktion - Die Signatur ist nicht korrekt"); return false; } for (TransactionInput i : inputs) { i.UTXO = JavaCryptoCoin.UTXOs.get(i.transactionOutputId); } if (getInputsValue() < JavaCryptoCoin.minimumTransaction) { System.out.println("# Transaktion Der Input ist zu gering: " + getInputsValue()); System.out.println("# Bitte geben Sie einen Betrag groesser als " + JavaCryptoCoin.minimumTransaction + " ein."); return false; } float leftOver = getInputsValue() - value; //get value of inputs then the left over change: transactionId = calculateHash(); outputs.add(new TransactionOutput(this.recipient, value, transactionId)); //send value to recipient outputs.add(new TransactionOutput(this.sender, leftOver, transactionId)); //send the left over 'change' back to sender for (TransactionOutput o : outputs) { JavaCryptoCoin.UTXOs.put(o.id, o); } for (TransactionInput i : inputs) { if (i.UTXO == null) { continue; } JavaCryptoCoin.UTXOs.remove(i.UTXO.id); } return true; } public float getInputsValue() { float total = 0; for (TransactionInput i : inputs) { if (i.UTXO == null) { continue; } total += i.UTXO.value; } return total; } public void generateSignature(PrivateKey privateKey) { String data = StringUtil.getStringFromKey(sender) + StringUtil.getStringFromKey(recipient) + Float.toString(value); signature = StringUtil.generateECDSASig(privateKey, data); } public boolean verifySignature() { String data = StringUtil.getStringFromKey(sender) + StringUtil.getStringFromKey(recipient) + Float.toString(value); return StringUtil.verifyECDSASig(sender, data, signature); } public float getOutputsValue() { float total = 0; for (TransactionOutput o : outputs) { total += o.value; } return total; } public String calculateHash() { sequence++; return StringUtil.generateSha256( StringUtil.getStringFromKey(sender) + StringUtil.getStringFromKey(recipient) + Float.toString(value) + sequence ); } } |
Nun fehlt noch die Hauptklasse für unser Glück – „JavaCryptoCoin“.
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
package net.bplaced.javacrypto.blockchain.step8; /* * 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): 12.06.2019 * Projekt/Project: Blockchain / JavaCryptoCoin * Funktion: Schritt 8: die neue Krypto-Währung - JavaCryptoCoin * Function: Step 8: the new crypto currency - JavaCryptoCoin * * 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.security.PublicKey; import java.util.ArrayList; import java.util.HashMap; import java.io.IOException; public class JavaCryptoCoin { public static ArrayList<Block> blockchain = new ArrayList<Block>(); public static HashMap<String, TransactionOutput> UTXOs = new HashMap<String, TransactionOutput>(); public static int difficulty = 4; // kann ganz vorsichtig erhöht werden public static float minimumTransaction = 0.1f; public static Wallet coinbase; public static Wallet walletA; public static Wallet walletB; public static Wallet miner; public static Transaction genesisTransaction; public static void main(String[] args) throws IOException { System.out.println("I08 BlockChain für Anfänger Stufe 08 JavaCryptoCoin"); // unsere variablen für das programm String filenameBlockchain = "i08_blockchain.txt"; String filenameBlockchainJson = "i08_blockchain.json"; String filenameWalletA = "i08_walleta.txt"; String filenameWalletAJson = "i08_walleta.json"; String filenameWalletB = "i08_walletb.txt"; String filenameMiner = "i08_miner.txt"; // generierung der wallets coinbase = new Wallet(); walletA = new Wallet(); walletB = new Wallet(); miner = new Wallet(); // erzeuge die genesis transaktion und sende 100 javacryptocoins an walletA // ("initial coin offering") genesisTransaction = new Transaction(coinbase.publicKey, walletA.publicKey, 100f, null); genesisTransaction.generateSignature(coinbase.privateKey); // manuelle signatur der genesis transaktion genesisTransaction.transactionId = "0"; // manuelles setzen der transaktion id genesisTransaction.outputs.add(new TransactionOutput(genesisTransaction.recipient, genesisTransaction.value, genesisTransaction.transactionId)); // manuelles hinzufügen der transaktion zu den Transactions Output // es ist wichtig die erste transaktion in der UTXOs liste zu speichern UTXOs.put(genesisTransaction.outputs.get(0).id, genesisTransaction.outputs.get(0)); // der erste block wird in die blockchain geschrieben und gemined System.out.println("\nErzeuge und mine den Genesis block"); Block genesis = new Block("0"); genesis.addTransaction(genesisTransaction); addBlock(genesis); System.out.println("\nGuthaben der Wallets:"); System.out.println("Guthaben von coinbase: " + coinbase.getBalance()); System.out.println("Guthaben von walletA : " + walletA.getBalance()); System.out.println("Guthaben von walletB : " + walletB.getBalance()); // System.out.println("Guthaben von miner : " + miner.getBalance()); // speicherung der blockchain und der wallets System.out.println("\nSpeicherung der Blockchain und der Wallets"); FileUtil.saveObject(filenameBlockchain, blockchain); FileUtil.saveObject(filenameWalletA, walletA); FileUtil.saveObject(filenameWalletB, walletB); FileUtil.saveObject(filenameMiner, miner); // der public key ist die empfänger-adresse, daher sichern wir diese daten System.out.println("\nEmpfänger-Adressen von walletA und walletB"); PublicKey publicKeyA = walletA.publicKey; PublicKey publicKeyB = walletB.publicKey; String publicKeyAString = StringUtil.getStringFromKey(publicKeyA); String publicKeyBString = StringUtil.getStringFromKey(publicKeyB); System.out.println("publicKeyAString:" + publicKeyAString); System.out.println("publicKeyBString:" + publicKeyBString); // eine überweisung von walletA an walletB System.out.println("\nÜberweisung 40 JCC von walletA an walletB"); Block blockNewA = new Block(blockchain.get(blockchain.size() - 1).hash); blockNewA.addTransaction(walletA.sendFunds(publicKeyB, 40f)); // ergänze die blockchain um den neuen block und lasse ihn minen addBlock(blockNewA); System.out.println("\nGuthaben der Wallets:"); System.out.println("Guthaben von walletA : " + walletA.getBalance()); System.out.println("Guthaben von walletB : " + walletB.getBalance()); // zwei überweisungen von walletB an walletA System.out.println("\n2 Überweisungen je 25 JCC von walletB an walletA"); Block blockNewB = new Block(blockchain.get(blockchain.size() - 1).hash); blockNewB.addTransaction(walletB.sendFunds(publicKeyA, 25f)); blockNewB.addTransaction(walletB.sendFunds(publicKeyA, 25f)); // ergänze die blockchain um den neuen block und lasse ihn minen addBlock(blockNewB); System.out.println("\nGuthaben der Wallets:"); System.out.println("Guthaben von walletA : " + walletA.getBalance()); System.out.println("Guthaben von walletB : " + walletB.getBalance()); // System.out.println(StringUtil.getJson(blockchain)); // speicherung der blockchain und der wallets System.out.println("\nSpeicherung der Blockchain und der Wallets"); FileUtil.saveObject(filenameBlockchain, blockchain); FileUtil.saveObject(filenameWalletA, walletA); FileUtil.saveObject(filenameWalletB, walletB); FileUtil.saveObject(filenameMiner, miner); // die blockchain funktioniert ohne online wallets, daher löschen wir walletB System.out.println("\nObjekt walletB gelöscht"); walletB = null; // mehrere transaktionen kommen in einen block Block block1 = new Block(blockchain.get(blockchain.size() - 1).hash); block1.addTransaction(walletA.sendFunds(publicKeyB, 40f)); block1.addTransaction(walletA.sendFunds(publicKeyB, 10.3f)); addBlock(block1); block1 = new Block(blockchain.get(blockchain.size() - 1).hash); block1.addTransaction(walletA.sendFunds(publicKeyB, 20f)); block1.addTransaction(walletA.sendFunds(publicKeyB, 1.1f)); addBlock(block1); block1 = new Block(blockchain.get(blockchain.size() - 1).hash); block1.addTransaction(walletA.sendFunds(publicKeyB, 60f)); addBlock(block1); System.out.println("\nBalances after multiple transactions"); System.out.println("Miners's balance is : " + miner.getBalance()); System.out.println("WalletA's balance is: " + walletA.getBalance()); // walletB laden System.out.println("\nobjekt walletB geladen"); walletB = (Wallet) FileUtil.loadObject(filenameWalletB); System.out.println("WalletB's balance is: " + walletB.getBalance()); System.out.println("\nSend Coin to walletA"); Block blockB1 = new Block(blockchain.get(blockchain.size() - 1).hash); blockB1.addTransaction(walletB.sendFunds(walletA.publicKey, 11.123f)); addBlock(blockB1); System.out.println("WalletA's balance is: " + walletA.getBalance()); System.out.println("WalletB's balance is: " + walletB.getBalance()); System.out.println("_miner's balance is : " + miner.getBalance()); System.out.println("\nSend Coin from miner to walletA"); Block blockMiner = new Block(blockchain.get(blockchain.size() - 1).hash); blockMiner.addTransaction(miner.sendFunds(walletA.publicKey, 3.99f)); addBlock(blockMiner); System.out.println("WalletA's balance is: " + walletA.getBalance()); System.out.println("WalletB's balance is: " + walletB.getBalance()); System.out.println("_miner's balance is : " + miner.getBalance()); System.out.println("\nSend 1 Coin from miner to walletA, 1+2+3 b an a"); blockMiner = new Block(blockchain.get(blockchain.size() - 1).hash); blockMiner.addTransaction(miner.sendFunds(walletA.publicKey, 1.00f)); System.out.println(isChainValid()); System.out.println("WalletA's balance is: " + walletA.getBalance()); System.out.println("WalletB's balance is: " + walletB.getBalance()); System.out.println("_miner's balance is : " + miner.getBalance()); blockMiner.addTransaction(walletA.sendFunds(publicKeyB, 44f)); blockMiner.addTransaction(walletB.sendFunds(walletA.publicKey, 1.00f)); // System.out.println("Transaction:\n" + StringUtil.getJson(blockMiner)); blockMiner.addTransaction(walletB.sendFunds(walletA.publicKey, 2.00f)); blockMiner.addTransaction(walletB.sendFunds(walletA.publicKey, 3.00f)); addBlock(blockMiner); System.out.println("WalletA's balance is: " + walletA.getBalance()); System.out.println("WalletB's balance is: " + walletB.getBalance()); System.out.println("_miner's balance is : " + miner.getBalance()); // save blockchain FileUtil.saveObject(filenameBlockchain, blockchain); System.out.println("\nBlockchain gespeichert in Datei:" + filenameBlockchain); FileUtil.saveJsonFile(filenameBlockchainJson, StringUtil.getJson(blockchain)); System.out.println("\nBlockchain im JSON-Format gespeichert in Datei:" + filenameBlockchainJson); System.out.println("\nDie Blockchain ist gültig:" + isChainValid()); // save wallet FileUtil.saveObject(filenameWalletA, walletA); System.out.println("\nWalletA gespeichert in Datei:" + filenameWalletA); FileUtil.saveJsonFile(filenameWalletAJson, StringUtil.getJson(walletA)); System.out.println("\nWalletA im JSON-Format gespeichert in Datei:" + filenameWalletAJson); System.out.println("\nProgramm beendet"); } public static Boolean isChainValid() { Block currentBlock; Block previousBlock; HashMap<String, TransactionOutput> tempUTXOs = new HashMap<>(); tempUTXOs.put(genesisTransaction.outputs.get(0).id, genesisTransaction.outputs.get(0)); for (int i = 1; i < blockchain.size(); i++) { currentBlock = blockchain.get(i); previousBlock = blockchain.get(i - 1); if (!currentBlock.hash.equals(currentBlock.calculateHash())) { System.out.println("# Die Current Hashes sind nicht gleich"); return false; } if (!previousBlock.hash.equals(currentBlock.previousHash)) { System.out.println("# Die Previous Hashes sind nicht gleich"); return false; } if (!currentBlock.mined) { System.out.println("# Dieser Block wurde noch nicht mined"); return false; } TransactionOutput tempOutput; for (int t = 0; t < currentBlock.transactions.size(); t++) { Transaction currentTransaction = currentBlock.transactions.get(t); if (!currentTransaction.verifySignature()) { System.out.println("# Die Signatur der Transaction(" + t + ") ist ungültig"); return false; } if (!currentTransaction.asReward) { if (currentTransaction.getInputsValue() != currentTransaction.getOutputsValue()) { System.out.println("# Die Inputs sind nicht gleich den Outputs der Transaktion(" + t + ")"); return false; } for (TransactionInput input : currentTransaction.inputs) { tempOutput = tempUTXOs.get(input.transactionOutputId); if (tempOutput == null) { System.out.println("# Der referenzierte Input der Transaktion(" + t + ") fehlt"); return false; } if (input.UTXO.value != tempOutput.value) { System.out .println("# Der referenzierte Input der Transaktion(" + t + ") Wert ist ungültig"); return false; } tempUTXOs.remove(input.transactionOutputId); } } for (TransactionOutput output : currentTransaction.outputs) { tempUTXOs.put(output.id, output); } if (currentTransaction.outputs.get(0).recipient != currentTransaction.recipient) { System.out.println("# Transaktion(" + t + ") Der Output Empfänger ist nicht wer er sein sollte"); return false; } if (!currentTransaction.asReward) { if (currentTransaction.outputs.get(1).recipient != currentTransaction.sender) { System.out.println("# Transaktion(" + t + ") Der Output 'change' ist nicht der Sender"); return false; } } } } return true; } public static void addBlock(Block newBlock) { newBlock.mineBlock(difficulty); blockchain.add(newBlock); } } |
Damit Ihr den Programmablauf versteht hier in kurzer Form die Schritte.
- Zuerst werden die Variablen definiert, insbesondere zur Speicherung auf einen Datenträger
- Danach werden die Geldbörsen erzeugt, wobei es Wallets für zwei „echte“ Benutzer (walletA und walletB) gibt, ein Wallet existiert für den „miner“ und das Wallet mit dem Namen „coinbase“ dient der Erzeugung des „ersten“ Geldes.
- Im dritten Schritt wird das „Startguthaben“ von 100 Münzen erzeugt und an das walletA übertragen; dadurch beträgt das Guthaben im System nun 100 Coins auf walletA.
- Nun übertragen wir 40 Coins von walletA an walletB, was die Guthaben entsprechend verändert (walletA = 60 Coins, walletB = 40 Coins).
- Jetzt versuchen wir, 2 Mal je 25 Coins von walletB an walletA zu übertragen, was nur teilweise gelingt, da das Guthaben nicht ausreichend ist, um beide Transaktionen auszuführen.
- Um nachzuweisen, dass die Blockchain weiter funktioniert auch wenn ein wallet (hier walletB) nicht im System „da“ ist löschen wir das zugehörige Objekt.
- Wir versuchen nun, mehrere Transaktionen in einem Block zu verarbeiten. Auch hier funktioniert das nur teilweise.
- Nun laden wir das walletB und überprüfen das Guthaben anhand der Blockchain und es werden 86,4 Coins ausgewiesen, was zusammen mit den 13,6 Coins in walletA unser Startguthaben von 100 Coins ergibt.
- Abschließend werden noch einige Transaktionen durchgeführt und die notwendigen Dateien auf der Festplatte gesichert.
Damit haben wir alle Programmteile besprochen und wir lassen das Programm „richtig“ laufen. Ich habe die Konsolenausgabe hier nur teilweise angezeigt (bitte scrollen), da sie etwas länger ist:
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 |
I08 BlockChain für Anfänger Stufe 08 JavaCryptoCoin Erzeuge und mine den Genesis block Die Transaktion wurde dem Block erfolgreich hinzugefügt Block Mined!!! 390 ms: 4854d4eb8c1fe576ac279802a57f099af9a0f8a6ff2a830f9cca8041d4b1564d Guthaben der Wallets: Guthaben von coinbase: 0.0 Guthaben von walletA : 100.0 Guthaben von walletB : 0.0 Speicherung der Blockchain und der Wallets Empfänger-Adressen von walletA und walletB publicKeyAString:MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEScvDpYRLINVigJdOxEbDtRjMQS0vMA/lpdftydVVBQZ3bQI0oZBBP/bJpN3CoY3AlDpRMreN2Irx72XNOvtytg== publicKeyBString:MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYXHoOr7sLeLKPj2qPVp7kSKy3k4qTTZSMRYzc3einNCj3IiXrbR94GexSQqJuvC0tdexSCZ7NzuKNZo+1E+RqQ== Überweisung 40 JCC von walletA an walletB Die Transaktion wurde dem Block erfolgreich hinzugefügt Block Mined!!! 328 ms: 553093c884e78cf0849cdae37039c442e95df370e6470cc0f3846a83111061bf Guthaben der Wallets: Guthaben von walletA : 60.0 Guthaben von walletB : 40.0 2 Überweisungen je 25 JCC von walletB an walletA Die Transaktion wurde dem Block erfolgreich hinzugefügt # Das Guthaben ist zu gering um die Transaktion auszuführen, die Transaktion wurde abgebrochen. # Diese Transaktion scheitert: Empfänger:Sun EC public key, 256 bits public x coord: 33378858203589411082106865749782113934658422295773760833105995548776950203654 public y coord: 54017830533894086356493771429888953364218696258141282374891677164192325661366 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) Überweisungsbetrag:25.0 Block Mined!!! 203 ms: 6131d603fba55fb6cdda4bcece645df693cee4dbf2620abef8d8c529711dad2e Guthaben der Wallets: Guthaben von walletA : 85.0 Guthaben von walletB : 15.0 Speicherung der Blockchain und der Wallets Objekt walletB gelöscht Die Transaktion wurde dem Block erfolgreich hinzugefügt Die Transaktion wurde dem Block erfolgreich hinzugefügt Block Mined!!! 94 ms: 6354d3ec6fb4ff6a11c39ec18a724e12c303a108311492ebfb72ffbb6c37cdff Die Transaktion wurde dem Block erfolgreich hinzugefügt Die Transaktion wurde dem Block erfolgreich hinzugefügt Block Mined!!! 125 ms: 330486a96a9534bf31494f3e640b2925f6b1a7a78a5066014f9e022f0948152e # Das Guthaben ist zu gering um die Transaktion auszuführen, die Transaktion wurde abgebrochen. # Diese Transaktion scheitert: Empfänger:Sun EC public key, 256 bits public x coord: 44075602819832653128694936671037367434671104569973485484731066422612138826960 public y coord: 74116643400072052553390565564929949154269360856850592756427062894661685186985 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) Überweisungsbetrag:60.0 Block Mined!!! 203 ms: 485488e38739ad5f478b102e675517b8b90bae6a4a7c184d1af3ab5782dc4971 Balances after multiple transactions Miners's balance is : 0.0 WalletA's balance is: 13.6 objekt walletB geladen WalletB's balance is: 86.4 Send Coin to walletA Die Transaktion wurde dem Block erfolgreich hinzugefügt Block Mined!!! 32 ms: 2876ad9c4414cd4afe72bebfb9ad6fa7b5caa9e75c052ab0578672172e4c68c9 WalletA's balance is: 24.723 WalletB's balance is: 75.277 _miner's balance is : 0.0 Send Coin from miner to walletA # Das Guthaben ist zu gering um die Transaktion auszuführen, die Transaktion wurde abgebrochen. # Diese Transaktion scheitert: Empfänger:Sun EC public key, 256 bits public x coord: 33378858203589411082106865749782113934658422295773760833105995548776950203654 public y coord: 54017830533894086356493771429888953364218696258141282374891677164192325661366 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) Überweisungsbetrag:3.99 Block Mined!!! 15 ms: 4854000bbfaee8065759ff7ad41001f564fce8f2606b1551b1ae82b5574952b0 WalletA's balance is: 24.723 WalletB's balance is: 75.277 _miner's balance is : 0.0 Send 1 Coin from miner to walletA, 1+2+3 b an a # Das Guthaben ist zu gering um die Transaktion auszuführen, die Transaktion wurde abgebrochen. # Diese Transaktion scheitert: Empfänger:Sun EC public key, 256 bits public x coord: 33378858203589411082106865749782113934658422295773760833105995548776950203654 public y coord: 54017830533894086356493771429888953364218696258141282374891677164192325661366 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) Überweisungsbetrag:1.0 true WalletA's balance is: 24.723 WalletB's balance is: 75.277 _miner's balance is : 0.0 # Das Guthaben ist zu gering um die Transaktion auszuführen, die Transaktion wurde abgebrochen. # Diese Transaktion scheitert: Empfänger:Sun EC public key, 256 bits public x coord: 44075602819832653128694936671037367434671104569973485484731066422612138826960 public y coord: 74116643400072052553390565564929949154269360856850592756427062894661685186985 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) Überweisungsbetrag:44.0 Die Transaktion wurde dem Block erfolgreich hinzugefügt Die Transaktion wurde dem Block erfolgreich hinzugefügt Die Transaktion wurde dem Block erfolgreich hinzugefügt Block Mined!!! 250 ms: 5040743d24c4be4fd46037b8c6748f2d6e24b796b9203079e77ec2d533e495f5 WalletA's balance is: 30.723 WalletB's balance is: 69.277 _miner's balance is : 0.0 Blockchain gespeichert in Datei:i08_blockchain.txt Blockchain im JSON-Format gespeichert in Datei:i08_blockchain.json Die Blockchain ist gültig:true WalletA gespeichert in Datei:i08_walleta.txt WalletA im JSON-Format gespeichert in Datei:i08_walleta.json Programm beendet |
Die Programmierung unseres JavaCryptoCoin ist „eigentlich“ beendet, um aber um ein Verhalten ähnlich zum Bitcoin darzustellen ist noch eine kleine Ergänzung notwendig, daher gibt es noch ein weiteres Kapitel.
Weiter geht es mit Teil 9: I09 Der JavaCryptoCoin komplett
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: 12.06.2019