fabric java chaincode 开发
链码的开发不部分参考官网demo即可。
本文不会详细介绍开发过程
笔者启动的是一个gradle工程,也就是jar包管理使用的是gradle。
chaincode 源码:
/*
Copyright IBM Corp., DTCC All Rights Reserved. SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.fabric.example; import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import io.netty.handler.ssl.OpenSsl;
import io.netty.util.internal.StringUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperledger.fabric.example.bean.Factor;
import org.hyperledger.fabric.shim.ChaincodeBase;
import org.hyperledger.fabric.shim.ChaincodeStub; import java.util.List; public class FactoringChaincode extends ChaincodeBase { private static Log _logger = LogFactory.getLog(FactoringChaincode.class); @Override
public Response init(ChaincodeStub stub) {
try {
_logger.info("Init java factoring chaincode");
String func = stub.getFunction();
if (!func.equals("init")) {
return newErrorResponse("function other than init is not supported");
}
_logger.info("begin test keepAlive");
stub.putStringState("keepAliveTest","keepAliveTestValue");
_logger.info("end test keepAlive");
return newSuccessResponse();
} catch (Throwable e) {
return newErrorResponse(e);
}
} @Override
public Response invoke(ChaincodeStub stub) {
try {
_logger.info("Invoke java factoring chaincode");
String func = stub.getFunction();
List<String> params = stub.getParameters();
_logger.debug("Invoke function is "+stub.getFunction()+"Parameter is "+params.toString());
if(params.isEmpty() || params.size()< || params.get().length()==){
return newErrorResponse("the invoke args not exist or arg[0] is emptyt");
}
if (func.equals("SaveData")) {
return saveData(stub, params);
}
if (func.equals("KeepaliveQuery")) {
return keepaliveQuery(stub, params);
}
if (func.equals("QueryDataByFabricTxId")) {
return queryDataByFabricTxId(stub, params);
}
if (func.equals("QueryDataByBusinessNo")) {
return queryDataByBusinessNo(stub, params);
}
return newErrorResponse("Invalid invoke function name. ");
} catch (Throwable e) {
return newErrorResponse(e);
}
} private Response keepaliveQuery(ChaincodeStub stub, List<String> params) {
String tarValue = stub.getStringState("keepAliveTest");
if(!"keepAliveTestValue".equals(tarValue)){
return newErrorResponse("ERROR! KeepaliveQuery get result is "+tarValue);
}
return newSuccessResponse("Reached".getBytes());
} private Response queryDataByBusinessNo(ChaincodeStub stub, List<String> params) {
String txId =new String(stub.getState(params.get()));
_logger.info("query data by businessNo:"+params.get()+",txId is"+txId);
return this.queryDataByFabricTxId(stub, Lists.newArrayList(txId));
} private Response queryDataByFabricTxId(ChaincodeStub stub, List<String> params) {
_logger.info("queryData by txId:"+params.get());
byte[] res = stub.getState(params.get());
return newSuccessResponse(new String(res),res);
} private Response saveData(ChaincodeStub stub, List<String> args) {
if(args.isEmpty() || args.size()<){
return newSuccessResponse("saveData wrong args");
}try{
Factor f = JSONArray.toJavaObject(JSONArray.parseObject(args.get()),Factor.class);
String businessNo = f.getBusinessNo();
if(StringUtil.isNullOrEmpty(businessNo)){
return newErrorResponse("businessNo must exist");
}
String txId = stub.getTxId();
stub.putState(txId,args.get().getBytes());
stub.putState(businessNo,txId.getBytes());
_logger.info("save data successfully with txid "+txId+",and businessNo"+businessNo);
}catch (Exception e){
return newErrorResponse(e.getMessage());
}
return newSuccessResponse();
} public static void main(String[] args) {
System.out.println("OpenSSL avaliable: " + OpenSsl.isAvailable());
new FactoringChaincode().start(args);
} }
keepaliveQuery方法是为了探活。因为如果某个节点上没有启动链码容器会对交易的速度结果有影响,所以采用这种方式,每个节点都需要调用一次该方法在开始正常业务的调用。
链码的逻辑很简单,需要注意的是,gradle工程的配置文件中,需要制定baseName是 chaincode。因为在节点实例化链码的时候会默认找名称为chaincode的jar包。
shadowJar {
baseName = 'chaincode'
version = null
classifier = null
manifest {
attributes 'Main-Class': 'org.hyperledger.fabric.example.FactoringChaincode'
}
}
mainfest中需要特别指定main方法的java 文件。否则在实例化的时候会报错。
需要注意的是,目前fabric应用的大部分地方场景中的部署环境是没有外网的。如银行,政府企业的环境。这个时候gradle就需要支持离线打包。
在build.gradle的配置文件中添加
dependencies { compile fileTree(dir: 'libs', includes: ['*.jar'])} 项目的根目录,跟Src同级建立一个libs文件夹,把需要的jar包放进去即可。
开发完成以后把编写的项目放到服务器上打包:
./peer chaincode package -n factor -l java -p /usr/local/workspace/java_chaincode/ -v 1.0 -s -S -i "AND ('Org1MSP.peer')" factor.out
-i "AND ('Org1MSP.peer')"表示该链码只能被Org1的peer节点实例化,其他节点实例化的话会报错。如果不指定这个参数,默认的限制是每个组织的admin可以实例化该链码。
打包的文件经过安装实例化就可以正常调用了。
附git地址 https://github.com/figo050518/fabric_java_chaincode
fabric java chaincode 开发的更多相关文章
- Hyperledger Fabric java chaincode 中文乱码问题
开发java chaincode过程中遇到一个中文乱码的问题.都是官方的demo,请求的sdk是用java写的,部署的chaincode有两种选择(不考虑node),一种go语言写的chaincode ...
- Hyperledger Fabric java chaincode 编译部署(1.4V)
前提条件: 构建好了一个拥有四个peer 一个Order 的1.4版本的Fabric网络. 证书通过Cryptogen生成,没有使用CA服务. 开启TLS. 网络中的peer都加入了一个 名为mych ...
- Hyperledger Fabric ChainCode开发
预览 Hyperledger Fabric的chaincode开发目前支持Go.Java.Node.js语言,下面以Go语言作为例子,我们先看下面的一个官方提供chaincode模板 ··· pack ...
- 用Hyperledger Fabric(超级账本)来构建Java语言开发区块链的环境
面向 Java 开发人员的链代码简介 您或许听说过区块链,但可能不确定它对 Java™ 开发人员有何用.本教程将帮助大家解惑.我将分步展示如何使用 Hyperledger Fabric v0.6 来构 ...
- HyperLedger Fabric ChainCode开发——shim.ChaincodeStubInterface用法
深蓝前几篇博客讲了Fabric的环境搭建,在环境搭建好后,我们就可以进行Fabric的开发工作了.Fabric的开发主要分成2部分,ChainCode链上代码开发和基于SDK的Application开 ...
- 搭建基于hyperledger fabric的联盟社区(四) --chaincode开发
前几章已经分别把三台虚拟机环境和配置文件准备好了,在启动fabric网络之前我们要准备好写好的chaincode.chaincode的开发一般是使用GO或者JAVA,而我选择的是GO语言.先分析一下官 ...
- 用Java为Hyperledger Fabric(超级账本)开发区块链智能合约链代码之部署与运行示例代码
部署并运行 Java 链代码示例 您已经定义并启动了本地区块链网络,而且已构建 Java shim 客户端 JAR 并安装到本地 Maven 存储库中,现在已准备好在之前下载的 Hyperledger ...
- Hyperledger Fabric chaincode 开发(疑难解答)
Q&A Q1: 使用fabric release 1.2 进行golang chaincode开发时报错: ..\..\hyperledger\fabric\vendor\github.com ...
- hyperledger fabric 中java chaincode 支持离线打包
联盟链由于其本身的特性,目前应用在一些大型国有企业银行比较多.出于安全考虑,这些企业一般会隔离外网环境.所以在实际生产需求中可能存在需要在一个离线的环境中打包安装chaincode的情况. 本文基于这 ...
随机推荐
- Linux驱动 - 多线程
1.头文件 #include <linux/kthread.h> 2.定义变量 static pid_t thread_id: //线程ID static struct completio ...
- java代码异常处理篇-----循环
总结:注意一个方法:nextLine();它表示:执行当前行,返回跳过的输入信息. package com.da; import java.util.InputMismatchException; i ...
- 2018年长沙理工大学第十三届程序设计竞赛 J杯子
链接:https://www.nowcoder.com/acm/contest/96/J来源:牛客网 杯子 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言655 ...
- MySQL 双主+keepalived 详细文档 M-M+keepalived
1. 操作系统,系统环境,目结结构,用户,权限,日志路径,脚本2. 配置规范化 1.1 操作系统准备 操作系统 Kylin Linux release 3.3.1707 (Core)数据库版本 mys ...
- 侯捷STL学习(一)--顺序容器测试
开始跟着<STL源码剖析>的作者侯捷真人视频,学习STL,了解STL背后的真实故事! 视频链接:侯捷STL 还有很大其他视频需要的留言 第一节:STL版本和重要资源 STL和标准库的区别 ...
- IDEA 运行spingboot时出现Process finished with exit code -1073741819 (0xC0000005)
经过多方查证,问题最终定位在金山词霸2016上,如果开启了金山词霸的取词和划意功能,就会出现此错误,估计是冲突吧. 解决办法:关掉金山词霸,或者把金山词霸的取词和划意功能关掉.经过尝试,发现只要在ID ...
- CreateRemoteThread 远程注入
在release中可以成功,在debug中被注入的程序停止工作 #pragma once#include "stdafx.h"#include <windows.h># ...
- #pragma execution_character_set("utf-8")
VC2010增加了“#pragma execution_character_set("utf-8")”,指示char的执行字符集是UTF-8编码. VS2010 设置 字符编码: ...
- AOP基础-JDK动态代理
动态代理技术就是用来产生一个目标对象的代理对象的,代理对象应与目标对象(被代理的对象)有相同的方法,实现对目标对象访问的拦截,并增强目标对象的一些功能,而不需要目标对象去做任何的更改,使得目标对象有更 ...
- css之content
content 属性与 :before 及 :after 伪元素配合使用,来插入生成内容.该属性用于定义元素之前或之后放置的生成内容.默认地,这往往是行内内容,不过该内容创建的框类型可以用属性 dis ...