2. Java SDK 使用说明
2.1. 基本概念定义
Java SDK定义了User、Node、ChainClient和ChainManager和SdkConfig几个类,分别介绍如下:
User: 表示链的一个用户信息,主要包括证书和private key,用来给要发送的交易payload签名或者给多签的payload签名。
Node:表示链的一个节点信息,它定义了节点的各种属性,如节点连接的RPC地址,连接所用的密钥信息等,一个ChainClient对象需要包含一个或多个Node,这样才能对过节点实现各种功能。
ChainClient:客户端开发最重要也是使用最多的类,代表逻辑上的一条链,所有客户端对链的操作接口都来自ChainClient。
ChainManager:负责管理所有创建过的链客户端,是一个链客户端管理类,避免用户同一条链客户端创建多个ChainClient。用户可以使用ChainManager来检查某条链客户端是否已经创建,或者直接创建某条链客户端,如果这条链客户端已经创建,ChainManager会直接返回之前已经创建过的。
SdkConfig: 创建ChainClient所需的配置类。
ChainClient对象给用户使用。数据结构定义如下:
public class User {
// the organization id of the user
private String orgId;
// user's private key used to sign transaction
private PrivateKey privateKey;
// user's certificate
private Certificate certificate;
// user's private key used to sign transaction
private PrivateKey tlsPrivateKey;
// user's certificate
private Certificate tlsCertificate;
// the bytes of user's certificate
private byte[] certBytes;
// the hash of the cert
private byte[] certHash;
private CryptoSuite cryptoSuite;
}
public class Node {
// node grpc address
private String grpcUrl;
// the organization's ca cert bytes
private byte[][] tlsCertBytes;
// the hostname in client certificate
private String hostname;
// TLS or PLAINTEXT
private String negotiationType;
// OPENSSL or JDK
private String sslProvider;
// node connect count
private int connectCount;
}
public class ChainClient {
// chainId is the identity of the chain
private String chainId;
// rpc connection Pool
private ConnectionPool connectionPool;
// archive config
private ArchiveConfig archiveConfig;
// the user used to sign transactions
private User clientUser;
}
public class ChainManager {
// chains' map
private final Map<String, ChainClient> chains = new HashMap<>();
// for singleton mode
private static final ChainManager chainManager = new ChainManager();
}
2.2. 环境准备
2.2.1. 软件依赖
java
jdk 8, jdk 11
下载地址:https://www.oracle.com/java/technologies/downloads/
若已安装,请通过命令查看版本:
$ java -version
java version "1.8.0_202"
2.2.2. 下载安装
$ git clone -b v2.3.1.3 --depth=1 https://git.chainmaker.org.cn/chainmaker/sdk-java.git
2.2.3. jar包依赖
需将sdk
中依赖的jar
包导入本地工程中,
同时,需将sdk
中lib
目录下的netty-tcnative-openssl-static-2.0.39.Final.jar
包导入工程中,以便适配国密tls
通信。
需要手动引入的jar包:io.netty.netty-handler 需要:4.1.53.Final - 4.1.65.Final,bcpkix-jdk15on 1.62+,grpc。
参考:https://git.chainmaker.org.cn/chainmaker/sdk-java-demo/-/tree/v2.3.0_online_opennet
2.3. 怎么使用SDK
2.3.1. maven中央仓库
<dependency>
<groupId>org.chainmaker</groupId>
<artifactId>chainmaker-sdk-java</artifactId>
<version>2.3.1.3</version>
</dependency>
2.3.2. 应用demo
java sdk应用示例,请参考: sdk-java-demo
2.3.3. 示例代码
2.3.3.1. 以参数形式创建ChainClient
更多内容请参看:
TestBase
public void initWithNoConfig() throws SdkException {
byte[][] tlsCaCerts = new byte[][]{FileUtils.getResourceFileBytes(ORG1_CERT_PATH)};
SdkConfig sdkConfig = new SdkConfig();
ChainClientConfig chainClientConfig = new ChainClientConfig();
sdkConfig.setChainClient(chainClientConfig);
RpcClientConfig rpcClientConfig = new RpcClientConfig();
rpcClientConfig.setMaxReceiveMessageSize(MAX_MESSAGE_SIZE);
ArchiveConfig archiveConfig = new ArchiveConfig();
archiveConfig.setDest(DEST);
archiveConfig.setType(TYPE);
archiveConfig.setSecretKey(SECRET_KEY);
NodeConfig nodeConfig = new NodeConfig();
nodeConfig.setTrustRootBytes(tlsCaCerts);
nodeConfig.setTlsHostName(TLS_HOST_NAME1);
nodeConfig.setEnableTls(true);
nodeConfig.setNodeAddr(NODE_GRPC_URL1);
nodeConfig.setConnCnt(CONNECT_COUNT);
NodeConfig[] nodeConfigs = new NodeConfig[]{nodeConfig};
chainManager = ChainManager.getInstance();
chainClient = chainManager.getChainClient(CHAIN_ID);
chainClientConfig.setOrgId(ORG_ID1);
chainClientConfig.setChainId(CHAIN_ID);
chainClientConfig.setUserKeyBytes(FileUtils.getResourceFileBytes(CLIENT1_TLS_KEY_PATH));
chainClientConfig.setUserCrtBytes(FileUtils.getResourceFileBytes(CLIENT1_TLS_CERT_PATH));
chainClientConfig.setUserSignKeyBytes(FileUtils.getResourceFileBytes(CLIENT1_KEY_PATH));
chainClientConfig.setUserSignCrtBytes(FileUtils.getResourceFileBytes(CLIENT1_CERT_PATH));
chainClientConfig.setRpcClient(rpcClientConfig);
chainClientConfig.setArchive(archiveConfig);
chainClientConfig.setNodes(nodeConfigs);
if (chainClient == null) {
chainClient = chainManager.createChainClient(sdkConfig);
}
}
2.3.3.2. 以配置文件形式创建ChainClient
更多内容请参看:
TestBase
public void init() throws IOException, SdkException {
Yaml yaml = new Yaml();
InputStream in = TestBase.class.getClassLoader().getResourceAsStream(SDK_CONFIG);
SdkConfig sdkConfig;
sdkConfig = yaml.loadAs(in, SdkConfig.class);
assert in != null;
in.close();
for (NodeConfig nodeConfig : sdkConfig.getChain_client().getNodes()) {
List<byte[]> tlsCaCertList = new ArrayList<>();
for (String rootPath : nodeConfig.getTrustRootPaths()){
List<String> filePathList = FileUtils.getFilesByPath(rootPath);
for (String filePath : filePathList) {
tlsCaCertList.add(FileUtils.getFileBytes(filePath));
}
}
byte[][] tlsCaCerts = new byte[tlsCaCertList.size()][];
tlsCaCertList.toArray(tlsCaCerts);
nodeConfig.setTrustRootBytes(tlsCaCerts);
}
chainManager = ChainManager.getInstance();
chainClient = chainManager.getChainClient(sdkConfig.getChain_client().getChainId());
if (chainClient == null) {
chainClient = chainManager.createChainClient(sdkConfig);
}
}
2.3.3.3. 创建合约
更多内容请参看:
TestUserContract
、TestEvmContract
,evm需要abi编码,故需特殊处理
public void testCreateContract() throws IOException, InterruptedException, ExecutionException, TimeoutException {
ResultOuterClass.TxResponse responseInfo = null;
try {
byte[] byteCode = FileUtils.getResourceFileBytes(CONTRACT_FILE_PATH);
// 1. create payload
Request.Payload payload = chainClient.createContractCreatePayload(CONTRACT_NAME, "1", byteCode,
ContractOuterClass.RuntimeType.WASMER, null);
//2. create payloads with endorsement
Request.EndorsementEntry[] endorsementEntries = SdkUtils.getEndorsers(payload, new User[]{adminUser1, adminUser2, adminUser3});
// 3. send request
responseInfo = chainClient.sendContractManageRequest(payload, endorsementEntries, rpcCallTimeout, syncResultTimeout);
} catch (SdkException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
Assert.assertNotNull(responseInfo);
}
2.3.3.4. 调用合约
更多内容请参看:
TestUserContract
、TestEvmContract
,evm需要abi编码,故需特殊处理
public void testInvokeContract() throws Exception {
ResultOuterClass.TxResponse responseInfo = null;
try {
responseInfo = chainClient.invokeContract(CONTRACT_NAME, INVOKE_CONTRACT_METHOD,
null, null, rpcCallTimeout, syncResultTimeout);
} catch (Exception e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
Assert.assertNotNull(responseInfo);
}
2.3.4. 更多示例和用法
更多示例和用法,请参看单元测试用例
功能 | 单测代码 |
---|---|
基础配置 | TestBase |
用户合约 | TestUserContract |
EVM合约 | TestEvmContract |
系统合约 | TestSystemContract |
链配置 | TestChainConfig |
证书管理 | TestBaseCertManage |
消息订阅 | TestSubscribe |
线上多签 | TestContractMultisign |
公钥身份 | TestPubkeyManage |
2.4. 接口说明
2.4.1. 1 用户合约接口
2.4.1.1. 1.1 生成用于创建合约的待签名payload
参数说明
contractName: 合约名
version: 版本号
runtimeType: 合约运行环境
params: 合约初始化参数
byteCodes: 合约字节数组
public Request.Payload createContractCreatePayload(String contractName, String version, byte[] byteCode,
ContractOuterClass.RuntimeType runtime, Map<String, byte[]> params)
2.4.1.2. 1.2 生成用于升级合约的待签名payload
参数说明
contractName: 合约名
version: 版本号
runtimeType: 合约运行环境
params: 合约初始化参数
byteCodes: 合约字节数组
public Request.Payload createContractUpgradePayload(String contractName, String version, byte[] byteCode,
ContractOuterClass.RuntimeType runtime, Map<String, byte[]> params)
2.4.1.3. 1.3 生成用于冻结合约的待签名payload
参数说明
contractName: 合约名
public Request.Payload createContractFreezePayload(String contractName) {}
2.4.1.4. 1.4 生成用于解冻合约的待签名payload
参数说明
contractName: 合约名
public Request.Payload createContractUnFreezePayload(String contractName) {}
2.4.1.5. 1.5 生成用于吊销合约的待签名payload
参数说明
contractName: 合约名
public Request.Payload createContractRevokePayload(String contractName) {}
2.4.1.6. 1.6 发送合约操作请求
参数说明
payload: 合约内容
endorsementEntries: 带签名的合约内容
rpcCallTimeout: 调用rcp接口超时时间, 单位:毫秒
syncResultTimeout: 同步获取执行结果超时时间,小于等于0代表不等待执行结果,直接返回(返回信息里包含交易Id),单位:毫秒
public ResultOuterClass.TxResponse sendContractManageRequest(Request.Payload payload, Request.EndorsementEntry[] endorsementEntries,
long rpcCallTimeout, long syncResultTimeout)
2.4.1.7. 1.7 执行合约
参数说明
contractName: 合约名
method: 方法名
params: 执行参数
rpcCallTimeout: 调用rcp接口超时时间, 单位:毫秒
syncResultTimeout: 同步获取执行结果超时时间,小于等于0代表不等待执行结果,直接返回(返回信息里包含交易Id),单位:毫秒
public ResultOuterClass.TxResponse invokeContract(String contractName, String method, String txId, Map<String, byte[]> params,
long rpcCallTimeout, long syncResultTimeout)
2.4.1.8. 1.8 查询合约接口
参数说明
contractName: 合约名
method: 方法名
txId: 交易Id
params: 执行参数
rpcCallTimeout: 执行超时时间,单位毫秒
public ResultOuterClass.TxResponse queryContract(String contractName, String method, String txId,
Map<String, byte[]> params, long rpcCallTimeout)
2.4.2. 2 系统合约接口
2.4.2.1. 2.1 根据交易Id查询交易
参数说明
txId: 交易Id
rpcCallTimeout:超时时间,单位毫秒
public ChainmakerTransaction.TransactionInfo getTxByTxId(String txId, long rpcCallTimeout)
2.4.2.2. 2.2 根据区块高度查询区块
参数说明
blockHeight: 区块高度
withRWSet: 是否返回读写集
rpcCallTimeout:超时时间,单位毫秒
public ChainmakerBlock.BlockInfo getBlockByHeight(long blockHeight, boolean withRWSet, long rpcCallTimeout)
2.4.2.3. 2.3 根据区块哈希查询区块
参数说明
blockHash: 区块高度
withRWSet: 是否返回读写集
rpcCallTimeout:超时时间,单位毫秒
public ChainmakerBlock.BlockInfo getBlockByHash(String blockHash, boolean withRWSet, long rpcCallTimeout)
2.4.2.4. 2.4 根据交易Id查询区块
参数说明
txId: 交易Id
withRWSet: 是否返回读写集
rpcCallTimeout:超时时间,单位毫秒
public ChainmakerBlock.BlockInfo getBlockByTxId(String txId, boolean withRWSet, long rpcCallTimeout)
2.4.2.5. 2.5 查询上一个配置块
参数说明
withRWSet: 是否返回读写集
rpcCallTimeout:超时时间,单位毫秒
public ChainmakerBlock.BlockInfo getLastConfigBlock(boolean withRWSet, long rpcCallTimeout)
2.4.2.6. 2.6 查询节点加入的链信息
参数说明
rpcCallTimeout:超时时间,单位毫秒
public Discovery.ChainList getNodeChainList(long rpcCallTimeout)
2.4.2.7. 2.7 查询链信息
参数说明
rpcCallTimeout:超时时间,单位毫秒
public Discovery.ChainInfo getChainInfo(long rpcCallTimeout)
2.4.2.8. 2.8 根据txId查询区块高度
参数说明
txId: 交易Id
rpcCallTimeout:超时时间,单位毫秒
public long getBlockHeightByTxId(String txId, long rpcCallTimeout)
2.4.2.9. 2.9 根据blockHash查询区块高度
参数说明
blockHash: 区块哈希
rpcCallTimeout:超时时间,单位毫秒
public long getBlockHeightByBlockHash(String blockHash, long rpcCallTimeout)
2.4.2.10. 2.10 根据区块高度查询完整区块
参数说明
blockHeight : 区块高度
rpcCallTimeout:超时时间,单位毫秒
public Store.BlockWithRWSet getFullBlockByHeight(long blockHeight, long rpcCallTimeout)
2.4.2.11. 2.11 查询最新区块信息
参数说明
withRWSet: 是否返回读写集
rpcCallTimeout:超时时间,单位毫秒
public ChainmakerBlock.BlockInfo getLastBlock(boolean withRWSet, long rpcCallTimeout)
2.4.2.12. 2.12 查询最新区块高度
参数说明
timeout:超时时间,单位毫秒
public long getCurrentBlockHeight(long timeout)
2.4.2.13. 2.13 根据区块高度查询区块头
参数说明
区块高度: blockHeight
rpcCallTimeout:超时时间,单位毫秒
public ChainmakerBlock.BlockHeader getBlockHeaderByHeight(long blockHeight, long timeout)
2.4.2.14. 2.14 系统合约调用
参数说明
method: 方法名
txId: 交易Id
params: 执行参数
rpcCallTimeout: 调用rcp接口超时时间, 单位:毫秒
syncResultTimeout: 同步获取执行结果超时时间,小于等于0代表不等待执行结果,直接返回(返回信息里包含交易Id),单位:毫秒
public ResultOuterClass.TxResponse invokeSystemContract(String contractName, String method, String txId, Map<String, byte[]> params,
long rpcCallTimeout, long syncResultTimeout)
2.4.2.15. 2.15 系统合约查询
参数说明
method: 方法名
txId: 交易Id
params: 执行参数
rpcCallTimeout: 调用rcp接口超时时间, 单位:毫秒
public ResultOuterClass.TxResponse (String contractName, String method, String txId,
Map<String, byte[]> params, long rpcCallTimeout)
2.4.2.16. 2.16 根据交易Id获取Merkle路径
参数说明 - txId: 交易Id
public byte[] getMerklePathByTxId(String txId, long rpcCallTimeout)
2.4.2.17. 2.17 开放系统合约
参数说明
grantContractList: 需要开放的系统合约字符串数组
public Request.Payload createNativeContractAccessGrantPayload(String[] grantContractList)
2.4.2.18. 2.18 弃用系统合约
参数说明
revokeContractList: 需要弃用的系统合约字符串数组
public Request.Payload createNativeContractAccessRevokePayload(String[] revokeContractList)
2.4.2.19. 2.19 查询弃用的系统合约名单
public Request.Payload createGetDisabledNativeContractListPayload()
2.4.2.20. 2.20 查询指定合约的信息,包括系统合约和用户合约
参数说明
contractName: 指定查询的合约名字,包括系统合约和用户合约
rpcCallTimeout: 调用rcp接口超时时间, 单位:毫秒
public String getContractInfo(String contractName, long rpcCallTimeout)
2.4.2.21. 2.21 查询所有的合约名单,包括系统合约和用户合约
public String getContractList(long rpcCallTimeout)
2.4.2.22. 2.22 查询已禁用的系统合约名单
public String getDisabledNativeContractList(long rpcCallTimeout)
2.4.3. 3 链配置接口
2.4.3.1. 3.1 查询最新链配置
public ChainConfigOuterClass.ChainConfig getChainConfig(long rpcCallTimeout)
2.4.3.2. 3.2 根据指定区块高度查询最近链配置
参数说明
blockHeight: 区块高度
public ChainConfigOuterClass.ChainConfig getChainConfigByBlockHeight(long blockHeight, long rpcCallTimeout)
2.4.3.3. 3.3 查询最新链配置序号Sequence
用于链配置更新
public long getChainConfigSequence(long rpcCallTimeout)
2.4.3.4. 3.4 更新Core模块待签名payload生成
参数说明
txSchedulerTimeout: 交易调度器从交易池拿到交易后, 进行调度的时间,其值范围为[0, 60],若无需修改,请置为-1
txSchedulerValidateTimeout: 交易调度器从区块中拿到交易后, 进行验证的超时时间,其值范围为[0, 60], 若无需修改,请置为-1
public Request.Payload createPayloadOfChainConfigCoreUpdate(int txSchedulerTimeout, int txSchedulerValidateTimeout, long rpcCallTimeout)
2.4.3.5. 3.5 更新Core模块待签名payload生成
参数说明
txTimestampVerify: 是否需要开启交易时间戳校验
(以下参数,若无需修改,请置为-1)
txTimeout: 交易时间戳的过期时间(秒),其值范围为[600, +∞)
blockTxCapacity: 区块中最大交易数,其值范围为(0, +∞]
blockSize: 区块最大限制,单位MB,其值范围为(0, +∞]
blockInterval: 出块间隔,单位:ms,其值范围为[10, +∞]
public Request.Payload createPayloadOfChainConfigBlockUpdate(boolean txTimestampVerify, int txTimeout, int blockTxCapacity,
int blockSize, int blockInterval, long rpcCallTimeout)
2.4.3.6. 3.6 添加信任组织根证书待签名payload生成
参数说明
trustRootOrgId: 组织Id
trustRootCrt: 根证书
public Request.Payload createPayloadOfChainConfigTrustRootAdd(String trustRootOrgId, String[] trustRootCrt, long rpcCallTimeout)
2.4.3.7. 3.7 更新信任组织根证书待签名payload生成
参数说明
trustRootOrgId: 组织Id
trustRootCrt: 根证书
public Request.Payload createPayloadOfChainConfigTrustRootUpdate(String trustRootOrgId, String[] trustRootCrt, long rpcCallTimeout)
2.4.3.8. 3.8 删除信任组织根证书待签名payload生成
参数说明
trustRootOrgId: 组织Id
public Request.Payload createPayloadOfChainConfigTrustRootDelete(String trustRootOrgId, long rpcCallTimeout)
2.4.3.9. 3.9 添加权限配置待签名payload生成
参数说明
permissionResourceName: 权限名
principle: 权限规则
public Request.Payload createPayloadOfChainConfigPermissionAdd(String permissionResourceName,
PolicyOuterClass.Policy principal, long rpcCallTimeout)
2.4.3.10. 3.10 更新权限配置待签名payload生成
参数说明
permissionResourceName: 权限名
principle: 权限规则
public Request.Payload createPayloadOfChainConfigPermissionUpdate(String permissionResourceName,
PolicyOuterClass.Policy principal, long rpcCallTimeout)
2.4.3.11. 3.11 删除权限配置待签名payload生成
参数说明
permissionResourceName: 权限名
public Request.Payload createPayloadOfChainConfigPermissionDelete(String permissionResourceName, long rpcCallTimeout)
2.4.3.12. 3.12 添加共识节点地址待签名payload生成
参数说明
nodeOrgId: 节点组织Id
nodeAddresses: 节点地址
public Request.Payload createPayloadOfChainConfigConsensusNodeAddrAdd(String nodeOrgId, String[] nodeAddresses, long rpcCallTimeout)
2.4.3.13. 3.13 更新共识节点地址待签名payload生成
参数说明
nodeOrgId: 节点组织Id
nodeOldAddress: 节点原地址
nodeNewAddress: 节点新地址
public Request.Payload createPayloadOfChainConfigConsensusNodeAddrUpdate(String nodeOrgId, String nodeOldAddress,
String nodeNewAddress, long rpcCallTimeout)
2.4.3.14. 3.14 删除共识节点地址待签名payload生成
参数说明
nodeOrgId: 节点组织Id
nodeAddress: 节点地址
public Request.Payload createPayloadOfChainConfigConsensusNodeAddrDelete(String nodeOrgId, String nodeAddress, long rpcCallTimeout)
2.4.3.15. 3.15 添加共识节点待签名payload生成
参数说明
nodeOrgId: 节点组织Id
nodeAddresses: 节点地址
public Request.Payload createPayloadOfChainConfigConsensusNodeOrgAdd(String nodeOrgId, String[] nodeAddresses, long rpcCallTimeout)
2.4.3.16. 3.16 更新共识节点待签名payload生成
参数说明
nodeOrgId: 节点组织Id
nodeAddresses: 节点地址
public Request.Payload createPayloadOfChainConfigConsensusNodeOrgUpdate(String nodeOrgId, String[] nodeAddresses, long rpcCallTimeout)
2.4.3.17. 3.17 删除共识节点待签名payload生成
参数说明
nodeOrgId: 节点组织Id
public Request.Payload createPayloadOfChainConfigConsensusNodeOrgDelete(String nodeOrgId, long rpcCallTimeout)
2.4.3.18. 3.18 添加共识扩展字段待签名payload生成
参数说明
params: Map<String, String>
public Request.Payload createPayloadOfChainConfigConsensusExtAdd(Map<String, byte[]> params, long rpcCallTimeout)
2.4.3.19. 3.19 添加共识扩展字段待签名payload生成
参数说明
params: Map<String, String>
public Request.Payload createPayloadOfChainConfigConsensusExtUpdate(Map<String, byte[]> params, long rpcCallTimeout)
2.4.3.20. 3.20 添加共识扩展字段待签名payload生成
参数说明
keys: 待删除字段
public Request.Payload createPayloadOfChainConfigConsensusExtDelete(String[] keys, long rpcCallTimeout)
2.4.3.21. 3.21 添加信任成员证书待签名payload生成
参数说明
trustMemberOrgId: 组织Id
trustMemberNodeId: 节点Id
trustMemberRole: 成员角色
trustMemberInfo: 成员信息内容
public Request.Payload createChainConfigTrustMemberAddPayload(String trustMemberOrgId, String trustMemberNodeId, String trustMemberRole,
String trustMemberInfo, long rpcCallTimeout)
2.4.3.22. 3.22 删除信任成员证书待签名payload生成
参数说明
trustMemberInfo: 成员信息内容
public Request.Payload createChainConfigTrustMemberAddPayload(String trustMemberInfo, long rpcCallTimeout)
2.4.3.23. 3.23 发送链配置更新请求
public ResultOuterClass.TxResponse updateChainConfig(Request.Payload payload, Request.EndorsementEntry[] endorsementEntries,
long rpcCallTimeout, long syncResultTimeout)
2.4.3.24. 3.25 修改地址类型payload生成
参数说明
addrType:地址类型,0-ChainMaker; 1-ZXL
rpcCallTimeout:超时时间
public Request.Payload createChainConfigAlterAddrTypePayload(String addressType, long rpcCallTimeout)
2.4.3.25. 3.27 开启或关闭链配置的Gas优化payload生成
参数说明
enable: 是否开启
rpcCallTimeout:超时时间
public Request.Payload createChainConfigOptimizeChargeGasPayload(Boolean enable, long rpcCallTimeout)
2.4.3.26. 3.28 查询最新权限配置列表
参数说明
rpcCallTimeout:超时时间
public List<ChainConfigOuterClass.ResourcePolicy> getChainConfigPermissionList(long rpcCallTimeout)
2.4.4. 4 证书管理接口
2.4.4.1. 4.1 用户证书添加
参数说明
rpcCallTimeout: 发送rpc请求的超时时间
public ResultOuterClass.TxResponse addCert(long rpcCallTimeout)
2.4.4.2. 4.2 用户证书删除
参数说明
payload: 合约内容
endorsementEntries: 带签名的合约内容
public ResultOuterClass.TxResponse deleteCert(Request.Payload payload, Request.EndorsementEntry[] endorsementEntries,
long rpcCallTimeout, long syncResultTimeout)
2.4.4.3. 4.3 用户证书冻结
参数说明
payload: 证书冻结的payload
endorsementEntries: 多签信息
public ResultOuterClass.TxResponse freezeCerts(Request.Payload payload, Request.EndorsementEntry[] endorsementEntries,
long rpcCallTimeout, long syncResultTimeout)
2.4.4.4. 4.4 用户证书解冻
参数说明
payload: 证书冻结的payload
endorsementEntries: 多签信息
public ResultOuterClass.TxResponse unfreezeCerts(Request.Payload payload, Request.EndorsementEntry[] endorsementEntries,
long rpcCallTimeout, long syncResultTimeout)
2.4.4.5. 4.5 用户证书吊销
参数说明
payload: 证书冻结的payload
endorsementEntries: 多签信息
public ResultOuterClass.TxResponse revokeCerts(Request.Payload payload, Request.EndorsementEntry[] endorsementEntries,
long rpcCallTimeout, long syncResultTimeout)
2.4.4.6. 4.6 冻结证书payload
参数说明
certHashes: 冻结证书列表
public Request.Payload createCertFreezePayload(String[] certHashes)
2.4.4.7. 4.7 解冻证书payload
参数说明
certHashes: 冻结证书列表
public Request.Payload createPayloadOfUnfreezeCerts(String[] certHashes)
2.4.4.8. 4.8 吊销证书
参数说明
certCrl: 证书吊销crl
public Request.Payload createPayloadOfRevokeCerts(String certCrl)
2.4.4.9. 4.9 用户证书查询
参数说明
certHashes: 证书Hash列表
public ResultOuterClass.CertInfos queryCert(String[] certHashes, long rpcCallTimeout)
2.4.5. 5 消息订阅接口
2.4.5.1. 5.1 区块订阅
参数说明
startBlock: 订阅起始区块高度,若为-1,表示订阅实时最新区块
endBlock: 订阅结束区块高度,若为-1,表示订阅实时最新区块
withRwSet: 是否返回读写集
onlyHeader: 是否只返回区块头
public void subscribeBlock(long startBlock, long endBlock, boolean withRwSet, boolean onlyHeader,
StreamObserver<ResultOuterClass.SubscribeResult> blockStreamObserver)
2.4.5.2. 5.2 交易订阅
参数说明
startBlock: 订阅起始区块高度,若为-1,表示订阅实时最新区块
endBlock: 订阅结束区块高度,若为-1,表示订阅实时最新区块
txType: 订阅交易类型,若为pb.TxType(-1),表示订阅所有交易类型
txIds: 订阅txId列表,若为空,表示订阅所有txId
public void subscribeTx(long startBlock, long endBlock, String contractName, String[] txIds,
StreamObserver<ResultOuterClass.SubscribeResult> txStreamObserver)
2.4.5.3. 5.3 事件订阅
参数说明
topic: 订阅话题
contractName: 订阅合约名
public void subscribeContractEvent(String topic, String contractName,
StreamObserver<ResultOuterClass.SubscribeResult> contractEventStreamObserver)
2.4.6. 6 归档类接口
2.4.6.1. 6.1 数据归档payload生成
参数说明
targetBlockHeight: 归档区块高度
public Request.Payload createArchiveBlockPayload(long targetBlockHeight)
2.4.6.2. 6.2 归档恢复payload生成
参数说明
payload: 归档恢复payload
public ResultOuterClass.TxResponse sendRestoreBlockRequest(Request.Payload payload, long timeout)
2.4.6.3. 6.3 发送数据归档请求
参数说明
payload: 数据归档payload
public ResultOuterClass.TxResponse sendArchiveBlockRequest(Request.Payload payload, long timeout)
2.4.6.4. 6.4 发送归档恢复请求
参数说明
payloadBytes: 归档恢复payload
public ResponseInfo sendRestoreBlockRequest(byte[] payloadBytes, long timeout)
throws ChainMakerCryptoSuiteException, ChainClientException {
}
2.4.6.5. 6.5 获取归档数据
参数说明
targetBlockHeight: 归档区块高度
public Store.BlockWithRWSet getArchivedFullBlockByHeight(long blockHeight)
throws InvalidProtocolBufferException, SQLException, ClassNotFoundException {
}
2.4.6.6. 6.6 获取归档区块信息
参数说明
targetBlockHeight: 归档区块高度
withRWSet: 是否获取读写集
public ChainmakerBlock.BlockInfo getArchivedBlockByHeight(long blockHeight, boolean withRWSet)
throws InvalidProtocolBufferException, SQLException, ClassNotFoundException {
}
2.4.7. 7 公钥身份类接口
2.4.7.1. 7.1 构造添加公钥身份请求
参数说明
pubkey: 公钥信息
orgId: 组织id
role: 角色,支持client,light,common
public Request.Payload createPubkeyAddPayload(String pubkey, String orgId, String role)
2.4.7.2. 7.2 构造删除公钥身份请求
参数说明
pubkey: 公钥信息
orgId: 组织id
public Request.Payload createPubkeyDelPayload(String pubkey, String orgId)
2.4.7.3. 7.3 构造查询公钥身份请求
参数说明
pubkey: 公钥信息
public Request.Payload createPubkeyQueryPayload(String pubkey)
2.4.7.4. 7.4 发送公钥身份管理请求(添加、删除)
参数说明
payload: 合约内容
endorsementEntries: 带签名的合约内容
rpcCallTimeout: 调用rcp接口超时时间, 单位:毫秒
syncResultTimeout: 同步获取执行结果超时时间,小于等于0代表不等待执行结果,直接返回(返回信息里包含交易Id),单位:毫秒
public ResultOuterClass.TxResponse sendPubkeyManageRequest(Request.Payload payload, Request.EndorsementEntry[] endorsementEntries,
long rpcCallTimeout, long syncResultTimeout)
2.4.8. 8 多签类接口
2.4.8.1. 8.1 发起多签请求
参数说明
payload: 多签payload
public ResultOuterClass.TxResponse multiSignContractReq(Request.Payload payload, long rpcCallTimeout)
2.4.8.2. 8.2 发起多签投票
参数说明
payload: 多签payload
endorsementEntry: 多签信息
public ResultOuterClass.TxResponse multiSignContractVote(Request.Payload payload, Request.EndorsementEntry endorsementEntry, long rpcCallTimeout)
2.4.8.3. 8.3 多签查询
参数说明
txId: 交易Id
public ResultOuterClass.TxResponse multiSignContractQuery(String txId, long rpcCallTimeout)
2.4.8.4. 8.4 创建多签请求payload
参数说明
params: 多签参数
public Request.Payload createMultiSignReqPayload(Map<String, byte[]> params)
2.4.8.5. 8.5 创建多签投票payload
参数说明
params: 多签参数
public Request.Payload createMultiSignVotePayload(Map<String, byte[]> params)
2.4.8.6. 8.6 创建多签查询payload
参数说明
params: 多签参数
public Request.Payload createMultiSignQueryPayload(Map<String, byte[]> params)
2.4.9. 9 管理类接口
2.4.9.1. 9.1 SDK停止接口:关闭连接池连接,释放资源
public void stop()
2.4.10. 10 gas管理相关接口
2.4.10.1. 10.1 构造设置gas管理员payload
参数说明
address: gas管理员的地址
public Request.Payload createSetGasAdminPayload(String address)
2.4.10.2. 10.2 查询gas管理员
参数说明
rpcCallTimeout: 调用rpc接口超时时间, 单位:毫秒
public String getGasAdmin(long rpcCallTimeout)
2.4.10.3. 10.3 构造充值gas账户payload
参数说明
rechargeGasList: 一个gas账户充值指定gas数量
public Request.Payload createRechargeGasPayload(AccountManager.RechargeGas[] rechargeGasList)
2.4.10.4. 10.4 查询gas账户余额(根据公钥)
参数说明
address: 查询gas余额的账户地址
rpcCallTimeout: 调用rpc接口超时时间, 单位:毫秒
public long getGasBalance(String address, long rpcCallTimeout)
2.4.10.5. 10.5 构造 退还gas账户的gas payload
参数说明
address: 退还gas的账户地址
amount: 退还gas的数量
public Request.Payload createRechargeGasPayload(AccountManager.RechargeGas[] rechargeGasList)
2.4.10.6. 10.6 构造 冻结指定gas账户 payload
参数说明
address: 冻结指定gas账户的账户地址
public Request.Payload createFrozenGasAccountPayload(String address)
2.4.10.7. 10.7 构造 退还gas账户的gas payload
参数说明
address: 解冻指定gas账户的账户地址
public Request.Payload createUnfrozenGasAccountPayload(String address)
2.4.10.8. 10.8 查询gas账户的状态
参数说明
address: 指定gas账户的账户地址
rpcCallTimeout: 调用rpc接口超时时间, 单位:毫秒
public boolean getGasAccountStatus(String address, long rpcCallTimeout)
2.4.10.9. 10.9 发送gas管理类请求
参数说明
payload: 交易payload
endorsementEntries: 背书签名信息列表
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
syncResultTimeout: 是否同步获取交易执行结果
public ResultOuterClass.TxResponse sendGasManageRequest(Request.Payload payload, Request.EndorsementEntry[] endorsementEntries, long rpcCallTimeout, long syncResultTimeout)
2.4.10.10. 10.10 为payload添加gas limit
参数说明
payload: 交易payload
limit: gas limit
public Request.Payload attachGasLimit(Request.Payload payload, Request.Limit limit)
2.4.10.11. 10.11 启用或停用Gas计费开关payload生成
参数说明
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public Request.Payload createChainConfigEnableOrDisableGasPayload(long rpcCallTimeout)
2.4.10.12. 10.12 构造 配置账户基础gas消耗数量 payload
参数说明
amount: 基础gas消耗数量
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public Request.Payload createSetInvokeBaseGasPayload(long amount, long rpcCallTimeout)
2.4.10.13. 10.13 估算交易的gas消耗量
参数说明
payload: 待估算gas消耗量的交易payload
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public long estimateGas(Request.Payload payload, long rpcCallTimeout)
2.4.11. 11 别名管理相关接口
2.4.11.1. 11.1 添加别名
参数说明
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public ResultOuterClass.TxResponse addAlias(long rpcCallTimeout)
2.4.11.2. 11.2 构造更新别名payload
参数说明
alias: 要更新的别名
certPEM: 对应的证书
public Request.Payload createUpdateAliasPayload(String alias, String certPem)
2.4.11.3. 11.3 发起更新别名交易
参数说明
payload: 待签名的payload
endorsementEntries: 背书签名信息列表
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public Request.Payload createUpdateAliasPayload(String alias, String certPem)
2.4.11.4. 11.4 查询别名详情交易
参数说明
aliasList: 要查询的别名列表
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public ResultOuterClass.AliasInfos queryAlias(String[] aliasList, long rpcCallTimeout)
2.4.11.5. 11.5 生成删除别名payload
参数说明
aliasList: 要查询的别名列表
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public Request.Payload createAliasDeletePayload(String[] aliasList)
2.4.11.6. 11.6 发起更新别名交易
参数说明
payload: 待签名的payload
endorsementEntries: 背书签名信息列表
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
syncResultTimeout: 是否同步获取交易执行结果
public ResultOuterClass.TxResponse deleteAlias(Request.Payload payload, Request.EndorsementEntry[] endorsementEntries,
long rpcCallTimeout, long syncResultTimeout)
2.4.12. 15 交易池相关接口
2.4.12.1. 15.1 获取交易池状态
参数说明
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public TransactionPool.TxPoolStatus getPoolStatus(long rpcCallTimeout)
2.4.12.2. 15.2 获取不同交易类型和阶段中的交易Id列表
参数说明
txType: 交易类型 在pb的txpool包中进行了定义
txStage: 交易阶段 在pb的txpool包中进行了定义
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public List<String> getTxIdsByTypeAndStage(TransactionPool.TxType txType, TransactionPool.TxStage txStage, long rpcCallTimeout)
2.4.12.3. 15.3 根据txIds获取交易池中存在的txs,并返回交易池缺失的tx的txIds
参数说明
txIds: 交易Id列表
rpcCallTimeout: 超时时间,单位:s,若传入-1,将使用默认超时时间:10s
public List<ChainmakerTransaction.Transaction> getTxsInPoolByTxIds(String[] txIds, long rpcCallTimeout)
2.5. 使用过程
客户端使用SDK的过程如下:
创建SdkConfig对象
获取ChainManager对象
使用ChainManager获取或创建链对象,创建ChainClient时需要将SdkConfig对象作为参数传入
调用ChainClient对象的接口进行操作
2.6. 使用示例
初始化,创建ChainClient
public void init() {
Yaml yaml = new Yaml();
InputStream in = TestBase.class.getClassLoader().getResourceAsStream(SDK_CONFIG);
SdkConfig sdkConfig;
sdkConfig = yaml.loadAs(in, SdkConfig.class);
assert in != null;
in.close();
for (NodeConfig nodeConfig : sdkConfig.getChain_client().getNodes()) {
List<byte[]> tlsCaCertList = new ArrayList<>();
for (String rootPath : nodeConfig.getTrustRootPaths()){
List<String> filePathList = FileUtils.getFilesByPath(rootPath);
for (String filePath : filePathList) {
tlsCaCertList.add(FileUtils.getFileBytes(filePath));
}
}
byte[][] tlsCaCerts = new byte[tlsCaCertList.size()][];
tlsCaCertList.toArray(tlsCaCerts);
nodeConfig.setTrustRootBytes(tlsCaCerts);
}
chainManager = ChainManager.getInstance();
chainClient = chainManager.getChainClient(sdkConfig.getChain_client().getChainId());
if (chainClient == null) {
chainClient = chainManager.createChainClient(sdkConfig);
}
}
创建合约
public void testCreateContract() throws IOException, InterruptedException, ExecutionException, TimeoutException {
ResultOuterClass.TxResponse responseInfo = null;
try {
byte[] byteCode = FileUtils.getResourceFileBytes(CONTRACT_FILE_PATH);
// 1. create payload
Request.Payload payload = chainClient.createContractCreatePayload(CONTRACT_NAME, "1", byteCode,
ContractOuterClass.RuntimeType.WASMER, null);
//2. create payloads with endorsement
Request.EndorsementEntry[] endorsementEntries = SdkUtils.getEndorsers(payload, new User[]{adminUser1, adminUser2, adminUser3});
// 3. send request
responseInfo = chainClient.sendContractManageRequest(payload, endorsementEntries, rpcCallTimeout, syncResultTimeout);
} catch (SdkException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
Assert.assertNotNull(responseInfo);
}
调用合约
public void testInvokeContract() throws Exception {
ResultOuterClass.TxResponse responseInfo = null;
try {
responseInfo = chainClient.invokeContract(CONTRACT_NAME, INVOKE_CONTRACT_METHOD,
null, null, rpcCallTimeout, syncResultTimeout);
} catch (Exception e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
Assert.assertNotNull(responseInfo);
}
2.7. SDK Jar包引用方式
2.7.1. 源码编译
git clone --depth=1 https://git.chainmaker.org.cn/chainmaker/sdk-java.git
// 说明:需要使用openjdk 1.8.151+并提前安装gradle,也可以使用intelliJ IDEA打开项目进行编译
cd chainamker-sdk-java
./gradlew build
2.7.2. maven中央仓库
<dependency>
<groupId>org.chainmaker</groupId>
<artifactId>chainmaker-sdk-java</artifactId>
<version>2.3.1.3</version>
</dependency>
2.7.3. 使用
2.7.3.1. 导入jar
包
导入jar
包,这里使用IntelliJ
为示例引用jar
包,将编译好的jar
包拷贝到需要使用sdk的项目下(一般可以在项目下建一个libs
目录),然后打开IntelliJ IDEA->File->Project Structures
,如下图点击“+”
号,选择JARs or Directories
,选中jar
包点击open
即可。
2.7.3.2. 依赖库
导入依赖jar
包,需将sdk
中依赖的jar
包导入本地工程中,同时,需将sdk
中lib
目录下的netty-tcnative-openssl-static-2.0.39.Final.jar
包导入工程中,以便适配国密tls
通信。
tcnative
的jar
包及动态库地址: tcnative
2.7.3.3. 引用
在要使用sdk的源文件里使用import引用sdk包,如下:
import org.chainmaker.sdk.*;
2.7.3.4. 应用demo
java sdk应用示例,请参考 sdk-java-demo
2.7.4. 密码机支持
2.7.4.1. 密码机介绍
项目 | 备注 |
---|---|
密码机厂商 | 三未新安 |
密码机型号 | SJJ1012-A |
2.7.4.2. 引用方式
将
sdk
中lib
目录下的crypto_v5.3.3.8.jar
、swxajce_v5.3.3.8.jar
包和swsds.ini
文件导入当前项目的lib
目录下,导入依赖
jar
包,需将sdk
中依赖的crypto_v5.3.3.8.jar
、swxajce_v5.3.3.8.jar
包导入本地工程中将
lib
目录下swsds.ini
文件中与密码机相关的配置进行修改
[HSM1]
# 密码机ip
ip=192.168.1.240
port=8008
passwd=11111111
2.7.4.3. 配置修改
2.7.4.3.1. 配置文件方式修改
sdk_config.yml(将
pkcs11.enable
设置为true)
pkcs11:
enabled: true # pkcs11 is not used by default
2.7.4.3.2. ChainClientConfig方式修改
sdk_config.yml(将
pkcs11.enable
设置为true)
ChainClientConfig chainClientConfig = new ChainClientConfig();
Pkcs11Config pkcs11Config = new Pkcs11Config();
pkcs11Config.setEnabled(true);
chainClientConfig.setPkcs11(pkcs11Config);
2.7.4.3.3. 用户配置
配置用户时,将
pkcs11Enable
参数设置为true
adminUser = new User(ORG_ID3, FileUtils.getResourceFileBytes(ADMIN3_KEY_PATH),
FileUtils.getResourceFileBytes(ADMIN3_CERT_PATH),
FileUtils.getResourceFileBytes(ADMIN3_TLS_KEY_PATH),
FileUtils.getResourceFileBytes(ADMIN3_TLS_CERT_PATH), true);
2.8. changelog
2.8.1. v2.3.1.2
概要 | 描述 |
---|---|
连接池频繁关闭/创建优化 | 添加连接池参数:softMinEvictableIdleTime,修改默认扫描时间5分钟。修改默认配置生产可用。 |
连接异常关闭后续处理 | 连接异常关闭之后,不返回连接到连接池,直接对连接进行销毁处理 |
订阅获取交易结果写入Map | 订阅修改交易结果写入map,修改mapValue类型为对象,invoke注册key,如果有key才会进行写入,拿到结果进行注销 |
修复ManagedChannel allocation site连接未正常关闭错误 | 在将对象设置为null之前,关闭该对象。 |
连接节点超时时间加长 | 连接超时时间默认从3秒改成10秒 |
2.8.2. v2.3.1.3
概要 | 描述 |
---|---|
连接池使用方式改为先进先出 | 在配置多个节点后,可达到负载均衡上链效果 |
修复连接关闭但未释放问题 | 修复连接异常关闭未从连接池销毁,导致所有连接不可用问题 |
有条件的负载订阅 | 可以通过修改配置文件中的node顺序,达到负载均衡的效果 |