区块链-java入门Demo

正在创建第一个区块链....... 
创建区块:00000d3c0681cd67f8050ab996e1400f99c0060ba4cb22d0c07685d9ae50cd10
正在创建第二个区块链....... 
创建区块:00000eafdd53bed5586d480d7704169c45b25fcb0bc5846b16be6fbeee88ec69
正在创建第三个区块链.......
创建区块:00000a6391f185b143bfccf571ef660204f945f43cb4101e804b360d06c9af66
区块链是否有效的: true
[
  {
    "hash": "00000d3c0681cd67f8050ab996e1400f99c0060ba4cb22d0c07685d9ae50cd10",
    "previousHash": "0",
    "data": "我是第一个区块链",
    "timeStamp": 1528268281634,
    "nonce": 7033501
  },
  {
    "hash": "00000eafdd53bed5586d480d7704169c45b25fcb0bc5846b16be6fbeee88ec69",
    "previousHash": "00000d3c0681cd67f8050ab996e1400f99c0060ba4cb22d0c07685d9ae50cd10",
    "data": "我是第二个区块链",
    "timeStamp": 1528268301568,
    "nonce": 340676
  },
  {
    "hash": "00000a6391f185b143bfccf571ef660204f945f43cb4101e804b360d06c9af66",
    "previousHash": "00000eafdd53bed5586d480d7704169c45b25fcb0bc5846b16be6fbeee88ec69",
    "data": "我是第三个区块链",
    "timeStamp": 1528268302664,
    "nonce": 319404
  }
]

Process finished with exit code 0


1.Block

package com.block;
import java.util.Date;

/**
 * @Author: cxx
 * 封装区块对象
 * @Date: 2018/6/6 14:45
 */
public class Block {
    public String hash;
    //上一个区块的hash值
    public String previousHash;
    //每个区块存放的信息,这里我们存放的是一串字符串
    private String data;
    //时间戳
    private long timeStamp;
    //挖矿者的工作量证明
    private int nonce;

    //构造
    public Block(String data,String previousHash ) {
        this.data = data;
        this.previousHash = previousHash;
        this.timeStamp = new Date().getTime();
        //根据previousHash、data和timeStamp产生唯一hash
        this.hash = calculateHash();
    }

    //基于上一块的内容计算新的散列
    public String calculateHash() {
        String calculatedhash = StringUtil.applySha256(
                previousHash +
                        Long.toString(timeStamp) +
                        Integer.toString(nonce) +
                        data
        );
        return calculatedhash;
    }

    //挖矿
    public void mineBlock(int difficulty) {
        //目标值,difficulty越大,下面计算量越大
        String target = StringUtil.getDificultyString(difficulty);
        //difficulty如果为5,那么target则为 00000
        while(!hash.substring( 0, difficulty).equals(target)) {
            nonce ++;
            hash = calculateHash();
        }
        System.out.println("创建区块:" + hash);
    }
}

2.StringUtil

package com.block;
import java.security.MessageDigest;
import com.google.gson.GsonBuilder;
/**
 * 工具类
 * 创建数字签名、返回JSON格式数据、返回难度字符串目标
 * @author pibigstar
 *
 */
public class StringUtil {

    //将Sha256应用到一个字符串并返回结果
    public static String applySha256(String input){
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(input.getBytes("UTF-8"));
            StringBuffer hexString = new StringBuffer();
            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);
        }
    }

    //返回JSON格式数据
    public static String getJson(Object o) {
        return new GsonBuilder().setPrettyPrinting().create().toJson(o);
    }

    //返回难度字符串目标,与散列比较。难度5将返回“00000”
    public static String getDificultyString(int difficulty) {
        return new String(new char[difficulty]).replace('\0', '0');
    }

    public static void main(String[] args) {
        System.out.println(getDificultyString(5));
    }


}

3.BlockChain

package com.block;
import java.util.ArrayList;
import com.google.gson.GsonBuilder;
/**
 * 创建区块链
 * @author pibigstar
 *
 */
public class BlockChain{
    //存放所有的区块集合
    public static ArrayList<Block> blockchain = new ArrayList<Block>();
    public static int difficulty = 5;//挖矿的难度,数字越大越难

    public static void main(String[] args) {
        System.out.println("正在创建第一个区块链....... ");
        addBlock(new Block("我是第一个区块链", "0"));//创世块

        System.out.println("正在创建第二个区块链....... ");
        addBlock(new Block("我是第二个区块链",blockchain.get(blockchain.size()-1).hash));

        System.out.println("正在创建第三个区块链.......");
        addBlock(new Block("我是第三个区块链",blockchain.get(blockchain.size()-1).hash));

        System.out.println("区块链是否有效的: " + isChainValid());

        String blockchainJson = StringUtil.getJson(blockchain);
        System.out.println(blockchainJson);
    }

    /**
     * 检查区块链的完整性
     * @return
     */
    public static Boolean isChainValid() {
        Block currentBlock;
        Block previousBlock;
        String hashTarget = new String(new char[difficulty]).replace('\0', '0');

        //循环区块链检查散列:
        for(int i=1; i < blockchain.size(); i++) {
            currentBlock = blockchain.get(i);
            previousBlock = blockchain.get(i-1);
            //比较注册散列和计算散列:
            if(!currentBlock.hash.equals(currentBlock.calculateHash()) ){
                System.out.println("Current Hashes not equal");
                return false;
            }
            //比较以前的散列和注册的先前的散列
            if(!previousBlock.hash.equals(currentBlock.previousHash) ) {
                System.out.println("Previous Hashes not equal");
                return false;
            }
            //检查哈希是否被使用
            if(!currentBlock.hash.substring( 0, difficulty).equals(hashTarget)) {
                System.out.println("这个区块还没有被开采。。。");
                return false;
            }

        }
        return true;
    }
    /**
     * 增加一个新的区块
     * @param newBlock
     */
    public static void addBlock(Block newBlock) {
        newBlock.mineBlock(difficulty);
        blockchain.add(newBlock);
    }
}




猜你喜欢

转载自blog.csdn.net/m0_37499059/article/details/80595150