Java实现简易区块链案例

wen java案例 5

从零手写:Java实现简易区块链的完整案例与核心原理剖析


目录导读

  1. 区块链的核心本质:不只是“链”那么简单
  2. 环境准备与数据结构设计(Block & Transaction)
  3. 工作量证明(PoW):Hashcash算法的Java实现
  4. 链的校验与防篡改逻辑:如何识别“坏块”
  5. 简易P2P通信:节点间同步与共识(可选进阶)
  6. 运行测试与结果分析:命令行模拟挖矿与验证
  7. 常见问题答疑(Q&A)
  8. 从Demo到生产级区块链的差距

区块链的核心本质:不只是“链”那么简单

很多人误以为区块链就是“一串用哈希连接的数据”,但真正的难点在于去中心化共识,本文的简易案例将聚焦于区块链的不可篡改性(哈希链)与工作量证明机制,你将看到,即便没有网络层,仅仅通过数据结构+算法,也能构建一个可验证的“数字账本”。

Java实现简易区块链案例

关键点:每个区块包含 index, timestamp, data, previousHash, hash, noncepreviousHash 是连接上一块的“铁链”,nonce 是挖矿的“随机数”。


环境准备与数据结构设计(Block & Transaction)

环境:JDK 8+,无需第三方库(使用 java.security.MessageDigest 实现SHA-256)。

public class Block {
    public String 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 = System.currentTimeMillis();
        this.hash = calculateHash(); // 首次计算
    }
    public String calculateHash() {
        String input = previousHash + Long.toString(timeStamp) 
                     + Integer.toString(nonce) + data;
        return SHA256Util.sha256(input); // 封装工具类
    }
    public void mineBlock(int difficulty) {
        String target = new String(new char[difficulty]).replace('\0', '0');
        while (!hash.substring(0, difficulty).equals(target)) {
            nonce++;
            hash = calculateHash();
        }
        System.out.println("挖矿成功: " + hash);
    }
}

SHA256Util工具类(核心代码):

public static String sha256(String input) {
    try {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(input.getBytes("UTF-8"));
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    } catch (Exception e) { throw new RuntimeException(e); }
}

设计思考:为什么必须用 String 存储data而不是对象?——为了演示简单,生产环境应序列化为JSON或二进制。


工作量证明(PoW):Hashcash算法的Java实现

目标:找到一个 nonce 使得区块哈希以 difficulty0 开头,难度越高,计算量指数级上升。

代码逻辑(已在上面 mineBlock 中):

  • 计算 target = 连续 difficulty0
  • 循环递增 nonce 并重新计算哈希,直到满足条件。

示例结果(难度=4时,通常需要数万次尝试):

挖矿成功: 0000f1a2b3c4d5e6f7a8b9...

链的校验与防篡改逻辑:如何识别“坏块”

区块链的“不可篡改”依赖每个区块的哈希链校验,若有人修改了第2块的数据,则第2块的哈希变化,导致第3块的 previousHash 不匹配,从而整条链断裂。

public class BlockChain {
    private List<Block> chain = new ArrayList<>();
    public boolean isValidChain() {
        Block currentBlock;
        Block previousBlock = chain.get(0);
        for (int i = 1; i < chain.size(); i++) {
            currentBlock = chain.get(i);
            // 1. 当前块的哈希是否被篡改(重新计算比对)
            if (!currentBlock.hash.equals(currentBlock.calculateHash())) {
                return false;
            }
            // 2. 前一块的哈希是否与记录的一致
            if (!previousBlock.hash.equals(currentBlock.previousHash)) {
                return false;
            }
            previousBlock = currentBlock;
        }
        return true;
    }
}

测试篡改

chain.get(1).data = "篡改数据";
System.out.println("链是否有效: " + isValidChain()); // 输出 false

简易P2P通信(可选进阶)

真实区块链需要节点间广播区块,本例可简化:用 ServerSocket + ObjectOutputStream 传输 Block 对象。
建议:先掌握单机版,再考虑网络同步,核心是最长链规则——当收到一条比本地更长的链时,替换本地链。


运行测试与结果分析:命令行模拟挖矿与验证

主类示例

public class Main {
    public static void main(String[] args) {
        BlockChain chain = new BlockChain();
        chain.addBlock(new Block("转账10元", "0"));
        chain.addBlock(new Block("转账20元", chain.getLatestBlock().hash));
        System.out.println("区块链完整性: " + chain.isValidChain());
    }
}

输出(简化):

正在挖矿第1个区块... 耗时2秒
正在挖矿第2个区块... 耗时5秒
区块链完整性: true

常见问题答疑(Q&A)

Q1:为什么 nonce 会溢出成为负数?
A:int 最大21亿,若难度过高会溢出,解决方案:使用 long 或重置 nonce 并改变时间戳。

Q2:如何调整挖矿难度?
A:通过动态计算每10分钟出一个区块的目标值,本例直接手动设置 difficulty

Q3:如何保护数据隐私?
A:本例使用明文 data,生产环境需对交易内容做加密或只存哈希(默克尔树)。


从Demo到生产级区块链的差距

本案例演示了区块链的数据不可篡改PoW机制,但距离生产级系统还差:

  • 共识算法(PBFT、Raft等)
  • 网络层(节点发现、广播、防女巫攻击)
  • 持久化存储(LevelDB、RocksDB)
  • 智能合约(Java需集成GraalVM或解释器)

学习建议:可在此基础上增加Merkle Tree、UTXO模型、数字签名,逐步向以太坊或比特币的简化版迈进。


本文所有代码均可在本地独立运行,彻底理解区块链底层逻辑后再进阶分布式网络,收益更大。

抱歉,评论功能暂时关闭!