區塊鏈-java入門Demo
阿新 • • 發佈:2019-02-14
正在建立第一個區塊鏈....... 建立區塊: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);
}
}