Hyperledger Fabric Java App Demo
编写一个应用程序来连接到 fabrc 网络中,通过调用智能合约来访问账本.

fabric gateway
fabric gateway 有两个项目,一个是 fabric-gateway-java , 一个是 fabric-gateway。
fabric-gateway-java 是比较早的项目,使用起来较为麻烦需要提供一个 connection.json 配置文件,该配置文件中要详细配置网络中的各个节点的信息。
fabric-gateway 使用起来较为简单,不在需要 connection.json 配置文件,只需要指定网络中的一个节点连接就可以了。
fabric 官方建议如果是 fabrc 2.4 或者之后的版本建议使用 fabric-gateway。

本篇内容基于
fabric-gateway讲解,fabric 版本 v2.4.1
使用 fabric-gateway
Fabric Gateway 是 Hyperledger Fabric 区块链网络的核心组件,代表客户端应用程序协调提交事务和查询分类账状态所需的操作。通过使用 Gateway,客户端应用程序只需要连接到 Fabric 网络中的单个端点。
官方示例: https://github.com/hyperledger/fabric-samples/tree/main/asset-transfer-events https://github.com/hyperledger/fabric-samples/tree/main/asset-transfer-basic
fabric-gateway 依赖
<dependency><groupId>org.hyperledger.fabric</groupId><artifactId>fabric-gateway</artifactId><version>1.0.1</version>
</dependency>
连接 fabric 网络
application.properties 配置文件:
# 应用名称
spring.application.name=hyperledger-fabric-app-java-demo
# 应用服务 WEB 访问端口
server.port=8080fabric.networkConnectionConfigPath=src/main/resources/org1ProdNetworkConnection.json
fabric.mspId=Org1MSP
fabric.certificatePath=src/main/resources/crypto-config/prod-network/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem
fabric.privateKeyPath=src/main/resources/crypto-config/prod-network/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/priv_sk
fabric.tlsCertPath=src/main/resources/crypto-config/prod-network/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
fabric.channel=businesschannellogging.level.org.hyperledger=trace
src/main/resources/crypto-config/prod-network 路径下存放的是身份信息文件.
初始化 Gateway , Network , Contract 对象
import io.grpc.ManagedChannel;
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hyperledger.fabric.client.CallOption;
import org.hyperledger.fabric.client.Contract;
import org.hyperledger.fabric.client.Gateway;
import org.hyperledger.fabric.client.Network;
import org.hyperledger.fabric.client.identity.Identities;
import org.hyperledger.fabric.client.identity.Signers;
import org.hyperledger.fabric.client.identity.X509Identity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;/*** author he peng* date 2022/1/22 21:21*/@Configuration
@AllArgsConstructor
@Slf4j
public class HyperLedgerFabricGatewayConfig {final HyperLedgerFabricProperties hyperLedgerFabricProperties;@Beanpublic Gateway gateway() throws Exception {BufferedReader certificateReader = Files.newBufferedReader(Paths.get(hyperLedgerFabricProperties.getCertificatePath()), StandardCharsets.UTF_8);X509Certificate certificate = Identities.readX509Certificate(certificateReader);BufferedReader privateKeyReader = Files.newBufferedReader(Paths.get(hyperLedgerFabricProperties.getPrivateKeyPath()), StandardCharsets.UTF_8);PrivateKey privateKey = Identities.readPrivateKey(privateKeyReader);Gateway gateway = Gateway.newInstance().identity(new X509Identity(hyperLedgerFabricProperties.getMspId() , certificate)).signer(Signers.newPrivateKeySigner(privateKey)).connection(newGrpcConnection()).evaluateOptions(CallOption.deadlineAfter(5, TimeUnit.SECONDS)).endorseOptions(CallOption.deadlineAfter(15, TimeUnit.SECONDS)).submitOptions(CallOption.deadlineAfter(5, TimeUnit.SECONDS)).commitStatusOptions(CallOption.deadlineAfter(1, TimeUnit.MINUTES)).connect();log.info("=========================================== connected fabric gateway {} " , gateway);return gateway;}private ManagedChannel newGrpcConnection() throws IOException, CertificateException {Reader tlsCertReader = Files.newBufferedReader(Paths.get(hyperLedgerFabricProperties.getTlsCertPath()));X509Certificate tlsCert = Identities.readX509Certificate(tlsCertReader);return NettyChannelBuilder.forTarget("peer0.org1.example.com:7051").sslContext(GrpcSslContexts.forClient().trustManager(tlsCert).build()).overrideAuthority("peer0.org1.example.com").build();}@Beanpublic Network network(Gateway gateway) {return gateway.getNetwork(hyperLedgerFabricProperties.getChannel());}@Beanpublic Contract catContract(Network network) {return network.getContract("hyperledger-fabric-contract-java-demo" , "CatContract");}@Beanpublic ChaincodeEventListener chaincodeEventListener(Network network) {return new ChaincodeEventListener(network);}
}
链码事件监听
用来监听交易完成之后通知的事件,事件中可以携带数据。
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.hyperledger.fabric.client.ChaincodeEvent;
import org.hyperledger.fabric.client.CloseableIterator;
import org.hyperledger.fabric.client.Network;import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;/*** @author he peng* @date 2022/3/4*/@Slf4j
public class ChaincodeEventListener implements Runnable {final Network network;public ChaincodeEventListener(Network network) {this.network = network;ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {@Overridepublic Thread newThread(Runnable r) {Thread thread = new Thread(r);thread.setDaemon(true);thread.setName(this.getClass() + "chaincode_event_listener");return thread;}});executor.execute(this);}@Overridepublic void run() {CloseableIterator<ChaincodeEvent> events = network.getChaincodeEvents("hyperledger-fabric-contract-java-demo");log.info("chaincodeEvents {} " , events);while (events.hasNext()) {ChaincodeEvent event = events.next();log.info("receive chaincode event {} , block number {} , payload {} ", event.getEventName() , event.getBlockNumber() , JSONArray.toJSONString(Base64.decodeBase64(event.getPayload())));}}
}
异步调用合约
@PutMapping("/async")public Map<String, Object> createCatAsync(@RequestBody CatDTO cat) throws Exception {Map<String, Object> result = Maps.newConcurrentMap();contract.newProposal("createCat").addArguments(cat.getKey(), cat.getName(), String.valueOf(cat.getAge()), cat.getColor(), cat.getBreed()).build().endorse().submitAsync();result.put("status", "ok");return result;}
完整示例代码项目:DevX/hyperledger-fabric-app-java-demo
相关文章:
Hyperledger Fabric Java App Demo
编写一个应用程序来连接到 fabrc 网络中,通过调用智能合约来访问账本. fabric gateway fabric gateway 有两个项目,一个是 fabric-gateway-java , 一个是 fabric-gateway。 fabric-gateway-java 是比较早的项目,使用起来较为麻烦需要提供一…...
Doris 在工商信息商业查询平台的湖仓一体建设实践(02)
信息服务行业可以提供多样化、便捷、高效、安全的信息化服务,为个人及商业决策提供了重要支撑与参考。本文以某工商信息商业查询平台为例,介绍其从传统 Lambda 架构到基于 Doris Multi-Catalog 的湖仓一体架构演进历程。同时通过一系列实践,展示了如何保证数据的准确性和实时…...
218.【2023年华为OD机试真题(C卷)】攀登者2(动态规划-JavaPythonC++JS实现)
🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-攀登者2二.解题思路三.题解代码Python题解代码…...
【精通C语言】:分支结构switch语句的灵活运用
🎥 屿小夏 : 个人主页 🔥个人专栏 : C语言详解 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一、switch语句1.1 语法1.2 代码示例 二、switch的控制语句2.1 break2.2 defualt子句 三、…...
数据结构和算法-数据结构的基本概念和三要素和数据类型和抽象数据类型
文章目录 总览数据结构的基本概念总览数据早期和现代的计算机处理的数据数据元素-描述一个个体数据对象-一类数据元素什么是数据结构小结 数据结构的三要素总览逻辑结构-集合结构逻辑结构-线性结构逻辑结构-树形结构逻辑结构-图形结构逻辑结构-小结数据的运算物理结构ÿ…...
LeetCode 2353. 设计食物评分系统【设计,哈希表,有序集合;堆+懒删除】1781
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
Redis (三)
1、redis复制 简单的概括就是主从复制,master以写为主,Slave以读为主,当master数据发生变化的时候,自动将更新的数据异步同步到其他的slave是数据库。 使用这种机制的话,可以做到读写分离,可以减轻主机负担…...
CompletableFuture超详解与实践
0.背景 一个接口可能需要调用 N 个其他服务的接口,这在项目开发中还是挺常见的。举个例子:用户请求获取订单信息,可能需要调用用户信息、商品详情、物流信息、商品推荐等接口,最后再汇总数据统一返回。 如果是串行(按…...
Maven之私服
1 介绍 团队开发现状分析私服是一台独立的服务器,用于解决团队内部的资源共享与资源同步问题Nexus Sonatype公司的一款maven私服产品 下载地址:https://help.sonatype.com/repomanager3/download win版安装包:https://pan.baidu.com/s/1wk…...
#define宏定义的初探
前言: 最基本的#define定义方式 #define可以定义宏,这点相信大家并不陌生,其定义的方式十分简单,给大家随便来一个最简单、最基础的定义方式看看: #include<stdio.h> #define a 3 int main() { printf(&quo…...
机器学习 -决策树的案例
场景 我们对决策树的基本概念和算法其实已经有过了解,那我们如何利用决策树解决问题呢? 构建决策树 数据准备 我们准备了一些数据如下: # 定义新的数据集 new_dataSet [[晴朗, 是, 高, 是],[雨天, 否, 低, 否],[阴天, 是, 中, 是],[晴朗…...
04、Kafka ------ 各个功能的作用解释(Cluster、集群、Broker、位移主题、复制因子、领导者副本、主题)
目录 启动命令:CMAK的用法★ 在CMAK中添加 Cluster★ 在CMAK中查看指定集群★ 在CMAK中查看 Broker★ 位移主题★ 复制因子★ 领导者副本和追随者副本★ 查看主题 启动命令: 1、启动 zookeeper 服务器端 小黑窗输入命令: zkServer 2、启动 …...
1、C语言:数据类型/运算符与表达式
数据类型/运算符/表达式 1.数据类型与长度2.常量3.声明4. 运算符5. 表达式 1.数据类型与长度 基本数据类型 类型说明char字符型,占用一个字节,可以存放本地字符集中的一个字符int整型,通常反映了所有机器中整数的最自然长度float单精度浮点…...
[ffmpeg系列 03] 文件、流地址(视频)解码为YUV
一 代码 ffmpeg版本5.1.2,dll是:ffmpeg-5.1.2-full_build-shared。x64的。 文件、流地址对使用者来说是一样。 流地址(RTMP、HTTP-FLV、RTSP等):信令完成后,才进行音视频传输。信令包括音视频格式、参数等协商。 接流的在实际…...
python算法每日一练:连续子数组的最大和
这是一道关于动态规划的算法题: 题目描述: 给定一个整数数组 nums,请找出该数组中连续子数组的最大和,并返回这个最大和。 示例: 输入:[-2, 1, -3, 4, -1, 2, 1, -5, 4] 输出:6 解释ÿ…...
一个vue3的tree组件
https://download.csdn.net/download/weixin_41012767/88709466...
新手练习项目 4:简易2048游戏的实现(C++)
名人说:莫听穿林打叶声,何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder) 目录 一、效果图二、代码(带注释)三、说明 一、效果图 二、代码(带…...
2023年度总结:技术沉淀、持续学习
2023年度总结:技术沉淀、持续学习 一、引言 今年是我毕业的第二个年头,也是完整的一年,到了做年终总结的时候了 这一年谈了女朋友,学习了不少技术,是充实且美好的一年! 首先先看年初定的小目标…...
Unity 利用UGUI之Slider制作进度条
在Unity中使用Slider和Text组件可以制作简单的进度条。 首先在场景中右键->UI->Slider,新建一个Slider组件: 同样方法新建一个Text组件,最终如图: 创建一个进度模拟脚本,Slider_Progressbar.cs using System.C…...
OCS2 入门教程(四)- 机器人示例
系列文章目录 前言 OCS2 包含多个机器人示例。我们在此简要讨论每个示例的主要特点。 System State Dim. Input Dim. Constrained Caching Double Integrator 2 1 No No Cartpole 4 1 Yes No Ballbot 10 3 No No Quadrotor 12 4 No No Mobile Manipul…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
