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

这其实跟比特币价格去年的突飞猛进是分不开的,比特币价格从去年初不到一千美金到今年初最高接近两万美金,赚钱效应已经足够博取大家眼球了,吃瓜群众对比特币价格一年上涨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. 4327: JSOI2012 玄武密码

    4327: JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老 ...

  2. spring-cloud-feign负载均衡组件

    Feign简介: Feign是一个声明式的Web服务客户端,使用Feign可使得Web服务客户端的写入更加方便.它具有可插拔注释支持,包括Feign注解和JAX-RS注解.Feign还支持可插拔编码器 ...

  3. PHP获取服务器IP和客户端IP

    <?php echo '前端机IP:'.$_SERVER['REMOTE_ADDR']; echo '<br />'; echo '后端机IP:'.$_SERVER['SERVER_ ...

  4. 第一阶段——CentOS6_Python3.6.1笔记(尚学堂-Python基础快速入门)+ 【补充】麦子-Python程序入门与进阶

    虚拟机环境: 设置网络 .修改网络地址 .设置网卡为nat模式 .确保物理机启动dhcp.net服务 .编辑文件:vim /etc/sysconfig/network-scripts/ifcfg-et ...

  5. hackerrank杂记

    https://www.hackerrank.com/challenges/py-set-discard-remove-pop/forum 知识点: *list:将list中的值取出,取出的数据大小是 ...

  6. How Classes are Found

    转载自: https://docs.oracle.com/javase/7/docs/technotes/tools/findingclasses.html How Classes are Found ...

  7. 032 Java再次总结

    1.大纲 多线程怎么用的,线程池,事务,传播机制与隔离级别,反射,泛型,数据库引擎的区别,数据库merge,窗口函数,fastJson,JVM调优,GC钩子,Linux的awk,shell,HashM ...

  8. 维护爬虫代理IP池--采集并验证

    任务分析 我们爬的免费代理来自于https://www.kuaidaili.com这个网站.用`requests`将ip地址与端口采集过来,将`IP`与`PORT`组合成`requests`需要的代理 ...

  9. Jmeter中实现base64加密

    Jmeter已不再提供内置base64加密函数,遇到base64加密需求,需要通过beanshell实现 直接上beanshell代码: import org.apache.commons.net.u ...

  10. Git ignore文件的用法

    这周为了往自己个人代码仓库里囤货,把在公司写的一些东西上传到了自己的GitHub代码仓库,手抖把测试用的日志也一并上传了.上传没多长时间就被运维找上门了,说commit里包含内网相关信息,要求删除.当 ...