changeset 108:31f87de2a1d4

add Block.java
author akahori
date Mon, 05 Nov 2018 10:15:38 +0900
parents 825e01825ad3
children 2e64b927388c
files src/main/java/christie/blockchain/Block.java src/main/java/christie/blockchain/BlockChain.java
diffstat 2 files changed, 139 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/christie/blockchain/Block.java	Mon Nov 05 10:15:38 2018 +0900
@@ -0,0 +1,50 @@
+package christie.blockchain;
+
+public class Block {
+    private BlockHeader header;
+
+    private String data;
+
+    public Block(long timestamp, String data){
+        this("".getBytes(), timestamp, data);
+    }
+
+    public Block(byte[] parentHash, long timestamp, String data) {
+        this.header = new BlockHeader(parentHash, timestamp);
+        this.data = data;
+    }
+
+    public BlockHeader getHeader(){
+        return this.header;
+    }
+
+    public long getTimestamp() {
+        return this.header.getTimestamp();
+    }
+
+    public byte[] getPresentHash(){
+        return this.header.getPresentHash();
+    }
+
+    public byte[] getParentHash(){
+        return this.header.getParentHash();
+    }
+
+    public String getData(){
+        return data;
+    }
+
+    public byte[] calcHash(){
+        return this.header.calcHash();
+    }
+
+    public void mineBlock(int difficulty){
+        this.header.mineBlock(difficulty);
+    }
+
+    public long getNonce(){
+        return this.header.getNonce();
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/christie/blockchain/BlockChain.java	Mon Nov 05 10:15:38 2018 +0900
@@ -0,0 +1,89 @@
+package christie.blockchain;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class BlockChain {
+
+    public ArrayList<Block> blockList = new ArrayList<Block>();
+
+    public static void main(String[] args) {
+        int difficulty = 1;
+        BlockChain blockChain = new BlockChain();
+
+        long startTime = System.currentTimeMillis();
+
+        Block genesisBlock = blockChain.createGenesisBlock("Hi im the first block");
+        genesisBlock.mineBlock(difficulty);
+        System.out.println("Hash for block 1 : " + genesisBlock.getData() + " Nonce : " + genesisBlock.getNonce());
+
+        Block secondBlock = blockChain.createNewBlock(genesisBlock, "Yo im the second block");
+        secondBlock.mineBlock(difficulty);
+        System.out.println("Hash for block 2 : " + secondBlock.getData() + " Nonce : " + secondBlock.getNonce());
+
+        Block thirdBlock = blockChain.createNewBlock(secondBlock, "Hey im the third block");
+        thirdBlock.mineBlock(difficulty);
+        System.out.println("Hash for block 3 : " + thirdBlock.getData() + " Nonce : " + thirdBlock.getNonce());
+
+
+        blockChain.blockList.add(genesisBlock);
+        blockChain.blockList.add(secondBlock);
+        blockChain.blockList.add(thirdBlock);
+
+        System.out.println("\nBlockchain is Valid: " + blockChain.isChainValid(difficulty));
+
+        long endTime = System.currentTimeMillis() - startTime;
+
+        System.out.println("end Time: " + endTime);
+
+    }
+
+    public Boolean isChainValid(int difficulty) {
+        Block currentBlock;
+        Block parentBlock;
+
+        String hashTarget = new String(new char[difficulty]).replace('\0', '0');
+
+        //loop through blockchain to check hashes:
+        for(int i=1; i < blockList.size(); i++) {
+            currentBlock = blockList.get(i);
+            parentBlock = blockList.get(i-1);
+
+
+            if(!Arrays.equals(currentBlock.getPresentHash(), currentBlock.calcHash())){
+                System.out.println("Current Hashes not equal");
+                return false;
+            }
+
+            if(!Arrays.equals(parentBlock.getPresentHash(), currentBlock.getParentHash())){
+                System.out.println("Previous Hashes not equal");
+                return false;
+            }
+
+            String hashStr = new String(currentBlock.getPresentHash(), Charset.forName("utf-16"));
+            if(!hashStr.substring( 0, difficulty).equals(hashTarget)) {
+                System.out.println("This block hasn't been mined");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public synchronized Block createNewBlock(Block parent, String data){
+        long time = System.currentTimeMillis() / 1000;
+        // もし, 時差があって, timeが親のタイムスタンプより低いなら, 親のタイムスタンプ + 1 を代入する
+        if (parent.getTimestamp() >= time) time = parent.getTimestamp() + 1;
+
+        Block block = new Block(parent.getPresentHash(), time, data);
+        return block;
+    }
+
+    public synchronized Block createGenesisBlock(String data){
+        long time = System.currentTimeMillis() / 1000;
+        Block block = new Block(time, data);
+        return block;
+    }
+
+
+}