最近区块链技术突然爆火,身边做技术的朋友茶余饭后无不谈点区块链或比特币的,为啥会这样了?

这其实跟比特币价格去年的突飞猛涨是分不开的,比特币价格从去年初不到一千美金到今年初最高接近两万美金,赚钱效应已经足够博取大家眼球了,吃瓜群众对比特币价格一年上涨20倍早已目瞪狗呆,个个备足钱袋,跃跃越试。可是,细问一下这些做技术的朋友比特币到底是个什么东西,它是如何构造出来的,能从技术角度解释下比特币吗,还真没几个能答得上来的,作为技术出身的我今天就来带大家用Java语言实现一个简单的比特币系统。
一、区块链
比特币是构建在区块链技术之上的一个加密数字货币,区块链顾名思义即由很多区块组成的链条,可以把区块链简单比喻为一本账本,把区块比喻为账本的一页记录,账本的每一页里都记录了很多比特币的转账交易,那根据这个账本里的所有交易记录应该是能算出任何一个交易者的余额,我们先来构造一个区块的结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
public class Block {
private int index;
private String hash;
private long timestamp;
private List<Transaction> transactions;
private int nonce;
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; } }
|
二、交易
转账交易即比特币的拥有方之间进行的相互转账行为,我们把这些比特币的拥有方暂时假设为比特币的钱包,钱包有对应的钱包地址,那这些转账交易实际上就是钱包地址之间的转账交易(类似于支付宝用户之间的转账,其实就是支付宝用户名之间的转账),这些转账交易需要被记录到账本里才算真正的生效。
由于比特币的转账交易设计比较复杂,我们今天暂时不深入讨论,所以这里我设计了一个简单的交易模型如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
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; } }
|
三、挖矿

挖矿到底是怎么回事?为什么那么多人吵着要去挖矿,梦想着一夜暴富?
我们可以简单的把挖矿比喻成矿工解一道数学难题的过程,只要解对了就能获取比特币系统奖励的一笔比特币,同时获取了区块链账本新区块的交易记账权,矿工会把比特币系统近期发生的转账交易记录到账本新的一页上,并获取交易的手续费,一旦交易被记录进了账本,交易就算完成了,接收方才能真正收到发送方转账的比特币。那这道数学难题到底长什么样了?
我们看下这个公式:
Hash = SHA-256(区块链的最后一个区块的Hash + 需记账交易记录信息 + 随机数)
这个公式已经很明白了,SHA-256是一种哈希加密算法,被加密的前两部分是固定不变的,我们只有依赖于随机数的不断变化计算出不同的hash结果,系统要求hash结果必须要以10个0开头,这个几率实在是太小太小,我们做测试可以简单一点,比如只要hash结果满足以4个0开头,我们就认为解题成功,即挖矿成功了,这时矿工就可以生成一个新的区块把需记账的交易记录全部记录进区块里去,同时再构造一笔系统奖励给自己的比特币的交易(发起方为系统,接收方为矿工,比特币金额假设为10个),将其也记录进账本,这样通过账本里的交易记录就会发现矿工的余额多了10个比特币了,我们看下挖矿的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
private 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)); }
|
四、余额
计算某个钱包地址的余额其实就是从区块链账本里找出所有该地址作为接收方的交易记录,将这些交易记录的发生金额累加就得到该地址收到的所有比特币金额了,然后找出所有该地址作为发送方的交易记录再次累加则得到改地址发送出去的所有比特币金额了,用收到的比特币金额之和减去发送出去的比特币金额之和就得到该地址的真正的比特币余额了,具体我们看下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
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; }
|
五、系统入口
最后,我们看下这个小比特币系统的运行效果,main函数代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| 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<>(); mineBlock(blockchain, txs, sender); System.out.println(sender + "钱包的余额为:" + getWalletBalance(blockchain, sender)); List<Transaction> txs1 = new ArrayList<>(); Transaction tx1 = new Transaction(CryptoUtil.UUID(), sender, recipient, 3); Transaction tx2 = new Transaction(CryptoUtil.UUID(), sender, recipient, 1); txs1.add(tx1); txs1.add(tx2); mineBlock(blockchain, txs1, sender); System.out.println(sender + "钱包的余额为:" + getWalletBalance(blockchain, sender)); System.out.println(recipient + "钱包的余额为:" + getWalletBalance(blockchain, recipient)); }
|
运行结果如下图所示:

至此,我们就用java语言基于区块链账本技术实现了一个简单的比特币系统,包含区块链功能,挖矿产生新比特币功能,转账交易功能,查询余额功能,当然,真正的比特币系统远不止这么简单,比如运用密码学生成比特币钱包与保证交易信息不被篡改,运用P2P通讯技术实现点对点分布式网络等功能。
源码:https://github.com/Hosiang1026/blockchain
本文标题: Java版简单的比特币系统-实战篇
本文作者: 狂欢马克思
发布时间: 2024年05月05日 00:00
最后更新: 2025年04月03日 11:07
原始链接: https://haoxiang.eu.org/4c1d6c/
版权声明: 本文著作权归作者所有,均采用CC BY-NC-SA 4.0许可协议,转载请注明出处!