changeset 146:0ef25958ac04

add transaction
author akahori
date Mon, 07 Jan 2019 16:02:26 +0900
parents 77169cd8a5e8
children 3ce77273d76b
files src/main/java/christie/blockchain/Block.java src/main/java/christie/blockchain/BlockChain.java src/main/java/christie/blockchain/BlockHeader.java src/main/java/christie/blockchain/ECKey.java src/main/java/christie/blockchain/FileData.java src/main/java/christie/blockchain/FileManager.java src/main/java/christie/blockchain/HashUtil.java src/main/java/christie/blockchain/Miner.java src/main/java/christie/blockchain/Transaction.java
diffstat 9 files changed, 156 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/christie/blockchain/Block.java	Wed Jan 02 21:48:37 2019 +0900
+++ b/src/main/java/christie/blockchain/Block.java	Mon Jan 07 16:02:26 2019 +0900
@@ -53,8 +53,8 @@
         return this.header.getNonce();
     }
 
-    public byte[] getPresentHashWithoutNonce(){
-        return this.header.getPresentHashWithoutNonce();
+    public byte[] getByteArrayWithoutNonce(){
+        return this.header.getByteArrayWithoutNonce();
     }
 
     public long getNumber() {
--- a/src/main/java/christie/blockchain/BlockChain.java	Wed Jan 02 21:48:37 2019 +0900
+++ b/src/main/java/christie/blockchain/BlockChain.java	Mon Jan 07 16:02:26 2019 +0900
@@ -1,6 +1,7 @@
 package christie.blockchain;
 
 import java.nio.charset.Charset;
+import java.security.Security;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -9,24 +10,39 @@
 
     public ArrayList<Block> blockList = new ArrayList<Block>();
 
+    int difficulty = 1;
+
+    private Block bestBlock;
 
 
     public static void main(String[] args) {
-        int difficulty = 1;
+
+        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+
+        ECKey ecKeyA = new ECKey();
+        ECKey ecKeyB = new ECKey();
+
+        Transaction transaction = new Transaction(ecKeyA.getPublicKey(), ecKeyB.getPublicKey(), "hello");
+        transaction.generateSignature(ecKeyA.getPrivateKey());
+        System.out.println(transaction.verifiySignature());
+    }
+
+    public void testBlockMining(){
         BlockChain blockChain = new BlockChain();
+        blockChain.difficulty = 1;
         Miner miner = new Miner();
         long startTime = System.currentTimeMillis();
 
-        Block genesisBlock = blockChain.createGenesisBlock("Hi im the first block");
-        miner.mineBlock(genesisBlock, difficulty);
+        Block genesisBlock = blockChain.createNewBlock("Hi im the first block");
+        miner.mineBlock(genesisBlock, blockChain.difficulty);
         System.out.println("Hash for block 1 : " + genesisBlock.getData() + " Nonce : " + genesisBlock.getNonce());
 
         Block secondBlock = blockChain.createNewBlock(genesisBlock, "Yo im the second block");
-        miner.mineBlock(secondBlock, difficulty);
+        miner.mineBlock(secondBlock, blockChain.difficulty);
         System.out.println("Hash for block 2 : " + secondBlock.getData() + " Nonce : " + secondBlock.getNonce());
 
         Block thirdBlock = blockChain.createNewBlock(secondBlock, "Hey im the third block");
-        miner.mineBlock(thirdBlock, difficulty);
+        miner.mineBlock(thirdBlock, blockChain.difficulty);
         System.out.println("Hash for block 3 : " + thirdBlock.getData() + " Nonce : " + thirdBlock.getNonce());
 
 
@@ -34,12 +50,13 @@
         blockChain.blockList.add(secondBlock);
         blockChain.blockList.add(thirdBlock);
 
-        System.out.println("\nBlockchain is Valid: " + blockChain.isChainValid(difficulty));
+        System.out.println("\nBlockchain is Valid: " + blockChain.isChainValid(blockChain.difficulty));
 
         long endTime = System.currentTimeMillis() - startTime;
 
         System.out.println("end Time: " + endTime);
 
+
     }
 
     public Boolean isChainValid(int difficulty) {
@@ -67,6 +84,10 @@
         return true;
     }
 
+    public synchronized Block createNewBlock(String data) {
+        return createGenesisBlock(data);
+    }
+
     public synchronized Block createNewBlock(Block parent, String data){
         long time = System.currentTimeMillis() / 1000;
         // もし, 時差があって, timeが親のタイムスタンプより低いなら, 親のタイムスタンプ + 1 を代入する
@@ -93,5 +114,8 @@
         return block;
     }
 
+    public synchronized Block getBestBlock() {
+        return bestBlock;
+    }
 
 }
--- a/src/main/java/christie/blockchain/BlockHeader.java	Wed Jan 02 21:48:37 2019 +0900
+++ b/src/main/java/christie/blockchain/BlockHeader.java	Mon Jan 07 16:02:26 2019 +0900
@@ -30,7 +30,7 @@
         this.timestamp = timestamp;
     }
 
-    public byte[] getHash(boolean withNonce){
+    public byte[] getParamByteArray(boolean withNonce){
 
         ByteArrayOutputStream output = new ByteArrayOutputStream();
 
@@ -57,15 +57,18 @@
     }
 
     public byte[] getParentHash() {
+
         return parentHash;
     }
 
     public byte[] getPresentHash() {
-        return hashUtil.sha256(getHash(true));
+
+        return hashUtil.sha256(getParamByteArray(true));
     }
 
-    public byte[] getPresentHashWithoutNonce(){
-        return getHash(false);
+    public byte[] getByteArrayWithoutNonce(){
+
+        return getParamByteArray(false);
     }
 
     public void setTimestamp(long timestamp) {
--- a/src/main/java/christie/blockchain/ECKey.java	Wed Jan 02 21:48:37 2019 +0900
+++ b/src/main/java/christie/blockchain/ECKey.java	Mon Jan 07 16:02:26 2019 +0900
@@ -11,6 +11,7 @@
 import java.security.*;
 import java.security.interfaces.ECPublicKey;
 import java.security.spec.ECGenParameterSpec;
+import java.util.Arrays;
 
 
 public class ECKey {
@@ -25,6 +26,9 @@
     private final PublicKey publicKey;
     private final Provider provider;
 
+    HashUtil hashUtil = new HashUtil();
+
+
     static {
         X9ECParameters params = SECNamedCurves.getByName("secp256k1");
         CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
@@ -71,14 +75,14 @@
         return CURVE.getCurve().createPoint(xCoord, yCoord);
     }
 
-    public byte[] applyECDSASig(byte[] input) {
+    public byte[] applyECDSASig(PrivateKey privateKey, byte[] input) {
         Signature dsa;
         byte[] output;
 
         if (privateKey == null)
             throw new RuntimeException();
         try {
-            dsa = Signature.getInstance("ECDSA", "BC");
+            dsa = Signature.getInstance("ECDSA","BC");
             dsa.initSign(privateKey);
             dsa.update(input);
             output = dsa.sign();
@@ -88,7 +92,7 @@
         return output;
     }
 
-    public static boolean verifyECDSASig(byte[] data, byte[] signature, PublicKey publicKey) {
+    public boolean verifyECDSASig(PublicKey publicKey, byte[] data, byte[] signature) {
         try {
             Signature ecdsaVerify = Signature.getInstance("ECDSA", "BC");
             ecdsaVerify.initVerify(publicKey);
@@ -99,4 +103,11 @@
         }
     }
 
+    public PrivateKey getPrivateKey() {
+        return privateKey;
+    }
+
+    public PublicKey getPublicKey() {
+        return publicKey;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/christie/blockchain/FileData.java	Mon Jan 07 16:02:26 2019 +0900
@@ -0,0 +1,26 @@
+package christie.blockchain;
+
+
+import org.msgpack.annotation.Message;
+
+import java.io.File;
+
+@Message
+public class FileData {
+
+    String filepath = "";
+    File file;
+
+    public FileData(){}
+
+    public File read(){
+        return this.file;
+
+    }
+
+    public void write(){
+
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/christie/blockchain/FileManager.java	Mon Jan 07 16:02:26 2019 +0900
@@ -0,0 +1,16 @@
+package christie.blockchain;
+
+import java.io.File;
+
+public class FileManager {
+
+
+    public void save(){
+
+    }
+
+    public void write(){
+
+    }
+
+}
--- a/src/main/java/christie/blockchain/HashUtil.java	Wed Jan 02 21:48:37 2019 +0900
+++ b/src/main/java/christie/blockchain/HashUtil.java	Mon Jan 07 16:02:26 2019 +0900
@@ -2,6 +2,8 @@
 
 import org.bouncycastle.crypto.digests.*;
 
+import static java.util.Arrays.copyOfRange;
+
 
 public class HashUtil {
     public byte[] sha256(byte[] input) {
@@ -42,6 +44,11 @@
         return resBuf;
     }
 
+    public byte[] sha3omit12(byte[] input) {
+        byte[] hash = sha3(input);
+        return copyOfRange(hash, 12, hash.length);
+    }
+
 
 
 }
--- a/src/main/java/christie/blockchain/Miner.java	Wed Jan 02 21:48:37 2019 +0900
+++ b/src/main/java/christie/blockchain/Miner.java	Mon Jan 07 16:02:26 2019 +0900
@@ -19,7 +19,7 @@
 
         //byte[] target = new String(new char[difficulty]).replace('\0', '0').getBytes();
         String target = new String(new char[difficulty]).replace('\0', '0');
-        byte[] hash = newBlock.getPresentHashWithoutNonce();
+        byte[] hash = newBlock.getByteArrayWithoutNonce();
 
         String hashStr = new String(hashUtil.sha256(hash), Charset.forName("utf-8"));
 
--- a/src/main/java/christie/blockchain/Transaction.java	Wed Jan 02 21:48:37 2019 +0900
+++ b/src/main/java/christie/blockchain/Transaction.java	Mon Jan 07 16:02:26 2019 +0900
@@ -3,6 +3,8 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.math.BigInteger;
+import java.security.PrivateKey;
+import java.security.PublicKey;
 
 // インターフェイスにしたほうがいいかもしれない. 後からdataの内容変える可能性がある.
 public class Transaction {
@@ -10,21 +12,26 @@
 
     private long nonce;
 
-    private byte[] sendAddress;
+    private PublicKey sendAddress;
 
-    private byte[] receiveAddress;
+    private PublicKey receiveAddress;
 
-    private byte[] data;
+    private String data;
 
     private long timestamp;
 
     private byte[] signature;
 
+    HashUtil hashUtil = new HashUtil();
+
+    ECKey ecKey = new ECKey();
+
+
     //public ArrayList<TransactionInput> inputs = new ArrayList<TransactionInput>();
     //public ArrayList<TransactionOutput> outputs = new ArrayList<TransactionOutput>();
 
 
-    public Transaction(byte[] sendAddress, byte[] receiveAddress, byte[] data){
+    public Transaction(PublicKey sendAddress, PublicKey receiveAddress, String data){
         this.sendAddress = sendAddress;
         this.receiveAddress = receiveAddress;
         this.data = data;
@@ -38,25 +45,59 @@
         this.inputs = inputs;
     }
 */
-    public byte[] calcHash(){
-        HashUtil hashUtil = new HashUtil();
 
-        byte[] timestampByte = BigInteger.valueOf(this.timestamp).toByteArray();
-
-        byte[] nonceByte = BigInteger.valueOf(this.nonce).toByteArray();
+    public byte[] getParamByteArray(){
 
         ByteArrayOutputStream output = new ByteArrayOutputStream();
 
+        byte[] timestampByte = BigInteger.valueOf(this.timestamp).toByteArray();
+        byte[] nonceByte = BigInteger.valueOf(this.nonce).toByteArray();
         try {
-            output.write(hash);
+            output.write(sendAddress.getEncoded());
+            output.write(receiveAddress.getEncoded());
+            output.write(nonceByte);
             output.write(timestampByte);
-            output.write(nonceByte);
+            output.write(signature);
         } catch (IOException e) {
             e.printStackTrace();
         }
 
-        return hashUtil.sha256(output.toByteArray());
+
+        return output.toByteArray();
 
     }
 
+    public byte[] gethash() {
+
+        return hashUtil.sha256(getParamByteArray());
+    }
+
+    public void generateSignature(PrivateKey privateKey) {
+        ByteArrayOutputStream _data = new ByteArrayOutputStream();
+        try {
+            _data.write(sendAddress.getEncoded());
+            _data.write(receiveAddress.getEncoded());
+            _data.write(data.getBytes());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        signature = ecKey.applyECDSASig(privateKey, _data.toByteArray());
+    }
+    //Verifies the data we signed hasnt been tampered with
+    public boolean verifiySignature() {
+        ByteArrayOutputStream _data = new ByteArrayOutputStream();
+        try {
+            _data.write(sendAddress.getEncoded());
+            _data.write(receiveAddress.getEncoded());
+            _data.write(data.getBytes());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return ecKey.verifyECDSASig(sendAddress, _data.toByteArray(), signature);
+    }
+
+
+
+
 }