本文通过示例阐述如何 运行应用,展示 示例执行流程,并指导如何 指定密码学套件。
运行应用
应用运行的过程主要分为 4 步:
准备环境
准备 SSL 连接文件和账户私钥文件。
要与 BaaS 平台建立 SSL 连接,您需准备三个证书文件:CA 机构的根证书(
trustCa
)、客户端的证书文件(client.crt
)以及客户端的私钥文件(client.key
)。此外,提交交易还需要账户的私钥文件(user.key
)。这四个文件的详细说明如下。具体说明也可以参考 合约体验链:本地生成证书请求和公私钥对。
文件名称
文件说明
文件来源
client.crt
客户端的证书文件
通过前往BaaS控制台,创建证书后,返回对应下载地址。
client.key
客户端的私钥文件
通过前往BaaS控制台,创建证书后,返回对应下载地址。
trustCa
存储 CA 证书的 trustStore
通过BaaS控制台中,根证书下载获取。
user.key
账户私钥文件
通过BaaS控制台,创建链账户后返回下载地址,需保存好文件,遗失无法恢复!
准备 TEE 硬件隐私合约链文件。
如果使用 TEE 硬件隐私合约链,还需要使用一个
tee_public_key.pem
文件,此文件可从已存在的 TEE 硬件隐私合约链申请,如果使用的是标准的合约链,则不需要使用此文件。文件名称
文件说明
文件来源
tee_public_key.pem
TEE 硬件隐私合约链,节点对外公开的公钥文件
通过 BaaS 平台下载。
看合约链节点信息。
要与合约链交互,您需要获取链节点的 IP 地址和端口号。在 BaaS 平台,通过查看目标合约链详情,在区块浏览器中查看节点详情,可获取链节点的 IP 地址和端口号。
编写应用
使用 IntelliJ IDEA 创建一个基于 Maven 构建的空项目(Demo)。创建完成后,项目目录结构应如下:
在上图中的
java
目录创建自定义包名,例如:com.example.demo,并将DemoSample.java
(点击下载DemoSample.java文件)中的内容完整拷贝至创建的包中,并将 SDK 必须使用的client.crt
、client.key
、trustCa
及user.key
文件放入到resources
目录中,如下图所示:重要在拷贝SDK内容时,如果出现中文乱码,请将IntelliJ IDEA文件编码格式设置UTF-8。
说明Demo项目中需要使用合约源代码编译后的字节码。有关合约源代码,参见 Solidity 合约开发;Solidity 编译工具参见 。WASM 的示例请参见 mychainx-example,支持0.10.2.12及以上版本。
在
pom.xml
中添加依赖。将 SDK 与项目使用的依赖引入到pom.xml
,并在resources
中添加log4j
的配置文件。说明在本步骤中,SDK 依赖的版本号请使用最新版本。
SDK在Maven仓库的坐标如下:
x86_64环境
<dependency> <groupId>com.alipay.mychainx</groupId> <artifactId>mychainx-sdk-java-all</artifactId> <version>0.10.2.24.5</version> </dependency>
arm_64环境
需要修改Netty依赖,具体修改如下。
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.52.Final</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-tcnative-boringssl-static</artifactId> <version>2.0.35.Final</version> </dependency> <dependency> <groupId>com.alipay.mychainx</groupId> <artifactId>mychainx-sdk-java-all</artifactId> <version>0.10.2.24.5</version> <exclusions> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> </exclusion> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-tcnative-boringssl-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.
错误信息
当收到交易的结果以后,若交易执行不正确,可以跟进错误码去定位错误原因。
ErrorCode
:MychainBaseResult
中errorCode
字段用来表示交易发送或者执行错误的原因。
当发送的请求是交易相关的内容时,可根据交易的返回值字段中获得关于交易执行错误更详细的错误码。以部署合约为例:
MychainBaseResult<ReplyTransactionReceipt> result = sdk.getContractService()
.deployContract(
DeployContractRequest.build(adminAccount.getIdentity(),
Utils.getIdentityByName(testContractId,env), contractCode, VMTypeEnum.EVM,
contractParameters, BigInteger.ZERO, params));
assertTrue(result.isSuccess());
assertEquals(0, result.getData().getTransactionReceipt().getResult());
若
result.getData().getTransactionReceipt().getResult()
为 0,代表交易执行成功,反之代表交易执行失败,可以通过result
的值从MychainErrorCodeEnum中
查找错误原因。result.isSuccess()
可以作为交易是否发送成功的标志。若交易发送失败,可通过result.getErrorCode()
获取错误码。
示例执行流程
初始化环境。
//step 1:init mychain env. initMychainEnv(); //step 2: init sdk. initSdk();
发起存证。
//step 3: deposit data depositdata();
部署智能合约。
//step 4: deploy a contract using useridentity. deployContract();
调用合约。
//step 5 issue 100 assets to testAccount1. issue();
关闭SDK。
////step 6 : 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);
if (KeyTypeEnum.KEY_SM2_PKCS8.equals(keyPair.getType())) {
// 国密
SignerBase signerBase = new SM2SignerV1(keyPair, HashTypeEnum.SM3);
} else {
//标准
SignerBase signerBase = MyCrypto.getInstance().createSigner(keyPair);
}
SDK 与合约平台之间的 SSL 通信不受密码学套件影响,由颁发证书的 PKI 机构决定。