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的情况. 本文基于这 ...
随机推荐
- 获取wifi热点
https://stackoverflow.com/questions/31555640/how-to-get-wifi-ssid-in-ios9-after-captivenetwork-is-de ...
- [转]在 Windows 操作系统中的已知安全标识符(Sid security identifiers)
安全标识符 (SID) 是用于标识安全主体或安全组在 Windows 操作系统中的可变长度的唯一值.常用 Sid 的 Sid 标识普通用户的一组或通用组.跨所有操作系统,它们的值保持不变. 此信息可用 ...
- Enable SVM while booted from alternate media (ZT)
http://www.seedsofgenius.net/uncategorized/solaris-tips-enable-svm-while-booted-from-alternate-media ...
- wamp集成环境下mysql数据库的分开部署和远程访问
今天折腾了一天一个小问题,就是明明正确的php代码在访问数据库的时候总是提示DB ERROR.后来才发现是填写数据库名的时候,写成了该数据库的ip地址(其实也是本机ip但是本机还是不能访问),而不是l ...
- css垂直居中方法(四)
第六种方法,使用css的writing-mode属性,结合margin:auto. 参考文章:改变CSS世界纵横规则的writing-mode属性 传统的web流中,margin设置auto值的时候, ...
- chromium浏览器开发系列第二篇:如何编译最新chromium
说一下为什么这么晚才发第二篇,上周和这周department的工作太多了,晚上都是十点半从公司出发,回家以后实在没有多余的精力去摸键盘了.所以请大家包涵! 上期回顾: chromium源码下载: 1. ...
- java定时器控制时间打印
public class test2 { public static void main(String []args){ Timer timer=new Timer(); timer.schedule ...
- python操作excel的读写
1.下载xlrd和xlwt pip install xlwd pip install xlrd pip install xlutils 2.读写操作(已存在的excel) #-*- coding:ut ...
- apt-cyg update --2017-02-17 07:57:24-- http://mirrors.163.com/cygwin//x86_64/setup.bz2 正在解析主机 mirrors.163.com... 123.58.173.185, 123.58.173.186 正在连接 mirrors.163.com|123.58.173.185|:80... 已连接。 已发出 HTT
apt-cyg update ---- ::-- http://mirrors.163.com/cygwin//x86_64/setup.bz2 正在解析主机 mirrors.163.com... 1 ...
- linux 创建docker基础镜像
通过Dockerfile创建镜像时,一般都是基于 Docker Hub 提供的官方镜像.以下分别介绍在ubuntu16和centos7 两个系统上创建个人私有基础镜像的方法. 一.ubuntu16创 ...