Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用【补充】

本文涉及的产品
.cn 域名,1个 12个月
简介: 在 Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用 中我已经把官方sdk具体改良办法,即使用办法发出来了,所有的类及文件都是完整的,在文章的结尾也说明了用法主要都依赖于ChaincodeManager这个智能合约管理器,建议以单例的形式生成该对象。

在 Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用 中我已经把官方sdk具体改良办法,即使用办法发出来了,所有的类及文件都是完整的,在文章的结尾也说明了用法主要都依赖于ChaincodeManager这个智能合约管理器,建议以单例的形式生成该对象。

 

鉴于新入门的朋友在实际运用上可能需要更加简单明了的方案,这里就把最直接的方案给出,具体是写了一个FabricManager管理器,这个管理器将会接管整个java sdk与peer节点服务器及orderer排序服务器的通讯过程,包括event等时间的拦截等等,但是这里还是给一个demo级的,具体实际运用需要大家根据自己的实际场景进行简单的修改和完善。

 

在此之前,请现将 Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用 这篇文章中的类及结构按照自己的需要结合到自己的项目中,确保不会报错。

然后我们开始编写FabricManager管理器,这个管理器包含两个简单部分,第一部分是项目配置,第二部分是调用方法。

 

项目配置

节点服务器设置

 

 1     /**
 2      * 根据节点作用类型获取节点服务器配置
 3      * 
 4      * @param type
 5      *            服务器作用类型(1、执行;2、查询)
 6      * @return 节点服务器配置
 7      */
 8     private FabricConfig getConfig() {
 9         FabricConfig config = new FabricConfig();//创建配置
10         config.setOrderers(getOrderers());//设置排序服务器
11         config.setPeers(getPeers());//[]设置节点服务器对象
12         config.setChaincode(getChaincode("xxx","xxxcc", "github.com/hyperledger/fabric/chaincode/go/release/xxx", "1.0"));//设置智能合约对象
13         config.setCryptoConfigPath(getCryptoConfigPath());//设置crypto-config所在路径
14         return config;
15     }

 

 

 

创建配置

 

 

FabricConfig.java类创建配置,在构造器里设置crypto-config所在路径默认路径为src/main/resources/fabric/crypto-config/

1     public FabricConfig() {
2         // 默认channel-artifacts所在路径 /xxx/WEB-INF/classes/fabric/channel-artifacts/
3         channelArtifactsPath = getChannlePath() + "/channel-artifacts/";
4         // 默认crypto-config所在路径 /xxx/WEB-INF/classes/fabric/crypto-config/
5         cryptoConfigPath = getChannlePath() + "/crypto-config/";
6     }

如下图未知:

 

设置排序服务器

 

通过getOrderers()方法新建排序服务器由config.setOrderers()方法添加排序服务器到设置

1     private Orderers getOrderers() {
2         Orderers orderer = new Orderers();
3         orderer.setOrdererDomainName("example.com");//设置排序服务器所在的根域名
4         orderer.addOrderer("orderer0.example.com", "grpc://x.x.x.x");//新增排序服务器
5         orderer.addOrderer("orderer1.example.com", "grpc://x.x.x.xx");
6         orderer.addOrderer("orderer2.example.com", "grpc://x.x.x.xxx");
7         return orderer;
8     }

排序服务器可以添加一个或多个,排序服务器的域名排序服务器的访问地址提供文件填写

 

 

设置节点服务器对象

 

通过getPeers ()方法新建节点服务器由config. setPeers ()方法添加节点服务器到设置

1     private Peers Peers() {
2         Peers peers = new Peers();
3         peers.setOrgName("XXX");//设置组织名称
4         peers.setOrgMSPID("XXXMSP");//组织名称+MSP
5         peers.setOrgDomainName("xxx.example.com");//设置组织根域名
6         peers.addPeer("peer1.xxx.example.com", "peer1.xxx.example.com", "grpc://x.x.x.x:7051", "grpc://x.x.x.x:7053", "http://x.x.x.x:7054");//添加排序服务器
7         return peers;
8     }

组织名称、MSPID、组织根域名根据实际情况填写

 

设置智能合约对象

通过getChaincode ()方法获取智能合约对象由config. setChaincode ()方法添加智能合约对象到设置

 1     private Chaincode getChaincode(String channelName, String chaincodeName, String chaincodePath, String chaincodeVersion) {
 2         Chaincode chaincode = new Chaincode();
 3         chaincode.setChannelName(channelName);//设置当前将要访问的智能合约所属频道名称
 4         chaincode.setChaincodeName(chaincodeName);//设置智能合约名称
 5         chaincode.setChaincodePath(chaincodePath);//设置智能合约安装路径
 6         chaincode.setChaincodeVersion(chaincodeVersion);//设置智能合约版本号
 7         chaincode.setInvokeWatiTime(100000);
 8         chaincode.setDeployWatiTime(120000);
 9         return chaincode;
10     }

 

项目配置到这里基本就完成了,接下来是调用过程。

在述说调用过程之前,我把完整的代码粘贴出来,当然还是demo级的,但已经可以使用于生产了,如下:

  1 package cn.xx.xxx.util;
  2 
  3 import java.io.File;
  4 import java.io.IOException;
  5 import java.security.NoSuchAlgorithmException;
  6 import java.security.NoSuchProviderException;
  7 import java.security.spec.InvalidKeySpecException;
  8 
  9 import org.hyperledger.fabric.sdk.exception.CryptoException;
 10 import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
 11 import org.hyperledger.fabric.sdk.exception.TransactionException;
 12 
 13 import cn.aberic.fabric.ChaincodeManager;
 14 import cn.aberic.fabric.FabricConfig;
 15 import cn.aberic.fabric.bean.Chaincode;
 16 import cn.aberic.fabric.bean.Orderers;
 17 import cn.aberic.fabric.bean.Peers;
 18 import lombok.extern.slf4j.Slf4j;
 19 
 20 @Slf4j
 21 public class FabricManager {
 22 
 23     private ChaincodeManager manager;
 24 
 25     private static FabricManager instance = null;
 26 
 27     public static FabricManager obtain()
 28             throws CryptoException, InvalidArgumentException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, TransactionException, IOException {
 29         if (null == instance) {
 30             synchronized (FabricManager2.class) {
 31                 if (null == instance) {
 32                     instance = new FabricManager();
 33                 }
 34             }
 35         }
 36         return instance;
 37     }
 38 
 39     private FabricManager()
 40             throws CryptoException, InvalidArgumentException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, TransactionException, IOException {
 41         manager = new ChaincodeManager(getConfig());
 42     }
 43 
 44     /**
 45      * 获取节点服务器管理器
 46      * 
 47      * @return 节点服务器管理器
 48      */
 49     public ChaincodeManager getManager() {
 50         return manager;
 51     }
 52 
 53     /**
 54      * 根据节点作用类型获取节点服务器配置
 55      * 
 56      * @param type
 57      *            服务器作用类型(1、执行;2、查询)
 58      * @return 节点服务器配置
 59      */
 60     private FabricConfig getConfig() {
 61         FabricConfig config = new FabricConfig();
 62         config.setOrderers(getOrderers());
 63         config.setPeers(getPeers());
 64         config.setChaincode(getChaincode("xxx", "xxxcc", "github.com/hyperledger/fabric/chaincode/go/release/xxx", "1.0"));
 65         config.setChannelArtifactsPath(getChannleArtifactsPath());
 66         config.setCryptoConfigPath(getCryptoConfigPath());
 67         return config;
 68     }
 69 
 70     private Orderers getOrderers() {
 71         Orderers orderer = new Orderers();
 72         orderer.setOrdererDomainName("example.com");
 73         orderer.addOrderer("orderer1.example.com", "grpc://x.x.x.x:7050");
 74         orderer.addOrderer("orderer0.example.com", "grpc://x.x.x.xx:7050");
 75         orderer.addOrderer("orderer2.example.com", "grpc://x.x.x.xxx:7050");
 76         return orderer;
 77     }
 78 
 79     /**
 80      * 获取节点服务器集
 81      * 
 82      * @return 节点服务器集
 83      */
 84     private Peers getPeers() {
 85         Peers peers = new Peers();
 86         peers.setOrgName("XXX");
 87         peers.setOrgMSPID("XXXMSP");
 88         peers.setOrgDomainName("xxx.example.com");
 89         peers.addPeer("peer1.xxx.example.com", "peer1.xxx.example.com", "grpc://x.x.x.x:7051", "grpc://x.x.x.x:7053", "http://x.x.x.x:7054");
 90         return peers;
 91     }
 92 
 93     /**
 94      * 获取智能合约
 95      * 
 96      * @param channelName
 97      *            频道名称
 98      * @param chaincodeName
 99      *            智能合约名称
100      * @param chaincodePath
101      *            智能合约路径
102      * @param chaincodeVersion
103      *            智能合约版本
104      * @return 智能合约
105      */
106     private Chaincode getChaincode(String channelName, String chaincodeName, String chaincodePath, String chaincodeVersion) {
107         Chaincode chaincode = new Chaincode();
108         chaincode.setChannelName(channelName);
109         chaincode.setChaincodeName(chaincodeName);
110         chaincode.setChaincodePath(chaincodePath);
111         chaincode.setChaincodeVersion(chaincodeVersion);
112         chaincode.setInvokeWatiTime(100000);
113         chaincode.setDeployWatiTime(120000);
114         return chaincode;
115     }
116 
117     /**
118      * 获取channel-artifacts配置路径
119      * 
120      * @return /WEB-INF/classes/fabric/channel-artifacts/
121      */
122     private String getChannleArtifactsPath() {
123         String directorys = FabricManager.class.getClassLoader().getResource("fabric").getFile();
124         log.debug("directorys = " + directorys);
125         File directory = new File(directorys);
126         log.debug("directory = " + directory.getPath());
127 
128         return directory.getPath() + "/channel-artifacts/";
129     }
130 
131     /**
132      * 获取crypto-config配置路径
133      * 
134      * @return /WEB-INF/classes/fabric/crypto-config/
135      */
136     private String getCryptoConfigPath() {
137         String directorys = FabricManager.class.getClassLoader().getResource("fabric").getFile();
138         log.debug("directorys = " + directorys);
139         File directory = new File(directorys);
140         log.debug("directory = " + directory.getPath());
141 
142         return directory.getPath() + "/crypto-config/";
143     }
144 
145 }

 

 

调用过程

 

调用过程其实就是对FabricManager管理器的具体应用,一般都在impl中进行,具体可执行代码如下:

1 ChaincodeManager manager = FabricManager.obtain().getManager();
2 
3 manager.invoke(fcn, arguments);
4 
5 manager.query(fcn, arguments);

具体返回结果的运用需要各位智能合约编写返回结果的解析来支持,这里需要结合业务来实操,无法说的详尽。

需要注意区块链的事务处理,另外还有invoke和query的区别。

 

至此整个java sdk的改良使用和调用方法应该就完成了,如果还有什么问题,可以留言讨论。

目录
相关文章
|
25天前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
|
1月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
27天前
|
SQL Java 数据库连接
从理论到实践:Hibernate与JPA在Java项目中的实际应用
本文介绍了Java持久层框架Hibernate和JPA的基本概念及其在具体项目中的应用。通过一个在线书店系统的实例,展示了如何使用@Entity注解定义实体类、通过Spring Data JPA定义仓库接口、在服务层调用方法进行数据库操作,以及使用JPQL编写自定义查询和管理事务。这些技术不仅简化了数据库操作,还显著提升了开发效率。
36 3
|
1月前
|
SQL 监控 Java
技术前沿:Java连接池技术的最新发展与应用
本文探讨了Java连接池技术的最新发展与应用,包括高性能与低延迟、智能化管理和监控、扩展性与兼容性等方面。同时,结合最佳实践,介绍了如何选择合适的连接池库、合理配置参数、使用监控工具及优化数据库操作,为开发者提供了一份详尽的技术指南。
32 7
|
1月前
|
SQL Java 数据库连接
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率。本文介绍了连接池的工作原理、优势及实现方法,并提供了HikariCP的示例代码。
47 3
|
1月前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
58 2
|
1月前
|
缓存 Java 数据库连接
Hibernate:Java持久层框架的高效应用
通过上述步骤,可以在Java项目中高效应用Hibernate框架,实现对关系数据库的透明持久化管理。Hibernate提供的强大功能和灵活配置,使得开发者能够专注于业务逻辑的实现,而不必过多关注底层数据库操作。
18 1
|
2月前
|
移动开发 前端开发 JavaScript
java家政系统成品源码的关键特点和技术应用
家政系统成品源码是已开发完成的家政服务管理软件,支持用户注册、登录、管理个人资料,家政人员信息管理,服务项目分类,订单与预约管理,支付集成,评价与反馈,地图定位等功能。适用于各种规模的家政服务公司,采用uniapp、SpringBoot、MySQL等技术栈,确保高效管理和优质用户体验。
|
2月前
|
SQL 监控 Java
Java性能优化:提升应用效率与响应速度的全面指南
【10月更文挑战第21】Java性能优化:提升应用效率与响应速度的全面指南
|
1月前
|
Java 开发者
Java中的多线程基础与应用
【10月更文挑战第24天】在Java的世界中,多线程是提高效率和实现并发处理的关键。本文将深入浅出地介绍如何在Java中创建和管理多线程,以及如何通过同步机制确保数据的安全性。我们将一起探索线程生命周期的奥秘,并通过实例学习如何优化多线程的性能。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往高效编程的大门。
20 0

热门文章

最新文章