Mercurial > hg > Database > Christie
changeset 110:eab161e557bd
fix Refactor
author | akahori |
---|---|
date | Mon, 19 Nov 2018 12:31:36 +0900 |
parents | 2e64b927388c |
children | 671246274719 |
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/HashUtil.java src/main/java/christie/blockchain/Miner.java src/main/java/christie/blockchain/Transaction.java |
diffstat | 7 files changed, 281 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/christie/blockchain/Block.java Mon Nov 05 10:16:28 2018 +0900 +++ b/src/main/java/christie/blockchain/Block.java Mon Nov 19 12:31:36 2018 +0900 @@ -1,17 +1,28 @@ package christie.blockchain; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + public class Block { private BlockHeader header; private String data; + private List<Transaction> transactionsList = new CopyOnWriteArrayList<>(); + public Block(long timestamp, String data){ - this("".getBytes(), timestamp, data); + this("".getBytes(), timestamp, data, null); + } + public Block(byte[] parentHash, long timestamp, String data){ + this(parentHash, timestamp, data, null); } - public Block(byte[] parentHash, long timestamp, String data) { + public Block(byte[] parentHash, long timestamp, String data, List<Transaction> transactionsList) { this.header = new BlockHeader(parentHash, timestamp); this.data = data; + if (this.transactionsList == null) { + this.transactionsList = new CopyOnWriteArrayList<>(); + } } public BlockHeader getHeader(){ @@ -34,17 +45,14 @@ return data; } - public byte[] calcHash(){ - return this.header.calcHash(); - } - - public void mineBlock(int difficulty){ - this.header.mineBlock(difficulty); - } + public void setNonce(long nonce) { this.header.setNonce(nonce);} public long getNonce(){ return this.header.getNonce(); } + public byte[] getPresentHashWithoutNonce(){ + return this.header.getPresentHashWithoutNonce(); + } }
--- a/src/main/java/christie/blockchain/BlockChain.java Mon Nov 05 10:16:28 2018 +0900 +++ b/src/main/java/christie/blockchain/BlockChain.java Mon Nov 19 12:31:36 2018 +0900 @@ -3,6 +3,7 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; public class BlockChain { @@ -11,19 +12,19 @@ public static void main(String[] args) { int difficulty = 1; BlockChain blockChain = new BlockChain(); - + Miner miner = new Miner(); long startTime = System.currentTimeMillis(); Block genesisBlock = blockChain.createGenesisBlock("Hi im the first block"); - genesisBlock.mineBlock(difficulty); + miner.mineBlock(genesisBlock, 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); + miner.mineBlock(secondBlock, 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); + miner.mineBlock(thirdBlock, difficulty); System.out.println("Hash for block 3 : " + thirdBlock.getData() + " Nonce : " + thirdBlock.getNonce()); @@ -50,18 +51,12 @@ 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")); + String hashStr = new String(currentBlock.getPresentHash(), Charset.forName("utf-8")); if(!hashStr.substring( 0, difficulty).equals(hashTarget)) { System.out.println("This block hasn't been mined"); return false;
--- a/src/main/java/christie/blockchain/BlockHeader.java Mon Nov 05 10:16:28 2018 +0900 +++ b/src/main/java/christie/blockchain/BlockHeader.java Mon Nov 19 12:31:36 2018 +0900 @@ -1,5 +1,7 @@ package christie.blockchain; +import org.bouncycastle.util.BigIntegers; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; @@ -15,30 +17,36 @@ private long nonce; + HashUtil hashUtil = new HashUtil(); + public BlockHeader(byte[] parentHash, long timestamp) { this.parentHash = parentHash; this.timestamp = timestamp; - this.presentHash = calcHash(); } - public byte[] calcHash(){ - HashUtil hashUtil = new HashUtil(); + public byte[] getHash(boolean withNonce){ + + ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] timestampByte = BigInteger.valueOf(this.timestamp).toByteArray(); - byte[] nonceByte = BigInteger.valueOf(this.nonce).toByteArray(); - - ByteArrayOutputStream output = new ByteArrayOutputStream(); - try { output.write(parentHash); output.write(timestampByte); - output.write(nonceByte); } catch (IOException e) { e.printStackTrace(); } - return hashUtil.sha256(output.toByteArray()); + if(withNonce){ + byte[] nonceByte = BigInteger.valueOf(this.nonce).toByteArray(); + try { + output.write(nonceByte); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return output.toByteArray(); } @@ -47,12 +55,12 @@ } public byte[] getPresentHash() { - if(this.presentHash == null){ - this.presentHash = calcHash(); - } - return this.presentHash; + return hashUtil.sha256(getHash(true)); } + public byte[] getPresentHashWithoutNonce(){ + return getHash(false); + } public long getTimestamp() { return timestamp; @@ -62,17 +70,7 @@ this.timestamp = timestamp; } - public void mineBlock(int difficulty) { - String target = new String(new char[difficulty]).replace('\0', '0'); - String hashStr = new String(presentHash, Charset.forName("utf-16")); - - while(!hashStr.substring( 0, difficulty).equals(target)) { - this.nonce ++; - this.presentHash = calcHash(); - hashStr = new String(this.presentHash, Charset.forName("utf-16")); - } - System.out.println("Block Mined!!! : " + hashStr); - } + public void setNonce(long nonce) { this.nonce = nonce; } public long getNonce(){ return this.nonce;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/christie/blockchain/ECKey.java Mon Nov 19 12:31:36 2018 +0900 @@ -0,0 +1,102 @@ +package christie.blockchain; + +import org.bouncycastle.asn1.sec.SECNamedCurves; +import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.bouncycastle.math.ec.ECPoint; + +import java.math.BigInteger; +import java.security.*; +import java.security.interfaces.ECPublicKey; +import java.security.spec.ECGenParameterSpec; + + +public class ECKey { + + public static final ECDomainParameters CURVE; + public static final ECParameterSpec CURVE_SPEC; + + public static final BigInteger HALF_CURVE_ORDER; + private static final SecureRandom secureRandom; + + private final PrivateKey privateKey; + private final PublicKey publicKey; + private final Provider provider; + + static { + X9ECParameters params = SECNamedCurves.getByName("secp256k1"); + CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH()); + CURVE_SPEC = new ECParameterSpec(params.getCurve(), params.getG(), params.getN(), params.getH()); + HALF_CURVE_ORDER = params.getN().shiftRight(1); + secureRandom = new SecureRandom(); + } + + public ECKey() { + this(secureRandom); + } + + public ECKey(SecureRandom secureRandom) { + this(new BouncyCastleProvider(), secureRandom); + } + + + public ECKey(Provider provider, SecureRandom secureRandom) { + this.provider = provider; + + KeyPairGenerator keyGen; + try { + keyGen = KeyPairGenerator.getInstance("EC"); + ECGenParameterSpec SECP256K1_CURVE = new ECGenParameterSpec("secp256k1"); + keyGen.initialize(SECP256K1_CURVE); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(ex); + } catch (InvalidAlgorithmParameterException ex) { + throw new AssertionError(ex); + } + + KeyPair keyPair = keyGen.generateKeyPair(); + + this.privateKey = keyPair.getPrivate(); + this.publicKey = keyPair.getPublic(); + + } + + private static ECPoint extractPublicKey(final ECPublicKey ecPublicKey) { + final java.security.spec.ECPoint publicPointW = ecPublicKey.getW(); + final BigInteger xCoord = publicPointW.getAffineX(); + final BigInteger yCoord = publicPointW.getAffineY(); + + return CURVE.getCurve().createPoint(xCoord, yCoord); + } + + public byte[] applyECDSASig(byte[] input) { + Signature dsa; + byte[] output; + + if (privateKey == null) + throw new RuntimeException(); + try { + dsa = Signature.getInstance("ECDSA", "BC"); + dsa.initSign(privateKey); + dsa.update(input); + output = dsa.sign(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return output; + } + + public static boolean verifyECDSASig(byte[] data, byte[] signature, PublicKey publicKey) { + try { + Signature ecdsaVerify = Signature.getInstance("ECDSA", "BC"); + ecdsaVerify.initVerify(publicKey); + ecdsaVerify.update(data); + return ecdsaVerify.verify(signature); + }catch(Exception e) { + throw new RuntimeException(e); + } + } + +}
--- a/src/main/java/christie/blockchain/HashUtil.java Mon Nov 05 10:16:28 2018 +0900 +++ b/src/main/java/christie/blockchain/HashUtil.java Mon Nov 19 12:31:36 2018 +0900 @@ -42,4 +42,6 @@ return resBuf; } + + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/christie/blockchain/Miner.java Mon Nov 19 12:31:36 2018 +0900 @@ -0,0 +1,70 @@ +package christie.blockchain; + +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.BigIntegers; + +import java.io.ByteArrayOutputStream; +import java.math.BigInteger; +import java.nio.charset.Charset; + + +public class Miner { + + HashUtil hashUtil = new HashUtil(); + + + public void mineBlock(Block newBlock, int difficulty) { + long nonce = 0; + + + //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(); + + String hashStr = new String(hashUtil.sha256(hash), Charset.forName("utf-8")); + + + while(!hashStr.substring( 0, difficulty).equals(target)) { + nonce ++; + byte[] concat = Arrays.concatenate(hash, BigInteger.valueOf(nonce).toByteArray()); + hashStr = new String(hashUtil.sha256(concat), Charset.forName("utf-8")); + } + newBlock.setNonce(nonce); + System.out.println("Block Mined!!! : " + hashStr); + + + + } + + public boolean increment(byte[] bytes) { + final int startIndex = 0; + int i; + for (i = bytes.length - 1; i >= startIndex; i--) { + bytes[i]++; + if (bytes[i] != 0) + break; + } + + return (i >= startIndex || bytes[startIndex] != 0); + } + + public int compareTo(byte[] buffer1, int offset1, int length1, + byte[] buffer2, int offset2, int length2) { + // Short circuit equal case + if (buffer1 == buffer2 && + offset1 == offset2 && + length1 == length2) { + return 0; + } + int end1 = offset1 + length1; + int end2 = offset2 + length2; + for (int i = offset1, j = offset2; i < end1 && j < end2; i++, j++) { + int a = (buffer1[i] & 0xff); + int b = (buffer2[j] & 0xff); + if (a != b) { + return a - b; + } + } + return length1 - length2; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/christie/blockchain/Transaction.java Mon Nov 19 12:31:36 2018 +0900 @@ -0,0 +1,62 @@ +package christie.blockchain; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; + +// インターフェイスにしたほうがいいかもしれない. 後からdataの内容変える可能性がある. +public class Transaction { + private byte[] hash; + + private long nonce; + + private byte[] sendAddress; + + private byte[] receiveAddress; + + private byte[] data; + + private long timestamp; + + private byte[] signature; + + //public ArrayList<TransactionInput> inputs = new ArrayList<TransactionInput>(); + //public ArrayList<TransactionOutput> outputs = new ArrayList<TransactionOutput>(); + + + public Transaction(byte[] sendAddress, byte[] receiveAddress, byte[] data){ + this.sendAddress = sendAddress; + this.receiveAddress = receiveAddress; + this.data = data; + + } +/* + public Transaction(byte[] from, byte[] to, byte[] value, ArrayList<TransactionInput> inputs) { + this.sendAddress = from; + this.receiveAddress = to; + this.value = value; + this.inputs = inputs; + } +*/ + public byte[] calcHash(){ + HashUtil hashUtil = new HashUtil(); + + byte[] timestampByte = BigInteger.valueOf(this.timestamp).toByteArray(); + + byte[] nonceByte = BigInteger.valueOf(this.nonce).toByteArray(); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + + try { + output.write(hash); + output.write(timestampByte); + output.write(nonceByte); + } catch (IOException e) { + e.printStackTrace(); + } + + return hashUtil.sha256(output.toByteArray()); + + } + +}