链码的开发不部分参考官网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 开发的更多相关文章

  1. Hyperledger Fabric java chaincode 中文乱码问题

    开发java chaincode过程中遇到一个中文乱码的问题.都是官方的demo,请求的sdk是用java写的,部署的chaincode有两种选择(不考虑node),一种go语言写的chaincode ...

  2. Hyperledger Fabric java chaincode 编译部署(1.4V)

    前提条件: 构建好了一个拥有四个peer 一个Order 的1.4版本的Fabric网络. 证书通过Cryptogen生成,没有使用CA服务. 开启TLS. 网络中的peer都加入了一个 名为mych ...

  3. Hyperledger Fabric ChainCode开发

    预览 Hyperledger Fabric的chaincode开发目前支持Go.Java.Node.js语言,下面以Go语言作为例子,我们先看下面的一个官方提供chaincode模板 ··· pack ...

  4. 用Hyperledger Fabric(超级账本)来构建Java语言开发区块链的环境

    面向 Java 开发人员的链代码简介 您或许听说过区块链,但可能不确定它对 Java™ 开发人员有何用.本教程将帮助大家解惑.我将分步展示如何使用 Hyperledger Fabric v0.6 来构 ...

  5. HyperLedger Fabric ChainCode开发——shim.ChaincodeStubInterface用法

    深蓝前几篇博客讲了Fabric的环境搭建,在环境搭建好后,我们就可以进行Fabric的开发工作了.Fabric的开发主要分成2部分,ChainCode链上代码开发和基于SDK的Application开 ...

  6. 搭建基于hyperledger fabric的联盟社区(四) --chaincode开发

    前几章已经分别把三台虚拟机环境和配置文件准备好了,在启动fabric网络之前我们要准备好写好的chaincode.chaincode的开发一般是使用GO或者JAVA,而我选择的是GO语言.先分析一下官 ...

  7. 用Java为Hyperledger Fabric(超级账本)开发区块链智能合约链代码之部署与运行示例代码

    部署并运行 Java 链代码示例 您已经定义并启动了本地区块链网络,而且已构建 Java shim 客户端 JAR 并安装到本地 Maven 存储库中,现在已准备好在之前下载的 Hyperledger ...

  8. Hyperledger Fabric chaincode 开发(疑难解答)

    Q&A Q1: 使用fabric release 1.2 进行golang chaincode开发时报错: ..\..\hyperledger\fabric\vendor\github.com ...

  9. hyperledger fabric 中java chaincode 支持离线打包

    联盟链由于其本身的特性,目前应用在一些大型国有企业银行比较多.出于安全考虑,这些企业一般会隔离外网环境.所以在实际生产需求中可能存在需要在一个离线的环境中打包安装chaincode的情况. 本文基于这 ...

随机推荐

  1. NHibernate使用总结(2)

    首先,映射文件的名称一定要是XXX.hbm.xml且生成方式一定要是嵌入的资源+不复制. hibernate.cfg.xml这个文件要放在根目录下,且生成方式必须是内容+始终复制. private v ...

  2. 有关UCOS_II在LPC1768上的应用

    https://www.cnblogs.com/chungshu/archive/2012/12/14/2818380.html

  3. 2015 浙江省赛 Beauty of Array (思维题)

    Beauty of Array Edward has an array A with N integers. He defines the beauty of an array as the summ ...

  4. java中内部类的讲解

    java中有一个内部类的概念,由于之前一直比较忙,没有单独拿出时间总结一下,今天我就把内部类的相关知识进行一下汇总,如果有不足之处,欢迎批评指正. 1)java内部类的概念.       在一个类的的 ...

  5. c语言-单链表(二)

    继续复习链表知识点,本章包含单链表的增加,删除,判断是否为空,和链表长度,以及链表的排序 几个知识点 1.链表的判断是否为空 //1.判断链表是否为空 bool isempty_list(PNODE ...

  6. awk简要使用

    1          前言 awk是Unix环境下一种非常好的语言,适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行特殊技巧程序设计.对于短消息来说,比如处理话单文件,使用awk就非常方便 ...

  7. Android studio导入svn工程

    Quick Start——> Check outproject from Version——> Subversion——> ‘+’加号 ——> 输入网址 ——> 注意选择 ...

  8. [codevs1159]最大全0子矩阵(悬线法)

    解题关键:悬线法模板题.注意此模板用到了滚动数组. #include<cstdio> #include<cstring> #include<algorithm> # ...

  9. Python 网络爬虫 008 (编程) 通过ID索引号遍历目标网页里链接的所有网页

    通过 ID索引号 遍历目标网页里链接的所有网页 使用的系统:Windows 10 64位 Python 语言版本:Python 2.7.10 V 使用的编程 Python 的集成开发环境:PyChar ...

  10. Flash of Unstyled Content (FOUC)

    在这次的产品发布中,客户发现了一个问题,就是在Firefox浏览器中,页面在加载的时候,出现没有样式的内容一闪而过的现象.其实,在测试过程中,我们也看到了类似的问题,但是并没有意识到这是一个问题,以为 ...