在 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,查询)
*
* @param type
* @return 节点服务器配置
创建配置
*/
private FabricConfig getConfig() {
FabricConfig config = new FabricConfig(); //创建配置
config.setOrderers(getOrderers()); //设置排序服务器
config.setPeers(getPeers()); //[]设置节点服务器对象
config.setChaincode(getChaincode("xxx", "xxxcc", "github.com/hyperledger/fabric/chaincode/go/release/xxx", "1.0")); //设置智能合约对象
config.setCryptoConfigPath(getCryptoConfigPath()); //设置crypto-config所在路径
return config;
}
FabricConfig.java 类创建配置,在构造器里设置 crypto-config 所在路径,默认路径为 src/main/resources/fabric/crypto-config/
如下图未知:
public FabricConfig() {
// 默认channel-artifacts所在路径 /xxx/web-INF/classes/fabric/channel-artifacts/
channelArtifactsPath = getChannlePath() + "/channel-artifacts/";
// 默认crypto-config所在路径 /xxx/WEB-INF/classes/fabric/crypto-config/
cryptoConfigPath = getChannlePath() + "/crypto-config/";
}
设置排序服务器
通过 getOrderers() 方法新建排序
服务器
,
在
由 config.setOrderers()
方法添加
排序服务器到设置
排序
.
private Orderers getOrderers() {
Orderers orderer = new Orderers();
orderer.setOrdererDomainName("example.com"); //设置排序服务器所在的根域名
orderer.addOrderer("orderer0.example.com", "grpc://x.x.x.x"); //新增排序服务器
orderer.addOrderer("orderer1.example.com", "grpc://x.x.x.xx");
orderer.addOrderer("orderer2.example.com", "grpc://x.x.x.xxx");
return orderer;
}
服务器可以添加一个或多个,排序服务器的域名
和
排序服务器的访问地址
按
提供
的
文件
填写
.
设置节点服务器对象
通过 getPeers () 方法新建节点
服务器
,
在
由 config. setPeers ()
方法添加节点
服务器到设置
组织名称,MSPID,组织根域名根据实际情况填写.
.
private Peers Peers() {
Peers peers = new Peers();
peers.setOrgName("XXX"); //设置组织名称
peers.setOrgMSPID("XXXMSP"); //组织名称+MSP
peers.setOrgDomainName("xxx.example.com"); //设置组织根域名
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"); //添加排序服务器
return peers;
}
设置智能合约对象
通过 getChaincode () 方法获取
智能合约对象
,
在
由 config. setChaincode ()
方法添加
智能合约对象到设置
项目配置到这里基本就完成了,接下来是调用过程.
.
private Chaincode getChaincode(String channelName, String chaincodeName, String chaincodePath, String chaincodeVersion) {
Chaincode chaincode = new Chaincode();
chaincode.setChannelName(channelName); //设置当前将要访问的智能合约所属频道名称
chaincode.setChaincodeName(chaincodeName); //设置智能合约名称
chaincode.setChaincodePath(chaincodePath); //设置智能合约安装路径
chaincode.setChaincodeVersion(chaincodeVersion); //设置智能合约版本号
chaincode.setInvokeWatiTime(100000);
chaincode.setDeployWatiTime(120000);
return chaincode;
}
在述说调用过程之前,我把完整的代码粘贴出来,当然还是 demo 级的,但已经可以使用于生产了,如下:
* 获取节点服务器管理器
package cn.xx.xxx.util;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.InvalidKeySpecException;
import org.hyperledger.fabric.sdk.exception.CryptoException;
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
import org.hyperledger.fabric.sdk.exception.TransactionException;
import cn.aberic.fabric.ChaincodeManager;
import cn.aberic.fabric.FabricConfig;
import cn.aberic.fabric.bean.Chaincode;
import cn.aberic.fabric.bean.Orderers;
import cn.aberic.fabric.bean.Peers;
import lombok.extern.slf4j.Slf4j;@Slf4j public class FabricManager {
private ChaincodeManager manager;
private static FabricManager instance = null;
public static FabricManager obtain() throws CryptoException,
InvalidArgumentException,
NoSuchAlgorithmException,
NoSuchProviderException,
InvalidKeySpecException,
TransactionException,
IOException {
if (null == instance) {
synchronized(FabricManager2.class) {
if (null == instance) {
instance = new FabricManager();
}
}
}
return instance;
}
private FabricManager() throws CryptoException,
InvalidArgumentException,
NoSuchAlgorithmException,
NoSuchProviderException,
InvalidKeySpecException,
TransactionException,
IOException {
manager = new ChaincodeManager(getConfig());
}
/***/
*
* @return 节点服务器管理器
* 根据节点作用类型获取节点服务器配置
* /
public ChaincodeManager getManager() {
return manager;
}
/ * *
* 服务器作用类型(1,执行;2,查询)
*
* @param type
* @return 节点服务器配置
* 获取节点服务器集
* /
private FabricConfig getConfig() {
FabricConfig config = new FabricConfig();
config.setOrderers(getOrderers());
config.setPeers(getPeers());
config.setChaincode(getChaincode("xxx", "xxxcc", "github.com/hyperledger / fabric / chaincode / go / release / xxx ", "1.0 "));
config.setChannelArtifactsPath(getChannleArtifactsPath());
config.setCryptoConfigPath(getCryptoConfigPath());
return config;
}
private Orderers getOrderers() {
Orderers orderer = new Orderers();
orderer.setOrdererDomainName("example.com ");
orderer.addOrderer("orderer1.example.com ", "grpc: //x.x.x.x:7050");
orderer.addOrderer("orderer0.example.com", "grpc://x.x.x.xx:7050");
orderer.addOrderer("orderer2.example.com", "grpc://x.x.x.xxx:7050");
return orderer;
}
/***/
*
* @return 节点服务器集
* 获取智能合约
* /
private Peers getPeers() {
Peers peers = new Peers();
peers.setOrgName("XXX");
peers.setOrgMSPID("XXXMSP");
peers.setOrgDomainName("xxx.example.com");
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");
return peers;
}
/***/
* 频道名称
*
* @param channelName
* @param chaincodeName
* 智能合约名称
* @param chaincodePath
* 智能合约路径
* @param chaincodeVersion
* 智能合约版本
* @return 智能合约
* 获取channel-artifacts配置路径
* /
private Chaincode getChaincode(String channelName, String chaincodeName, String chaincodePath, String chaincodeVersion) {
Chaincode chaincode = new Chaincode();
chaincode.setChannelName(channelName);
chaincode.setChaincodeName(chaincodeName);
chaincode.setChaincodePath(chaincodePath);
chaincode.setChaincodeVersion(chaincodeVersion);
chaincode.setInvokeWatiTime(100000);
chaincode.setDeployWatiTime(120000);
return chaincode;
}
/ * *
* 获取crypto-config配置路径
*
* @return /WEB-INF/classes/fabric/channel-artifacts/
*/
private String getChannleArtifactsPath() {
String directorys = FabricManager.class.getClassLoader().getResource("fabric").getFile();
log.debug("directorys = " + directorys);
File directory = new File(directorys);
log.debug("directory = " + directory.getPath());
return directory.getPath() + "/channel-artifacts/";
}
/**
调用过程
*
* @return /WEB-INF/classes/fabric/crypto-config/
*/
private String getCryptoConfigPath() {
String directorys = FabricManager.class.getClassLoader().getResource("fabric").getFile();
log.debug("directorys = " + directorys);
File directory = new File(directorys);
log.debug("directory = " + directory.getPath());
return directory.getPath() + "/crypto-config/";
}
}
调用过程其实就是对 FabricManager 管理器的具体应用,一般都在 impl 中进行,具体可执行代码如下:
具体返回结果的运用需要各位智能合约编写返回结果的解析来支持,这里需要结合业务来实操,无法说的详尽.
ChaincodeManager manager = FabricManager.obtain().getManager();
manager.invoke(fcn, arguments);
manager.query(fcn, arguments);
需要注意区块链的事务处理,另外还有 invoke 和 query 的区别.
至此整个 java sdk 的改良使用和调用方法应该就完成了,如果还有什么问题,可以留言讨论.
来源: https://www.cnblogs.com/aberic/p/8269244.html