常见问题

本文针对当前版本Java SDK的常见问题提供解决方法以供参考。

说明

若发送交易出现SERVICE_TX_WAITING_VERIFY=413或者SERVICE_TX_WAITING_EXECUTE=414错误码,请您通过调用查询收据接口进行排查。

Illegal key size or default parameters

问题背景

加载user.key失败,提示key长度不合法。

运行错误提示
09:49:40.623 [main] ERROR com.github.lyd.msg.provider.DemoSample - unable to read private key,wrong password? errorCode :{MychainSdkErrorCodeEnum{errorCode='30001', errorDesc='sdk invalid private key'}}
09:49:40.626 [main] ERROR com.github.lyd.msg.provider.DemoSample - unable to read encrypted data: 1.2.840.113549.1.12.1.3 not available: Illegal key size or default parameters
Exception in thread "main" com.alipay.mychain.sdk.exceptions.MychainSdkException: unable to read encrypted data: 1.2.840.113549.1.12.1.3 not available: Illegal key size or default parameters
ERROR

解决方案

出现此错误的原因是个别JDK的默认配置限制了key的长度,因此SDK在加载key文件时解密失败。

可在DemoSample.javamain函数最开始位置,增加一段代码来进行处理,如下所示。

    String errorString = "Failed to modify key-length permissions";
    int newMaxKeyLength;
    try {
        if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) {
            System.out.println("will modify aes length");
            Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection");
            Constructor con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Object allPermissionCollection = con.newInstance();
            Field f = c.getDeclaredField("all_allowed");
            f.setAccessible(true);
            f.setBoolean(allPermissionCollection, true);
            c = Class.forName("javax.crypto.CryptoPermissions");
            con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Object allPermissions = con.newInstance();
            f = c.getDeclaredField("perms");
            f.setAccessible(true);
            ((Map) f.get(allPermissions)).put("*", allPermissionCollection);
            c = Class.forName("javax.crypto.JceSecurityManager");
            f = c.getDeclaredField("defaultPolicy");
            f.setAccessible(true);
            Field mf = Field.class.getDeclaredField("modifiers");
            mf.setAccessible(true);
            mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
            f.set(null, allPermissions);
            newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
        }
    } catch (Exception e) {
        throw new RuntimeException(errorString, e);
    }
    if (newMaxKeyLength < 256) {
        throw new RuntimeException(errorString);
    }

Connection reset by peer

问题背景

SDK出现cause: Connection reset by peer的异常。

image.png

问题分析

  • 如果A端的Socket因为主动关闭或者因为异常退出被关闭,B端仍发送数据,发送的第一个数据包则引发Connect reset by peer异常(A端连接断开后,B端给通道中写数据)。

  • A端退出,但退出时并未关闭该连接,B端如果仍然从连接中读数据则抛出Connect reset by peer异常(A端连接断开后B端仍然从通道中读数据)。

  • 主动给客户端推送TCP层的reset包,客户端收到后,报Connect reset by peer异常。

解决方案

  1. 查看区块链是否运行正常,是否主动关闭了与SDK之间的链接。

  2. SDK与链之间是否经过了SLB(负载均衡),且SDK进程中,是否启动了多个连接,如果是,可以重启SDK解决,并将SDK升级到0.10.2.24.5。

    查看是否建立多个链接:netstat -na | grep ip:端口

    显示ESTABLISHED则是建立成功的连接。

    image.png

General OpenSslEngine problem

问题背景

SDK启动时报以下异常,导致SDK启动失败。

1112

解决方案

  1. 排查SDK启动的证书、密码是否正确。

  2. 排查SDK启动的证书是否过期。

    openssl x509 -in client.crt -noout -dates

    2
  3. 排查netty-tcnative包是否冲突,netty和netty-tcnative包需要是以下配套版本,命令如下:

    io.netty:netty-all:jar:4.1.29.Final
    io.netty:netty-tcnative-boringssl-static:jar:2.0.17.Final
    重要

    可以通过mvn dependency:tree查看JAR包依赖关系。

invalid keypair

问题背景

SDK提示invalid keypair。

image.png

问题分析

构造keypair的代码如下。

image.png

使用keypair对象时,keypair == null或者keypair的type不正确。

3

解决方案

  1. 创建签名,是根据用户的私钥进行签名的,所以需要检查用户的私钥是否正确。

  2. 打断点查看获取的Keypair对象是否为null,或者keypair对象中的type=unknown,在构造Keypair的位置打断点进一步分析。

  3. 查看bouncycastel包是否存在冲突,SDK在V0.10.2.22之前要求bouncycastel包的版本为1.60。

  4. 检查JDK的版本,目前已知SDK运行时,JDK不会存在问题的版本:JDK 1.8.0_151、JDK 1.8.0_251。

  5. 排查netty-all和netty-tcnative包是否冲突,如果依赖了netty-tcnative-openssl需要排除掉,且当前需求的版本配置如下。

    io.netty:netty-all:jar:4.1.29.Final
    io.netty:netty-tcnative-boringssl-static:jar:2.0.17.Final

合约是否支持对象类型解析

问题背景

定义的这些值在SDK中怎么解析?

image.png

解决方案

SDK中暂时不支持对象类型解析,可以通过以下文档查看SDK支持的合约参数解析类型:

同一个事件有订阅次数的限制吗?

问题背景

同一个事件有订阅次数的限制吗?

解决方案

  1. 同一个session,默认最大是10次,不区分事件类型。

    可以在mychain.conf中进行配置:event_plugin.max_session_filter_number

  2. 一个节点支持的最大订阅数量:1000,不区分事件类型。

    在mychain.conf文件中可以配置:max_filter_number

客户端A和B同时连链,A可以监听B的事件吗?

问题背景

初始化得到一个SDK A,使用这个SDK A订阅一个合约事件。然后初始化得到了一个SDK B,使用SDK B发起合约交易。请问SDK A中能监听到触发的合约事件吗?

解决方案

客户端A和B同时连链,A可以监听B的事件。

引用SDK后提示ClassNotFoundException

问题背景

例如出现以下问题:

image.png

解决方案

  1. 查找不到的这个类是属于哪个包的。

  2. 执行命令:mvn dependency:tree,查看这个包是否产生冲突。

  3. 当前SDK依赖的netty和netty-tcnative包版本如下:

    io.netty:netty-all:jar:4.1.29.Final
    io.netty:netty-tcnative-boringssl-static:jar:2.0.17.Final

sendRequest, connect failed

问题背景

出现以下错误日志:

[log:2022-05-09 12:23:48.385 [SenderWorker-thread-0] ERROR MychainClient - [networkconnection] sendRequest, connect failed, seq:25911219 ]

解决方案

  1. 检查本机网络是否正常。

  2. 检查链节点是否正常,是否可以访问,是否停机了。

  3. 检查链节点出块是否正常。

  4. 是否出现了多连接,如果是可以重启SDK解决,建议升级SDK版本到2.24.5。

    查看是否建立多个连接:netstat -na | grep ip:端口

    显示ESTABLISHED则是建立成功的连接。

    image.png

断网后sdk error日志量太大/进程挂掉怎么处理

问题背景

  1. 链节点断开后,SDK不断重连,导致进程挂掉。

  2. 日志量很大。

解决方案

SDK从2.23开始,可以设置重连的频率,但是2.23之前的版本没法处理,可升级SDK版本。

5

参数说明

示例一:

connectionRetryDelayMs = 1000(1秒)

maxConnectionRetryDelayFactor = 5

则重连的频率为:1秒,2秒,3秒,4秒,5秒,最后会稳定在5s重连一次。

示例二:

connectionRetryDelayMs = 2000(2秒)

maxConnectionRetryDelayFactor = 5

那重连的频率就是:2秒,4秒,6秒,8秒,10秒,最后会稳定在10s重连一次已读。

SDK获取Service时报NullPointerException

问题背景

java.lang.NullPointerException: null
at com.alipay.mychain.sdk.api.MychainClient.getContractService(MychainClient.java:150)

解决方案

这种获取Service时报空指针异常,一般是因为SDK启动失败,可以去查看SDK启动位置失败的原因进行分析。

Identity类型和交易Hash是多少位的

问题背景

问题一:Identity是多少位?

问题二:txHash是多少位?

解决方案

image.png

  1. Identity是32位的,如果转化为16进制是64个字符。

  2. txHash是32位的,如果转化为16进制是64个字符。

arm64_linux环境集成方式

问题背景

arm64_linux环境下如何集成mychain-java-sdk。

解决方案

  1. 在官网下载对应版本的Jar包。

    说明

    V0.10.2.24.5无需下载Jar包,通过Maven坐标即可引入,具体参见Java SDK说明

  2. 将Jar包安装到本地仓库。

    • 安装V0.10.2.20的Jar包执行命令如下。

      mvn install:install-file -Dfile=mychainx-sdk-java-all-0.10.2.20.jar -DgroupId=com.alipay.mychainx -DartifactId=mychainx-sdk-java-all -Dversion=0.10.2.20 -Dpackaging=jar
    • 安装V0.10.2.12的Jar包执行命令如下。

      mvn install:install-file -Dfile=mychainx-sdk-java-all-0.10.2.12.jar -DgroupId=com.alipay.mychainx -DartifactId=mychainx-sdk-java-all -Dversion=0.10.2.12 -Dpackaging=jar
  3. 本地项目中添加以下依赖。

    重要

    请替换官网示例中的对应依赖。

            <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.34.Final</version>
            </dependency>
            <dependency>
                <groupId>com.alipay.mychainx</groupId>
                <artifactId>mychainx-sdk-java-all</artifactId>
                <!--请使用最新 SDK 版本 或者0.10.2.12 -->
                <version>0.10.2.20</version>
            </dependency>
            <dependency>
                <groupId>org.bouncycastle</groupId>
                <artifactId>bcpkix-jdk15on</artifactId>
                <version>1.60</version>
            </dependency>
  4. 替换Maven仓库io.netty.netty-tcnative-boringssl-static.2.0.34.Final的JAR包。

    2.0.34的JAR包为:netty-tcnative-boringssl-static-2.0.34.Final.jar(4.6MB)

    具体操作如下:

    1. 进入Maven仓库netty-tcnative-boringssl-static.2.0.34.Final目录下。

      cd ~/.m2/repository/io/netty/netty-tcnative-boringssl-static/2.0.34.Final
    2. 将以下JAR包替换为上面附件中的JAR包。

      image.png

out of gas

问题背景

调用合约,产生的out of gas异常。

如果执行时间很长,合约接口中客户批量操作,则数量越多,出现的概率越大。

SDK中报错:errorCode : 10200, errorDesc : out of gas

问题分析

链上执行交易使用的gas超过了配置的gaslimit。

gaslimit取值规则:

SDK传的gas如果不是0则取链配置的gaslimit和SDK传的值中取一个最小值作为limit,如果SDK传的gas为0,则取链配置的gaslimit为limit,SDK默认传输的gaslimit为0。

解决方案

  1. 即使将gas调大,但这个合约的执行比较长,仍会影响链的出块,建议优化合约。

  2. 优化一下合约,建议不要进行此类较复杂的批量操作。

  3. 现在不支持调整链的gas,现在的gaslimit已经够大了。

针对solidity的解析,支持ABIEncoderV2么?

问题背景

ABIEncoderV2的特性:支持返回User对象:

如果是ABIEncoderV1,编译合约的时候会报以下错误。

6

解决方案

对SDK进行验证。

image.png

可以看到部署合约成功,调用合约成功,但是SDK无法解析出User对象。

结论:mychain java sdk针对solidity的解析,不支持ABIEncoderV2全部功能,其中对象类型无法解析。

日志配置推荐(logback)

问题背景

  • 如何配置SDK的日志打印。

  • 当前slf4j-api版本:1.7.25。

解决方案

使用logback。

pom依赖添加如下

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.1.11</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.11</version>
</dependency>

logback.xml

logback.xml放置在resource目录下。

logback.xml文件的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<!--定义日志文件的存储地址,勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value=" ../mychain-java-sdk/log " />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
 </encoder>
 </appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
 <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/unionsdk-btn-sdk.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
 <maxFileSize>100MB</maxFileSize> <!-- 日志文件过大会使的编辑器打开非常慢,因此设置日志最大50MB -->
<maxHistory>30</maxHistory> <!-- 保存30天 -->
<totalSizeCap>10GB</totalSizeCap> <!-- 总日志大小 -->
</rollingPolicy>
 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
 </encoder>
<!--日志文件最大的大小-->
<!-- <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">-->
<!-- <MaxFileSize>3MB</MaxFileSize>-->
<!-- </triggeringPolicy>-->
</appender>

<!-- 日志输出级别 -->
<root level=" debug ">
 <appender-ref ref="STDOUT" />
 <appender-ref ref="FILE" />
 </root>
</configuration>
重要

其中../mychain-java-sdk/log为日志路径,需要修改为自己的路径,level="debug"为日志级别,可以修改为:error, warn, info, debug, trace等级别。

class org.bouncycastle.asn1.ASN1Primitive overrides final method equals.(Ljava/lang/Object;)Z

问题背景

SDK版本:

image.png

SDK报错:

image.png

解决方案

bcprov包冲突,由于项目依赖的其他包使用了其他版本,和SDK需要的版本有冲突。

从2.22开始,SDK要求bcprov版本必须是1.66,2.22之前bcprov版本是1.60。

说明

可以通过mvn dependency:tree查看JAR包依赖关系。

合约返回10201,output打印时有乱码

问题背景

合约源码:111

返回的output:

08c379a0
0000000000000000000000000000000000000000000000000000000000000020   //字符串偏移
0000000000000000000000000000000000000000000000000000000000000012   //字符串长度
546f6b656e49442072657065746974696f6e0000000000000000000000000000    //字符串内容

SDK解析错误:image.png

output直接进行getString()时,返回结果是空的。

如果直接进行new String(output.getBytes())时,又有乱码。

解决方案

SDK解析时需要去掉前4个字节。

2.22之前的SDK版本:

//调用合约
CallContractResponse replyTransactionReceipt = sdk.getContractService().callContract(request);

// 
如果response返回的code是 10201,按照以下方式解析output 

byte[] decode = replyTransactionReceipt.getTransactionReceipt().getOutput();
byte[] content = new byte[decode.length-4];
System.arraycopy(decode,4,content,0,content.length);
EVMOutput vmOutput = new EVMOutput(ByteUtils.toHexString(content));
System.out.println(vmOutput.getString());

2.22及2.22之后的SDK版本:

//调用合约
CallContractResponse replyTransactionReceipt = sdk.getContractService().callContract(request);

//如果response返回的code是 10201,按照以下方式解析output 

String errorDesc = EVMOutput.evmRevertDecoder(replyTransactionReceipt.getTransactionReceipt().getOutput());
System.out.println(errorDesc);

unable to read encrypted data: Error finalising cipher

问题背景

用户证书的密码不正确。

image.png

解决方案

修改用户证书密码。

Input stream does not contain valid private key

问题背景

只要IP正确,均可以连接成功,但是握手失败,错误提示:Input stream does not contain valid private key

1113

解决方案

  1. client.key密码不正确。

  2. JDK版本问题。

目前已知版本的报错情况如下。

JDK版本

是否报错

JDK 1.8.0_151

不报错

JDK 1.8.0_251

不报错

JDK 1.8.0_221

报错

JDK 1.8.0_291

报错

JDK 1.8.0_301

报错

decode trustCa happens IOException with password:xxxxxx

问题背景

错误提示:Init SslContext exception:load custom key store happen IOExceptionconnect是成功的,但握手失败。

910

解决方案

  1. trustca密码不正确。

  2. 目前已发现JDK 11会出现此问题,推荐使用JDK 1.8。

  3. 检查trustCa文件是否进行过重置密码,是否重置失败。

  4. trustCa是否是对应当前连接链的trustCa文件。

  5. 排查netty-all、netty-tcnative、org.bouncycastle包冲突。

  6. POM依赖中,把以下内容注释掉,因为编译会改变resource目录下的trustCa文件。

    <build>
           <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>true</filtering>
                </resource>
            </resources>
    </build>

OPENSSL_internal:KEY_VALUES_MISMATCH

问题背景

错误提示:

io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: error:0b000074:X.509 certificate routines:OPENSSL_internal:KEY_VALUES_MISMATCH
11

解决方案

client.crt错误或者client.key错误。

verification of certificate failed

问题背景

错误提示:

2022-04-13 13:41:47.746 [WorkThreadPool-1-2] DEBUG i.netty.handler.ssl.ReferenceCountedOpenSslContext - verification of certificate failed
java.security.cert.CertificateException: Unable to construct a valid chain
12
重要

trustca报错时间点大于client.key,或者client.crt

解决方案

检查trustca文件是否正确。

如何订阅EVM合约内部自定义事件

问题背景

如何订阅evm合约自定义的事件。

解决方案

EVM合约示例如下:

13

调用SDK接口进行监听:

13

SDK连接Nginx代理后的链节点报错

问题背景

错误描述:

OPENSSL_internal:WRONG_VERSION_NUMBER
23

Nginx配置:

说明

以下IP为测试IP。

1415
重要

此配置是通过HTTP的通道配置的。

解决方案

Nginx配置时,不能配置HTTP通道的方式,因为SDK默认是使用tcp + rlp的方式连接的,所以如果SDK内使用tcp方式连接的话,Nginx中,也需要通过配置tcp的通道才可以。

image.png

the timestamp of tx is not in valid period

问题背景

发起交易时,出现the timestamp of tx is not in valid period的异常。

解决方案

重启SDK解决。

由于链节点出块的时间戳和SDK发起交易的时间戳相差太大,大于1个小时,SDK不重启的情况下,需要等待链节点追块完成后,才能正常发送交易。

TEE链请求公钥验证不正确

问题背景

以TEE链的方式请求时,提示公钥不正确。

解决方案

  1. 链公钥获取(登录阿里云BaaS控制台下载),下载的公钥,其格式如下:

    1516

  2. 使用公钥进行加密请求。

    重要

    请不要忘记写下面红框中的内容。

    17

SDK如何设置签名

问题背景

SDK设置签名的方式有哪些?

解决方案

全局配置:SDK启动时配置

protected List<Keypair> abstractAdminKeyPairs = new ArrayList<>();
Pkcs8KeyOperator pkcs8KeyOperator = new Pkcs8KeyOperator();
String path = this.getClass().getClassLoader().getResource("").getPath();
Keypair ecKeyPair1 = pkcs8KeyOperator.load(path + properties.getProperty("client1.pk8"),
                                           keyPassword);
Keypair ecKeyPair2 = pkcs8KeyOperator.load(path + properties.getProperty("client2.pk8"),
                                           keyPassword);
Keypair ecKeyPair3 = pkcs8KeyOperator.load(path + properties.getProperty("client3.pk8"),
                                           keyPassword);
Keypair ecKeyPair4 = pkcs8KeyOperator.load(path + properties.getProperty("client4.pk8"),
                                           keyPassword);

abstractAdminKeyPairs.add(ecKeyPair1);
abstractAdminKeyPairs.add(ecKeyPair2);
abstractAdminKeyPairs.add(ecKeyPair3);
abstractAdminKeyPairs.add(ecKeyPair4);

List<SignerBase> signerBaseList = new ArrayList<>();
for (Keypair keypair : abstractAdminKeyPairs) {
    SignerBase signerBase = MyCrypto.getInstance().createSigner(keypair);
    signerBaseList.add(signerBase);
}
signerOption.setSigners(signerBaseList);
//配置到clientEnv中
clientEnv = ClientEnv.build(socketAddressArrayList, sslOption, signerOption);

局部配置:SDK发起交易时配置签名

// sign request
long ts = sdk.getNetwork().getSystemTimestamp();
preResetPubKeyRequest.setTxTimeNonce(ts, BaseFixedSizeUnsignedInteger.Fixed64BitUnsignedInteger
    .valueOf(RandomUtil.randomize(ts + preResetPubKeyRequest.getTransaction().hashCode())), true);
preResetPubKeyRequest.complete();
SignerBase signer = env.getSignerOption().getSigners().get(0);  
List<SignerBase> signers = new ArrayList<>();
signers.add(signer);
sdk.getAccountService().signRequest(signers, preResetPubKeyRequest);

局部配置的例子:

存证,先用admin创建一个用户,然后用创建的账户进行存证。

首先,创建一个新用户。

其次,使用新用户进行存证,进行存证之前,单独对这个账户进行了签名,签名用的私钥,就是创建账户时生成的私钥。

image.png

zk_lib:could not load a native libary

问题背景

image.png

解决方案

这块是零知识证明相关的,如果没用到,暂时可以忽略该异常。

说明

V0.10.2.24版本开始,启动时,可以选择关闭加载zk_lib包,在ClientEnv类中可以配置setLoadZkLib(false)。

SDK启动构造KeyPair时,提示Unknown Source

问题背景

image.png

解决方案

如果私钥路径没问题,获取的byte[]也没有问题,可以分析下私钥对应的密码有没有问题,现在发现的原因是私钥密码不正确会导致以上问题。

Mychain-java-sdk国密如何使用

问题背景

国密如何使用。

解决方案

一、TLS使用国密(可选)

  • SDK开始支持的版本:V0.10.2.22。

  • 配置SDK启动位置。

    以下位置设置为true。

    18

二、交易使用国密

  • SDK开始支持的版本:V0.10.2.14。

  • 国密交易:hash算法为国密SM3;签名算法为SM2。

  • 配置SDK启动位置配置全局国密算法。

    IHash hash = HashFactory.getHash(HashTypeEnum.SM3);
    DigestOption digestOption = new DigestOption();
    digestOption .setDefaultDigestType(HashTypeEnum.SM3));
    clientEnv.setDigestOption(digestOption);

    账户签名配置部分需要如下配置:

    19
  • 操作的账户必须为国密账户。

    用户的账户名称需要单独使用国密SM3进行hash。

    byte[] id = HashFactory.getHash(HashTypeEnum.SM3).hash(ByteUtils.stringToByteArray(identityName));
    Identity identity = new Identity(id);

连接正常但握手失败

问题背景

20

解决方案

  1. client.keyclient.crt、trustca证书是否正确,client.crt证书是否过期,client.keytrustca密码是否正确

  2. 访问的链端口是否正确,是否是链节点之间共识同步的端口号。

  3. 如果分析证书和链证书是完全一致的,则看看项目pom.xml中引用的org.bouncycastle相关包的版本是否正确,2.22版本之前为1.6.0,之后为1.66,可以通过命令:mvn dependency:tree查看是否存在冲突。

    如果出现以下情况,则表示有冲突,需要将1.62版本排除掉。

    21
  4. 链出块是否正常。

  5. tcnative包是否冲突,需要netty和netty-tcnative的版本配套如下。

    io.netty:netty-all:jar:4.1.29.Final
    io.netty:netty-tcnative-boringssl-static:jar:2.0.17.Final

    如果netty-tcnative版本不正确,通常会报以下异常:

    22
  6. 如果本地访问如:localhost,需要定义为127.0.0.1。

  7. 部署时如果出现问题,请检查JDK环境中是否引用了bcprov-jdk15-135.jar包。

    如果未引用,可以通过以下步骤进行添加。

    1. 查找SDK的安装位置:which java

    2. 进入到SDK的安装位置。

    3. java安装目录下找到jre/lib/security/java.security文件。

    4. 添加一行:security.provider=org.bouncycastle.jce.provider.BouncyCastleProvider,(如果系统提示不能操作,切换到管理员权限,sudo su - root)。

    5. 进入jre/lib/ext目录下,将bcprov-jdk15-135.jar放进去。

    重要

    不能在java.security中添加配置,也不能在ext目录下添加bcprov-jdk15-135.jar包,即使改了名字也不能放在里面。

mychain-java-sdk支持的监控

问题背景

SDK支持监控吗?

解决方案

  1. 开启QPS和TPS的监控。

    执行命令如下:

    ClientEnv -> MetricsOption.setEnableMetrics(true)

    执行后,会在控制台打印当前的QPS和TPS。

  2. 查询mychain链监控接口。

存证交易的data大小限制是多少

问题背景

存证交易的data大小限制是多少?

解决方案

存证交易的data数据大小有上限限制,此限制为合约链的一个配置选项,通常默认1 MB,实际根据合约链的配置情况而定。

通常接口中参数amount转账金额的含义

问题背景

例如depositDataRequest中最后一个参数amount的含义是什么?

public void depositData() {
        String content = "hello world";
        DepositDataRequest depositDataRequest = new DepositDataRequest(
                userIdentity,
                adminAccount.getIdentity(),
                content.getBytes(), BigInteger.valueOf(10));
        DepositDataResponse depositDataResponse = sdk.getAccountService().depositData(depositDataRequest);
        if (!depositDataResponse.isSuccess()) {
            exit("depositData", getErrorMsg((int) depositDataResponse.getTransactionReceipt().getResult()));
        } else {
            System.out.println("depositData success.返回信息:" + depositDataResponse.toString());
        }
    }

解决方案

以上述的示例进行说明:

这个是交易里面的字段,单纯存证的话可以不管,但是存证的接口里面也包含了转账的能力,如果amount这个字段填写了,就会把这个from里面的资产转移那个数目到to账户里面去,如果不填,就不进行转账。