美文网首页
区块链的简单实现

区块链的简单实现

作者: 小吖么小一郎 | 来源:发表于2019-11-18 14:16 被阅读0次

区块

import java.util.Date;

/**
 * ClassName:Block
 * Description:
 */
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();
        this.hash = calulateHash(); // 根据previoushash,data和timeStamp产生唯一hash
    }
    // 基于上一块的内容计算新的散列
    public String calulateHash(){
        String calulatedhash = StringUtil.applySha256(
                previousHash + Long.toString(timeStamp) + Integer.toString(nonce) + data
        );
        return calulatedhash;
    }
    // 挖矿
    public void mineBlock(int difficulty){
        String target = StringUtil.getDificultyString(difficulty);  // 目标值,difficulty越大,下面计算量越大
        while (!hash.substring(0,difficulty).equals(target)){   // difficulty如果为5, 那么target则为 00000
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            nonce++;
            hash = calulateHash();
        }
        System.out.println("创建区块 : " + hash);
    }
}

区块连接

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;

/**
 * ClassName:BlockChain
 * Description:
 */
public class BlockChain {
    private static final Logger log = LoggerFactory.getLogger(BlockChain.class);
    public static ArrayList<Block> blockChain = new ArrayList<>();  // 存放所有的区块集合
    public static int difficulty = 5;

    public static void main(String[] args){
        log.info("正在创建第一个区块 ...... ");
        addBlock(new Block("第一个区块","0"));    // 创世块

        log.info("正在创建第二个区块 ......");
        addBlock(new Block("第二个区块",blockChain.get(blockChain.size()-1).hash));

        log.info("正在创建第三个区块 ......");
        addBlock(new Block("第三个区块",blockChain.get(blockChain.size()-1).hash));

        log.info("区块链是否有效的 : " + isChainValid());

        String blockChainJson = StringUtil.getJson(blockChain);
        log.info(blockChainJson);

    }

    // 检查区块链的完整性
    private 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.calulateHash())){
                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;
    }


    // 增加一个新的区块
    public static void addBlock(Block newBLock){
        newBLock.mineBlock(difficulty);
        blockChain.add(newBLock);
    }
}

挖矿难度设计和SHA256加密

import com.google.gson.GsonBuilder;

import java.security.MessageDigest;

/**
 * ClassName:StringUtil
 * Description:
 */

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');
    }

}

相关文章

网友评论

      本文标题:区块链的简单实现

      本文链接:https://www.haomeiwen.com/subject/hltbictx.html