ITPub博客

首页 > 区块链 > 区块链 > Hyperledger Fabric 2.x Java 区块链应用

Hyperledger Fabric 2.x Java 区块链应用

原创 区块链 作者:小程序开发 时间:2022-07-12 13:12:33 0 删除 编辑

file

一、说明

本文将使用  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 中的地址,内容中分别包含了  channels、 organizations、 orderers、 peers、 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

 

四、连接合约

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

/**
 * 连接网关
 */@Beanpublic 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();
}/**
 * 获取通道
 */@Beanpublic Network network(Gateway gateway) {	return gateway.getNetwork(this.channelName);
}/**
 * 获取合约
 */@Beanpublic Contract contract(Network network) {	return network.getContract(this.contractName);
}

 

五、合约调用

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

@Resourceprivate Contract contract;@Resourceprivate 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


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70019616/viewspace-2905322/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
自橙一派www.zcypai.com公司专注于微信领域内的系统开发,主营业务包括有微信公众号开发和微信小程序开发等,提供运维指导,软件使用及推广引流服务。

注册时间:2022-07-03

  • 博文量
    15
  • 访问量
    11379