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

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

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

四、余额

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

具体我们看下代码:
上海java培训


/**
* 查询余额
* @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基于区块链账本技术实现了一个简单的比特币系统了,包含区块链功能,挖矿产生新比特币功能,转账交易功能,查询余额功能,完整的代码找小助手领取。

运行结果如下图所示:

欢迎大家评论留言,想获取更多内容或资料支持请点击 上海java培训

惊奇!用Java也能实现比特币系统的更多相关文章

  1. [原创]Java应用性能远程监控系统(C/S架构)

    Java应用性能远程监控系统(使用C/S架构) 适用于监控所有Java应用,具有堆内存监控.方法区监控.GC监控.类加载监控.类编译监控与线程监控,提供堆快照下载,线程快照下载.体验网址:http:/ ...

  2. 区块链区块的生成和链接,比特币btc的产生,UTXO的生成和消耗,比特币系统

    区块链区块的生成和链接,比特币btc的产生,UTXO的生成和消耗,比特币系统 区块链区块的生成和链接,比特币btc的产生,UTXO的生成和消耗,比特币系统

  3. OSGi 系列(一)之什么是 OSGi :Java 语言的动态模块系统

    OSGi 系列(一)之什么是 OSGi :Java 语言的动态模块系统 OSGi 的核心:模块化.动态.基于 OSGi 就可以模块化的开发 java 应用,模块化的部署 java 应用,还可以动态管理 ...

  4. java.io.FileNotFoundException: generatorConfig.xml (系统找不到指定的文件。)

    在使用MyBatis的逆向工程生成代码时,一直报错java.io.FileNotFoundException: generatorConfig.xml (系统找不到指定的文件.),如图 文件结构如下: ...

  5. OSGi是什么:Java语言的动态模块系统(一)

    OSGi是什么 OSGi亦称做Java语言的动态模块系统,它为模块化应用的开发定义了一个基础架构.OSGi容器已有多家开源实现,比如Knoflerfish.Equinox和Apache的Felix.您 ...

  6. Atitit.Java exe bat  作为windows系统服务程序运行

    Atitit.Java exe bat  作为windows系统服务程序运行 1. 使用SC命令+srvany.exe (不错,推荐)+net start1 1.1. First 创建一个java的运 ...

  7. Java生鲜电商平台-系统异常状态的设计与架构(APP应用或者生鲜小程序)

    Java生鲜电商平台-系统异常状态的设计与架构 说明:在实际开发Java生鲜电商平台的时候,异常状态的设计关系着整体系统的性能问题,架构设计,以及稳定性方面,对此,我根据实际的业务场景,进行了系统设计 ...

  8. Java生鲜电商平台-系统报表设计与架构

    Java生鲜电商平台-系统报表设计与架构 说明:任何一个运行的平台都需要一个很清楚的报表来显示,那么作为Java开源生鲜电商平台而言,我们应该如何设计报表呢?或者说我们希望报表来看到什么数据呢?   ...

  9. SSM开发基于Java EE在线图书销售系统

           SSM(Spring+Spring MVC+MyBatis)开发基于Java EE在线图书销售系统  网站成功建立和运行很大部分取决于网站开发前的规划,因此为了在网站建立过程中避免一些不 ...

随机推荐

  1. 小米平板4 Plus获取Root超级权限的步骤

    小米平板4 Plus有么好方法开启Root权限?大家都清楚,Android机器有Root权限,一旦手机开启root相关权限,就可以实现更强大的功能,打比方大家部门的营销部门的同事,使用个别营销应用都需 ...

  2. JS中函数常见的表现形式以及立即执行函数

    函数常见的几种表现形式: 1.一般形式(函数声明): 会进行函数的预解释,函数会进行声明和定义,在函数体前面或则后面都可以进行调用. 2.函数表达式(匿名函数): 会进行函数的预解析,函数会进行声明但 ...

  3. 关于javascript闭包(Closure)和return之间的暧昧关系

    什么是闭包?阮一峰老师说的很清楚了,定义在一个函数内部的函数,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁. 首先要了解Javascript的变量作用域:全局变量和局部变量.全局嘛,就是共 ...

  4. CF809E Surprise me!

    题解: 一道很套路的题目 首先一个结论 $\phi(xy)=\frac{\phi(x)*\phi(y)*gcd(x,y)}{\phi(gcd(x,y))}$ 这个按照$\phi$的定义很容易知道 然后 ...

  5. Mac安装nginx配置过程

    mac电脑系统重装了,记录一下安装nginx的过程: 1.打开终端 2.安装Command Line tools xcode-select --install 3.安装brew命令 ruby -e & ...

  6. python DNN

    exam_relu_softmax_dnn ''' 문) bmi.csv 데이터셋을 이용하여 다음과 같이 DNN모델을 생성하시오. 조건1> X,Y변수 -> X변수 : heigh ...

  7. 平滑升级nginx到新版本

    这里测试一下nginx的平滑升级,以备不时之需 查看nginx版本号: [root@zklf-server01 ~]# /application/nginx/sbin/nginx -V nginx v ...

  8. 运营-赵本山最近有点烦:二人转产业链滑铁卢 关联公司IPO预披露

    http://news.cecb2b.com/info/20141117/2868962.shtml

  9. sublime text 3 package Install 安装失败解决方法

    失败原因为官网地址被墙,导致channel_v3文件无法访问. 解决方法: 点击Preferences——>Package Settings——>Package Control——> ...

  10. java PDF分页打印

    将获取的pdf文件按页拆分:参考https://q.cnblogs.com/q/99944/ pdf文件有多页,第一页需设置横向打印,其他页设置为纵向打印. PDDocument document = ...