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包导入本地工程中, 同时,需将sdklib目录下的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. 接口说明

请参看:《chainmaker-java-sdk》

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的过程如下:

  1. 创建SdkConfig对象

  2. 获取ChainManager对象

  3. 使用ChainManager获取或创建链对象,创建ChainClient时需要将SdkConfig对象作为参数传入

  4. 调用ChainClient对象的接口进行操作

2.6. 使用示例

  1. 初始化,创建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);
       }
   }
  1. 创建合约

   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);
   }
  1. 调用合约

   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包导入本地工程中,同时,需将sdklib目录下的netty-tcnative-openssl-static-2.0.39.Final.jar包导入工程中,以便适配国密tls通信。 tcnativejar包及动态库地址: 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. 引用方式

  • sdklib目录下的crypto_v5.3.3.8.jarswxajce_v5.3.3.8.jar包和swsds.ini文件导入当前项目的lib目录下,

  • 导入依赖jar包,需将sdk中依赖的crypto_v5.3.3.8.jarswxajce_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顺序,达到负载均衡的效果