From 0072a19da356f928c081f1a50c52bd24f0456d64 Mon Sep 17 00:00:00 2001 From: roman Date: Mon, 12 Nov 2018 16:55:17 +0300 Subject: [PATCH 1/9] Stage 1 completed with 3 blocks in a blockchain --- .idea/misc.xml | 5 +++- src/blockchain/Block.java | 59 +++++++++++++++++++++++++++++++++++++++ src/blockchain/Main.java | 13 ++++++++- 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 src/blockchain/Block.java diff --git a/.idea/misc.xml b/.idea/misc.xml index a165cb3..dcfac18 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,9 @@ - + + + + \ No newline at end of file diff --git a/src/blockchain/Block.java b/src/blockchain/Block.java new file mode 100644 index 0000000..74a1a78 --- /dev/null +++ b/src/blockchain/Block.java @@ -0,0 +1,59 @@ +package blockchain; + +import java.security.MessageDigest; +import java.time.LocalDateTime; + + +public class Block { + private String prevHash; + private String hash; + private int id; + private LocalDateTime timeStamp; + + public Block(Block prevblock){ + if(prevblock == null) { + this.prevHash = "0"; + this.id = 1; + } + else { + this.prevHash = prevblock.getHash(); + this.id = prevblock.getId() + 1; + } + this.hash = applySha256(this.prevHash); + this.timeStamp = LocalDateTime.now(); + } + + public int getId() { + return id; + } + + public String getHash() { + return hash; + } + + public String getPrevHash() { + return prevHash; + } + + public LocalDateTime getTimeStamp(){ + return timeStamp; + } + + public static String applySha256(String input){ + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + /* Applies sha256 to our input */ + byte[] hash = digest.digest(input.getBytes("UTF-8")); + StringBuilder hexString = new StringBuilder(); + 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); + } + } +} diff --git a/src/blockchain/Main.java b/src/blockchain/Main.java index adf1d02..6e20499 100644 --- a/src/blockchain/Main.java +++ b/src/blockchain/Main.java @@ -2,6 +2,17 @@ public class Main { public static void main(String[] args) { - System.out.print("Hello world!"); + Block block = null; + for (int i = 0; i < 3; i++){ + block = new Block(block); + System.out.println("Block:"); + System.out.println("Id: " + block.getId()); + System.out.println("Timestamp: " + block.getTimeStamp()); + System.out.println("Hash of the previous block:"); + System.out.println(block.getPrevHash()); + System.out.println("Hash of the block:"); + System.out.println(block.getHash()); + System.out.println(""); + } } } \ No newline at end of file From 02cab3b183150af9a72a72c1d494400c96bbff05 Mon Sep 17 00:00:00 2001 From: roman Date: Thu, 15 Nov 2018 14:48:33 +0300 Subject: [PATCH 2/9] Stage 2 completed with 10 blocks in a blockchain --- .idea/misc.xml | 2 +- src/blockchain/Block.java | 51 +++++++++++++++++----- src/blockchain/Main.java | 91 ++++++++++++++++++++++++++++++++++----- 3 files changed, 122 insertions(+), 22 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index dcfac18..5cdffd2 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/src/blockchain/Block.java b/src/blockchain/Block.java index 74a1a78..b80c494 100644 --- a/src/blockchain/Block.java +++ b/src/blockchain/Block.java @@ -1,16 +1,25 @@ package blockchain; +import java.io.Serializable; +import java.time.LocalTime; + import java.security.MessageDigest; -import java.time.LocalDateTime; +import java.util.Date; +import java.util.Random; + + +public class Block implements Serializable{ -public class Block { private String prevHash; private String hash; private int id; - private LocalDateTime timeStamp; + private long timeStamp; + private int magicNumber; + private int timeSpent; - public Block(Block prevblock){ + public Block(Block prevblock, int difficulty){ + LocalTime start = LocalTime.now(); if(prevblock == null) { this.prevHash = "0"; this.id = 1; @@ -19,8 +28,22 @@ public Block(Block prevblock){ this.prevHash = prevblock.getHash(); this.id = prevblock.getId() + 1; } - this.hash = applySha256(this.prevHash); - this.timeStamp = LocalDateTime.now(); + String zeros = ""; + for (int i = 0; i < difficulty; i++){ + zeros += "0"; + } + + do { + setMagicNumber(); + this.hash = applySha256(this.prevHash + this.magicNumber); + }while(!this.hash.startsWith(zeros)); + LocalTime finish = LocalTime.now(); + this.timeSpent = finish.toSecondOfDay() - start.toSecondOfDay(); + this.timeStamp = new Date().getTime(); + } + + private void setMagicNumber() { + this.magicNumber = new Random().nextInt(Integer.MAX_VALUE); } public int getId() { @@ -35,18 +58,22 @@ public String getPrevHash() { return prevHash; } - public LocalDateTime getTimeStamp(){ + public long getTimeStamp(){ return timeStamp; } - public static String applySha256(String input){ + public int getTimeSpent() { + return timeSpent; + } + + public String applySha256(String input){ try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); /* Applies sha256 to our input */ byte[] hash = digest.digest(input.getBytes("UTF-8")); StringBuilder hexString = new StringBuilder(); - for (int i = 0; i < hash.length; i++) { - String hex = Integer.toHexString(0xff & hash[i]); + for (byte i : hash) { + String hex = Integer.toHexString(0xff & i); if(hex.length() == 1) hexString.append('0'); hexString.append(hex); } @@ -56,4 +83,8 @@ public static String applySha256(String input){ throw new RuntimeException(e); } } + + public int getMagicNumber(){ + return this.magicNumber; + } } diff --git a/src/blockchain/Main.java b/src/blockchain/Main.java index 6e20499..2462f08 100644 --- a/src/blockchain/Main.java +++ b/src/blockchain/Main.java @@ -1,18 +1,87 @@ package blockchain; +import java.io.*; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Scanner; + public class Main { public static void main(String[] args) { - Block block = null; - for (int i = 0; i < 3; i++){ - block = new Block(block); - System.out.println("Block:"); - System.out.println("Id: " + block.getId()); - System.out.println("Timestamp: " + block.getTimeStamp()); - System.out.println("Hash of the previous block:"); - System.out.println(block.getPrevHash()); - System.out.println("Hash of the block:"); - System.out.println(block.getHash()); - System.out.println(""); + LinkedList blockchain = null; + boolean isNewFile = false; + boolean blockchainValid = false; + int difficulty = setDifficulty(); + File file = new File("D:\\hyperskillGit\\blockchain\\MyBlockchain"); + try { + isNewFile = file.createNewFile(); + + if(isNewFile){ + System.out.println("The new blockchain file was successfully created."); + blockchain = new LinkedList(); + blockchainValid = true; + } else { + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis); + blockchain = (LinkedList) ois.readObject(); + System.out.println("The Blockchain was read from the file"); + ois.close(); + blockchainValid = isBlockchainValid(blockchain); + } + }catch (IOException e){ + System.out.println("Cannot create the file: " + file.getPath()); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + if(blockchainValid) { + for (int i = 0; i < 10; i++) { + if (isNewFile && i == 0) { + blockchain.add(new Block(null, difficulty)); + } else { + blockchain.add(new Block(blockchain.peekLast(), difficulty)); + } + + System.out.println("Block:"); + System.out.println("Id: " + blockchain.peekLast().getId()); + System.out.println("Timestamp: " + blockchain.peekLast().getTimeStamp()); + System.out.println("Magic number: " + blockchain.peekLast().getMagicNumber()); + System.out.println("Hash of the previous block:"); + System.out.println(blockchain.peekLast().getPrevHash()); + System.out.println("Hash of the block:"); + System.out.println(blockchain.peekLast().getHash()); + System.out.println("Block was generating for " + blockchain.peekLast().getTimeSpent() + " seconds"); + System.out.println(""); + try { + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(blockchain); + oos.close(); + System.out.println("The Blockchain was successfully written to the file"); + System.out.println(""); + } catch (FileNotFoundException e) { + System.out.println("File not found"); + } catch (IOException e) { + System.out.println("Cannot write to the file"); + } + } + }else{ + System.out.println("Blockchain loaded from file is not valid."); + } + } + + public static int setDifficulty(){ + Scanner in = new Scanner(System.in); + System.out.println("Set difficulty (number of zeros in the beginning of hash): "); + return in.nextInt(); + } + + public static boolean isBlockchainValid(LinkedList bc){ + int cnt = 0; + for (int i = 0; i < bc.size() - 1; i++){ + if(!bc.get(i).getHash().equals(bc.get(i+1).getPrevHash())){ + cnt++; + } } + return cnt==0; } } \ No newline at end of file From 25fcce379a0208f4f21700e5826e0fe9da9929a6 Mon Sep 17 00:00:00 2001 From: roman Date: Fri, 16 Nov 2018 16:39:06 +0300 Subject: [PATCH 3/9] Stage 3 completed with 20 miners --- src/blockchain/Block.java | 30 +++++--- src/blockchain/Blockchain.java | 121 +++++++++++++++++++++++++++++++++ src/blockchain/Main.java | 92 +++++-------------------- src/blockchain/Miner.java | 38 +++++++++++ 4 files changed, 196 insertions(+), 85 deletions(-) create mode 100644 src/blockchain/Blockchain.java create mode 100644 src/blockchain/Miner.java diff --git a/src/blockchain/Block.java b/src/blockchain/Block.java index b80c494..3aedb7a 100644 --- a/src/blockchain/Block.java +++ b/src/blockchain/Block.java @@ -9,7 +9,7 @@ -public class Block implements Serializable{ +class Block implements Serializable{ private String prevHash; private String hash; @@ -42,31 +42,43 @@ public Block(Block prevblock, int difficulty){ this.timeStamp = new Date().getTime(); } - private void setMagicNumber() { + public synchronized void printOutResults(){ + System.out.println("Id: " + this.getId()); + System.out.println("Timestamp: " + this.getTimeStamp()); + System.out.println("Magic number: " + this.getMagicNumber()); + System.out.println("Hash of the previous block:"); + System.out.println(this.getPrevHash()); + System.out.println("Hash of the block:"); + System.out.println(this.getHash()); + System.out.println("Block was generating for " + this.getTimeSpent() + " seconds"); + } + + + private synchronized void setMagicNumber() { this.magicNumber = new Random().nextInt(Integer.MAX_VALUE); } - public int getId() { + public synchronized int getId() { return id; } - public String getHash() { + public synchronized String getHash() { return hash; } - public String getPrevHash() { + public synchronized String getPrevHash() { return prevHash; } - public long getTimeStamp(){ + public synchronized long getTimeStamp(){ return timeStamp; } - public int getTimeSpent() { + public synchronized int getTimeSpent() { return timeSpent; } - public String applySha256(String input){ + public synchronized String applySha256(String input){ try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); /* Applies sha256 to our input */ @@ -84,7 +96,7 @@ public String applySha256(String input){ } } - public int getMagicNumber(){ + public synchronized int getMagicNumber(){ return this.magicNumber; } } diff --git a/src/blockchain/Blockchain.java b/src/blockchain/Blockchain.java new file mode 100644 index 0000000..cba5ad0 --- /dev/null +++ b/src/blockchain/Blockchain.java @@ -0,0 +1,121 @@ +package blockchain; + +import java.io.*; +import java.util.LinkedList; + +/** + * Created by Пользователь on 16.11.2018. + */ +class Blockchain { + private volatile LinkedList blockchain = null; + private boolean newFile = false; + private int difficulty = 0; + + + public Blockchain(String filePath) { + File file = new File(filePath);//"D:\\hyperskillGit\\blockchain\\MyBlockchain"); + readBlockchainFromFile(file); + + } + + public synchronized void readBlockchainFromFile(File file) { + try { + newFile = file.createNewFile(); + if (newFile) { + System.out.println("The new blockchain file was successfully created."); + this.blockchain = new LinkedList(); + this.difficulty = 0; + } else { + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis); + this.blockchain = (LinkedList) ois.readObject(); + System.out.println("The Blockchain was read from the file"); + ois.close(); + this.difficulty = getDifficultyFromFile(this.blockchain.peekLast().getHash()); + } + } catch (IOException e) { + System.out.println("Cannot create the file: " + file.getPath()); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + public synchronized void writeBlockchainToFile(String filePath) { + File file = new File(filePath); + try { + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(blockchain); + oos.close(); + System.out.println("The Blockchain was successfully written to the file"); + System.out.println(""); + } catch (FileNotFoundException e) { + System.out.println("File not found"); + } catch (IOException e) { + System.out.println("Cannot write to the file"); + } + } + + public synchronized void setDifficulty() { + Block b = this.blockchain.peekLast(); + if (b == null) { + this.difficulty = 0; + } else { + if (b.getTimeSpent() < 10) { + this.difficulty += 1; + System.out.println("N was increased to " + this.difficulty); + } else if (b.getTimeSpent() >= 60) { + this.difficulty -= 1; + System.out.println("N was decreased to " + this.difficulty); + } else { + System.out.println("N stays the same"); + } + } + } + + public synchronized int getDifficulty() { + return this.difficulty; + } + + public synchronized LinkedList getBlockchain() { + return this.blockchain; + } + + public synchronized boolean addBlock(Block block) { + Block blockPrev = this.blockchain.peekLast(); + if (block != null) { + if (blockPrev == null && block.getPrevHash().equals("0")) { //first block + this.blockchain.add(block); + return true; + } else if (blockPrev.getHash().equals(block.getPrevHash())) { //block is valid + this.blockchain.add(block); + return true; + } else { + return false; + } + } else { + return false; + } + } + + public synchronized boolean isBlockchainValid() { + int cnt = 0; + if (!this.newFile) { + for (int i = 0; i < this.blockchain.size() - 1; i++) { + if (!this.blockchain.get(i).getHash().equals(this.blockchain.get(i + 1).getPrevHash())) { + cnt++; + } + } + } + return cnt == 0; + } + + private int getDifficultyFromFile(String hash){ + int i = 0; + while (hash.charAt(i) == '0'){ + i++; + } + return i; + } + +} diff --git a/src/blockchain/Main.java b/src/blockchain/Main.java index 2462f08..67372ae 100644 --- a/src/blockchain/Main.java +++ b/src/blockchain/Main.java @@ -1,87 +1,27 @@ package blockchain; -import java.io.*; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.Scanner; public class Main { - public static void main(String[] args) { - LinkedList blockchain = null; - boolean isNewFile = false; - boolean blockchainValid = false; - int difficulty = setDifficulty(); - File file = new File("D:\\hyperskillGit\\blockchain\\MyBlockchain"); - try { - isNewFile = file.createNewFile(); - if(isNewFile){ - System.out.println("The new blockchain file was successfully created."); - blockchain = new LinkedList(); - blockchainValid = true; - } else { - FileInputStream fis = new FileInputStream(file); - ObjectInputStream ois = new ObjectInputStream(fis); - blockchain = (LinkedList) ois.readObject(); - System.out.println("The Blockchain was read from the file"); - ois.close(); - blockchainValid = isBlockchainValid(blockchain); - } - }catch (IOException e){ - System.out.println("Cannot create the file: " + file.getPath()); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - - if(blockchainValid) { - for (int i = 0; i < 10; i++) { - if (isNewFile && i == 0) { - blockchain.add(new Block(null, difficulty)); - } else { - blockchain.add(new Block(blockchain.peekLast(), difficulty)); - } + public static void main(String[] args) throws InterruptedException { + String filePath = "D:\\hyperskillGit\\blockchain\\MyBlockchain"; + Blockchain blockchain = new Blockchain(filePath); + Thread[] miners = new Miner[20]; - System.out.println("Block:"); - System.out.println("Id: " + blockchain.peekLast().getId()); - System.out.println("Timestamp: " + blockchain.peekLast().getTimeStamp()); - System.out.println("Magic number: " + blockchain.peekLast().getMagicNumber()); - System.out.println("Hash of the previous block:"); - System.out.println(blockchain.peekLast().getPrevHash()); - System.out.println("Hash of the block:"); - System.out.println(blockchain.peekLast().getHash()); - System.out.println("Block was generating for " + blockchain.peekLast().getTimeSpent() + " seconds"); - System.out.println(""); - try { - FileOutputStream fos = new FileOutputStream(file); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(blockchain); - oos.close(); - System.out.println("The Blockchain was successfully written to the file"); - System.out.println(""); - } catch (FileNotFoundException e) { - System.out.println("File not found"); - } catch (IOException e) { - System.out.println("Cannot write to the file"); - } + if(blockchain.isBlockchainValid()) { + for (int i = 0; i < miners.length; i++) { + miners[i] = new Miner(blockchain, i+1); } - }else{ - System.out.println("Blockchain loaded from file is not valid."); - } - } - - public static int setDifficulty(){ - Scanner in = new Scanner(System.in); - System.out.println("Set difficulty (number of zeros in the beginning of hash): "); - return in.nextInt(); - } - - public static boolean isBlockchainValid(LinkedList bc){ - int cnt = 0; - for (int i = 0; i < bc.size() - 1; i++){ - if(!bc.get(i).getHash().equals(bc.get(i+1).getPrevHash())){ - cnt++; + for (Thread miner: miners){ + miner.start(); } + for (Thread miner: miners){ + miner.join(); + } + blockchain.writeBlockchainToFile(filePath); + } + else { + System.out.println("Blockchain loaded from file is not valid."); } - return cnt==0; } } \ No newline at end of file diff --git a/src/blockchain/Miner.java b/src/blockchain/Miner.java new file mode 100644 index 0000000..fee528e --- /dev/null +++ b/src/blockchain/Miner.java @@ -0,0 +1,38 @@ +package blockchain; + +import java.util.LinkedList; + +/** + * Created by Пользователь on 16.11.2018. + */ +public class Miner extends Thread{ + private Blockchain blockchain; + private int minerNumber; + + public Miner(Blockchain blockchain,int minerNumber){ + this.blockchain = blockchain; + this.minerNumber = minerNumber; + } + + + @Override + public void run(){ + + synchronized (Blockchain.class) { + boolean blockIsValid = blockchain.addBlock(new Block(blockchain.getBlockchain().peekLast(), blockchain.getDifficulty())); + + if (blockIsValid) { + System.out.println(""); + System.out.println("Block:"); + System.out.println("Created by miner # " + this.minerNumber); + blockchain.getBlockchain().peekLast().printOutResults(); + blockchain.setDifficulty(); + } else { + System.out.println("Generated block is not valid, so no block was added to the blockchain"); + } + } + + } + + +} From 2175fd72dad608c925cca7ba6325e19ba8c96e97 Mon Sep 17 00:00:00 2001 From: Roman Shilov Date: Sat, 17 Nov 2018 18:18:28 +0300 Subject: [PATCH 4/9] added ArrayList for miners, synchronize miner to block class from blockchain, made Blockchain public static --- .idea/misc.xml | 5 +---- src/blockchain/Block.java | 16 ++++++++-------- src/blockchain/Blockchain.java | 8 +++++--- src/blockchain/Main.java | 17 +++++++++++------ src/blockchain/Miner.java | 13 +++++-------- 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 5cdffd2..b7148e8 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,9 +1,6 @@ - - - - + \ No newline at end of file diff --git a/src/blockchain/Block.java b/src/blockchain/Block.java index 3aedb7a..f7c7381 100644 --- a/src/blockchain/Block.java +++ b/src/blockchain/Block.java @@ -54,31 +54,31 @@ public synchronized void printOutResults(){ } - private synchronized void setMagicNumber() { + private void setMagicNumber() { this.magicNumber = new Random().nextInt(Integer.MAX_VALUE); } - public synchronized int getId() { + public int getId() { return id; } - public synchronized String getHash() { + public String getHash() { return hash; } - public synchronized String getPrevHash() { + public String getPrevHash() { return prevHash; } - public synchronized long getTimeStamp(){ + public long getTimeStamp(){ return timeStamp; } - public synchronized int getTimeSpent() { + public int getTimeSpent() { return timeSpent; } - public synchronized String applySha256(String input){ + public String applySha256(String input){ try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); /* Applies sha256 to our input */ @@ -96,7 +96,7 @@ public synchronized String applySha256(String input){ } } - public synchronized int getMagicNumber(){ + public int getMagicNumber(){ return this.magicNumber; } } diff --git a/src/blockchain/Blockchain.java b/src/blockchain/Blockchain.java index cba5ad0..127fd72 100644 --- a/src/blockchain/Blockchain.java +++ b/src/blockchain/Blockchain.java @@ -18,7 +18,7 @@ public Blockchain(String filePath) { } - public synchronized void readBlockchainFromFile(File file) { + public void readBlockchainFromFile(File file) { try { newFile = file.createNewFile(); if (newFile) { @@ -31,6 +31,7 @@ public synchronized void readBlockchainFromFile(File file) { this.blockchain = (LinkedList) ois.readObject(); System.out.println("The Blockchain was read from the file"); ois.close(); + fis.close(); this.difficulty = getDifficultyFromFile(this.blockchain.peekLast().getHash()); } } catch (IOException e) { @@ -40,13 +41,14 @@ public synchronized void readBlockchainFromFile(File file) { } } - public synchronized void writeBlockchainToFile(String filePath) { + public void writeBlockchainToFile(String filePath) { File file = new File(filePath); try { FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(blockchain); oos.close(); + fos.close(); System.out.println("The Blockchain was successfully written to the file"); System.out.println(""); } catch (FileNotFoundException e) { @@ -56,7 +58,7 @@ public synchronized void writeBlockchainToFile(String filePath) { } } - public synchronized void setDifficulty() { + public void setDifficulty() { Block b = this.blockchain.peekLast(); if (b == null) { this.difficulty = 0; diff --git a/src/blockchain/Main.java b/src/blockchain/Main.java index 67372ae..a409f4f 100644 --- a/src/blockchain/Main.java +++ b/src/blockchain/Main.java @@ -1,16 +1,21 @@ package blockchain; -public class Main { +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +public class Main { + public static Blockchain blockchain; public static void main(String[] args) throws InterruptedException { - String filePath = "D:\\hyperskillGit\\blockchain\\MyBlockchain"; - Blockchain blockchain = new Blockchain(filePath); - Thread[] miners = new Miner[20]; + Scanner in = new Scanner(System.in); + String filePath = in.nextLine();//"D:\\hyperskillGit\\blockchain\\MyBlockchain"; + blockchain= new Blockchain(filePath); + List miners = new ArrayList<>(); if(blockchain.isBlockchainValid()) { - for (int i = 0; i < miners.length; i++) { - miners[i] = new Miner(blockchain, i+1); + for (int i = 0; i < 8; i++) { + miners.add(new Miner(i+1)); } for (Thread miner: miners){ miner.start(); diff --git a/src/blockchain/Miner.java b/src/blockchain/Miner.java index fee528e..d2ad7e9 100644 --- a/src/blockchain/Miner.java +++ b/src/blockchain/Miner.java @@ -6,11 +6,9 @@ * Created by Пользователь on 16.11.2018. */ public class Miner extends Thread{ - private Blockchain blockchain; private int minerNumber; - public Miner(Blockchain blockchain,int minerNumber){ - this.blockchain = blockchain; + public Miner(int minerNumber){ this.minerNumber = minerNumber; } @@ -18,15 +16,14 @@ public Miner(Blockchain blockchain,int minerNumber){ @Override public void run(){ - synchronized (Blockchain.class) { - boolean blockIsValid = blockchain.addBlock(new Block(blockchain.getBlockchain().peekLast(), blockchain.getDifficulty())); - + synchronized (Block.class) { + boolean blockIsValid = Main.blockchain.addBlock(new Block(Main.blockchain.getBlockchain().peekLast(), Main.blockchain.getDifficulty())); if (blockIsValid) { System.out.println(""); System.out.println("Block:"); System.out.println("Created by miner # " + this.minerNumber); - blockchain.getBlockchain().peekLast().printOutResults(); - blockchain.setDifficulty(); + Main.blockchain.getBlockchain().peekLast().printOutResults(); + Main.blockchain.setDifficulty(); } else { System.out.println("Generated block is not valid, so no block was added to the blockchain"); } From 5aec3aa82e3d59c3b6298f64775ecf15b5032dc7 Mon Sep 17 00:00:00 2001 From: roman Date: Tue, 20 Nov 2018 10:46:03 +0300 Subject: [PATCH 5/9] Stage 4 completed --- .idea/misc.xml | 5 ++++- .idea/project.iml | 2 +- src/blockchain/Block.java | 26 ++++++++++++++++++----- src/blockchain/Blockchain.java | 12 +++++++++++ src/blockchain/Main.java | 33 ++++++++++++++++++++-------- src/blockchain/Miner.java | 2 +- src/blockchain/User.java | 39 ++++++++++++++++++++++++++++++++++ 7 files changed, 102 insertions(+), 17 deletions(-) create mode 100644 src/blockchain/User.java diff --git a/.idea/misc.xml b/.idea/misc.xml index b7148e8..df7e8eb 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,9 @@ - + + + + \ No newline at end of file diff --git a/.idea/project.iml b/.idea/project.iml index 47baa8c..a241e87 100644 --- a/.idea/project.iml +++ b/.idea/project.iml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/src/blockchain/Block.java b/src/blockchain/Block.java index f7c7381..1492a80 100644 --- a/src/blockchain/Block.java +++ b/src/blockchain/Block.java @@ -5,12 +5,15 @@ import java.security.MessageDigest; import java.util.Date; +import java.util.LinkedList; +import java.util.List; import java.util.Random; class Block implements Serializable{ + private List messagesStack = new LinkedList(); private String prevHash; private String hash; private int id; @@ -18,15 +21,15 @@ class Block implements Serializable{ private int magicNumber; private int timeSpent; - public Block(Block prevblock, int difficulty){ + public Block(Block prevBlock, int difficulty){ LocalTime start = LocalTime.now(); - if(prevblock == null) { + if(prevBlock == null) { this.prevHash = "0"; this.id = 1; } else { - this.prevHash = prevblock.getHash(); - this.id = prevblock.getId() + 1; + this.prevHash = prevBlock.getHash(); + this.id = prevBlock.getId() + 1; } String zeros = ""; for (int i = 0; i < difficulty; i++){ @@ -42,7 +45,7 @@ public Block(Block prevblock, int difficulty){ this.timeStamp = new Date().getTime(); } - public synchronized void printOutResults(){ + public synchronized void printOutResults() { System.out.println("Id: " + this.getId()); System.out.println("Timestamp: " + this.getTimeStamp()); System.out.println("Magic number: " + this.getMagicNumber()); @@ -50,6 +53,14 @@ public synchronized void printOutResults(){ System.out.println(this.getPrevHash()); System.out.println("Hash of the block:"); System.out.println(this.getHash()); + if (this.id == 1 || messagesStack.isEmpty()){ + System.out.println("Block data: no messages"); + }else{ + System.out.println("Block data: "); + for(String s: messagesStack) { + System.out.println(s); + } + } System.out.println("Block was generating for " + this.getTimeSpent() + " seconds"); } @@ -99,4 +110,9 @@ public String applySha256(String input){ public int getMagicNumber(){ return this.magicNumber; } + + public void writeMessagesStack(LinkedList messagesStack){ + this.messagesStack.addAll(messagesStack); + } + } diff --git a/src/blockchain/Blockchain.java b/src/blockchain/Blockchain.java index 127fd72..c0cc8a7 100644 --- a/src/blockchain/Blockchain.java +++ b/src/blockchain/Blockchain.java @@ -2,11 +2,13 @@ import java.io.*; import java.util.LinkedList; +import java.util.List; /** * Created by Пользователь on 16.11.2018. */ class Blockchain { + private LinkedList messages = new LinkedList(); private volatile LinkedList blockchain = null; private boolean newFile = false; private int difficulty = 0; @@ -120,4 +122,14 @@ private int getDifficultyFromFile(String hash){ return i; } + public synchronized void addMessagesToTheBlockchain(String msg){ + this.messages.add(msg); + } + + public synchronized void addMessagesToTheBlock(){ + this.blockchain.peekLast().writeMessagesStack(this.messages); + this.messages.clear(); + } + + } diff --git a/src/blockchain/Main.java b/src/blockchain/Main.java index a409f4f..657809d 100644 --- a/src/blockchain/Main.java +++ b/src/blockchain/Main.java @@ -7,26 +7,41 @@ public class Main { public static Blockchain blockchain; + public static List users = new ArrayList(); + public static List miners = new ArrayList(); + public static void main(String[] args) throws InterruptedException { Scanner in = new Scanner(System.in); String filePath = in.nextLine();//"D:\\hyperskillGit\\blockchain\\MyBlockchain"; - blockchain= new Blockchain(filePath); - List miners = new ArrayList<>(); + blockchain = new Blockchain(filePath); + + - if(blockchain.isBlockchainValid()) { - for (int i = 0; i < 8; i++) { - miners.add(new Miner(i+1)); + if (blockchain.isBlockchainValid()) { + users.add(new User("Tom")); + users.add(new User("Sara")); + users.add(new User("John")); + + for (int i = 0; i < 7; i++) { + miners.add(new Miner(i + 1)); } - for (Thread miner: miners){ + for (Thread miner : miners) { miner.start(); } - for (Thread miner: miners){ + + users.forEach(Thread::start); + for (Thread miner : miners) { miner.join(); } + for(Thread user:users){ + user.interrupt(); + } blockchain.writeBlockchainToFile(filePath); - } - else { + System.exit(0); + + } else { System.out.println("Blockchain loaded from file is not valid."); } + } } \ No newline at end of file diff --git a/src/blockchain/Miner.java b/src/blockchain/Miner.java index d2ad7e9..6adf026 100644 --- a/src/blockchain/Miner.java +++ b/src/blockchain/Miner.java @@ -1,6 +1,5 @@ package blockchain; -import java.util.LinkedList; /** * Created by Пользователь on 16.11.2018. @@ -19,6 +18,7 @@ public void run(){ synchronized (Block.class) { boolean blockIsValid = Main.blockchain.addBlock(new Block(Main.blockchain.getBlockchain().peekLast(), Main.blockchain.getDifficulty())); if (blockIsValid) { + Main.blockchain.addMessagesToTheBlock(); System.out.println(""); System.out.println("Block:"); System.out.println("Created by miner # " + this.minerNumber); diff --git a/src/blockchain/User.java b/src/blockchain/User.java new file mode 100644 index 0000000..1117716 --- /dev/null +++ b/src/blockchain/User.java @@ -0,0 +1,39 @@ +package blockchain; + +import java.io.InputStream; +import java.nio.channels.Channels; +import java.util.Scanner; + +/** + * Created by Пользователь on 19.11.2018. + */ +public class User extends Thread { + private String name; + private String message; + Scanner in = new Scanner(System.in); + + public User(String name){ + this.name = name; + } + + @Override + public void run() { + while (!this.isInterrupted()) { + newMaessage(); + Main.blockchain.addMessagesToTheBlockchain(getMessage()); + } + } + + private synchronized void newMaessage(){ + if(!this.isInterrupted()) { + + String s = in.nextLine(); + this.message = this.name + ": " + s; + } + } + + public String getMessage(){ + return this.message; + } + +} From 5f7602be029bb21faa9b56ed1a9127f577f48805 Mon Sep 17 00:00:00 2001 From: roman Date: Tue, 20 Nov 2018 13:11:51 +0300 Subject: [PATCH 6/9] On stage 4 added true multy-threading --- src/blockchain/Block.java | 12 +++-------- src/blockchain/Blockchain.java | 13 ++++++++++-- src/blockchain/Miner.java | 37 +++++++++++++++++----------------- src/blockchain/User.java | 8 +++++--- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/blockchain/Block.java b/src/blockchain/Block.java index 1492a80..3c3c244 100644 --- a/src/blockchain/Block.java +++ b/src/blockchain/Block.java @@ -19,10 +19,9 @@ class Block implements Serializable{ private int id; private long timeStamp; private int magicNumber; - private int timeSpent; public Block(Block prevBlock, int difficulty){ - LocalTime start = LocalTime.now(); + if(prevBlock == null) { this.prevHash = "0"; this.id = 1; @@ -40,12 +39,11 @@ public Block(Block prevBlock, int difficulty){ setMagicNumber(); this.hash = applySha256(this.prevHash + this.magicNumber); }while(!this.hash.startsWith(zeros)); - LocalTime finish = LocalTime.now(); - this.timeSpent = finish.toSecondOfDay() - start.toSecondOfDay(); + this.timeStamp = new Date().getTime(); } - public synchronized void printOutResults() { + public void printOutResults() { System.out.println("Id: " + this.getId()); System.out.println("Timestamp: " + this.getTimeStamp()); System.out.println("Magic number: " + this.getMagicNumber()); @@ -61,7 +59,6 @@ public synchronized void printOutResults() { System.out.println(s); } } - System.out.println("Block was generating for " + this.getTimeSpent() + " seconds"); } @@ -85,9 +82,6 @@ public long getTimeStamp(){ return timeStamp; } - public int getTimeSpent() { - return timeSpent; - } public String applySha256(String input){ try { diff --git a/src/blockchain/Blockchain.java b/src/blockchain/Blockchain.java index c0cc8a7..ab5f348 100644 --- a/src/blockchain/Blockchain.java +++ b/src/blockchain/Blockchain.java @@ -11,6 +11,7 @@ class Blockchain { private LinkedList messages = new LinkedList(); private volatile LinkedList blockchain = null; private boolean newFile = false; + private int timeSpent; private int difficulty = 0; @@ -65,10 +66,10 @@ public void setDifficulty() { if (b == null) { this.difficulty = 0; } else { - if (b.getTimeSpent() < 10) { + if (getTimeSpent() < 10) { this.difficulty += 1; System.out.println("N was increased to " + this.difficulty); - } else if (b.getTimeSpent() >= 60) { + } else if (getTimeSpent() >= 60) { this.difficulty -= 1; System.out.println("N was decreased to " + this.difficulty); } else { @@ -131,5 +132,13 @@ public synchronized void addMessagesToTheBlock(){ this.messages.clear(); } + public void setTimeSpent(int timeSpent){ + this.timeSpent = timeSpent; + } + public int getTimeSpent() { + return timeSpent; + } + + } diff --git a/src/blockchain/Miner.java b/src/blockchain/Miner.java index 6adf026..fe01c81 100644 --- a/src/blockchain/Miner.java +++ b/src/blockchain/Miner.java @@ -1,35 +1,36 @@ package blockchain; +import java.time.LocalTime; + /** * Created by Пользователь on 16.11.2018. */ -public class Miner extends Thread{ +public class Miner extends Thread { private int minerNumber; - public Miner(int minerNumber){ + + public Miner(int minerNumber) { this.minerNumber = minerNumber; } @Override - public void run(){ - - synchronized (Block.class) { - boolean blockIsValid = Main.blockchain.addBlock(new Block(Main.blockchain.getBlockchain().peekLast(), Main.blockchain.getDifficulty())); - if (blockIsValid) { - Main.blockchain.addMessagesToTheBlock(); - System.out.println(""); - System.out.println("Block:"); - System.out.println("Created by miner # " + this.minerNumber); - Main.blockchain.getBlockchain().peekLast().printOutResults(); - Main.blockchain.setDifficulty(); - } else { - System.out.println("Generated block is not valid, so no block was added to the blockchain"); - } - } - + public void run() { + LocalTime start = LocalTime.now(); + while (!Main.blockchain.addBlock(new Block(Main.blockchain.getBlockchain().peekLast(), Main.blockchain.getDifficulty()))) { } + Main.blockchain.addMessagesToTheBlock(); + LocalTime finish = LocalTime.now(); + Main.blockchain.setTimeSpent(finish.toSecondOfDay() - start.toSecondOfDay()); + System.out.println(""); + System.out.println("Block:"); + System.out.println("Created by miner # " + this.minerNumber); + Main.blockchain.getBlockchain().peekLast().printOutResults(); + System.out.println("Block was generating for " + Main.blockchain.getTimeSpent() + " seconds"); + Main.blockchain.setDifficulty(); } } + + diff --git a/src/blockchain/User.java b/src/blockchain/User.java index 1117716..df917ff 100644 --- a/src/blockchain/User.java +++ b/src/blockchain/User.java @@ -26,9 +26,11 @@ public void run() { private synchronized void newMaessage(){ if(!this.isInterrupted()) { - - String s = in.nextLine(); - this.message = this.name + ": " + s; + synchronized (User.class) { + System.out.print(this.name + ": "); + String s = in.nextLine(); + this.message = this.name + ": " + s; + } } } From b830850fe903f63058ec7ca786ed46c044120b75 Mon Sep 17 00:00:00 2001 From: roman Date: Tue, 20 Nov 2018 15:31:05 +0300 Subject: [PATCH 7/9] Stage 5 complited --- src/blockchain/Block.java | 32 +++++++++++++++++---- src/blockchain/Blockchain.java | 33 +++++++++++++++++++-- src/blockchain/GenerateKeys.java | 34 ++++++++++++++++++++++ src/blockchain/Main.java | 9 ++++-- src/blockchain/Message.java | 49 ++++++++++++++++++++++++++++++++ src/blockchain/Miner.java | 7 ++++- src/blockchain/User.java | 19 +++++++++---- 7 files changed, 167 insertions(+), 16 deletions(-) create mode 100644 src/blockchain/GenerateKeys.java create mode 100644 src/blockchain/Message.java diff --git a/src/blockchain/Block.java b/src/blockchain/Block.java index 3c3c244..0430cb0 100644 --- a/src/blockchain/Block.java +++ b/src/blockchain/Block.java @@ -1,6 +1,7 @@ package blockchain; import java.io.Serializable; +import java.io.UnsupportedEncodingException; import java.time.LocalTime; import java.security.MessageDigest; @@ -13,12 +14,13 @@ class Block implements Serializable{ - private List messagesStack = new LinkedList(); + private List messagesStack = new LinkedList(); private String prevHash; private String hash; private int id; private long timeStamp; private int magicNumber; + private long maxMsgID; public Block(Block prevBlock, int difficulty){ @@ -43,7 +45,7 @@ public Block(Block prevBlock, int difficulty){ this.timeStamp = new Date().getTime(); } - public void printOutResults() { + public void printOutResults() throws UnsupportedEncodingException { System.out.println("Id: " + this.getId()); System.out.println("Timestamp: " + this.getTimeStamp()); System.out.println("Magic number: " + this.getMagicNumber()); @@ -55,8 +57,10 @@ public void printOutResults() { System.out.println("Block data: no messages"); }else{ System.out.println("Block data: "); - for(String s: messagesStack) { - System.out.println(s); + for(Message s: messagesStack) { + String str = new String(s.getList().get(0), "UTF-8"); + + System.out.println(str); } } } @@ -105,8 +109,26 @@ public int getMagicNumber(){ return this.magicNumber; } - public void writeMessagesStack(LinkedList messagesStack){ + public void writeMessagesStack(LinkedList messagesStack){ this.messagesStack.addAll(messagesStack); } + public LinkedList getMessageStack(){ + return (LinkedList) this.messagesStack; + } + + private void setMaxMsgID(){ + long max = 0; + for(int i = 0; i < this.messagesStack.size(); i++){ + if(max < this.messagesStack.get(i).getId()){ + max = this.messagesStack.get(i).getId(); + } + } + this.maxMsgID = max; + } + + public long getMaxMsgID(){ + return this.maxMsgID; + } + } diff --git a/src/blockchain/Blockchain.java b/src/blockchain/Blockchain.java index ab5f348..9fc6f5a 100644 --- a/src/blockchain/Blockchain.java +++ b/src/blockchain/Blockchain.java @@ -8,11 +8,12 @@ * Created by Пользователь on 16.11.2018. */ class Blockchain { - private LinkedList messages = new LinkedList(); + private LinkedList messages = new LinkedList(); private volatile LinkedList blockchain = null; private boolean newFile = false; private int timeSpent; private int difficulty = 0; + private static long ids = 1; public Blockchain(String filePath) { @@ -28,6 +29,7 @@ public void readBlockchainFromFile(File file) { System.out.println("The new blockchain file was successfully created."); this.blockchain = new LinkedList(); this.difficulty = 0; + this.ids = 1; } else { FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); @@ -35,6 +37,9 @@ public void readBlockchainFromFile(File file) { System.out.println("The Blockchain was read from the file"); ois.close(); fis.close(); + if(blockchain.peekLast().getMessageStack().peekLast() != null) { + this.ids = blockchain.peekLast().getMessageStack().peekLast().getId() + 1L; + } this.difficulty = getDifficultyFromFile(this.blockchain.peekLast().getHash()); } } catch (IOException e) { @@ -111,6 +116,15 @@ public synchronized boolean isBlockchainValid() { cnt++; } } + //check that every message has an identifier greater than the maximum identifier of the previous block + for(int i = this.blockchain.size() - 1; i > 0; i--){ + for(int j = 0; j < this.blockchain.get(i).getMessageStack().size(); j++) { + if (!(this.blockchain.get(i-1).getMaxMsgID() < this.blockchain.get(i).getMessageStack().get(j).getId())) + { + cnt++; + } + } + } } return cnt == 0; } @@ -123,8 +137,17 @@ private int getDifficultyFromFile(String hash){ return i; } - public synchronized void addMessagesToTheBlockchain(String msg){ - this.messages.add(msg); + public synchronized void addMessagesToTheBlockchain(Message msg) throws Exception { + if(msg.getId() < this.ids) { + if(msg.verifySignature(msg.getList().get(0),msg.getList().get(1))) { + this.messages.add(msg); + } + else { + System.out.println("Signature is wrong"); + } + }else{ + System.out.println("Messaage rejected"); + } } public synchronized void addMessagesToTheBlock(){ @@ -135,10 +158,14 @@ public synchronized void addMessagesToTheBlock(){ public void setTimeSpent(int timeSpent){ this.timeSpent = timeSpent; } + public int getTimeSpent() { return timeSpent; } + public long setMsgID(){ + return ids++; + } } diff --git a/src/blockchain/GenerateKeys.java b/src/blockchain/GenerateKeys.java new file mode 100644 index 0000000..1400b66 --- /dev/null +++ b/src/blockchain/GenerateKeys.java @@ -0,0 +1,34 @@ +package blockchain; + +import java.security.*; + +/** + * Created by Пользователь on 20.11.2018. + */ +public class GenerateKeys { + + private KeyPairGenerator keyGen; + private KeyPair pair; + private PrivateKey privateKey; + private PublicKey publicKey; + + public GenerateKeys(int keylenth) throws NoSuchAlgorithmException, NoSuchProviderException { + this.keyGen = KeyPairGenerator.getInstance("RSA"); + this.keyGen.initialize(keylenth); + } + + public void createKeys(){ + this.pair = this.keyGen.generateKeyPair(); + this.privateKey = pair.getPrivate(); + this.publicKey = pair.getPublic(); + } + + public PrivateKey getPrivateKey(){ + return this.privateKey; + } + + public PublicKey getPublicKey() { + return this.publicKey; + } + +} diff --git a/src/blockchain/Main.java b/src/blockchain/Main.java index 657809d..1961d8b 100644 --- a/src/blockchain/Main.java +++ b/src/blockchain/Main.java @@ -1,6 +1,8 @@ package blockchain; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; @@ -9,12 +11,15 @@ public class Main { public static Blockchain blockchain; public static List users = new ArrayList(); public static List miners = new ArrayList(); + public static GenerateKeys gk; - public static void main(String[] args) throws InterruptedException { + + public static void main(String[] args) throws InterruptedException, NoSuchProviderException, NoSuchAlgorithmException { Scanner in = new Scanner(System.in); String filePath = in.nextLine();//"D:\\hyperskillGit\\blockchain\\MyBlockchain"; blockchain = new Blockchain(filePath); - + gk = new GenerateKeys(1024); + gk.createKeys(); if (blockchain.isBlockchainValid()) { diff --git a/src/blockchain/Message.java b/src/blockchain/Message.java new file mode 100644 index 0000000..cb875ef --- /dev/null +++ b/src/blockchain/Message.java @@ -0,0 +1,49 @@ +package blockchain; + +import javax.management.openmbean.InvalidKeyException; +import java.io.Serializable; +import java.security.Signature; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Пользователь on 20.11.2018. + */ +public class Message implements Serializable{ + private List list; + private long id; + + //The constructor of Message class builds the list that will be written to the file. + //The list consists of the message and the signature. + public Message(String data, long id) throws Exception { + list = new ArrayList(); + list.add(data.getBytes()); + list.add(sign(data)); + this.id = id; + } + + //The method that signs the data using the private key that is stored in keyFile path + public byte[] sign(String data) throws Exception{ + Signature rsa = Signature.getInstance("SHA1withRSA"); + rsa.initSign(Main.gk.getPrivateKey()); + rsa.update(data.getBytes()); + return rsa.sign(); + } + + //Method for signature verification that initializes with the Public Key, + //updates the data to be verified and then verifies them using the signature + public boolean verifySignature(byte[] data, byte[] signature) throws Exception { + Signature sig = Signature.getInstance("SHA1withRSA"); + sig.initVerify(Main.gk.getPublicKey()); + sig.update(data); + return sig.verify(signature); + } + + public List getList() { + return list; + } + + public long getId(){ + return this.id; + } +} diff --git a/src/blockchain/Miner.java b/src/blockchain/Miner.java index fe01c81..0b852bd 100644 --- a/src/blockchain/Miner.java +++ b/src/blockchain/Miner.java @@ -1,6 +1,7 @@ package blockchain; +import java.io.UnsupportedEncodingException; import java.time.LocalTime; /** @@ -25,7 +26,11 @@ public void run() { System.out.println(""); System.out.println("Block:"); System.out.println("Created by miner # " + this.minerNumber); - Main.blockchain.getBlockchain().peekLast().printOutResults(); + try { + Main.blockchain.getBlockchain().peekLast().printOutResults(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } System.out.println("Block was generating for " + Main.blockchain.getTimeSpent() + " seconds"); Main.blockchain.setDifficulty(); } diff --git a/src/blockchain/User.java b/src/blockchain/User.java index df917ff..d44f555 100644 --- a/src/blockchain/User.java +++ b/src/blockchain/User.java @@ -9,7 +9,7 @@ */ public class User extends Thread { private String name; - private String message; + private Message message; Scanner in = new Scanner(System.in); public User(String name){ @@ -20,7 +20,11 @@ public User(String name){ public void run() { while (!this.isInterrupted()) { newMaessage(); - Main.blockchain.addMessagesToTheBlockchain(getMessage()); + try { + Main.blockchain.addMessagesToTheBlockchain(getMessage()); + } catch (Exception e) { + e.printStackTrace(); + } } } @@ -28,13 +32,18 @@ private synchronized void newMaessage(){ if(!this.isInterrupted()) { synchronized (User.class) { System.out.print(this.name + ": "); - String s = in.nextLine(); - this.message = this.name + ": " + s; + String data = in.nextLine(); + data = this.name + ": " + data; + try { + this.message = new Message(data,Main.blockchain.setMsgID()); + } catch (Exception e) { + e.printStackTrace(); + } } } } - public String getMessage(){ + public Message getMessage(){ return this.message; } From 0ca0816b0515414267cc6aa357dddae733b3e0ac Mon Sep 17 00:00:00 2001 From: roman Date: Tue, 20 Nov 2018 16:58:23 +0300 Subject: [PATCH 8/9] added VC fields to Miner and User --- src/blockchain/Miner.java | 19 +++++++++++++++++++ src/blockchain/User.java | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/blockchain/Miner.java b/src/blockchain/Miner.java index 0b852bd..c93007d 100644 --- a/src/blockchain/Miner.java +++ b/src/blockchain/Miner.java @@ -9,10 +9,12 @@ */ public class Miner extends Thread { private int minerNumber; + private int VC = 0; public Miner(int minerNumber) { this.minerNumber = minerNumber; + this.VC = 0; } @@ -26,6 +28,8 @@ public void run() { System.out.println(""); System.out.println("Block:"); System.out.println("Created by miner # " + this.minerNumber); + addVC(100); + System.out.println(this.minerNumber + " gets " + 100 + "VC"); try { Main.blockchain.getBlockchain().peekLast().printOutResults(); } catch (UnsupportedEncodingException e) { @@ -35,6 +39,21 @@ public void run() { Main.blockchain.setDifficulty(); } + public void addVC(int add){ + this.VC += add; + } + + public void sendVC(int sub){ + if(this.VC < sub){ + System.out.println("Not enough VC, send transaction suspend"); + }else{ + this.VC -= sub; + } + } + + public int getVC() { + return this.VC; + } } diff --git a/src/blockchain/User.java b/src/blockchain/User.java index d44f555..39f96e9 100644 --- a/src/blockchain/User.java +++ b/src/blockchain/User.java @@ -11,6 +11,7 @@ public class User extends Thread { private String name; private Message message; Scanner in = new Scanner(System.in); + private int VC = 100; public User(String name){ this.name = name; @@ -47,4 +48,20 @@ public Message getMessage(){ return this.message; } + public void addVC(int add){ + this.VC += add; + } + + public void sendVC(int sub){ + if(this.VC < sub){ + System.out.println("Not enough VC, send transaction suspend"); + }else{ + this.VC -= sub; + } + } + + public int getVC() { + return this.VC; + } + } From 4ef138ae420ec5a697a513a196a336360b3a25fd Mon Sep 17 00:00:00 2001 From: roman Date: Wed, 21 Nov 2018 11:21:57 +0300 Subject: [PATCH 9/9] few refactoring changes --- src/blockchain/Block.java | 12 +++++------- src/blockchain/Blockchain.java | 20 ++++++++------------ src/blockchain/GenerateKeys.java | 11 +++++------ src/blockchain/Main.java | 13 +++++-------- src/blockchain/Message.java | 9 +++------ src/blockchain/Miner.java | 5 +---- src/blockchain/User.java | 9 +++------ 7 files changed, 30 insertions(+), 49 deletions(-) diff --git a/src/blockchain/Block.java b/src/blockchain/Block.java index 0430cb0..fec0bfc 100644 --- a/src/blockchain/Block.java +++ b/src/blockchain/Block.java @@ -2,8 +2,6 @@ import java.io.Serializable; import java.io.UnsupportedEncodingException; -import java.time.LocalTime; - import java.security.MessageDigest; import java.util.Date; import java.util.LinkedList; @@ -14,7 +12,7 @@ class Block implements Serializable{ - private List messagesStack = new LinkedList(); + private List messagesStack = new LinkedList<>(); private String prevHash; private String hash; private int id; @@ -41,7 +39,7 @@ public Block(Block prevBlock, int difficulty){ setMagicNumber(); this.hash = applySha256(this.prevHash + this.magicNumber); }while(!this.hash.startsWith(zeros)); - + setMaxMsgID(); this.timeStamp = new Date().getTime(); } @@ -119,9 +117,9 @@ public LinkedList getMessageStack(){ private void setMaxMsgID(){ long max = 0; - for(int i = 0; i < this.messagesStack.size(); i++){ - if(max < this.messagesStack.get(i).getId()){ - max = this.messagesStack.get(i).getId(); + for (Message aMessagesStack : this.messagesStack) { + if (max < aMessagesStack.getId()) { + max = aMessagesStack.getId(); } } this.maxMsgID = max; diff --git a/src/blockchain/Blockchain.java b/src/blockchain/Blockchain.java index 9fc6f5a..76538c5 100644 --- a/src/blockchain/Blockchain.java +++ b/src/blockchain/Blockchain.java @@ -2,13 +2,10 @@ import java.io.*; import java.util.LinkedList; -import java.util.List; -/** - * Created by Пользователь on 16.11.2018. - */ + class Blockchain { - private LinkedList messages = new LinkedList(); + private LinkedList messages = new LinkedList<>(); private volatile LinkedList blockchain = null; private boolean newFile = false; private int timeSpent; @@ -19,7 +16,6 @@ class Blockchain { public Blockchain(String filePath) { File file = new File(filePath);//"D:\\hyperskillGit\\blockchain\\MyBlockchain"); readBlockchainFromFile(file); - } public void readBlockchainFromFile(File file) { @@ -27,9 +23,9 @@ public void readBlockchainFromFile(File file) { newFile = file.createNewFile(); if (newFile) { System.out.println("The new blockchain file was successfully created."); - this.blockchain = new LinkedList(); + this.blockchain = new LinkedList<>(); this.difficulty = 0; - this.ids = 1; + Blockchain.ids = 1; } else { FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); @@ -38,7 +34,7 @@ public void readBlockchainFromFile(File file) { ois.close(); fis.close(); if(blockchain.peekLast().getMessageStack().peekLast() != null) { - this.ids = blockchain.peekLast().getMessageStack().peekLast().getId() + 1L; + Blockchain.ids = blockchain.peekLast().getMessageStack().peekLast().getId() + 1L; } this.difficulty = getDifficultyFromFile(this.blockchain.peekLast().getHash()); } @@ -137,8 +133,8 @@ private int getDifficultyFromFile(String hash){ return i; } - public synchronized void addMessagesToTheBlockchain(Message msg) throws Exception { - if(msg.getId() < this.ids) { + public void addMessagesToTheBlockchain(Message msg) throws Exception { + if(msg.getId() < Blockchain.ids) { if(msg.verifySignature(msg.getList().get(0),msg.getList().get(1))) { this.messages.add(msg); } @@ -150,7 +146,7 @@ public synchronized void addMessagesToTheBlockchain(Message msg) throws Exceptio } } - public synchronized void addMessagesToTheBlock(){ + public void addMessagesToTheBlock(){ this.blockchain.peekLast().writeMessagesStack(this.messages); this.messages.clear(); } diff --git a/src/blockchain/GenerateKeys.java b/src/blockchain/GenerateKeys.java index 1400b66..abf980d 100644 --- a/src/blockchain/GenerateKeys.java +++ b/src/blockchain/GenerateKeys.java @@ -2,13 +2,11 @@ import java.security.*; -/** - * Created by Пользователь on 20.11.2018. - */ -public class GenerateKeys { + +class GenerateKeys { private KeyPairGenerator keyGen; - private KeyPair pair; + private PrivateKey privateKey; private PublicKey publicKey; @@ -18,7 +16,8 @@ public GenerateKeys(int keylenth) throws NoSuchAlgorithmException, NoSuchProvide } public void createKeys(){ - this.pair = this.keyGen.generateKeyPair(); + KeyPair pair; + pair = this.keyGen.generateKeyPair(); this.privateKey = pair.getPrivate(); this.publicKey = pair.getPublic(); } diff --git a/src/blockchain/Main.java b/src/blockchain/Main.java index 1961d8b..ee3ee75 100644 --- a/src/blockchain/Main.java +++ b/src/blockchain/Main.java @@ -9,8 +9,8 @@ public class Main { public static Blockchain blockchain; - public static List users = new ArrayList(); - public static List miners = new ArrayList(); + public static List users = new ArrayList<>(); + public static List miners = new ArrayList<>(); public static GenerateKeys gk; @@ -30,17 +30,14 @@ public static void main(String[] args) throws InterruptedException, NoSuchProvid for (int i = 0; i < 7; i++) { miners.add(new Miner(i + 1)); } - for (Thread miner : miners) { - miner.start(); - } + miners.forEach(Thread::start); users.forEach(Thread::start); + for (Thread miner : miners) { miner.join(); } - for(Thread user:users){ - user.interrupt(); - } + blockchain.writeBlockchainToFile(filePath); System.exit(0); diff --git a/src/blockchain/Message.java b/src/blockchain/Message.java index cb875ef..35a3236 100644 --- a/src/blockchain/Message.java +++ b/src/blockchain/Message.java @@ -1,22 +1,19 @@ package blockchain; -import javax.management.openmbean.InvalidKeyException; import java.io.Serializable; import java.security.Signature; import java.util.ArrayList; import java.util.List; -/** - * Created by Пользователь on 20.11.2018. - */ -public class Message implements Serializable{ + +class Message implements Serializable{ private List list; private long id; //The constructor of Message class builds the list that will be written to the file. //The list consists of the message and the signature. public Message(String data, long id) throws Exception { - list = new ArrayList(); + list = new ArrayList<>(); list.add(data.getBytes()); list.add(sign(data)); this.id = id; diff --git a/src/blockchain/Miner.java b/src/blockchain/Miner.java index c93007d..e340889 100644 --- a/src/blockchain/Miner.java +++ b/src/blockchain/Miner.java @@ -4,10 +4,7 @@ import java.io.UnsupportedEncodingException; import java.time.LocalTime; -/** - * Created by Пользователь on 16.11.2018. - */ -public class Miner extends Thread { +class Miner extends Thread { private int minerNumber; private int VC = 0; diff --git a/src/blockchain/User.java b/src/blockchain/User.java index 39f96e9..53d8a4c 100644 --- a/src/blockchain/User.java +++ b/src/blockchain/User.java @@ -1,13 +1,10 @@ package blockchain; -import java.io.InputStream; -import java.nio.channels.Channels; + import java.util.Scanner; -/** - * Created by Пользователь on 19.11.2018. - */ -public class User extends Thread { + +class User extends Thread { private String name; private Message message; Scanner in = new Scanner(System.in);