区块
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');
}
}
网友评论