基于Java 语言实现区块链的 Proof of Concept 版本
1. 创建区块类
/**
* 区块链 里边存放的数据是:
* data 数据
* preHash 上一个区块的hash值
* hash 自己的 hash值 它是由存储在区块链的信息 计算出来的(data + 之前区块的哈希值) ,采用 sha256 算法
*/
public class Block {
private Object data;
private String preHash;
private String hash;
public Block(Object data, String preHash) {
this.data = data;
this.preHash = preHash;
this.hash = this.computeHash();
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getPreHash() {
return preHash;
}
public void setPreHash(String preHash) {
this.preHash = preHash;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public String computeHash() {
return new Encrypt().SHA256(this.data + this.preHash);
}
@Override
public String toString() {
return "Block{" +
"data=" + data +
", preHash='" + preHash + '\'' +
", hash='" + hash + '\'' +
'}';
}
public static void main(String[] args) {
Block block = new Block("转账10元","1234");
System.out.println(block);
}
}
2. 创建区块的链
对于祖先节点的处理; 对于区块链的验证
/**
* 区块的链
*/
public class Chain {
private List<Block> chain = new ArrayList<>();
public Chain() {
chain.add(bigBang());
}
public Chain(List<Block> chain) {
chain.add(bigBang());
this.chain.addAll(chain);
}
/**
* 每个区块都会生成一个祖先区块
* @return
*/
public Block bigBang() {
// 创建祖先节点 hash为空
return new Block("祖先","");
}
/**
* 获取最后一个区块的信息
* @return
*/
public Block getLatestBlock() {
return getChain().get(this.chain.size()-1);
}
/**
* 添加区块到区块链上
* 找到最近一个block的hash
* 这个hash就是新区块的preHash
*/
public void addBlockToChain(Block newBlock) {
newBlock.setPreHash(this.getLatestBlock().computeHash());
newBlock.setHash(newBlock.computeHash());
this.chain.add(newBlock);
}
public List<Block> getChain() {
return chain;
}
public void setChain(List<Block> chain) {
this.chain = chain;
}
/**
* 验证这个当前的区块链是否合法
* 当前的区块是否被篡改
* 我们要验证区块的preHash是否等于previous区块hash
*/
public Boolean validateBlockChain() {
// 创始区块的校验
if (this.chain.size() == 1) {
// 比较创始区块的hash值
if (! this.chain.get(0).getHash().equalsIgnoreCase(this.chain.get(0).computeHash())) {
return false;
}
return true;
} else {
// this.chain[1] 是第二个区块
// 我们从第二个区块开始验证
// 验证到最后一个区块 this.chain.size() -1
for (int i = 1; i <= this.chain.size() -1; i++) {
Block blockValidate = this.chain.get(i);
// 验证当前数据是否被篡改
if (!blockValidate.getHash().equalsIgnoreCase(blockValidate.computeHash())) {
System.out.println("数据被篡改!");
return false;
}
// 验证区块的previousHash 是否等于 previous区块的hash
Block previousBlock = this.chain.get(i-1);
//
if (!blockValidate.getPreHash().equalsIgnoreCase(previousBlock.getHash())) {
System.out.println("前后区块链接断裂!");
return false;
}
}
return true;
}
}
@Override
public String toString() {
return "Chain{" +
"chain=" + chain +
'}';
}
public static void main(String[] args) {
Chain chain = new Chain();
// System.out.println(chain.validateBlockChain());
Block block1 = new Block("转账10元","1234");
chain.addBlockToChain(block1);
Block block2 = new Block("转账20元","1234");
chain.addBlockToChain(block2);
System.out.println(chain);
System.out.println(chain.validateBlockChain());
// 篡改区块链上的数据
chain.getChain().get(1).setData("转账30元");
System.out.println(chain.validateBlockChain());
// 篡改区块链的hash值
chain.getChain().get(1).setHash(chain.getChain().get(1).computeHash());
System.out.println(chain.validateBlockChain());
}
}
3. SHA-256 算法
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
*JAVA 已经实现了 SHA-256 和 SHA-512 两种 Hash 算法
*利用 java.security.MessageDigest 调用已经集成的 Hash 算法
*创建 Encrypt 对象,并调用 SHA256 或者 SHA512 并传入要加密的文本信息,分别得到 SHA-256 或 SHA-512 两种被加密的 hash 串。
*若要改为 MD5 算法,修改传入参数 strType 为 "MD5" 即可得到 MD5 加密功能。
*/
public class Encrypt {
/**
* 传入文本内容,返回 SHA-256 串
*
* @param strText
* @return
*/
public String SHA256(final String strText) {
return SHA(strText, "SHA-256");
}
/**
* 传入文本内容,返回 SHA-512 串
*
* @param strText
* @return
*/
public String SHA512(final String strText) {
return SHA(strText, "SHA-512");
}
/**
* 字符串 SHA 加密
*
* @param strText
* @param strType
* @return
*/
private String SHA(final String strText, final String strType) {
// 返回值
String strResult = null;
// 是否是有效字符串
if (strText != null && strText.length() > 0) {
try {
// SHA 加密开始
// 创建加密对象 并傳入加密類型
MessageDigest messageDigest = MessageDigest.getInstance(strType);
// 传入要加密的字符串
messageDigest.update(strText.getBytes());
// 得到 byte 類型结果
byte byteBuffer[] = messageDigest.digest();
// 將 byte 轉換爲 string
StringBuffer strHexString = new StringBuffer();
// 遍歷 byte buffer
for (int i = 0; i < byteBuffer.length; i++) {
String hex = Integer.toHexString(0xff & byteBuffer[i]);
if (hex.length() == 1) {
strHexString.append('0');
}
strHexString.append(hex);
}
// 得到返回結果
strResult = strHexString.toString();
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
return strResult;
}
}
标签:Concept,Java,String,chain,return,区块,public,hash,Proof
From: https://blog.51cto.com/u_4981212/5870536