当前位置:   article > 正文

java 封装postman_区块链技术入门(下)Java实践

@author jared jia

本文目录:

本文目录:

1、区块链技术常见架构 2、基于java的区块链系统开发 (1)开发环境 (2)区块链模型构建 (3)共识机制实现 (4)P2P网络开发 (5)系统测试 3、源代码与参考文献 (1)本文完整源代码地址 (2)参考书籍 (3)参考资料


1、区块链技术常见架构

8b4c5102754965f545661601494f1e16.png目前主流的区块链技术架构主要分为五层:

数据层是最底层的技术,主要实现了数据存储、账户信息、交易信息等模块,数据存储主要基于Merkle树,通过区块的方式和链式结构实现,而账户和交易基于数字签名、哈希函数和非对称加密技术等多种密码学算法和技术,来保证区块链中数据的安全性。 

网络层主要实现网络节点的连接和通讯,又称点对点技术,各个区块链节点通过网络进行通信。共识层是通过共识算法,让网络中的各个节点对全网所有的区块数据真实性正确性达成一致,防止出现拜占庭攻击、51攻击等区块链共识算法攻击。

激励层主要是实现区块链代币的发行和分配机制,是公有链的范畴,我们不做分析。应用层一般把区块链系统作为一个平台,在平台之上实现一些去中心化的应用程序或者智能合约,平台提供运行这些应用的虚拟机。

接下来我们基于Java语言来开发一套小型的区块链系统,来实现数据层、网络层、共识层的一些功能,用简单的代码来直观抽象的概念,以便加深对区块链技术基础理论的理解。

2、基于java的区块链系统开发

(1)开发环境
开发工具 VSCode
开发语言 Java
JDK版本 JDK1.8或者OpenJDK11
开发框架 SpringBoot2.2.1
工程管理 Maven3.6
测试工具 Postman
(2)区块链模型构建

区块是区块链系统的最小单元,第一步我们先实现最简单的区块结构,新建Block.java类,主要包含以下几个字段:Block.java

/**

* 区块结构

*

* @author Jared Jia

*

*/

public class Block implements Serializable {

private static final long serialVersionUID = 1L;

/**

* 区块索引号(区块高度)

*/

private int index;

/**

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

*/

private String hash;

/**

* 前一个区块的hash值

*/

private String previousHash;

/**

* 生成区块的时间戳

*/

private long timestamp;

/**

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

*/

private int nonce;

/**

* 当前区块存储的业务数据集合(例如转账交易信息、票据信息、合同信息等)

*/

private List<Transaction> transactions;

/*** 省略get set方法****/

}

第二步,创建一个链式结构对象,按照先后顺序来保存区块对象,从来形成一个有序的区块链表,考虑到线程安全问题,采用CopyOnWriteArrayList来实现,为了方便测试,暂且把区块链结构保存在本地缓存中,实际的区块链网络最终会实现持久层的功能,把区块链数据保存至数据库中:BlockCache.java

public class BlockCache {

/**

* 当前节点的区块链结构

*/

private List<Block> blockChain = new CopyOnWriteArrayList<Block>();

public List<Block> getBlockChain() {

return blockChain;

}

public void setBlockChain(List<Block> blockChain) {

this.blockChain = blockChain;

}

}

第三步,有了区块链结构后,需要新增向区块链中添加区块的方法,同时区块链中必须有个创世区块,我们直接通过硬编码实现:BlockService.java

/**

* 区块链核心服务

*

* @author Jared Jia

*

*/

@Service

public class BlockService {

@Autowired

BlockCache blockCache;

/**

* 创建创世区块

* @return

*/

public String createGenesisBlock() {

Block genesisBlock = new Block();

//设置创世区块高度为1

genesisBlock.setIndex(1);

genesisBlock.setTimestamp(System.currentTimeMillis());

genesisBlock.setNonce(1);

//封装业务数据

List<Transaction> tsaList = new ArrayList<Transaction>();

Transaction tsa = new Transaction();

tsa.setId("1");

tsa.setBusinessInfo("这是创世区块");

tsaList.add(tsa);

Transaction tsa2 = new Transaction();

tsa2.setId("2");

tsa2.setBusinessInfo("区块链高度为:1");

tsaList.add(tsa2);

genesisBlock.setTransactions(tsaList);

//设置创世区块的hash值

genesisBlock.setHash(calculateHash("",tsaList,1));

//添加到已打包保存的业务数据集合中

blockCache.getPackedTransactions().addAll(tsaList);

//添加到区块链中

blockCache.getBlockChain().add(genesisBlock);

return JSON.toJSONString(genesisBlock);

}

}

以上关键代码实现之后,我们就构建了一个非常简单的区块链模型,包含一个基本的区块模型和一个区块链模型,并且能够生成新的区块并添加到区块链中。

(3)共识机制实现

共识机制有很多种,各有各的优势与缺点,接下来我们就用java代码来模拟实现我们最为熟知的一种机制:工作量证明(Proof of Work),顾名思义就是对工作量的证明,计算的过程一般被形象地称为“挖矿”。

BTC网络PoW使用的Hashcash算法,大致逻辑如下:

  1. 获取某种公开可知的数据data(BTC网络中,指的是区块头);

  2. 添加一个计数器nonce,初始值设置为0;

  3. 计算data与nonce拼接字符串的哈希值;

  4. 检查上一步的哈希值是否满足某个条件,满足则停止计算,不满足则nonce加1,然后重复第3步和第4步,直到满足这个特定的条件为止。

接下来我们用Java代码实现这个算法,设定满足的特定条件为,Hash值前4位都是0,则计算成功。

第一步,我们新建一个共识机制服务类,添加一个“挖矿”方法,计算成功后,获取记账权,调用添加区块的方法,把区块添加到区块链中:PowService.java

/**

* 共识机制

* 采用POW即工作量证明实现共识

* @author Administrator

*

*/

@Service

public class PowService {

@Autowired

BlockCache blockCache;

@Autowired

BlockService blockService;

/**

* 通过“挖矿”进行工作量证明,实现节点间的共识

*

* @return

*/

public Block mine(){

// 封装业务数据集合,记录区块产生的节点信息,临时硬编码实现

List<Transaction> tsaList = new ArrayList<Transaction>();

Transaction tsa1 = new Transaction();

tsa1.setId("1");

tsa1.setBusinessInfo("这是IP为:"+CommonUtil.getLocalIp()+",端口号为:"+blockCache.getP2pport()+"的节点挖矿生成的区块");

tsaList.add(tsa1);

Transaction tsa2 = new Transaction();

tsa2.setId("2");

tsa2.setBusinessInfo("区块链高度为:"+(blockCache.getLatestBlock().getIndex()+1));

tsaList.add(tsa2);

// 定义每次哈希函数的结果

String newBlockHash = "";

int nonce = 0;

long start = System.currentTimeMillis();

System.out.println("开始挖矿");

while (true) {

// 计算新区块hash值

newBlockHash = blockService.calculateHash(blockCache.getLatestBlock().getHash(), tsaList, nonce);

// 校验hash值

if (blockService.isValidHash(newBlockHash)) {

System.out.println("挖矿完成,正确的hash值:" + newBlockHash);

System.out.println("挖矿耗费时间:" + (System.currentTimeMillis() - start) + "ms");

break;

}

System.out.println("第"+(nonce+1)+"次尝试计算的hash值:" + newBlockHash);

nonce++;

}

// 创建新的区块

Block block = blockService.createNewBlock(nonce, blockCache.getLatestBlock().getHash(), newBlockHash, tsaList);

return block;

}

}

第二步,编写测试共识机制服务的Controller类方法:BlockController.java

/**

* 工作量证明PoW

* 挖矿生成新的区块

*/

@GetMapping("/mine")

@ResponseBody

public String createNewBlock() {

powService.mine();

return JSON.toJSONString(blockCache.getBlockChain());

}

第三步,启动系统,进行测试。首先执行http://localhost:8080/create方法,生成创世区块。其次调用http://localhost:8080/mine方法进行工作量计算证明,生成新的区块,并添加到本地区块链中:0a3e4406b40ef1d608d0da42a82cc309.png

 我们来看一下,系统后台计算的过程,此次计算共花费1048ms计算出满足条件的Hash值,共计算4850次:2481a0c926d384c0295fb09ced79efe0.png

至此,我们实现了一个简单的工作量证明机制,并在当前区块链系统节点上运行,完成了正确结果的计算,生成了一个新的区块。

(4)P2P网络开发

前几步中区块链节点的维护都是基于单节点的运行,实际的区块链是有多个节点同时运行的分布式网络系统,所有节点同时计算抢夺记账权,共同维护一条完整的区块链。

接下来我们基于Java的WebSocket实现一个Peer-to-Peer网络,实现多个节点间的相互通信,通过本章节,我们将要实现以下功能:

- 创建一个基于java的p2p网络

- 运行多个节点,且多个节点通过p2p网络自动同步区块信息

- 一个节点挖矿生成新的区块后,自动广播给其他所有节点

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/417238
推荐阅读
相关标签
  

闽ICP备14008679号