文档

Java SDK 快速开始

更新时间:

本文通过示例阐述如何 运行应用,展示 示例执行流程,并指导如何 指定密码学套件

运行应用

应用运行的过程主要分为 4 步:

  1. 准备环境

  2. 编写应用

  3. 编译应用

  4. 执行应用

准备环境

  • 准备 SSL 连接文件和账户私钥文件。

    要与 BaaS 平台建立 SSL 连接,您需准备三个证书文件:CA 机构的根证书(trustCa)、客户端的证书文件(client.crt)以及客户端的私钥文件(client.key)。此外,提交交易还需要账户的私钥文件(user.key)。这四个文件的详细说明如下。

    文件名称

    文件说明

    文件来源

    client.crt 

    客户端的证书文件 

    使用 BaaS 提供的 密钥生成工具生成证书请求文件 client.csr,提交请求文件到 BaaS 平台申请证书,申请成功后可下载此 crt 文件。 

    client.key

    客户端的私钥文件

    通过 BaaS 提供的 密钥生成工具生成。

    trustCa

    存储 CA 证书的 trustStore

    通过 BaaS 平台下载,trustCa 文件密码为 mychain。 

    user.key

    账户私钥文件 

    通过 BaaS 提供的 密钥生成工具手动生成,或自动生成下载。

  • 准备 TEE 硬件隐私合约链文件。

    如果使用 TEE 硬件隐私合约链,还需要使用一个 tee_rsa_public_key.pem文件,此文件可从已存在的 TEE 硬件隐私合约链申请,如果使用的是标准的合约链,则不需要使用此文件。

    文件名称

    文件说明

    文件来源

    tee_rsa_public_key.pem 

    TEE 硬件隐私合约链,节点对外公开的 RSA 公钥文件 

    通过 BaaS 平台下载。 

  • 看合约链节点信息。

    要与合约链交互,您需要获取链节点的 IP 地址和端口号。在 BaaS 平台,通过查看目标合约链详情,在区块浏览器中查看节点详情,可获取链节点的 IP 地址和端口号。

编写应用

  1. 使用 IntelliJ IDEA 创建一个基于 Maven 构建的空项目(Demo)。创建完成后,项目目录结构应如下:

    1545295559042-521770ec-412b-49ed-935e-a6b644bb0949.png

  2. 在上图中的 java目录创建自定义包名,例如:com.example.demo,并将 DemoSample.java(点击下载 DemoSample.java文件)中的内容完整拷贝至创建的包中,并将 SDK 必须使用的 client.crtclient.keytrustCa及 user.key文件放入到 resources目录中,如下图所示:

    1

    说明

    Demo 项目中需要使用合约源代码编译后的字节码。有关合约源代码,参见 Solidity 合约开发;Solidity 编译工具参见 Solidity 合约编译工具

  3. 在 pom.xml中添加依赖。将 SDK 与项目使用的依赖引入到 pom.xml,并在 resources中添加 log4j的配置文件。

    重要

    在本步骤中,SDK 依赖的版本号请使用最新版本。

    完整 pom 依赖可参考:

    <dependencies>
         <dependency>
             <groupId>com.alipay.mychainx</groupId>
             <artifactId>mychainx-sdk</artifactId>
             <!--请使用最新 SDK 版本 -->
             <version>0.10.2.12</version>
         </dependency>
         <dependency>
             <groupId>org.bouncycastle</groupId>
             <artifactId>bcpkix-jdk15on</artifactId>
             <version>1.60</version>
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
             <artifactId>netty-all</artifactId>
             <version>4.1.29.Final</version>
         </dependency>
         <dependency>
             <groupId>io.netty</groupId>
             <artifactId>netty-tcnative-boringssl-static</artifactId>
             <version>2.0.17.Final</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>1.7.25</version>
         </dependency>
           <dependency>
               <groupId>commons-io</groupId>
               <artifactId>commons-io</artifactId>
               <version>2.6</version>
           </dependency>
           <dependency>
               <groupId>com.alibaba</groupId>
               <artifactId>fastjson</artifactId>
               <version>1.2.83</version>
           </dependency>
           <dependency>
               <groupId>com.google.guava</groupId>
               <artifactId>guava</artifactId>
               <version>20.0</version>
           </dependency>
           <dependency>
               <groupId>org.apache.commons</groupId>
               <artifactId>commons-collections4</artifactId>
               <version>4.2</version>
           </dependency>
           <dependency>
               <groupId>org.apache.commons</groupId>
               <artifactId>commons-lang3</artifactId>
               <version>3.5</version>
           </dependency>
    </dependencies>
    
     <build>
         <extensions>
             <extension>
                 <groupId>kr.motd.maven</groupId>
                 <artifactId>os-maven-plugin</artifactId>
                 <version>1.6.1</version>
             </extension>
         </extensions>
     </build>

    在某些情况下,可能会出现如下异常:

    2

    异常原因有可能是 Netty 加载失败,可以尝试修改 netty 依赖,如下所示:

    <dependency>
              <groupId>com.alipay.mychainx</groupId>
              <artifactId>mychainx-sdk</artifactId>
              <!--请使用最新 SDK 版本 -->
              <version>0.10.2.12</version>
              <exclusions>
                  <exclusion>
                      <groupId>io.netty</groupId>
                      <artifactId>netty-tcnative-openssl-static</artifactId>
                  </exclusion>
              </exclusions>
    </dependency>

    log4j.properties 文件内容如下:

     log4j.rootLogger=INFO, R
    
     # 日志输出位置为控制台
     log4j.appender.stdout=org.apache.log4j.ConsoleAppender
     log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
     log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
    
     # 日志输出位置为文件
     log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
     log4j.appender.R.File=./sdk.log
     log4j.appender.R.layout=org.apache.log4j.PatternLayout
     log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
    
     # mychain-sdk日志开关配置
     log4j.logger.MychainClient=OFF

    如果您使用的是logback的日志框架,则日志开关的配置方法如下:

    <logger name="MychainClient" level="OFF"/>

编译应用

在项目根路径运行 mvn clean compile执行项目编译。

执行应用

在 DemoSample.java中,运行该项目。生成的日志文件位于 项目根路径 ./sdk.log,若从日志中搜索到“Hand shake success”,则代表与区块链平台连接成功。

预期输出如下:

create testAccount1 success.
create testAccount2 success.
deploy contract success.
issue success.
transfer success.
check account balance success.

示例执行流程

  1. 初始化环境。

     //step 1: init logger.
     initLogger();
    
     //step 2:init mychain env.
     env = initMychainEnv();
    
     //step 3: start sdk.
     MychainClient  sdk = new MychainClient();
     sdk.init(env);
  2. 创建账户交易。

     //step 4: init account that will be created.
     initAccount();
    
     //step 5: init private key list which will be used during transaction.
     initPrivateKeyList();
    
     //step 6: execute create two accounts.
     createAccount();
  3. 部署智能合约。

     //step 7 : deploy a contract using testAccount1.
     deployContract();
  4. 申购积分。

     //step 8:issue 100 credits to testAccount2.
     issue();
  5. 进行账户间转账。

     //step 9 : transfer 50 credits from testAccount2 to testAccount1
     transfer();
  6. 查询账户余额。

     //step 10 : query testAccount2 whose balance should be 50.
     BigInteger balance = query(test2PrivateKeyArrayList,testAccount2);
    
     //step 11 : compare to expect balance.
     expect(balance,BigInteger.valueOf(50));
  7. 关闭 SDK 连接。

     //step 12 : sdk shut down
     sdk.shutDown();

指定密码学套件

合约链的链环境可能使用以下两种密码学套件中的一种:

  • classic:使用国际商用密码算法,包括 SHA256 摘要、ECC 公钥算法、AES 对称加密等,标准合约链默认为此套件配置;

  • china-sm:使用中国国家商用密码算法,包括 SM3 摘要、SM2 公钥算法、SM4 对称加密等,国密算法合约链默认为此套件配置。

如果不清楚 SDK 连接的目标合约链使用的是哪一种密码套件,可咨询该链的管理员。构建 ClientEnv时,必须明确指定 SignerBase。示例如下:

Pkcs8KeyOperator pkcs8KeyOperator = new Pkcs8KeyOperator();
Keypair keyPair = pkcs8KeyOperator.load(privateKeyPath, keyPassword);
SignerBase signerBase = MyCrypto.getInstance().createSigner(keyPair);
说明

SDK 与合约平台之间的 SSL 通信不受密码学套件影响,由颁发证书的 PKI 机构决定。