百木园-与人分享,
就是让自己快乐。

Hyperledger Fabric 2.x Java区块链应用

file

一、说明

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

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

网络拓扑图:

file

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

 

二、Mavn依赖

添加网关sdk的依赖:

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

 

三、准备配置文件

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

file

 

3.1. 准备网络证书

创建目录 crypto-config 把 orderer 和 peer 节点的证书文件复制进来。

证书文件从 fabric-samples 的 test-network 目录中复制 ordererOrganizations 与 peerOrganizations 文件夹:

file

 

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


来源:https://www.cnblogs.com/xyou/p/15976296.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Hyperledger Fabric 2.x Java区块链应用

相关推荐

  • 暂无文章