1.说明上一篇《Hyperledger Fabric 2.x 自定义智能合约》分享了智能合约的安装,使用cli客户端调用合约;本文将使用基于fabric-gateway-java的Java代码接入区块链网络并进行交易,并集成SpringBoot框架。FabricGatewaySDK实现了Fabric编程模型,提供了一系列简单的API供应用程序与Fabric区块链网络进行交互;网络拓扑图:文件应用将它们的网络交互委托给它们的网关,每个网关都了解网络通道拓扑,包括一个组织的多个Peer节点和排序节点,使应用能够专注于业务逻辑;对等节点可以使用八卦协议在组织内部和组织之间相互通信。2.mavn依赖添加网关sdk:org.hyperledger.fabricfabric-gateway-java2.2.3依赖>3。准备配置文件工程目录结构如下图所示:3.1.准备网络证书创建目录crypto-config并复制排序节点和对等节点的证书文件。从fabric-samples的test-network目录中复制证书文件,复制ordererOrganizations和peerOrganizations文件夹:3.2.创建一个网络配置,创建一个文件connection.json,内容如下:{"name":"basic-network","version":"1.0.0","client":{"organization":"Org1",“连接”:{“超时”:{“对等”:{“背书”:“300”},“订购者”:“300”}}},“频道”:{“我的频道”:{“订购者”:["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":{"路径":"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"}}},"订购者":{"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":{“路径”:“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“:{“验证”:真},“tlsCACerts”:{“路径”:“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":{“路径”:“src/main/resources/crypto-config/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem”},“注册商”:[{“enrollId”:"admin","enrollSecret":"adminpw"}]}}}需要根据实际情况修改url中的地址,内容分别包括channel、organization、orderer、peer、ca的配置。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四、连接合约到分别构建gateways和channels以及合约的Bean对象,代码如下:/***ConnectGateway*/@BeanpublicGatewayconnectGateway()throwsIOException,InvalidKeyException,CertificateException{//使用org1中的user1初始化一个网关钱包账户连接网络Walletwallet=Wallets.newFileSystemWallet(Paths.get(this.walletDirectory));X509Certificate证书=readX509Certificate(Paths.get(this.certificatePath));PrivateKeyprivateKey=getPrivateKey(Paths.get(this.privateKeyPath));wallet.put(用户名,Identities.newX509Identity(this.mspid,certificate,privateKey));//根据connection.json获取Fabric网络连接对象Gateway.Builderbuilder=Gateway.createBuilder().identity(wallet,username).networkConfig(Paths.get(this.networkConfigPath));//连接网关returnbuilder.connect();}/***获取通道*/@BeanpublicNetworknetwork(Gatewaygateway){returngateway.getNetwork(this.channelName);}/***获取合约*/@BeanpublicContractcontract(Networknetwork){returnnetwork.getContract(this.contractName);}5.合约调用创建controller类,注入Contract对象调用合约方法:@ResourceprivateContr行为合同;@ResourceprivateNetwork网络;@GetMapping("/getUser")publicStringgetUser(StringuserId)throwsContractException{byte[]queryAResultBefore=contract.evaluateTransaction("getUser",userId);returnnewString(queryAResultBefore,StandardCharsets.UTF_8);}@GetMapping("/addUser")publicStringaddUser(StringuserId,StringuserName,Stringmoney)抛出ContractException,InterruptedException,TimeoutException{byte[]invokeResult=contract.createTransaction("addUser").setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER))).submit(userId,userName,money);StringtxId=newString(invokeResult,StandardCharsets.UTF_8);returntxId;}六、测试接口调用接口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返回:2ae291bb6a366b5ba01ad49e4237da8def9e9828cc2c982e8c49d4b763af01577.代码下载gitee:https://gitee.com/zlt2000/my-fabric-application-javagithub:https://github.com/zlt2000/my-fabric-application-java