智能合约开发 java,智能合约Java开发指南

本文介绍了如何使用Java进行Hyperledger Fabric智能合约的开发。Java链码主要包含init和invoke两个方法,前者在链码初始化和升级时调用,用于初始化数据,后者处理业务逻辑。示例中展示了如何实现简单的资产转移功能,包括初始化和转账操作。此外,还提到了delete和query函数,分别用于账户删除和查询。
摘要由CSDN通过智能技术生成

本节介绍如何使用Java语言进行智能合约的开发。

链码结构

在Java语言的链码主要由以下方法组成:

/**

* Defines methods that all chaincodes must implement.

*/

publicinterfaceChaincode{

/**

*Called during an instantiate transaction after the container has been

*established, allowing the chaincode to initialize its internal data

*/

publicResponseinit(ChaincodeStubstub);

/**

*Called for every Invoke transaction. The chaincode may change its state

*variables.

*/

publicResponseinvoke(ChaincodeStubstub);

}

init: 链码在初始化和升级时调用此接口,初始化相关的数据。

invoke:主要用于实现链码的内部业务逻辑,您可以在该方法中实现相关的业务。

链码示例

Hyperledger Fabric 提供了很多官方链码样例,具体请参考fabric 官方示例。 我们以 Hyperledger Fabric 官方提供的 example02 样例为例,为大家介绍链码的开发规范。

简单示例

首先,我们看一个空链码结构的示例代码

importjava.util.List;

importcom.google.protobuf.ByteString;

importio.netty.handler.ssl.OpenSsl;

importorg.apache.commons.logging.Log;

importorg.apache.commons.logging.LogFactory;

importorg.hyperledger.fabric.shim.ChaincodeBase;

importorg.hyperledger.fabric.shim.ChaincodeStub;

importstaticjava.nio.charset.StandardCharsets.UTF_8;

/*

* 一个管理资产的简单链码

*/

publicclassSimpleAssetDemoextendsChaincodeBase{

/*

* 在链码实例化期时调用Init初始化数据

*/

@Override

publicResponseinit(ChaincodeStubstub){

}

/*

* Invoke在每一比交易时都会被调用,该方法应该包含 set 以及 get 来创建和获取对应的键值

*/

@Override

publicResponseinvoke(ChaincodeStubstub){

}

publicstaticvoidmain(String[]args){

newSimpleAssetDemo().start(args);

}

}

init 示例

Init 函数在链码实例化以及升级的时候会被调用。在实现 Init 函数的过程中,可使用 JAVA 语言版本的合约 API 列表来对参数和分布式账本进行操作。

@Override

publicResponseinit(ChaincodeStubstub){

try{

_logger.info("Init java simple chaincode");

// 调用 getFunction 方法获取当前调用的函数

Stringfunc=stub.getFunction();

if(!func.equals("init")){

returnnewErrorResponse("function other than init is not supported");

}

// 调用API getParameters 获取调用的参数

Listargs=stub.getParameters();

if(args.size()!=4){

returnnewErrorResponse("Incorrect number of arguments. Expecting 4");

}

// 初始化相关数据

Stringaccount1Key=args.get(0);

intaccount1Value=Integer.parseInt(args.get(1));

Stringaccount2Key=args.get(2);

intaccount2Value=Integer.parseInt(args.get(3));

_logger.info(String.format("account %s, value = %s; account %s, value %s",account1Key,account1Value,account2Key,account2Value));

// 调用 putStringState 方法将数据写入账本中

stub.putStringState(account1Key,args.get(1));

stub.putStringState(account2Key,args.get(3));

returnnewSuccessResponse();

}catch(Throwablee){

returnnewErrorResponse(e);

}

}

本示例要求用户输入的参数为KEY1_NAME, VALUE1, KEY2_NAME, VALUE2,并初始化2个键值对,调用 putStringState 将数据写入分布式账本中。

invoke 示例

invoke 函数是对用户具体业务逻辑的实现,用户可以根据不同的业务处理逻辑,调用不同的业务处理函数,如invoke,delete 和 query 函数。

// invoke把用户调用的function细分到几个子function, 包含invoke,delete和query

@Override

publicResponseinvoke(ChaincodeStubstub){

try{

_logger.info("Invoke java simple chaincode");

Stringfunc=stub.getFunction();

Listparams=stub.getParameters();

if(func.equals("invoke")){

returninvoke(stub,params);

}

if(func.equals("delete")){

returndelete(stub,params);

}

if(func.equals("query")){

returnquery(stub,params);

}

returnnewErrorResponse("Invalid invoke function name. Expecting one of: [\"invoke\", \"delete\", \"query\"]");

}catch(Throwablee){

returnnewErrorResponse(e);

}

}

invoke 函数

业务逻辑 invoke 函数实现了业务逻辑中的资产转移,将 accountFrom 的资产转移 amount 个单位给 accountTo。

// invoke实现了两个键之间的value转移,输入参数为KEY1_NAME, KEY2_NAME,VALUE

privateResponseinvoke(ChaincodeStubstub,Listargs){

if(args.size()!=3){

returnnewErrorResponse("Incorrect number of arguments. Expecting 3");

}

StringaccountFromKey=args.get(0);

StringaccountToKey=args.get(1);

// 获取accountFromKey的当前资产情况

StringaccountFromValueStr=stub.getStringState(accountFromKey);

if(accountFromValueStr==null){

returnnewErrorResponse(String.format("Entity %s not found",accountFromKey));

}

intaccountFromValue=Integer.parseInt(accountFromValueStr);

// 获取accountToKey的当前资产情况

StringaccountToValueStr=stub.getStringState(accountToKey);

if(accountToValueStr==null){

returnnewErrorResponse(String.format("Entity %s not found",accountToKey));

}

intaccountToValue=Integer.parseInt(accountToValueStr);

intamount=Integer.parseInt(args.get(2));

if(amount>accountFromValue){

returnnewErrorResponse(String.format("not enough money in account %s",accountFromKey));

}

// 业务逻辑:实现资产的转移

accountFromValue-=amount;

accountToValue+=amount;

_logger.info(String.format("new value of A: %s",accountFromValue));

_logger.info(String.format("new value of B: %s",accountToValue));

// 将更新后的资产更新到账本中

stub.putStringState(accountFromKey,Integer.toString(accountFromValue));

stub.putStringState(accountToKey,Integer.toString(accountToValue));

_logger.info("Transfer complete");

returnnewSuccessResponse("invoke finished successfully",ByteString.copyFrom(accountFromKey+": "+accountFromValue+" "+accountToKey+": "+accountToValue,UTF_8).toByteArray());

}

使用 API getStringState 获取到 KEY_NAME 对应的资产总值

调用业务逻辑实现 amount 个资产单位的转移

调用 API putStringState 将更新后的资产情况写入到账本中

注:上述实现的是一个类似转账的简单逻辑,但并未对参数的合法性诸如转账金额大于零、余额不为负等进行校验。

delete 函数

业务逻辑 delete 函数实现了业务逻辑中的账户删除功能。

// 从状态中删除实体

privateResponsedelete(ChaincodeStubstub,Listargs){

if(args.size()!=1){

returnnewErrorResponse("Incorrect number of arguments. Expecting 1");

}

Stringkey=args.get(0);

// 从分类帐中的状态删除密钥

stub.delState(key);

returnnewSuccessResponse();

}

query 函数

业务逻辑 query 函数实现了业务逻辑中的账户查询功能,通过调用 API GetState 查询对应账户的资产。

// query callback representing the query of a chaincode

privateResponsequery(ChaincodeStubstub,Listargs){

if(args.size()!=1){

returnnewErrorResponse("Incorrect number of arguments. Expecting name of the person to query");

}

Stringkey=args.get(0);

//byte[] stateBytes

Stringval=stub.getStringState(key);

if(val==null){

returnnewErrorResponse(String.format("Error: state for %s is null",key));

}

_logger.info(String.format("Query Response:\nName: %s, Amount: %s\n",key,val));

returnnewSuccessResponse(val,ByteString.copyFrom(val,UTF_8).toByteArray());

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值