用Fabric 2.0 Java SDK 进行合约交易

  • 张小雨
  • 更新于 2020-02-24 21:16
  • 阅读 6797

用Fabric 2.0 Java SDK 通过网关调用合约。

根据前面的步骤,可以前往我的主页阅读。 我们基于cli客户端完成了一系列操作,但是正常情况下,我们的工程一般会使用SDK去调用网络完成交易,因此从这一篇开始实践如何基于Java SDK调用Fabric 2.0网络完成交易。

1. Gateway

在进行实践前,有一个比较新的概念需要了解就是Gateway。 为了应对由于Fabric网络中的变化频繁所造成的后果,Fabric 2.0 原本的SDK之上添加了一层网关Gateway,用于减轻应用程序的负担。

具体拓扑结构如下: Java SDK 实践

MagnetoCorpDigiBank应用程序(发行和购买)将各自的网络交互委托给其网关。每个网关都了解网络通道拓扑,其中包括两个组织MagnetoCorp和DigiBank的多个peers和order,使应用程序专注于业务逻辑。节点间可以使用gossip协议在组织内部和组织之间相互共识交互。

2. 环境准备

系统工具 版本 备注
Window 10
Fabric 2.0 已部署好mychannel通道以及mycc合约到两个组织节点
Java 1.8
Maven 3.5.2

Fabric 网络结构

节点类型 节点名 所属组织 ip 服务端口
orderer orderer.example.com - 192.168.2.104 7050
peer peer0.org1.example.com org1 192.168.2.104 7051
peer peer1.org1.example.com org1 192.168.2.104 8051
peer peer0.org2.example.com org2 192.168.2.104 9051
peer peer1org2.example.com org2 192.168.2.104 10051
ca ca1.org1.example.com org1 192.168.2.104 7054
ca ca2.org1.example.com org2 192.168.2.104 8054

3. 创建基础工程

新建一个Maven工程,添加以下依赖:

<dependency>
  <groupId>org.hyperledger.fabric</groupId>
  <artifactId>fabric-gateway-java</artifactId>
  <version>2.0.0</version>
</dependency>

4. 创建connectionProfile

connectionProfile用于创建一个连接网络对象,如果有跑过first-network的朋友,相比记得一个ccp.sh的命令,生成的connection-org1.jsonconnection-org1.yaml这种文件,其实这些就是我们所需要的connectionProfile,可以直接使用。 当然也可以自行编写,自行编写请参考官方模板

4.1 配置文件结构说明

整体connectionProfile结构如下 Java SDK 实践

包含字段说明:

参数名 描述
name 自定义网络名称
version 自定义网络版本
client 客户端相关信息
channels 网络所包含的通道信息
organizations 网络中组织信息
orderers 排序节点信息
peer pee节点信息
certificateAuthorities ca节点信息

下面分别解释下各个配置:

4.1.1 客户端client

Java SDK 实践

4.1.2 通道channels

Java SDK 实践

其中节点对象有4中角色定义:

角色 描述
endorsingPeer 具有背书权限节点
chaincodeQuery 具有合约查询权限节点
ledgerQuery 具有账本查询权限节点
eventSource event hub节点

4.1.3 组织organizations

Java SDK 实践

其中admin私钥与admin签名证书支持路径与文件内容,路径使用参数path,对应值填写路径,文件内容使用参数pem,对应值填写私钥或者证书内容。

4.1.4 排序节点 orderers

Java SDK 实践

4.1.5 节点 peer

与排序节点类似,如果是tls必须配置tlsCACerts Java SDK 实践

4.1.6 certificateAuthorities

与排序节点类似,如果是tls必须配置tlsCACerts

Java SDK 实践

5. JAVA工程目录说明

新建的工程目录如下:

Java SDK 实践 - 工程目录

src/main/java : 存放demo主程序类
src/main/resources/connection.json : 上面新建好的connectionProfile
src/main/resources/crypto-config: 存放fabric网络证书内容(选择用到的就行)

6. 开发实践

6.1 创建网关账户

网关账户就是相当于连接Fabric网络的Fabric用户对象。

//使用org1中的user1初始化一个网关wallet账户用于连接网络
Wallet wallet = Wallets.newInMemoryWallet();
Path certificatePath = credentialPath.resolve(Paths.get("signcerts", "User1@org1.example.com-cert.pem"));
certificate = readX509Certificate(certificatePath);

Path privateKeyPath = credentialPath.resolve(Paths.get("keystore", "priv_sk"));
privateKey = getPrivateKey(privateKeyPath);
 //放进wallet
wallet.put("user",Identities.newX509Identity("Org1MSP",certificate,privateKey));

账户对象都可以存放到wallet里面,方便存取。 证书对象使用的是org1的user私钥,证书。

6.2 创建网关

通过connectionProfile以及网关账户创建网关:

//根据connection-org1.json 获取Fabric网络连接对象
GatewayImpl.Builder builder = (GatewayImpl.Builder) Gateway.createBuilder();

builder.identity(wallet, "user").networkConfig(NETWORK_CONFIG_PATH);

NETWORK_CONFIG_PATH : connectionProfile文件路径

6.3 连接网关

//连接网关
gateway = builder.connect();
//获取mychannel通道
Network network = gateway.getNetwork("mychannel");
//获取合约对象
Contract contract = network.getContract("mycc");

网关连接后 getNetwork:可以根据通道名称获取 Fabric 具体通道网络 network.getContract:可以根据合约名称获取部署到对应通道的智能合约对象

6.4 交易

基于上一部分的智能合约,有一个addTen的交易,结果是对象加10。

首先我们对合约对象a当前的值进行查询

//查询合约对象evaluateTransaction
byte[] queryAResultBefore = contract.evaluateTransaction("query","a");
System.out.println("交易前:"+new String(queryAResultBefore, StandardCharsets.UTF_8));

然后调用addTen 进行a+10

// 创建并且提交交易
byte[] invokeResult = contract.createTransaction("addTen")
        .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)))
        .submit("a");
System.out.println(new String(invokeResult, StandardCharsets.UTF_8));

此处setEndorsingPeers 设置背书节点,这里选择了通道中背书权限节点集合

交易完成后再次进行查询:

//查询合约对象evaluateTransaction
byte[] queryAResultAfter = contract.evaluateTransaction("query","a");
System.out.println("交易后:"+new String(queryAResultAfter, StandardCharsets.UTF_8));

最后控制台输出: Java SDK 实践

交易成功。

7. 总结

在调用交易方面,通过网关这种方式 简单了很多,后面应用程序进行设计的时候,可以将网关这个包单独封装,应用程序再进行调用,可以基于网关这层保障应用程序的业务稳定性。而再创建通道、加入通道、部署合约等操作应该还是SDK那套,后续章节也将继续实践。

转载自: https://me.csdn.net/qq_28540443

点赞 3
收藏 3
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

1 条评论

请先 登录 后评论
张小雨
张小雨
攻坚联盟链