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的情况. 本文基于这 ...
随机推荐
- (转)配置ORACLE 11g绿色版客户端和PLSQL环境
本文转载自:http://my.oschina.net/jang/blog/83009 本方法是通过使用ORACLE官方提供的精简版客户端,即绿色免安装的客户端. 下载地址(此处提供的是官方各版本下载 ...
- 卸载驱动时,没有/lib/modules目录
卸载驱动时,没有/lib/modules目录,怎么办? 答:没有这个目录,就创建这个目录! #rmmod spi_oled_drv #rmmod: chdir (/lib/modules): no ...
- Centos 7.2 编译安装 git
一. 下载最新版GIT安装包: https://www.kernel.org/pub/software/scm/git/ 选择想要安装的版本,下载,解压 命令: .tar.gz $ cd git- 二 ...
- C语言学习笔记--内存分区
1. 程序中的栈 1.1 栈的简介 (1)栈中现代计算机程序里最为重要的概念之一 (2)栈在程序中用于维护函数调用上下文 (3)函数中的参数和局部变量存储在栈上 (4)栈保存了一个函数调用所需的维护信 ...
- Xcode快捷
- Android键盘属性
在主xml中android:windowSoftInputMode的属性"stateUnspecified"软键盘的状态(是否它是隐藏或可见)没有被指定.系统将选择一个合适的状态或 ...
- PROCEDURE存储过程传入表参数
) ,itemNum ) ,itemQty )) ---2.创建一个存储过程以表值参数作为输入 alter proc usp_TestProcWithTable @tb LocationTa ...
- HDU 5242 树链剖分思想的贪心
题意及博客 树链剖分分为2步,第一次求出深度,重儿子,第二次求出重链,用到了启发式的思想,即对于比较重的儿子,尽量去完整的维护它.类似于我们去合并两个堆,明显把小的堆逐个插入大的堆中会比大的往小的插更 ...
- 解决swfupload改变display属性后flash重新加载的问题(chome,safari内核的所有浏览器)
最近在做的项目中有要用到上传控件,所有就用到了swfupload flash上传控件 因为在项目中要使用到Tab控件,tab控件通过改变display属性来控制tab页的显 示与隐藏.当swfuplo ...
- docker学习(2)基本命令
原文地址:http://blog.csdn.net/we_shell/article/details/38368137 1. 查看docker信息(version.info) # 查看docker版本 ...