主页 > imtoken官方网址 > 使用Java开发自己的区块链产品:联盟链!

使用Java开发自己的区块链产品:联盟链!

imtoken官方网址 2023-07-10 05:19:09

使用Java开发自己的区块链产品:联盟链!

背景

公司想开发区块链,本来想着用以太坊开发合约或者用第三方平台来做,后来发现不符合业务需求。 原因很简单。 以太坊、超级账本等平台都是共享账本,有代币、挖矿等模块。 我们需要的是几家公司结盟,共同见证和记录一些不可篡改的交互信息。 例如A公司向B公司发送xxx请求,B公司响应。 其实需要的是分布式数据库,性能更好。 它不能像比特币那样在 10 分钟内生成一个块。 我们更想要的是数据库的性能和区块链的一些特性。

经过

该项目于2018年3月上旬开始研发,1月发布第一个版本。 主要做了存储模块、加密模块、网络通信、PBFT共识算法、公钥私钥、区块内容分析和存储等。初步具备了区块链的基本特性,但是默克尔树、智能合约等细节还没有到位。

所以,希望各位高手不吝赐教,集思广益,提出意见或解决方案,做一个适合更多区块链场景的区块链平台项目,而不仅仅是账本和各种傻逼代币。

理想的区块链平台:

比特币属于联盟链吗_区块链和比特币的关系_比特币交易链区块拥堵

项目指导

主要包括存储模块、网络模块、PBFT共识算法、加密模块、区块解析存储等。

区块链和比特币的关系_比特币交易链区块拥堵_比特币属于联盟链吗

项目属于“链”,不属于“币”。 不涉及虚拟货币和挖矿。

存储模块

块存储类似 Sql 的语句。 联盟预先设置好满足业务场景需要的数据库表结构,然后设置各节点对表的操作权限(ADD、UPDATE、DELETE)。 以后每个节点都可以根据自己允许的权限执行Sql语句。 写好,打包成Block,然后在全网广播,等待全网验证签名、权限等信息的合法性。 如果区块合法,则进入PBFT共识算法机制,各节点开始按照PrePrepare、Prepare、Commit等状态依次执行,直到2f+1次提交,开始生成新区块本地。 新区块生成后,各节点解析区块内容并入库。

场景更广泛,可以设置不同的表结构或多个表来完成各类信息的存储。 比如商品溯源,从生产厂家、运输工具、经销商、消费者等,每个环节都可以对某一商品进行ADD信息操作。

存储使用key-value数据库rocksDB。 懂比特币的都知道,比特币用的是levelDB,都是类似的东西。 在yml中修改db.levelDB为true,db.RocksDB为false,可以动态切换使用哪个数据库。

结构类似于SQL语句,如ADD(增删改查)tableName(表名)ID(主键)JSON(记录的json)。 这里设置了回滚的逻辑,即当你进行ADD操作时,会同时存储一条Delete语句,以备以后可能的回滚操作。

网络模块

网络层使用节点之间的长期连接,断开和重连,然后维护心跳包。 网络框架使用的是t-io,也是oschina知名的开源项目。 t-io采用AIO的方式,在大量长连接的情况下性能优异,占用资源极少,并且具有分组功能,特别适合多联盟链的SaaS平台。 并且包含心跳包、断线重连、重试等优秀功能。

区块链和比特币的关系_比特币属于联盟链吗_比特币交易链区块拥堵

在项目中,每个节点既是服务端又是客户端。 作为服务器,它连接着其他N-1个节点,作为客户端,它连接着其他N-1个节点的服务器。 同一个联盟,设置一个Group,每次发消息直接调用sendGroup方法。

但需要注意的是,由于本项目采用pbft共识算法比特币属于联盟链吗,在达成共识的过程中,会出现N次方的网络通信。 当节点数量较多时,比如达到 100 个,每次共识都会给网络带来沉重的负担。 这是算法本身的局限性。

共识模块 PBFT

分布式共识算法是分布式系统的核心。 常见的有Paxos、pbft、bft、raft、pow等,区块链中常见的有POW、POS、DPOS、pbft等。

比特币采用 POW 工作量证明,需要大量资源进行哈希计算(挖矿),产生区块的权利由矿工完成。 其他人可能会使用选举投票来决定谁将生成区块。 共同特点是只有特定的节点才能产生区块,然后广播给其他节点。

区块链分为三种类型:

由于私有链是一个封闭的生态存储系统,使用类Paxos共识算法可以达到最优性能(超过半数同意); 联盟链具有半公开、半开放的特点,因此拜占庭容错是合适的选择之一,例如IBM Hyperledger项目; 对于公链来说,这种共识算法的要求已经超出了普通分布式系统建设的范围,加上交易的特点,因此需要引入更多的安全考虑。 所以比特币的POW是一个非常好的选择。

我们这里可以选择raft和pbft,分别是私有链和联盟链。 在项目中,我使用了修改后的pbft共识算法。

比特币属于联盟链吗_区块链和比特币的关系_比特币交易链区块拥堵

首先简单了解一下pbft:

从全网节点中选出一个主节点(Leader),新的区块由主节点产生。 每个节点将客户端发送的交易广播到全网,主节点将从网络中收集到的多个需要放入新区块的交易排序存储成一个列表,并将该列表广播到全网。 每个节点收到交易列表后,根据排序模拟执行这些交易。 所有交易执行完毕后,根据交易结果计算出新区块的哈希摘要,并向全网广播。 如果一个节点收到2f(f是可容忍的拜占庭节点数)其他节点发送的总结等于自己,它向全网广播commit消息。 如果一个节点收到 2f+1(包括它自己)的提交消息,它就可以向本地区块链和状态数据库提交新的区块。 当客户端收到f+1次成功返回(即使有f次失败和f次恶意错误返回,f+1次正确的占多数),就可以认为写请求成功了。

可以看出,传统的pbft需要先选举一个leader,然后leader收集交易,打包,然后广播出去。 然后每个节点开始验证,投票,累加新区块的commit数,最后落地。

而这里我对pbft做了修改,是一个联盟,每个节点都是平等的,性能要高。 所以我不希望每个节点产生一条指令,发给其他节点,然后大家选出一个节点在网络上收集指令组合,然后产生一个区块。 过于复杂,存在leader节点失效的隐患。

我对pbft的修改是不需要选leader,任何节点都可以出块,然后广播到全网。 其他节点收到出块请求后,进入Pre-Prepare状态,对格式、哈希、签名、表权限进行验证,验证通过后进入Prepare状态,向全网广播。 当每个节点自身积累的Prepare数大于2f+1时,进入commit状态,并向全网广播该状态。 当每个节点累积的Commit数大于2f+1时,认为达成共识,将Block加入区块链,然后执行Block中的sql语句。

显然,与有领导时相比,缺少了秩序的概念。 当有领导者时,区块的顺序可以得到保证。 当需要并发出块时,leader可以按顺序广播。 比如大家已经到了block number=5,然后需要再生成2个。 当有leader时,会按照6和7的顺序产生,当没有leader时,可能会出现多个节点同时产生6的情况。 为了避免fork,我做了一些处理,具体实现逻辑可以看我的代码。

区块信息查询

每个节点通过执行相同的sql实现一个同步的sqlite数据库(或其他关系型数据库如mysql)。 未来数据的查询直接查询sqlite,性能比传统区块链项目更高。

比特币交易链区块拥堵_比特币属于联盟链吗_区块链和比特币的关系

由于每个节点都可以出块,所以在高并发下可能会出现块不一致的情况。 如果链因为某种原因分叉,也提供回滚机制,可以回滚sql。 原理也很简单。 当你ADD一条数据的时候,我会在block中同时记录两条指令,一条是ADD,一条是DELETE,用于回滚。 同理,UPDATE时也会保存原来的旧数据。 block内的sql落地,比如依次执行1-10条指令,回滚时从10-1开始执行回滚指令。

每个节点都会记录自己已经同步的区块的值,以便随时将SQL存入数据库。

区块链信息的查询很简单,直接做数据库查询就可以了。 与需要检索整个区块链索引树的比特币相比,速度和便利性有很大的不同。

简单说明

解压我发给大家的md_blockchain_manager工程源码,然后在工程中导入sql数据库文件,修改application.yml数据库配置,最后启动manager工程。

然后修改md_blockchain中application.yml中的name,appid对应manager项目数据库中的某个值,作为节点。 如果有多个节点,某个节点对应数据库,填写每个节点的ip。 managerUrl是manager项目的url,让项目可以访问manager项目。

md_blockchian项目启动时,在ClientStarter类中可以看到。 当它启动时比特币属于联盟链吗,它会从管理器项目中拉取所有节点的数据并连接它们。 如果自身的ip和appId不在manager数据库中,则无法启动。

访问 localhost:8080/block?content=1 即可生成区块。 正常使用时至少要启动4个节点,否则无法达成共识,而PBFT需要2f+1个节点同意才能出块。 为了测试方便,可以直接将pbftSize的返回值修改为0,这样就可以玩单节点了。 如果有多个节点,在生成Block之后,你会发现其他节点也会自动同步自己新生成的Block。 目前代码中默认设置了一个表格message,里面只有一个字段内容,相当于一个简单的区块链记事本。 当有4个节点时,你可以同时访问其中的几个来生成块来测试它们是否会分叉。 也可以关掉其中一个,看看其他三个能不能达成共识(拜占庭最多允许f个节点故障,4个节点允许1个故障),恢复故障的,看看其他正常节点的block能不能达成同步。 执行各种测试。

区块链和比特币的关系_比特币属于联盟链吗_比特币交易链区块拥堵

通过localhost:8080/block/sqlite可以查看到sqlite中存储的数据,这是在Block中执行sql语句后的结果。

我把项目部署到docker上,一共启动了4个节点,如图:

比特币交易链区块拥堵_区块链和比特币的关系_比特币属于联盟链吗

比特币交易链区块拥堵_比特币属于联盟链吗_区块链和比特币的关系

区块链和比特币的关系_比特币属于联盟链吗_比特币交易链区块拥堵

比特币交易链区块拥堵_比特币属于联盟链吗_区块链和比特币的关系

比特币属于联盟链吗_区块链和比特币的关系_比特币交易链区块拥堵

另外,在高并发的情况下,每个节点同时出块,系统处理共识,做一些测试保证区块链不分叉。

生成块的接口是为测试而编写的。 正常的流程是调用指令接口,先产生满足自己需求的指令,然后组合多条指令调用BlockController中生成块的接口。

这是我第一次发表基于Java的区块链项目的文章。 不知你喜不喜欢? 喜欢的话可以点击观看哦。 如果你想研究源码,加我WX:codedq。 另外,喜欢pbft共识算法、Paxos等算法的小伙伴也可以通过项目实战深入挖掘算法。

比特币交易链区块拥堵_区块链和比特币的关系_比特币属于联盟链吗