Demo:第一章:Java实现比特币系统

2021-09-22 10:57:26 浏览数 (1)

创建一个maven项目 pom.xml:

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.blockchain.block</groupId>
    <artifactId>blockchain</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java-version>1.8</java-version>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>${java-version}</source>
                    <target>${java-version}</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <archive>
                        <addMavenDescriptor>false</addMavenDescriptor>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>com.blockchain.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>blockchain</finalName>
        <defaultGoal>compile</defaultGoal>
    </build>
    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.7</version>
        </dependency>
    </dependencies>
</project>

创建二个实体类: Block

代码语言:javascript复制
package com.blockchain.model;

import java.util.List;

import com.alibaba.fastjson.JSON;
import com.blockchain.security.CryptoUtil;

/**
 * 区块结构
 * @author zhiwei liao
 *
 */
public class Block {

	/**
	 * 区块索引号
	 */
	private int index;
	/**
	 * 当前区块的hash值,区块唯一标识
	 */
	private String hash;
	/**
	 * 生成区块的时间戳
	 */
	private long timestamp;
	/**
	 * 当前区块的交易集合
	 */
	private List<Transaction> transactions;
	/**
	 * 工作量证明,计算正确hash值的次数
	 */
	private int nonce;
	/**
	 * 前一个区块的hash值
	 */
	private String previousHash;

	public Block() {
		super();
	}

	public Block(int index, long timestamp, List<Transaction> transactions, int nonce, String previousHash, String hash) {
		super();
		this.index = index;
		this.timestamp = timestamp;
		this.transactions = transactions;
		this.nonce = nonce;
		this.previousHash = previousHash;
		this.hash = hash;
	}

	public int getIndex() {
		return index;
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public long getTimestamp() {
		return timestamp;
	}

	public void setTimestamp(long timestamp) {
		this.timestamp = timestamp;
	}

	public List<Transaction> getTransactions() {
		return transactions;
	}

	public void setTransactions(List<Transaction> transactions) {
		this.transactions = transactions;
	}

	public int getNonce() {
		return nonce;
	}

	public void setNonce(int nonce) {
		this.nonce = nonce;
	}

	public String getPreviousHash() {
		return previousHash;
	}

	public void setPreviousHash(String previousHash) {
		this.previousHash = previousHash;
	}

	public String getHash() {
		return hash;
	}

	public void setHash(String hash) {
		this.hash = hash;
	}
	
	/**
	 * 挖矿
	 * @param blockchain 整个区块链
	 * @param txs 需记账交易记录
	 * @param address 矿工钱包地址
	 * @return
	 */
	public static void mineBlock(List<Block> blockchain, List<Transaction> txs, String address) {
		//加入系统奖励的交易
		Transaction sysTx = new Transaction(CryptoUtil.UUID(), "", address, 10);
		txs.add(sysTx);
		//获取当前区块链里的最后一个区块
	    Block latestBlock = blockchain.get(blockchain.size() - 1);
		//随机数
		int nonce = 1;
		String hash = "";
		while(true){
			hash = CryptoUtil.SHA256(latestBlock.getHash()   JSON.toJSONString(txs)   nonce);
			if (hash.startsWith("0000")) {
		        System.out.println("=====计算结果正确,计算次数为:"  nonce  ",hash:"   hash);
		        break;
	        }
			nonce  ;
			System.out.println("计算错误,hash:"   hash); 
		}
		
		//解出难题,可以构造新区块并加入进区块链里
		Block newBlock = new Block(latestBlock.getIndex()   1, System.currentTimeMillis(), txs, nonce, latestBlock.getHash(), hash);
		blockchain.add(newBlock);
		System.out.println("挖矿后的区块链:"   JSON.toJSONString(blockchain));
    }
	
}

Transaction

代码语言:javascript复制
package com.blockchain.model;


/**
 * 交易
 * @author zhiwei liao
 */
public class Transaction {
	/**
	 * 交易唯一标识
	 */
	private String id;
	/**
	 * 交易发送方
	 */
	private String sender;
	/**
	 * 交易接收方
	 */
	private String recipient;
	/**
	 * 交易金额
	 */
	private int amount;

	public Transaction() {
		super();
	}

	public Transaction(String id, String sender, String recipient, int amount) {
		super();
		this.id = id;
		this.sender = sender;
		this.recipient = recipient;
		this.amount = amount;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
	
	public String getSender() {
		return sender;
	}

	public void setSender(String sender) {
		this.sender = sender;
	}

	public String getRecipient() {
		return recipient;
	}

	public void setRecipient(String recipient) {
		this.recipient = recipient;
	}
	
	public int getAmount() {
		return amount;
	}

	public void setAmount(int amount) {
		this.amount = amount;
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result   ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Transaction other = (Transaction) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
}

加密工具类

代码语言:javascript复制
package com.blockchain.security;

import java.security.MessageDigest;
import java.util.UUID;


/**
 * 加密工具类
 * 
 * @author zhiwei liao
 *
 */
public class CryptoUtil {
	private CryptoUtil() {
	}

	public static String SHA256(String str) {
		MessageDigest messageDigest;
		String encodeStr = "";
		try {
			messageDigest = MessageDigest.getInstance("SHA-256");
			messageDigest.update(str.getBytes("UTF-8"));
			encodeStr = byte2Hex(messageDigest.digest());
		} catch (Exception e) {
			System.out.println("getSHA256 is error"   e.getMessage());
		}
		return encodeStr;
	}

	public static String UUID() {
		return UUID.randomUUID().toString().replaceAll("\-", "");
	}

	private static String byte2Hex(byte[] bytes) {
		StringBuilder builder = new StringBuilder();
		String temp;
		for (int i = 0; i < bytes.length; i  ) {
			temp = Integer.toHexString(bytes[i] & 0xFF);
			if (temp.length() == 1) {
				builder.append("0");
			}
			builder.append(temp);
		}
		return builder.toString();
	}

}

Main方法执行:

代码语言:javascript复制
package com.blockchain;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.blockchain.model.Block;
import com.blockchain.model.Transaction;
import com.blockchain.security.CryptoUtil;
/**
 * 交易
 * @author zhiwei liao
 */
public class Main {
	
	public static void main(String[] args) {
		//创建一个空的区块链
		List<Block> blockchain = new ArrayList<>();
		//生成创世区块
		Block block = new Block(1, System.currentTimeMillis(), new ArrayList<Transaction>(), 1, "1", "1");
		//加入创世区块到区块链里
		blockchain.add(block);
		System.out.println(JSON.toJSONString(blockchain));
		
		// 发送方钱包地址
		String sender = "sender_wallet";
		//接收方钱包地址
		String recipient = "recipient_wallet";
		
		//创建一个空的交易集合
		List<Transaction> txs = new ArrayList<>();
		//挖矿
		Block.mineBlock(blockchain, txs, sender);
		System.out.println(sender   "钱包的余额为:"   getWalletBalance(blockchain, sender));
		
		//创建一个空的交易集合
		List<Transaction> txs1 = new ArrayList<>();
		//已发生但未记账的交易记录,发送者给接收者转账3个比特币
		Transaction tx1 = new Transaction(CryptoUtil.UUID(), sender, recipient, 3);
		//已发生但未记账的交易记录,发送者给接收者转账1个比特币
		Transaction tx2 = new Transaction(CryptoUtil.UUID(), sender, recipient, 1);
		txs1.add(tx1);
		txs1.add(tx2);
		//挖矿
		Block.mineBlock(blockchain, txs1, sender);
		System.out.println(sender   "钱包的余额为:"   getWalletBalance(blockchain, sender));
		System.out.println(recipient   "钱包的余额为:"   getWalletBalance(blockchain, recipient));
    }
	
	/**
	 * 查询余额
	 * @param blockchain
	 * @param address
	 * @return
	 */
	public static int getWalletBalance(List<Block> blockchain, String address) {
		int balance = 0;
		for (Block block : blockchain) {
	        List<Transaction> transactions = block.getTransactions();
	        for (Transaction transaction : transactions) {
	            if (address.equals(transaction.getRecipient())) {
	            	balance  = transaction.getAmount();
                }
	            if (address.equals(transaction.getSender())) {
	            	balance -= transaction.getAmount();
                }
            }
        }
		return balance;
	}
}

这样一个简单的比特币系统就做好啦

0 人点赞