LITESDK
说明:LITESDK是轻量级的JAVASDK,获取安装包请点击此处
快速开始
接口使用流程示例
说明:为了更好的理解接口的使用,本示例将从创建账户、编译合约、部署合约、调用合约和返回值解析这个大致流程作介绍,具体详细接口可参考API接口。
初始化服务
首先获取对应的Service服务,在获取Service服务时需要指定一个ProviderManager实例。
// 获取providerManager
DefaultHttpProvider defaultHttpProvider = new DefaultHttpProvider.Builder().setUrl(DEFAULT_URL).build();
ProviderManager providerManager = ProviderManager.createManager(defaultHttpProvider);
// 获取对应的服务
ContractService contractService = ServiceManager.getContractService(providerManager);
AccountService accountService = ServiceManager.getAccountService(providerManager);
创建账户
使用初始化好的AccountService创建一个账户
Account account = accountService.genSM2Account();
构造交易
构造交易传入需要的交易参数,详细使用见交易封装
Transaction transaction = new Transaction.HVMBuilder(account.getAddress())
.deploy("hvm-jar/hvmbasic-1.0.0-student.jar")
.build();
发送请求
使用初始化好的ContractService完成请求的发送,需要指定交易,拿到结果
ReceiptResponse receiptResponse = contractService.deploy(transaction).send().polling();
解析结果
使用Decoder中的方法进行对应的解码操作
Decoder.decodeHVM(receiptResponse.getRet(), String.class);
HVM合约完整示例
// 初始化服务
DefaultHttpProvider defaultHttpProvider = new DefaultHttpProvider.Builder().setUrl(DEFAULT_URL).build();
ProviderManager providerManager = ProviderManager.createManager(defaultHttpProvider);
ContractService contractService = ServiceManager.getContractService(providerManager);
AccountService accountService = ServiceManager.getAccountService(providerManager);
// 创建账户
Account account = accountService.genSM2Account();
// 构造交易
Transaction transaction = new Transaction.HVMBuilder(account.getAddress())
.deploy("hvm-jar/hvmbasic-1.0.0-student.jar")
.build();
// 发送部署请求
ReceiptResponse receiptResponse = contractService.deploy(transaction).send().polling();
System.out.println("合约地址: " + receiptResponse.getContractAddress());
System.out.println("部署返回(未解码): " + receiptResponse.getRet());
System.out.println("部署返回(解码):" + Decoder.decodeHVM(receiptResponse.getRet(), String.class));
// 调用合约
Transaction transaction1 = new Transaction.HVMBuilder(account.getAddress()).invoke(receiptResponse.getContractAddress(), new StudentInvoke()).build();
ReceiptResponse receiptResponse1 = contractService.invoke(transaction1).send().polling();
// 结果解码
System.out.println("调用返回(未解码): " + receiptResponse1.getRet());
System.out.println("调用返回(解码):" + Decoder.decodeHVM(receiptResponse1.getRet(), String.class));
使用说明
获取SDK
SDK说明
Hyperchain Java SDK 是提供给外部应用使用的与 Hyperchain 平台交互的工具包
配置依赖
配过对应的配置,可以直接获取到Hyperchain Java SDK
<dependency>
<groupId>cn.hyperchain</groupId>
<artifactId>LITESDK</artifactId>
<version>0.0.1</version>
</dependency>
// https://mvnrepository.com/artifact/cn.hyperchain/LITESDK
compile group: 'cn.hyperchain', name: 'LITESDK', version: '0.0.1'
// https://mvnrepository.com/artifact/cn.hyperchain/LITESDK
libraryDependencies += "cn.hyperchain" % "LITESDK" % "0.0.1"
// https://mvnrepository.com/artifact/cn.hyperchain/LITESDK
@Grapes(
@Grab(group='cn.hyperchain', module='LITESDK', version='0.0.1')
)
<dependency org="cn.hyperchain" name="LITESDK" rev="0.0.1"/>
初始化
初始化HttpProvider
HttpProvider为SDK中提供http网络消息服务,他提供一种网络通信方式,提供给上层调用。
定义
Provider的接口定义如下:
public interface HttpProvider {
String post(String body, Map<String, String> headers) throws RequestException;
PStatus getStatus();
String getUrl();
}
DefaultHttpProvider
DefaultHttpProvider是实现了HttpProvider的类,其提供了build构造器,你可以使用如下方式创建一个HttpProvider
创建DefaultHttpProvider:
DefaultHttpProvider defaultHttpProvider = new DefaultHttpProvider.Builder()
.setUrl(DEFAULT_URL)
.build();
实现自定义Provider
用户还可以编写自己的类实现HttpProvider接口,来在使用自己的工具,或者库来发送网络请求
ProviderManager
ProviderManager是SDK中管理消息网络发送的类,进行网络消息的负载均衡以及节点切换控制,ProviderManager可以包含多个Provider,上层通过ProviderManager发送网络请求,由ProviderManager选择具体发送节点 创建ProviderManager:
ProviderManager providerManager = ProviderManager.createManager(defaultHttpProvider);
用户可以在创建providerManager时提供多个Provider,这样在发送网络请求的时候ProviderManager会在添加的所有Provider中根据内部策略选择一个进行发送。
ProviderManager providerManager2 = ProviderManager.createManager(defaultHttpProvider1, defaultHttpProvider2 , myHttpProvider);
获取服务(Service)
Service是SDK对外部提供的接口,用户使用SDK的功能,就需要先获取到对应的Service
Service种类
当前SDK提供2种Service(未来将会扩展):
ContractService
ContractService提供了合约相关的接口,包括部署合约,调用合约等。其接口定义如下
public interface ContractService {
Request<TxHashResponse> deploy(Transaction transaction, int... nodeIds);
Request<TxHashResponse> invoke(Transaction transaction, int... nodeIds);
Request<ReceiptResponse> getReceipt(String txHash, int... nodeIds);
}
AccountService
ContractService提供了账户相关的接口,其接口定义如下
public interface AccountService {
Account genSM2Account();
}
Server获取
Server统一通过ServiceManager获取,如:
ContractService contractService = ServiceManager.getContractService(providerManager);
AccountService accountService = ServiceManager.getAccountService(providerManager);
创建账户
在获取到账户服务之后,用户可以通过账户服务来创建一个账户,创建的账户会用来进行交易的签名
Account account = accountService.genSM2Account();
交易类型
交易体的封装
SDK对于发送的交易需要进行封装,不同虚拟机的交易类型不同,同时SDK也需要将传进来的交易参数进行编码
SDK
使用构造器模式来创建相应虚拟机的Builder
来完成对Transaction
的创建,通过调用build()
函数来获取到Transaction
实例
class Builder {
Builder deploy();
Builder invoke();
Transaction build();
}
Transaction tx = new Transaction.Builder().build();
下面将详细展开具体Transaction
构造
HVM合约交易封装
HVM
合约交易的构造器继承自Transaction.Builder
,HVMBuilder
可以构造HVM
虚拟机的部署合约和调用合约两种交易
创建构造器
方法原型
public HVMBuilder(String from)
参数说明
参数名 | 参数描述 | |
---|---|---|
from | string | 调用者账户地址 |
使用示例
String accountAddress = "856E2B9A5FA82FD1B031D1FF6863864DBAC7995D";
HVMBuilder builder = new Transaction.HVMBuilder(accountAddress);
获取部署交易
方法原型
public Builder deploy(String jarPath)
参数说明
参数名 | 参数描述 | |
---|---|---|
jarPath | string | 合约jar包文件路径 |
使用示例
String accountAddress = "856E2B9A5FA82FD1B031D1FF6863864DBAC7995D";
String jarPath = "/usr/tmp/hvm-contract.jar";
Transaction tx = new Transaction.HVMBuilder(accountAddress).deploy(jarPath).build();
说明:合约jar包路径若为相对路径,则相对于当前SDK执行环境的classpath路径
获取调用交易
方法原型
public Builder invoke(String contractAddress, BaseInvoke baseInvoke)
参数说明
参数名 | 参数描述 | |
---|---|---|
contractAddress | string | 调用合约地址 |
baseInvoke | BaseInvoke | HVM合约的调用Bean实例 |
使用示例
String accountAddress = "856E2B9A5FA82FD1B031D1FF6863864DBAC7995D";
String contractAddr = "ec425efb6bd536b9874038a012e753022e75302a";
BaseInvoke baseInvoke = new StudentInvoke();
Transaction tx = new Transaction.HVMBuilder(accountAddress).invoke(contractAddr, baseInvoke).build();
说明:BaseInvoke的实现类必须包含空参构造函数
请求响应
请求类型
SDK网络请求接口将会返回请求参数Request
类型,Request
依照jsonRPC
来进行参数的封装,我们需要请求参数拥有如下参数:
- jsonrpc: 协议版本
- namespace: 命名空间
- method: 调用远程方法名
- params: 调用远程方法需要的参数
- id: 请求标识
SDK将根据不同的Service
接口,返回不同Request
子类,同时将用户调用接口的参数params
封装到Request
请求中,而Request
返回的Response
将根据不同的Service
接口绑定。
Request
拥有send()
和sendAsync()
同步发送和异步发送两个方法:
send()
: 同步发送返回Request
根据不同接口绑定的Response
sendAsync()
: 异步发送返回Request
根据不同接口绑定了Response
的Future
接口
响应类型
SDK网络请求Request
发送后将返回Response
响应,Response
将返回如下信息:
- jsonrpc: 协议版本
- code: 状态码
- message: 状态消息
- result: 请求结果
- id: 请求标识
SDK会将不同的返回结果result
根据接口封装成不同的Response
子类,Response
类型在生成Request
时绑定。
Response
可以获取状态码、状态消息等,而不同的Response
可以获取到不同的结果。
合约接口
获取合约Service
方法原型
public static ContractService getContractService(ProviderManager providerManager)
参数说明
参数名 | 参数描述 | |
---|---|---|
providerManager | ProviderManager | Provider管理器 |
返回值:ContractService
接口
使用示例
ProviderManager providerManager = ProviderManager.createManager(defaultHttpProvider);
ContractService contractService = ServiceManager.getContractService(providerManager);
部署合约
方法原型
Request<TxHashResponse> deploy(Transaction transaction, int... nodeIds)
参数说明
参数名 | 参数描述 | |
---|---|---|
transaction | Transaction | 部署交易 |
nodeIds | int[] | 限制请求节点id,空则为随机节点 |
返回值:绑定TxHashResponse
的Request
,调用发送接口后获取到TxHashResponse
TxHashResponse
拥有结构如下:
- txHash: 交易哈希值
使用示例
TxHashResponse txHashResponse = contractService.deploy(transaction).send();
ReceiptResponse receiptResponse = txHashResponse.polling();
System.out.println("合约地址: " + receiptResponse.getContractAddress());
说明:TxHashResponse可以获取交易的哈希值,通过polling()轮询获取交易回执Receipt
调用合约
方法原型
Request<TxHashResponse> invoke(Transaction transaction, int... nodeIds)
参数说明
参数名 | 参数描述 | |
---|---|---|
transaction | Transaction | 调用交易 |
nodeIds | int[] | 限制请求节点id,空则为随机节点 |
返回值:绑定TxHashResponse
的Request
,调用发送接口后获取到TxHashResponse
TxHashResponse
拥有结构如下:
- txHash: 交易哈希值
使用示例
TxHashResponse txHashResponse = contractService.invoke(transaction1).send();
ReceiptResponse receiptResponse = txHashResponse.polling();
System.out.println("调用返回(未解码): " + receiptResponse.getRet());
System.out.println("调用返回(解码):" + Decoder.decodeHVM(receiptResponse.getRet(), String.class));
说明:TxHashResponse可以获取交易的哈希值,通过polling()轮询获取交易回执Receipt
查询回执
方法原型
Request<ReceiptResponse> getReceipt(String txHash, int... nodeIds)
参数说明
参数名 | 参数描述 | |
---|---|---|
txHash | String | 交易哈希 |
nodeIds | int[] | 限制请求节点id,空则为随机节点 |
返回值:绑定ReceiptResponse
的Request
,调用发送接口后获取到ReceiptResponse
TxHashResponse
拥有结构如下:
- txHash: 交易哈希值
- ret: 交易执行结果
- log: 交易日志
- VMType: 虚拟机类型
- gasUsed: 消耗的
gas
使用示例
TxHashResponse txHashResponse = contractService.invoke(transaction1).send();
ReceiptResponse receiptResponse1 = txHashResponse.polling(); // 获取回执方式1
ReceiptResponse receiptResponse2 = contractService.getReceipt(txHashResponse.getTxHash()); // 获取回执方式1
System.out.println("调用返回(未解码): " + receiptResponse2.getRet());
System.out.println("调用返回(解码):" + Decoder.decodeHVM(receiptResponse2.getRet(), String.class));
说明:获取回执可以通过TxHashResponse获取的txHash值调用接口获取,也可以TxHashResponse的polling()函数轮询获取交易回执Receipt
工具接口
解码
在SDK中提供了解码类进行返回结果的解码,解码的定义如下:
public static <T> T decodeHVM(String encode, Class<T> clazz)
参数说明
参数名 | 参数描述 | |
---|---|---|
encode | String | 未解码的结果 |
clazz | Class | 指定的class类型 |
返回值 :指定类型的对象
使用示例
Decoder.decodeHVM(receiptResponse1.getRet(), String.class)
ByteUtil
ByteUtil类提供了多种数据类型转换的接口,如
public static String decodeHex(String hex)
参数说明
参数名 | 参数描述 | |
---|---|---|
hex | String | 十六进制字符串 |
返回值 :十六进制字符串对应的utf-8字符串
注意事项
对于调用返回的错误码,含义如下:
code | |
---|---|
0 | 请求成功 |
-32700 | 服务端接收到无效的json。该错误发送于服务器尝试解析json文本 |
-32600 | 无效的请求(比如非法的JSON格式) |
-32601 | 方法不存在或者无效 |
-32602 | 无效的方法参数 |
-32603 | JSON-RPC内部错误 |
-32000 | Hyperchain内部错误或者空指针或者节点未安装solidity环境 |
-32001 | 请求的数据不存在 |
-32002 | 余额不足 |
-32003 | 签名非法 |
-32004 | 合约部署出错 |
-32005 | 合约调用出错 |
-32006 | 系统繁忙(出现此错误,请考虑是否限流导致,将使SDK获取不到信息) |
-32007 | 交易重复 |
-32008 | 合约操作权限不够 |
-32009 | (合约)账户不存在 |
-32010 | namespace不存在 |
-32011 | 账本上无区块产生,查询最新区块的时候可能抛出该错误 |
-32096 | http请求处理超时 |
-32097 | Hypercli用户令牌无效 |
-32098 | 请求未带cert或者错误cert导致认证失败 |
-32099 | 请求tcert失败 |
-9995 | 请求失败(通常是请求体过长) |
-9996 | 请求失败(通常是请求消息错误) |
-9997 | 异步请求失败 |
-9998 | 请求超时 |
-9999 | 获取平台响应失败 |