前一段时间参与一个区块链项目,需要在搭建的前台通过JAVA程序调用由Go语言编写的智能合约完成设计的业务逻辑,Fabric官方提供了fabric-java-sdk可以用于在java环境下对Fabric区块链进行二次开发。经过一番网络搜索后,发现在博客园上有一位大牛——Aberic(https://www.cnblogs.com/aberic/)在他的博客里编写了基于fabric-java-sdk的JAVA端调用程序,对我的帮助很大,在这里先对这位大牛表示敬意。
本文是对我在学习Aberic的程序过程中做的笔记的整理,记录一下这次的学习过程,本着开源的精神(因为大牛已经把代码给放出来了),我在这里就不再重复放代码,只是增加一些我个人的学习笔记,意图是做一个阶段性的整理。
1.在自己编写的main方法中调用FabricManager.obtain()获得一个FabricManager类实例,再调用getConfig()方法加载配置信息
2.
2.1 在getConfig()方法中加载配置文件(如果区块链相关的配置信息写在配置文件中),初始化数据库连接信息(Fabric中用的数据库是couchDB,一种非关系型的文档结构数据库,存储key-value形式的数据),再加载证书和通道相关文件的路径。
2.2 通过getOrders()方法加载排序节点相关配置信息,设置根域名和排序服务器对象(设置orderer节点名称和所在地址)
2.3 通过getPeers()方法加载节点服务相关配置信息,设置组织名称,组织MSPID,根域名,节点服务器对象(包含节点名称,节点事件监听名称,节点访问地址,节点事件监听访问地址,CA访问地址)
2.4 通过getChaincode()方法加载chaincode相关信息,需要定义Chaincode对象(包含归属的channel名称,chaincode名称,安装路径,版本号),设置执行智能合约操作等待时间,执行智能合约实例等待时间
3.调用ChaincodeManager构造方法生成ChaincodeManager实例对象
3.1 用第2步生成的FabricConfig对象来构造ChaincodeManager实例对象
3.2 创建HFClient的实例对象,这一步我理解的是生成一个Hyperledger Fabric的客户端(这里就是调用的fabric-java-sdk生成实例)
3.3 获取FaricOrg组织信息,先从java.io.tempdir中找HFCSampletest.properties(这个文件我并没有去创建,但后来能够找到,应该是在最初时自动创建的),根据文件创建FabricStore对象;再调用FabricOrg的构造器根据从FaricConfig对象中获取的信息和FabricStore信息实例化FabricOrg对象
3.3.1 将获得的Peers相关信息对FabricOrg进行赋值
for (int i = 0; i < peers.get().size(); i++) {
addPeerLocation(peers.get().get(i).getPeerName(), peers.get().get(i).getPeerLocation());
addEventHubLocation(peers.get().get(i).getPeerEventHubName(), peers.get().get(i).getPeerEventHubLocation());
setCALocation(peers.get().get(i).getCaLocation());
}
3.3.2 将获得的Orderers相关信息对FabricOrg进行赋值
for (int i = 0; i < orderers.get().size(); i++) {
addOrdererLocation(orderers.get().get(i).getOrdererName(), orderers.get().get(i).getOrdererLocation());
}
3.3.3 为FabricOrg设置根域名信息
setDomainName(peers.getOrgDomainName());
3.3.4 根据Peers节点信息设置组织管理员
setAdmin(fabricStore.getMember("admin", peers.getOrgName()));
3.3.5 调用FabricStore的getMemeber()获取指定名称用户,如果得到的对象为空,则调用FabricUser创建一个name为admin,组织名为org的默认组织管理员信息数据(这是默认情况)
3.3.6 到cryptoConfigPath下获取证书和私钥文件
3.3.7 调用setPeerAdmin()方法设置组织单节点管理员(一个特殊用户,可以创建通道,连接对等Peer节点,并安装链码)
setPeerAdmin(fabricStore.getMember(peers.getOrgName() + "Admin", peers.getOrgName(), peers.getOrgMSPID(), findFileSk(skFile), certificateFile));
3.4通过getChannel()方法获取通道信息
3.4.1 为HFClient客户端设定节点管理员权限
client.setUserContext(fabricOrg.getPeerAdmin());
3.4.2 设置channel对象,调用HFClient.newChannel(),在方法中维护了一个Map,保存Channel名称和channel实例
3.4.3 通过循环获取通道中各个Peers节点的证书,定义peerProperties对象:设置pemfile属性(证书文件路径),hostnameOverride(Peers节点的根域名),sslProvider(ssl提供者:openSSL),negotiationType(Peers节点之间的通信类型:TLS),设定grpc.ManagedChannelBuilderOption.maxInboundMessageSize为9000000(这个地方也不知道代表什么意思,我理解的是grpc协议中,每次可以传递的最大消息大小)
3.4.4 向channel中添加Peer节点,判断当前Peer节点是否为EventHub(如果不是,则调用HFClient的newEventHub()方法创建一个事件监听节点,需要的信息都在Peers节点对象中)
3.4.5 通过循环获取通道中的Orderers节点的证书,定义ordererProperties对象:设置pemfile属性(证书文件路径),hostnameOverride(Peers节点的根域名),sslProvider(ssl提供者:openSSL),negotiationType(Peers节点之间的通信类型:TLS),设定grpc.ManagedChannelBuilderOption.maxInboundMessageSize为9000000,设定ordererWaitTimeMilliSecs为300000(我理解这个应该是orderer节点的等待时间)
3.4.6 向channel中添加orderer节点
3.4.7 调用channel.initialize()方法完成channel初始化并启动通道,同时EventHub连接完成
3.4.8 判断当前建立的FabricConfig是否为isRegisterEvent(),默认为false(这里也没有很明白究竟是什么意思)
3.5 通过getChaincodeID()方法获取ChainCodeID对象,设置了chaincode的名称、版本号、安装路径
3.6 设置客户端的节点管理员权限
4.通过获得的chaincodeManager对象,调用invoke()方法执行指定的智能合约,并为其传递参数
5.调用query()方法执行智能合约中的查询