关注墨瑾轩,带你探索编程的奥秘!
超萌技术攻略,轻松晋级编程高手
技术宝库已备好,就等你来挖掘
订阅墨瑾轩,智趣学习不孤单
即刻启航,编程之旅更有趣
“区块链听着高大上,但代码写起来像‘天书’?”——别慌!今天我们就用Java+Merkle Tree+P2P网络三板斧,教你如何从零打造分布式账本!从“单机记账”到“全网共识”一网打尽!
问题:区块链的核心结构是什么?Java如何实现?
解决方案:区块→链→Merkle Tree,用Java代码“搭积木”!
import java.util.Date;
public class Block {
private int index;
private String previousHash;
private String data;
private String hash;
private long timestamp;
private int nonce; // 工作量证明(PoW)用
// 构造函数
public Block(int index, String previousHash, String data) {
this.index = index;
this.previousHash = previousHash;
this.data = data;
this.timestamp = new Date().getTime();
this.hash = calculateHash(); // 计算哈希值
}
// 计算哈希(SHA-256)
private String calculateHash() {
String input = index + previousHash + data + timestamp + nonce;
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = digest.digest(input.getBytes());
return bytesToHex(hashBytes);
} catch (Exception e) {
throw new RuntimeException("哈希计算失败", e);
}
}
// 辅助方法:将字节数组转为十六进制字符串
private String bytesToHex(byte[] hash) {
StringBuilder hexString = new StringBuilder();
for (byte b : hash)
hexString.append(String.format("%02x", b));
return hexString.toString();
}
// 工作量证明(PoW)
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: " + hash);
}
}
import java.util.ArrayList;
public class Blockchain {
private ArrayList<Block> chain;
private int difficulty = 4; // 工作量难度
public Blockchain() {
chain = new ArrayList<>();
createGenesisBlock(); // 创建创世区块
}
// 创建创世区块(索引0)
private void createGenesisBlock() {
Block genesis = new Block(0, "0", "创世区块");
genesis.mineBlock(difficulty); // 挖矿
chain.add(genesis);
}
// 添加新区块
public void addBlock(String data) {
Block newBlock = new Block(
chain.size(),
chain.get(chain.size() - 1).getHash(),
data
);
newBlock.mineBlock(difficulty); // 挖矿
chain.add(newBlock);
}
// 验证区块链有效性
public boolean isValid() {
for (int i = 1; i < chain.size(); i++) {
Block current = chain.get(i);
Block previous = chain.get(i - 1);
// 验证哈希是否正确
if (!current.getHash().equals(current.calculateHash()))
return false;
// 验证前一个哈希是否正确
if (!current.getPreviousHash().equals(previous.getHash()))
return false;
}
return true;
}
}
关键点:
difficulty
越高,挖矿耗时越长,安全性越高。问题:如何让多个节点组成网络并同步数据?
解决方案:Socket通信+JSON协议+广播机制,让节点“组团打怪”!
import java.io.*;
import java.net.*;
import java.util.*;
public class Node {
private ServerSocket server;
private Blockchain blockchain;
private int port;
public Node(int port) {
this.port = port;
this.blockchain = new Blockchain();
try {
server = new ServerSocket(port);
System.out.println("节点启动,监听端口:" + port);
startListening();
} catch (IOException e) {
throw new RuntimeException("节点启动失败", e);
}
}
// 监听传入连接
private void startListening() {
new Thread(() -> {
while (true) {
try {
Socket socket = server.accept();
new ConnectionHandler(socket, this).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
// 处理连接
private class ConnectionHandler extends Thread {
private Socket socket;
private Node node;
public ConnectionHandler(Socket socket, Node node) {
this.socket = socket;
this.node = node;
}
@Override
public void run() {
try {
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Object message = in.readObject();
if (message instanceof Block) {
Block receivedBlock = (Block) message;
System.out.println("收到新区块:" + receivedBlock.getHash());
blockchain.addBlock(receivedBlock.getData()); // 简化处理
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 广播消息到其他节点
public void broadcastBlock(Block block) {
List<Integer> otherPorts = Arrays.asList(5001, 5002, 5003); // 假设有其他节点
for (int port : otherPorts) {
if (port != this.port) {
try (
Socket socket = new Socket("localhost", port);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream())
) {
out.writeObject(block);
System.out.println("广播区块到端口:" + port);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
关键点:
ServerSocket
监听,Socket
主动连接其他节点。问题:如何让区块链执行复杂逻辑?
解决方案:Java接口+事件驱动+链上存储,让合约“自己做主”!
// 定义智能合约接口
public interface SmartContract {
void execute(Transaction transaction); // 执行交易逻辑
}
// 实现一个简单的转账合约
public class TransferContract implements SmartContract {
private Map<String, Double> balances = new HashMap<>();
@Override
public void execute(Transaction transaction) {
String from = transaction.getFrom();
String to = transaction.getTo();
double amount = transaction.getAmount();
if (balances.getOrDefault(from, 0.0) < amount)
throw new RuntimeException("余额不足!");
balances.put(from, balances.get(from) - amount);
balances.put(to, balances.getOrDefault(to, 0.0) + amount);
System.out.println("转账成功!");
}
}
public class Transaction {
private String from;
private String to;
private double amount;
public Transaction(String from, String to, double amount) {
this.from = from;
this.to = to;
this.amount = amount;
}
// Getters and Setters
}
关键点:
Map
存储账户余额,但实际需用持久化存储(如数据库)。问题:如何用分布式账本追踪商品来源?
解决方案:区块链+智能合约+API,让每瓶红酒都有“身份证”!
// 定义商品溯源合约
public class SupplyChainContract implements SmartContract {
private Map<String, String> productHistory = new HashMap<>();
@Override
public void execute(Transaction transaction) {
String productId = transaction.getProductId();
String event = transaction.getEvent();
productHistory.put(productId, productHistory.getOrDefault(productId, "") + event + "\n");
System.out.println("商品事件记录:" + event);
}
}
// 扩展交易类,添加商品信息
public class SupplyChainTransaction extends Transaction {
private String productId;
private String event; // 例如:"2023-09-01 进口到上海港"
// 构造函数和方法略
}
@RestController
public class BlockchainController {
@Autowired
private Blockchain blockchain;
@PostMapping("/transaction")
public ResponseEntity<String> addTransaction(@RequestBody Transaction transaction) {
// 验证交易
// ...
// 执行智能合约
SmartContract contract = new SupplyChainContract();
contract.execute(transaction);
// 将交易打包到新区块
blockchain.addBlock(transaction.toString());
return ResponseEntity.ok("交易成功!");
}
}
关键点:
语言 | 优势 | 劣势 |
---|---|---|
Java | 生态完善(Spring、Netty)、跨平台 | 代码冗长,性能略逊于C++/Rust |
Solidity | 专为以太坊设计,合约开发友好 | 仅支持以太坊,学习成本高 |
Rust | 内存安全,适合高性能节点开发 | 学习曲线陡峭,社区资源较少 |
通过这四步,你已经掌握了Java在分布式账本技术的核心玩法!记住: