difficulty可以改成8
java
package org.example;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
class Block {
private int index;
private long timestamp;
private String data;
private String previousHash;
private String hash;
private int nonce;
public Block(int index, long timestamp, String data, String previousHash) {
this.index = index;
this.timestamp = timestamp;
this.data = data;
this.previousHash = previousHash;
this.nonce = 0;
this.hash = calculateHash();
}
public String calculateHash() {
try {
String input = index + timestamp + data + previousHash + nonce;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = digest.digest(input.getBytes());
// 将字节数组转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : hashBytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
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("Block mined! Nonce: " + nonce + ", Hash: " + hash);
}
// Getters
public int getIndex() { return index; }
public long getTimestamp() { return timestamp; }
public String getData() { return data; }
public String getPreviousHash() { return previousHash; }
public String getHash() { return hash; }
public int getNonce() { return nonce; }
@Override
public String toString() {
return "Block #" + index +
" [Hash: " + hash +
", Prev: " + previousHash +
", Nonce: " + nonce +
", Data: " + data + "]";
}
public void setPreviousHash(String hash) {
this.previousHash=hash;
}
}
class Blockchain {
private List<Block> chain;
private int difficulty;
public Blockchain(int difficulty) {
this.chain = new ArrayList<>();
this.difficulty = difficulty;
createGenesisBlock();
}
private void createGenesisBlock() {
Block genesisBlock = new Block(0, System.currentTimeMillis(), "Genesis Block", "0");
chain.add(genesisBlock);
System.out.println("Genesis Block created!");
}
public Block getLatestBlock() {
return chain.get(chain.size() - 1);
}
public void addBlock(Block newBlock) {
newBlock.setPreviousHash(getLatestBlock().getHash());
newBlock.mineBlock(difficulty);
chain.add(newBlock);
System.out.println("Block #" + newBlock.getIndex() + " added to the blockchain!");
}
public boolean isChainValid() {
for (int i = 1; i < chain.size(); i++) {
Block currentBlock = chain.get(i);
Block previousBlock = chain.get(i - 1);
// 验证当前区块的哈希是否正确
if (!currentBlock.getHash().equals(currentBlock.calculateHash())) {
System.out.println("Block #" + currentBlock.getIndex() + " has invalid hash!");
return false;
}
// 验证与前一个区块的链接
if (!currentBlock.getPreviousHash().equals(previousBlock.getHash())) {
System.out.println("Block #" + currentBlock.getIndex() + " has invalid previous hash!");
return false;
}
// 验证工作量证明(难度要求)
String target = new String(new char[difficulty]).replace('\0', '0');
if (!currentBlock.getHash().substring(0, difficulty).equals(target)) {
System.out.println("Block #" + currentBlock.getIndex() + " does not meet difficulty requirement!");
return false;
}
}
return true;
}
public void printChain() {
System.out.println("\n===== Blockchain =====");
for (Block block : chain) {
System.out.println(block);
}
System.out.println("======================");
}
// 内部类扩展Block以添加setPreviousHash方法
static class BlockExtended extends Block {
public BlockExtended(int index, long timestamp, String data, String previousHash) {
super(index, timestamp, data, previousHash);
}
public void setPreviousHash(String previousHash) {
// 使用反射或其他方法设置,这里简化处理
// 实际应用中可能需要修改Block类设计
// 这里仅用于演示目的
try {
java.lang.reflect.Field field = Block.class.getDeclaredField("previousHash");
field.setAccessible(true);
field.set(this, previousHash);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class SimpleBlockchain {
public static void main(String[] args) {
// 创建难度为2的区块链
Blockchain blockchain = new Blockchain(2);
// 添加新区块
Blockchain.BlockExtended block1 = new Blockchain.BlockExtended(
1,
System.currentTimeMillis(),
"Transaction Data 1",
""
);
blockchain.addBlock(block1);
Blockchain.BlockExtended block2 = new Blockchain.BlockExtended(
2,
System.currentTimeMillis(),
"Transaction Data 2",
""
);
blockchain.addBlock(block2);
// 打印区块链
blockchain.printChain();
// 验证区块链
System.out.println("\nIs blockchain valid? " + blockchain.isChainValid());
// 尝试篡改数据
System.out.println("\nAttempting to tamper with Block 1 data...");
// 注意:实际应用中需要更安全的数据访问方式
// 这里仅用于演示篡改检测
Block blockToTamper = blockchain.getLatestBlock(); // 获取最后一个区块
try {
java.lang.reflect.Field dataField = Block.class.getDeclaredField("data");
dataField.setAccessible(true);
dataField.set(blockToTamper, "Tampered Data");
} catch (Exception e) {
e.printStackTrace();
}
// 再次验证区块链
System.out.println("Is blockchain valid after tampering? " + blockchain.isChainValid());
}
}
-
Block 类:
-
表示区块链中的单个区块
-
包含索引、时间戳、数据、前一个区块的哈希、当前哈希和随机数(nonce)
-
calculateHash()
方法使用 SHA-256 算法计算区块哈希 -
mineBlock()
方法实现工作量证明(挖矿)过程
-
-
Blockchain 类:
-
管理整个区块链
-
createGenesisBlock()
创建创世区块(第一个区块) -
addBlock()
添加新区块并执行挖矿 -
isChainValid()
验证区块链的完整性 -
printChain()
打印整个区块链
-
-
BlockExtended 内部类:
-
扩展 Block 类以添加设置前一个哈希的方法
-
实际应用中可能需要修改 Block 类设计
-
-
SimpleBlockchain 主类:
-
演示区块链的创建、添加区块和验证过程
-
包含篡改检测演示
-
程序功能:
-
创建创世区块
-
添加新区块并执行工作量证明(挖矿)
-
打印整个区块链
-
验证区块链完整性
-
演示篡改检测