用Java实现简单的比特币系统

最近区块链技术突然爆火,身边做技术的朋友茶余饭后不谈点区块链什么的都被认为是跟不上时代了,为啥会这样了?

这其实跟比特币价格去年的突飞猛进是分不开的,比特币价格从去年初不到一千美金到今年初最高接近两万美金,赚钱效应已经足够博取大家眼球了,吃瓜群众对比特币价格一年上涨20倍早已目瞪狗呆,个个备足钱袋,跃跃欲试。

可是,细问一下这些朋友比特币到底是个什么东西,它是如何构造出来的,还真没几个能答得上来的,作为技术出身的我们今天就来带大家用Java语言实现一个简单比特币系统,以期让大家能对区块链与比特币的底层实现技术有一个入门性的认识。

区块链

比特币是构建在区块链技术之上的一个加密数字货币,区块链顾名思义即由很多区块组成的链条,可以把区块链简单比喻为一本账本,把区块比喻为账本的一页记录,账本的每一页里都记录了很多比特币的转账交易,那根据这个账本里的所有交易记录应该是能算出任何一个交易者的余额,我们先来构造一个区块的结构

public class Block {

/**

* 区块索引号

*/

private int index;

/**

* 当前区块的hash值,区块唯一标识

*/

private String hash;

/**

* 生成区块的时间戳

*/

private long timestamp;

/**

* 当前区块的交易集合

*/

private List transactions;

/**

* 工作量证明,计算正确hash值的次数

*/private int nonce;

/**

* 前一个区块的hash值

*/

private String previousHash;

}

转账交易

转账交易即比特币的拥有方之间进行的相互转账行为,我们把这些比特币的拥有方暂时假设为比特币的钱包,钱包有对应的钱包地址,那这些转账交易实际上就是钱包地址之间的转账交易(类似于支付宝用户之间的转账,其实就是支付宝用户名之间的转账),这些转账交易需要被记录到账本里才算真正的生效。

由于比特币的转账交易设计比较复杂,我们今天暂时不深入讨论,所以这里我设计了一个简单的交易模型如下:

public class Transaction {

/**

* 交易唯一标识

*/

private String id;

/**

* 交易发送方钱包地址

*/

private String sender;

/**

* 交易接收方钱包地址

*/

private String recipient;

/**

* 交易金额

*/

private int amount;

}

挖矿

挖矿到底是怎么回事?

为什么那么多人吵着要去挖矿,梦想着一夜暴富?

我们可以简单的把挖矿比喻成矿工解一道数学难题的过程,只要解对了就能获取比特币系统奖励的一笔比特币,同时获取了区块链账本新区块的交易记账权,矿工会把比特币系统近期发生的转账交易记录到账本新的一页上,并获取交易的手续费,一旦交易被记录进了账本,交易就算完成了,接收方才能真正收到发送方转账的比特币。

那这道数学难题到底长什么样了?

我们看下这个数学难题的公式:

Hash = SHA-256(区块链的最后一个区块的Hash + 需记账交易记录信息 + 随机数)

这个公式已经很明白了,SHA-256是一种哈希加密算法,被加密的前两部分是固定不变的,我们只有依赖于随机数的不断变化计算出不同的hash结果,系统要求hash结果必须要以10个0开头,这个几率实在是太小太小,我们做测试可以简单一点。

比如:只要hash结果满足以4个0开头,我们就认为解题成功,即挖矿成功了,这时矿工就可以生成一个新的区块把需记账的交易记录全部记录进区块里去,同时再构造一笔系统奖励给自己的比特币的交易(发起方为系统,接收方为矿工,比特币金额假设为10个),将其也记录进账本,这样通过账本里的交易记录就会发现矿工的余额多了10个比特币了

我们看下挖矿的代码:

/**

* 挖矿

* @param blockchain 整个区块链

* @param txs 需记账交易记录,包含

* @param address 矿工钱包地址

* @return

*/

private static void mineBlock(List blockchain, List 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));

}

余额

计算某个钱包地址的余额其实就是从区块链账本里找出所有该地址作为接收方的交易记录,将这些交易记录的发生金额累加就得到该地址收到的所有比特币金额了,然后找出所有该地址作为发送方的交易记录再次累加则得到该地址发送出去的所有比特币金额了,用收到的比特币金额之和减去发送出去的比特币金额之和就得到该地址真正的比特币余额了。

具体我们看下代码:

/**

* 查询余额

* @param blockchain

* @param address

* @return

*/

public static int getWalletBalance(Listblockchain, String address) {

int balance = 0;

for (Block block : blockchain) {

Listtransactions = block.getTransactions();

for (Transaction transaction : transactions) {

if (address.equals(transaction.getRecipient())) {

balance += transaction.getAmount();

}

if (address.equals(transaction.getSender())) {

balance -= transaction.getAmount();

}

}

}

return balance;

}

至此,我们就用java基于区块链账本技术实现了一个简单的比特币系统了,包含区块链功能,挖矿产生新比特币功能,转账交易功能,查询余额功能,完整的代码找小助手领取。

运行结果如下图所示:

当然,真正的比特币系统远不止这么简单,比如:结合密码学来保证转账交易不被篡改,结合P2P的技术实现点对点分布式网络等功能。

我们这里只是抛砖引玉,想要深入学习的朋友们可以参考我们提供的视频资料。

原文发布于微信公众号 - 纯洁的微笑(keeppuresmile)

原文发表时间:2018-04-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏区块链大本营

太简单!只学十分钟,Python菜鸟也能开发一个区块链客户端

可以说,区块链是自互联网诞生以来最重要和最具颠覆性的技术之一。作为比特币和其他加密货币背后的核心技术,区块链在过去几年获得了广泛关注。

882
来自专栏CDA数据分析师

快速了解区块链背后的三项基本技术

? 作者 Thijs Maas 编译 Mika 本文为 CDA 数据分析师原创作品,转载需授权 如果问十个人"什么是区块链技术?",你可能会得到十种不同的...

4055
来自专栏一块探索区块链

基于Java语言构建区块链(四)—— 交易(UTXO)

上一篇 文章,我们实现了区块数据的持久化,本篇开始交易环节的实现。交易这一环节是整个比特币系统当中最为关键的一环,并且区块链唯一的目的就是通过安全的、可信的方式...

5005
来自专栏区块链

打造一个最小区块链

虽然有人认为区块链本身仍有很多问题需要解决,但毫无疑问,这种新颖的技术是计算机界的奇迹。 但是,究竟什么是区块链?

3904
来自专栏FreeBuf

由MtGox停止提现白话比特币交易安全

文/pnig0s|小P 由知乎上的一个问题引出:http://www.zhihu.com/question/22787360/answer/22662598 ...

17310
来自专栏服务端技术杂谈

智能合约开发

以太坊平台对底层区块链技术进行了封装,让区块链应用开发者可以直接基于其进行开发,开发者只要专注于应用本身的开发,从而大大降低了难度。 以太坊则是“图灵完备的”,...

3616
来自专栏微服务生态

JAVA并发全景图1.1版

如果大家看不清上述图片,可以点击如下URL查看大图: http://img.blog.csdn.net/20170524150154080?watermark...

743
来自专栏极客编程

用Solidity语言通过以太坊钱包开发hello world示例

使用以太坊钱包开发实现经典的HelloWord智能合约类。本文中,我们将看到如何编写简单的合约并将其部署到区块链上。我们还将通过发送和读取数据来了解如何与我们的...

731
来自专栏极客编程

学习以太坊Dapp开发

比特币设计的初衷就是要避免依赖中心化的机构,没有发行机构,也不可能操纵发行数量。既然没有中心化的信用机构,在电子货币运行的过程中,也势必需要一种机制来认可运行在...

1002
来自专栏学习圈

以太坊开发入门 - 基本概念

本质上是一个去中心的数据库,区块链包含一串数据块,每个数据块中包含若干交易数据、时间戳等信息,可用于验证交易的有效性。

2377

扫码关注云+社区