diff --git a/src/noobchain/Block.java b/src/noobchain/Block.java index 7986167..122a917 100644 --- a/src/noobchain/Block.java +++ b/src/noobchain/Block.java @@ -43,19 +43,19 @@ public void mineBlock(int difficulty) { } //Add transactions to this block - public boolean addTransaction(Transaction transaction) { + public void addTransaction(Transaction transaction) throws IllegalStateException { //process transaction and check if valid, unless block is genesis block then ignore. if(transaction == null) return false; if((!"0".equals(previousHash))) { if((transaction.processTransaction() != true)) { System.out.println("Transaction failed to process. Discarded."); - return false; + throw new IllegalStateException("Transaction failed to process. Discarded."); } } transactions.add(transaction); System.out.println("Transaction Successfully added to Block"); - return true; + } } diff --git a/src/noobchain/NoobChain.java b/src/noobchain/NoobChain.java index 3d306f2..af9c54e 100644 --- a/src/noobchain/NoobChain.java +++ b/src/noobchain/NoobChain.java @@ -1,4 +1,5 @@ package noobchain; + import java.security.Security; import java.util.ArrayList; //import java.util.Base64; @@ -7,141 +8,161 @@ import java.util.Map; public class NoobChain { - + public static ArrayList blockchain = new ArrayList(); - public static HashMap UTXOs = new HashMap(); - + public static HashMap UTXOs = new HashMap(); + public static int difficulty = 3; public static float minimumTransaction = 0.1f; public static Wallet walletA; public static Wallet walletB; public static Transaction genesisTransaction; - public static void main(String[] args) { - //add our blocks to the blockchain ArrayList: - Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); //Setup Bouncey castle as a Security Provider - - //Create wallets: + public static void main(String[] args) { + // add our blocks to the blockchain ArrayList: + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // Setup Bouncey castle as a + // Security Provider + + // Create wallets: walletA = new Wallet(); - walletB = new Wallet(); + walletB = new Wallet(); Wallet coinbase = new Wallet(); - - //create genesis transaction, which sends 100 NoobCoin to walletA: - genesisTransaction = new Transaction(coinbase.publicKey, walletA.publicKey, 100f, null); - genesisTransaction.generateSignature(coinbase.privateKey); //manually sign the genesis transaction - genesisTransaction.transactionId = "0"; //manually set the transaction id - genesisTransaction.outputs.add(new TransactionOutput(genesisTransaction.reciepient, genesisTransaction.value, genesisTransaction.transactionId)); //manually add the Transactions Output - UTXOs.put(genesisTransaction.outputs.get(0).id, genesisTransaction.outputs.get(0)); //its important to store our first transaction in the UTXOs list. - - System.out.println("Creating and Mining Genesis block... "); - Block genesis = new Block("0"); - genesis.addTransaction(genesisTransaction); - addBlock(genesis); - - //testing - Block block1 = new Block(genesis.hash); - System.out.println("\nWalletA's balance is: " + walletA.getBalance()); - System.out.println("\nWalletA is Attempting to send funds (40) to WalletB..."); - block1.addTransaction(walletA.sendFunds(walletB.publicKey, 40f)); - addBlock(block1); - System.out.println("\nWalletA's balance is: " + walletA.getBalance()); - System.out.println("WalletB's balance is: " + walletB.getBalance()); - - Block block2 = new Block(block1.hash); - System.out.println("\nWalletA Attempting to send more funds (1000) than it has..."); - block2.addTransaction(walletA.sendFunds(walletB.publicKey, 1000f)); - addBlock(block2); - System.out.println("\nWalletA's balance is: " + walletA.getBalance()); - System.out.println("WalletB's balance is: " + walletB.getBalance()); - - Block block3 = new Block(block2.hash); - System.out.println("\nWalletB is Attempting to send funds (20) to WalletA..."); - block3.addTransaction(walletB.sendFunds( walletA.publicKey, 20)); - System.out.println("\nWalletA's balance is: " + walletA.getBalance()); - System.out.println("WalletB's balance is: " + walletB.getBalance()); - - isChainValid(); - + + // create genesis transaction, which sends 100 NoobCoin to walletA: + try { + genesisTransaction = new Transaction(coinbase.publicKey, walletA.publicKey, 100f, null); + genesisTransaction.generateSignature(coinbase.privateKey); // manually sign the genesis transaction + genesisTransaction.transactionId = "0"; // manually set the transaction id + genesisTransaction.outputs.add(new TransactionOutput(genesisTransaction.reciepient, + genesisTransaction.value, genesisTransaction.transactionId)); // manually add the Transactions + // Output + UTXOs.put(genesisTransaction.outputs.get(0).id, genesisTransaction.outputs.get(0)); // its important to + // store our first + // transaction in the + // UTXOs list. + + System.out.println("Creating and Mining Genesis block... "); + Block genesis = new Block("0"); + genesis.addTransaction(genesisTransaction); + addBlock(genesis); + + // testing + Block block1 = new Block(genesis.hash); + System.out.println("\nWalletA's balance is: " + walletA.getBalance()); + System.out.println("\nWalletA is Attempting to send funds (40) to WalletB..."); + block1.addTransaction(walletA.sendFunds(walletB.publicKey, 40f)); + addBlock(block1); + System.out.println("\nWalletA's balance is: " + walletA.getBalance()); + System.out.println("WalletB's balance is: " + walletB.getBalance()); + + Block block2 = new Block(block1.hash); + System.out.println("\nWalletA Attempting to send more funds (1000) than it has..."); + block2.addTransaction(walletA.sendFunds(walletB.publicKey, 1000f)); + addBlock(block2); + System.out.println("\nWalletA's balance is: " + walletA.getBalance()); + System.out.println("WalletB's balance is: " + walletB.getBalance()); + + Block block3 = new Block(block2.hash); + System.out.println("\nWalletB is Attempting to send funds (20) to WalletA..."); + block3.addTransaction(walletB.sendFunds(walletA.publicKey, 20)); + System.out.println("\nWalletA's balance is: " + walletA.getBalance()); + System.out.println("WalletB's balance is: " + walletB.getBalance()); + + isChainValid(); + } catch (Exception e) { + // TODO: handle exception + System.out.println(e.getMessage()); + } + } - + public static Boolean isChainValid() { - Block currentBlock; + Block currentBlock; Block previousBlock; String hashTarget = new String(new char[difficulty]).replace('\0', '0'); - HashMap tempUTXOs = new HashMap(); //a temporary working list of unspent transactions at a given block state. + HashMap tempUTXOs = new HashMap(); // a temporary working + // list of unspent + // transactions at a + // given block + // state. tempUTXOs.put(genesisTransaction.outputs.get(0).id, genesisTransaction.outputs.get(0)); - - //loop through blockchain to check hashes: - for(int i=1; i < blockchain.size(); i++) { - + + // loop through blockchain to check hashes: + for (int i = 1; i < blockchain.size(); i++) { + currentBlock = blockchain.get(i); - previousBlock = blockchain.get(i-1); - //compare registered hash and calculated hash: - if(!currentBlock.hash.equals(currentBlock.calculateHash()) ){ + previousBlock = blockchain.get(i - 1); + // compare registered hash and calculated hash: + if (!currentBlock.hash.equals(currentBlock.calculateHash())) { System.out.println("#Current Hashes not equal"); return false; } - //compare previous hash and registered previous hash - if(!previousBlock.hash.equals(currentBlock.previousHash) ) { + // compare previous hash and registered previous hash + if (!previousBlock.hash.equals(currentBlock.previousHash)) { System.out.println("#Previous Hashes not equal"); return false; } - //check if hash is solved - if(!currentBlock.hash.substring( 0, difficulty).equals(hashTarget)) { + // check if hash is solved + if (!currentBlock.hash.substring(0, difficulty).equals(hashTarget)) { System.out.println("#This block hasn't been mined"); return false; } - - //loop thru blockchains transactions: + + // loop thru blockchains transactions: TransactionOutput tempOutput; - for(int t=0; t