Hyperledger Fabric 2.x Java区块链应用

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

封面.jpeg

一、说明

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

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

网络拓扑图:

拓扑图.png

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

 

二、Mavn依赖

添加网关sdk的依赖:

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

 

三、准备配置文件

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

工程目录结构.png

 

3.1. 准备网络证书

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

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

复制证书.png

 

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

目录
相关文章
|
26天前
|
人工智能 安全 Java
Java和Python在企业中的应用情况
Java和Python在企业中的应用情况
48 7
|
20天前
|
缓存 Java 开发者
Java多线程并发编程:同步机制与实践应用
本文深入探讨Java多线程中的同步机制,分析了多线程并发带来的数据不一致等问题,详细介绍了`synchronized`关键字、`ReentrantLock`显式锁及`ReentrantReadWriteLock`读写锁的应用,结合代码示例展示了如何有效解决竞态条件,提升程序性能与稳定性。
74 6
|
19天前
|
监控 Java 数据库连接
Java线程管理:守护线程与用户线程的区分与应用
在Java多线程编程中,线程可以分为守护线程(Daemon Thread)和用户线程(User Thread)。这两种线程在行为和用途上有着明显的区别,了解它们的差异对于编写高效、稳定的并发程序至关重要。
26 2
|
29天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
52 6
|
25天前
|
关系型数据库 MySQL Java
MySQL索引优化与Java应用实践
【11月更文挑战第25天】在大数据量和高并发的业务场景下,MySQL数据库的索引优化是提升查询性能的关键。本文将深入探讨MySQL索引的多种类型、优化策略及其在Java应用中的实践,通过历史背景、业务场景、底层原理的介绍,并结合Java示例代码,帮助Java架构师更好地理解并应用这些技术。
25 2
|
28天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
29天前
|
Java 测试技术 API
Java 反射机制:深入解析与应用实践
《Java反射机制:深入解析与应用实践》全面解析Java反射API,探讨其内部运作原理、应用场景及最佳实践,帮助开发者掌握利用反射增强程序灵活性与可扩展性的技巧。
79 4
|
开发框架 .NET 区块链
Hyperledger fabric部署链码(五)初始化与链码升级
fabric部署chaincode-go(智能合约)系列之五
211 0
|
测试技术 Go 区块链
Hyperledger fabric 测试环境部署
Hyperledger fabric 测试环境部署及相关问题解答
282 3
Hyperledger fabric 测试环境部署
|
JavaScript 测试技术 Go
Hyperledger fabric部署链码(一)打包链码
fabric部署chaincode-go(智能合约)系列之一
257 0
下一篇
DataWorks