附录 A Solidity与Java的编码解码
类型对应
当使用LiteSDK编译solidity合约时,由于java和solidity本身类型的不兼容,所以在调用solidity方法传参数的时候需要对java类型进行相应的编码解码,LiteSDK内部的Abi
类,与solidity的abi文件对应,用来提供solidity合约的函数入参、返回值等信息,方便我们对solidity类型和java类型做转换,目前Litesdk支持的对应类型如下:
JAVA | SOLIDITY |
---|---|
boolean/Boolean | bool |
BigInteger | int、int8、int16……int256 |
BigInteger | uint、uint8、uint16……uint256 |
String | string |
byte[]/Byte[] | bytes、bytes1、bytes2……bytes32 |
string | address |
Array /List | array |
编码
编码时需要提供以下信息:
- solidity合约对应的abi对象,
- 调用方法名
- 封装后的java参数
实现java与solidity之间的类型转换。(注:如果是部署需要提供bin文件,具体参照部署合约一节)
Abi对象
通过LiteSDK提供的FileUtil
工具类读取文件内容得到abi字符串,并利用Abi
类的fromJson
方法生成封装的Abi对象,使用方法如下:
InputStream abiIs = Thread.currentThread().getContextClassLoader().getResourceAsStream("xxx.abi");
String abiStr = FileUtil.readFile(abiIs);
Abi abi = Abi.fromJson(abiStr);
调用方法名
调用方法名需要按格式$(method_name)(type1[,type2…])
填,假如solidity的函数签名为
function TestUint(uint8 a) returns (uint8) {
return a;
}
则我们提供的调用方法名为TestUint(uint8)
,如果函数多个参数,则调用方法名的类型之间用,分隔。
封装的java参数
LiteSDK提供了FuncParams
工具类封装需要转换成solidity类型的java参数,使用方法如下:
FuncParams params = new FuncParams();
// param 是类型对应表里对应的java参数
params.addParams(param1);
params.addParams(param2);
// 构造交易时将构造好的FuncParams对象传进去
Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).invoke(contractAddress, <method_name>, abi, params).build();
解码
解码与编码类似,需要提供Abi对象、方法名和编码的solidity结果,具体可见编码一节。
调用evm合约得到交易回执ReceiptResponse
后,需要对solidity合约的返回值进行解析,使用方法如下:
String ret = receiptResponse.getRet();
byte[] fromHex = ByteUtil.fromHex(ret);
// 通过abi的方法名解码,由于返回值可能有多个,所以解码得到的其实是一个List<?>,当中的每个对象
// 对应一个返回值。如该例子返回值为 int256,在java中对应的是BigInter,所以对返回的decodeResult
// 遍历强转为BigInteger
List<?> decodeResult = abi.getFunction("TestInt(int256)").decodeResult(fromHex);
for (Object result : decodeResult) {
System.out.println(result.getClass());
System.out.println(((BigInteger) result).toString());
}
当前内容版权归 Hyperchain 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 Hyperchain .