view src/main/java/christie/blockchain/BlockChain.java @ 198:dd3c0ba6a0a6

fix topology manager
author akahori
date Sat, 09 Mar 2019 21:53:37 +0900
parents 0ef25958ac04
children
line wrap: on
line source

package christie.blockchain;

import java.nio.charset.Charset;
import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BlockChain {

    public ArrayList<Block> blockList = new ArrayList<Block>();

    int difficulty = 1;

    private Block bestBlock;

    public static void main(String[] args) {

        /*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());*/
        new BlockChain().testBlockMining();
    }

    public void testBlockMining(){
        BlockChain blockChain = new BlockChain();
        blockChain.difficulty = 2;
        Miner miner = new Miner();
        long startTime = System.currentTimeMillis();

        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, 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, blockChain.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(blockChain.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(parentBlock.getPresentHash(), currentBlock.getParentHash())){
                System.out.println("Previous Hashes not equal");
                return false;
            }

            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;
            }
        }
        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 を代入する
        if (parent.getTimestamp() >= time) time = parent.getTimestamp() + 1;

        return createNewBlock(parent, data, time);
    }

    public synchronized  Block createNewBlock(Block parent, String data, long time){
        final long blockNumber = parent.getNumber() + 1;
        long difficulty = 1;

        Block block = new Block(parent.getPresentHash(),
                difficulty, blockNumber,
                time);

        return block;
    }

    public synchronized Block createGenesisBlock(String data){
        long time = System.currentTimeMillis() / 1000;
        Block block = new Block(1, time);
        return block;
    }

    public synchronized Block getBestBlock() {
        return bestBlock;
    }

    public long getSize() {
        return bestBlock.getNumber() + 1;
    }
}