区块链可以简单抽象成将一个个区块存放在一个链表中,每新增一个块就把它放置在链表尾端,并通过区块之间信息的传递形成独一无二的hash,来确保区块链的数据未被篡改过。
区块的实现
区块的基本属性有:
当前区块的hash值
前一个区块的hash值
当前区块的数据值
当前块的时间戳
其中,通过对前一区块的hash(若为第一个区块则为0)、当前区块的数据值和当前的时间戳进行加密处理,可以生成一个独一无二的属于当前区块hash值。
public class Block {
public String hash;//当前块的哈希值
public String previousHash;//前一个块的哈希值
private String data;//当前块的数据
private long timeStamp;//当前块的时间戳
//初始化区块
public Block(String data, String previousHash) {
this.data = data;
this.previousHash = previousHash;
this.timeStamp = System.currentTimeMillis();
this.hash = calculateHash();
}
//通过sha256散列算法生成hash值
public String calculateHash() {
String calculatedhash =
StringUtil.applySha256(previousHash
+Long.toString(timeStamp)
+data);
return calculatedhash;
}
}
sha256散列算法
之所以选用SHA256是因为它的大小正合适,一方面产生重复hash值的可能性很小,另一方面在区块链实际应用过程中,有可能会产生大量的区块,而使得信息量很大,那么256位的大小就比较恰当了。
public class StringUtil {
public static String applySha256(String input){
try {
//指定使用的加密算法为SHA-256
MessageDigest digest = MessageDigest.getInstance("SHA-256");
//计算当前输入数据的散列值
byte[] hash = digest.digest(input.getBytes(StandardCharsets.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);
}
}
}
测试
创建一个链表用来存放区块,从而形成区块链。
public class NoobChain {
public static ArrayList<Block> blockchain = new ArrayList<Block>();
public static void main(String[] args) {
//将每一个块添加到区块链中
//传入块的信息:当前块的数据信息、上一块的hash值
blockchain.add(new Block("The first block", "0"));
blockchain.add(new Block("The second block", blockchain.get(blockchain.size() - 1).hash));
blockchain.add(new Block("The third block", blockchain.get(blockchain.size() - 1).hash));
//将区块链用整齐的格式打印出来
String blockchainJson = new GsonBuilder().setPrettyPrinting().create().toJson(blockchain);
System.out.println(blockchainJson);
}
}
检验区块链的完整性
检验区块链是否完整,是通过验证当前块和上一块的hash是否正确来实现的。由于区块链的每个节点生成后便不可修改,所以当某一块的hash值发生变化时,则证明其数据等信息被篡改过,区块链不再完整。
//判断区块链是否有效
public static Boolean isChainValid() {
Block currentBlock;
Block previousBlock;
//通过检查哈希值来判断是否是一个有效的区块链
for (int i = 1; i < blockchain.size(); i++) {
currentBlock = blockchain.get(i);
previousBlock = blockchain.get(i - 1);
//比较块中的注册hash和再次计算的hash值是否相同
if (!currentBlock.hash.equals(currentBlock.calculateHash())) {
System.out.println("Current Hashes not equal");
return false;
}
//比较前一个块的hash值和当前块的previousHash值是否相同
if (!previousBlock.hash.equals(currentBlock.previousHash)) {
System.out.println("Previous Hashes not equal");
return false;
}
}
return true;
}
区块链中的任何区块出现改变都会导致hash变化,这个函数返回false,也就证明了区块链无效了。
本文参考:java开发区块链只需150行代码文章来源:https://www.toymoban.com/news/detail-516521.html
Java源代码保存在GitHub文章来源地址https://www.toymoban.com/news/detail-516521.html
到了这里,关于Java实现简单的区块链的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!