Hyperledger Fabric 2.x Java区块链应用

java

一、说明

在上一篇文章中 《Hyperledger Fabric 2.x 自定义智能合约》 分享了智能合约的安装并使用 cli 客户端进行合约的调用;本文将使用 Java 代码基于 fabric-gateway-java 进行区块链网络的访问与交易,并集成 SpringBoot 框架。

Fabric Gateway SDK 实现Fabric的编程模型,提供了一系列简单的API给应用程序与Fabric区块链网络进行交互;

网络拓扑图:

应用程序将各自的网络交互委托给其网关,每个网关都了解网络信道拓扑,包括组织的多个Peer节点和排序节点,使应用程序专注于业务逻辑;Peer节点可以使用gossip协议在组织内部和组织之间相互通信。

二、Mavn依赖

添加网关sdk的依赖:

<dependency>

<groupId>org.hyperledger.fabric</groupId>

<artifactId>fabric-gateway-java</artifactId>

<version>2.2.3</version>

</dependency>

三、准备配置文件

工程的目录结构如下图所示:

3.1. 准备网络证书

创建目录 crypto-configordererpeer 节点的证书文件复制进来。

证书文件从 fabric-samplestest-network 目录中复制 ordererOrganizationspeerOrganizations 文件夹:

3.2. 创建网络配置

创建文件 connection.json 内容如下:

{

"name": "basic-network",

"version": "1.0.0",

"client": {

"organization": "Org1",

"connection": {

"timeout": {

"peer": {

"endorser": "300"

},

"orderer": "300"

}

}

},

"channels": {

"mychannel": {

"orderers": [

"orderer.example.com"

],

"peers": {

"peer0.org1.example.com": {

"endorsingPeer": true,

"chaincodeQuery": true,

"ledgerQuery": true,

"eventSource": true

},

"peer0.org2.example.com": {

"endorsingPeer": true,

"chaincodeQuery": true,

"ledgerQuery": true,

"eventSource": true

}

}

}

},

"organizations": {

"Org1": {

"mspid": "Org1MSP",

"peers": [

"peer0.org1.example.com"

],

"certificateAuthorities": [

"ca-org1"

],

"adminPrivateKeyPEM": {

"path": "src/main/resources/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk"

},

"signedCertPEM": {

"path": "src/main/resources/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem"

}

},

"Org2": {

"mspid": "Org2MSP",

"peers": [

"peer0.org2.example.com"

],

"certificateAuthorities": [

"ca-org2"

],

"adminPrivateKeyPEM": {

"path": "src/main/resources/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore/priv_sk"

},

"signedCertPEM": {

"path": "src/main/resources/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts/Admin@org2.example.com-cert.pem"

}

}

},

"orderers": {

"orderer.example.com": {

"url": "grpcs://192.168.28.134:7050",

"mspid": "OrdererMSP",

"grpcOptions": {

"ssl-target-name-override": "orderer.example.com",

"hostnameOverride": "orderer.example.com"

},

"tlsCACerts": {

"path": "src/main/resources/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt"

},

"adminPrivateKeyPEM": {

"path": "src/main/resources/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/msp/keystore/priv_sk"

},

"signedCertPEM": {

"path": "src/main/resources/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/msp/signcerts/Admin@example.com-cert.pem"

}

}

},

"peers": {

"peer0.org1.example.com": {

"url": "grpcs://192.168.28.134:7051",

"grpcOptions": {

"ssl-target-name-override": "peer0.org1.example.com",

"hostnameOverride": "peer0.org1.example.com",

"request-timeout": 120001

},

"tlsCACerts": {

"path": "src/main/resources/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"

}

},

"peer0.org2.example.com": {

"url": "grpcs://192.168.28.134:9051",

"grpcOptions": {

"ssl-target-name-override": "peer0.org2.example.com",

"hostnameOverride": "peer0.org2.example.com",

"request-timeout": 120001

},

"tlsCACerts": {

"path": "src/main/resources/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"

}

}

},

"certificateAuthorities": {

"ca-org1": {

"url": "https://192.168.28.134:7054",

"grpcOptions": {

"verify": true

},

"tlsCACerts": {

"path": "src/main/resources/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem"

},

"registrar": [

{

"enrollId": "admin",

"enrollSecret": "adminpw"

}

]

},

"ca-org2": {

"url": "https://192.168.28.134:8054",

"grpcOptions": {

"verify": true

},

"tlsCACerts": {

"path": "src/main/resources/crypto-config/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem"

},

"registrar": [

{

"enrollId": "admin",

"enrollSecret": "adminpw"

}

]

}

}

}

需按实际情况修改url中的地址,内容中分别包含了 channelsorganizationsordererspeersca 的配置

3.3. SpringBoot配置

application.yml 中添加以下内容,用于访问网关的相关配置:

fabric:

# wallet文件夹路径(自动创建)

walletDirectory: wallet

# 网络配置文件路径

networkConfigPath: connection.json

# 用户证书路径

certificatePath: crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem

# 用户私钥路径

privateKeyPath: crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/priv_sk

# 访问的组织名

mspid: Org1MSP

# 用户名

username: user1

# 通道名字

channelName: mychannel

# 链码名字

contractName: mycc

四、连接合约

分别构建网关、通道和合约的Bean对象,代码如下:

/**

* 连接网关

*/

@Bean

public Gateway connectGateway() throws IOException, InvalidKeyException, CertificateException {

//使用org1中的user1初始化一个网关wallet账户用于连接网络

Wallet wallet = Wallets.newFileSystemWallet(Paths.get(this.walletDirectory));

X509Certificate certificate = readX509Certificate(Paths.get(this.certificatePath));

PrivateKey privateKey = getPrivateKey(Paths.get(this.privateKeyPath));

wallet.put(username, Identities.newX509Identity(this.mspid, certificate, privateKey));

//根据connection.json 获取Fabric网络连接对象

Gateway.Builder builder = Gateway.createBuilder()

.identity(wallet, username)

.networkConfig(Paths.get(this.networkConfigPath));

//连接网关

return builder.connect();

}

/**

* 获取通道

*/

@Bean

public Network network(Gateway gateway) {

return gateway.getNetwork(this.channelName);

}

/**

* 获取合约

*/

@Bean

public Contract contract(Network network) {

return network.getContract(this.contractName);

}

五、合约调用

创建controller类,注入Contract对象调用合约方法:

@Resource

private Contract contract;

@Resource

private Network network;

@GetMapping("/getUser")

public String getUser(String userId) throws ContractException {

byte[] queryAResultBefore = contract.evaluateTransaction("getUser",userId);

return new String(queryAResultBefore, StandardCharsets.UTF_8);

}

@GetMapping("/addUser")

public String addUser(String userId, String userName, String money) throws ContractException, InterruptedException, TimeoutException {

byte[] invokeResult = contract.createTransaction("addUser")

.setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)))

.submit(userId, userName, money);

String txId = new String(invokeResult, StandardCharsets.UTF_8);

return txId;

}

六、测试接口

调用接口 getUser

http://127.0.0.1:9001/getUser?userId=1

返回:

{

"money": 300,

"name": "zlt",

"userId": "1"

}

调用接口 addUser

http://127.0.0.1:9001/addUser?userId=6&userName=test6&money=600

返回:

2ae291bb6a366b5ba01ad49e4237da8def9e9828cc2c982e8c49d4b763af0157

七、代码下载

gitee:https://gitee.com/zlt2000/my-fabric-application-java

github:https://github.com/zlt2000/my-fabric-application-java

扫码关注有惊喜!

以上是 Hyperledger Fabric 2.x Java区块链应用 的全部内容, 来源链接: utcz.com/z/390998.html

回到顶部