更新时间:2020-03-26 17:27
部署合约,同步方式调用。
public DeployContractResponse deployContract(DeployContractRequest request)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | DeployContractRequest | 部署合约的请求 |
返回字段 | 字段类型 | 说明 |
---|---|---|
response | DeployContractResponse | 部署合约的响应 |
DeployContractRequest request = new DeployContractRequest(acctId, contractId, code,
vmType, parameters, value);
// 请参考错误信息章节,检查返回的数据
DeployContractResponse response = sdk.getContractService().deployContract(request);
部署合约,异步方式调用。
public int asyncDeployContract(DeployContractRequest request, IAsyncCallback callback)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | DeployContractRequest | 部署合约的请求 |
callback | true | IAsyncCallback | 回调函数 |
返回字段 | 字段类型 | 说明 |
---|---|---|
result | int | 发送返回值 |
DeployContractRequest request = new DeployContractRequest(acctId, contractId, code,
vmType, parameters, value);
//deploy contract
int result = sdk.getContractService().asyncDeployContract(
request,
new IAsyncCallback() {
@Override
public void onResponse(int errorCode, Response response) {
// 请参考错误信息章节,检查返回的数据
System.out.println("async deploy contract, errorCode:" + errorCode + ", response: " + response.getErrorCode());
}
});
部署合约的参数:
参数 | 类型 | 说明 |
---|---|---|
acctId | Identity | 部署合约的账户 ID |
contractId | Identity | 合约 ID |
code | byte[] | 合约代码 |
vmTypeEnum | VMTypeEnum | 虚拟机类型,默认使用 evm 虚拟机,后续支持其它虚拟机类型。 |
parameters | Parameters | 合约参数 |
value | BigInteger | 合约金额 |
部署合约的返回参数:
参数 | 类型 | 说明 |
---|---|---|
transactionReceipt | TransactionReceipt | 交易收据 |
blockNumber | BigInteger | 区块号 |
调用合约,同步方式调用。
public CallContractResponse callContract(CallContractRequest request)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | CallContractRequest | 调用合约的请求 |
返回字段 | 字段类型 | 说明 |
---|---|---|
result | CallContractResponse | 调用合约的响应 |
CallContractRequest request = new CallContractRequest();
// 请参考错误信息章节,检查返回的数据
CallContractResponse response = sdk.getContractService().callContract(request);
调用合约,异步方式调用。
public int asyncCallContract(CallContractRequest request, IAsyncCallback callback)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | CallContractRequest | 调用合约的请求 |
callback | true | IAsyncCallback | 回调函数 |
返回字段 | 字段类型 | 说明 |
---|---|---|
result | int | 发送返回值 |
CallContractRequest request = new CallContractRequest();
int result = sdk.getContractService().asyncCallContract(
request,
new IAsyncCallback() {
@Override
public void onResponse(int errorCode, Response response) {
// 请参考错误信息章节,检查返回的数据
System.out.println("async call contract, errorCode:" + errorCode + ", response: " + response.getErrorCode());
}
);
调用合约的参数:
参数 | 类型 | 说明 |
---|---|---|
acctId | Identity | 提交交易的账户 ID |
contractId | Identity | 合约 ID |
parameters | Parameters | 合约参数 |
vmTypeEnum | VMTypeEnum | 虚拟机类型 |
value | BigInteger | 合约金额 |
调用合约的返回参数:
参数 | 类型 | 说明 |
---|---|---|
transactionReceipt | TransactionReceipt | 交易收据 |
blockNumber | BigInteger | 区块号 |
升级合约,同步方式调用。
public UpdateContractResponse updateContract(UpdateContractRequest request)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | UpdateContractRequest | 升级合约的请求 |
返回字段 | 字段类型 | 说明 |
---|---|---|
response | UpdateContractResponse | 升级合约的响应 |
UpdateContractRequest request = new UpdateContractRequest(contractId, code, vmTypeEnum);
// 请参考错误信息章节,检查返回的数据
UpdateContractResponse response = sdk.getContractService().updateContract(request);
升级合约,异步方式调用。
public int asyncUpdateContract(UpdateContractRequest request, IAsyncCallback callback)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | UpdateContractRequest | 升级合约的请求 |
callback | true | IAsyncCallback | 回调函数 |
返回字段 | 字段类型 | 说明 |
---|---|---|
result | int | 发送返回值 |
UpdateContractRequest request = new UpdateContractRequest(contractId, code, vmTypeEnum);
int result = sdk.getContractService().asyncUpdateContract(
request,
new IAsyncCallback() {
@Override
public void onResponse(int errorCode, Response response) {
// 请参考错误信息章节,检查返回的数据
System.out.println("async update contract, errorCode:" + errorCode + ", response: " + response.getErrorCode());
}
});
升级合约的参数:
参数 | 类型 | 说明 |
---|---|---|
contractId | Identity | 合约 ID |
code | byte[] | 目标合约的字节码,采用 16 进制表示,无需“0x”作为前缀。 |
vmTypeEnum | VMTypeEnum | 虚拟机类型 |
升级合约时,传入的 bytecode 字节码为 runtime 字节码。如果使用二进制 solc 编译工具,可直接获取 --bin-runtime
参数,即正常 --bin
参数编译的字节码的子集。runtime 字节码也可通过本地执行合约部署操作来获取。
部署合约的返回参数:
参数 | 类型 | 说明 |
---|---|---|
transactionReceipt | TransactionReceipt | 交易收据 |
blockNumber | BigInteger | 区块号 |
冻结合约,同步方式调用。
public FreezeContractResponse freezeContract(FreezeContractRequest request)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | FreezeContractRequest | 冻结合约的请求 |
返回字段 | 字段类型 | 说明 |
---|---|---|
response | FreezeContractResponse | 冻结合约的响应 |
FreezeContractRequest request = new FreezeContractRequest(from, to);
// 请参考错误信息章节,检查返回的数据
FreezeContractResponse result = sdk.getContractService().freezeContract(request)
冻结合约,异步方式调用。
public int asyncFreezeContract(FreezeContractRequest request,IAsyncCallback callback)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | FreezeContractRequest | 冻结合约的请求 |
callback | true | IAsyncCallback | 回调函数 |
返回字段 | 字段类型 | 说明 |
---|---|---|
result | int | 发送返回值 |
FreezeContractRequest request = new FreezeContractRequest(from, to);
int result = sdk.getContractService().asyncFreezeContract(
request
, new IAsyncCallback() {
@Override
public void onResponse(int errorCode, Response response) {
// 请参考错误信息章节,检查返回的数据
System.out.println("async freeze contract, errorCode:" + errorCode + ", response: " + response.getErrorCode());
}
});
冻结合约的参数:
参数 | 类型 | 说明 |
---|---|---|
from | Identity | 冻结合约的操作者 ID |
to | Identity | 待冻结的合约 ID |
冻结合约的返回参数:
参数 | 类型 | 说明 |
---|---|---|
transactionReceipt | TransactionReceipt | 交易收据 |
blockNumber | BigInteger | 区块号 |
解除冻结合约,同步方式调用。
public UnFreezeContractResponse unFreezeContract(UnFreezeContractRequest request)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | UnFreezeContractRequest | 解除冻结合约的请求 |
返回字段 | 字段类型 | 说明 |
---|---|---|
response | UnFreezeContractResponse | 解除冻结合约的响应 |
UnFreezeContractRequest request = new UnFreezeContractRequest(id, frozenId);
// 请参考错误信息章节,检查返回的数据
UnFreezeContractResponse response = sdk.getContractService().unFreezeContract(request);
解除冻结合约,异步方式调用。
public int asyncUnFreezeContract(UnFreezeContractRequest request,IAsyncCallback callback)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
request | true | UnFreezeContractRequest | 解除冻结合约的请求 |
callback | true | IAsyncCallback | 回调函数 |
返回字段 | 字段类型 | 说明 |
---|---|---|
result | int | 发送返回值 |
UnFreezeContractRequest request = new UnFreezeContractRequest(id, frozenId);
int result = sdk.getContractService().asyncUnFreezeContract(
request,
new IAsyncCallback() {
@Override
public void onResponse(int errorCode, Response response) {
// 请参考错误信息章节,检查返回的数据
System.out.println("async unFreeze contract, errorCode:" + errorCode + ", response: " + response.getErrorCode());
}
});
解冻合约的参数:
参数 | 类型 | 说明 |
---|---|---|
from | Identity | 解冻合约的操作者 ID |
to | Identity | 待解冻的合约 ID |
解冻合约的返回参数:
参数 | 类型 | 说明 |
---|---|---|
transactionReceipt | TransactionReceipt | 交易收据 |
blockNumber | BigInteger | 区块号 |
参数对象用于编码合约方法和参数。
函数名称 | 参数类型 | 参数说明 |
---|---|---|
setMethodSignature() | String |
添加函数选择器,即方法与参数列表构成的字符串 |
getEncodedData() | String |
EVM 参数字节码 |
addInt() | BigInteger |
添加静态的 int 类型的数据 |
addUInt() | BigInteger |
添加静态的 uint 类型的数据 |
addBool() | boolean |
添加静态的 bool 类型的数据 |
addIdentity() | Identity |
添加静态的 identity 类型的数据 |
addString () | String |
添加动态的 string 类型的数据 |
addBytes() | byte[] |
添加动态的 bytes 类型的数据 |
addBytesN() | byte[] |
添加静态的 bytes 类型的数据 |
addIntArray() | List<BigInteger> |
添加动态的 int 数组类型的数据 |
addUIntArray() | List<BigInteger> |
添加动态的 uint 数组类型的数据 |
addBytesNArray() | byte[] value |
添加动态的 bytes数组类型的数据 |
addBooleanArray() | List<Boolean> |
添加动态的 bool 数组类型的数据 |
EVMOutput,解析交易收据的 logData 和 output,可参考 EVM 合约编码说明 中的脚本示例。
函数名称 | 参数类型 | 参数说明 |
---|---|---|
getInt() | BigInteger |
获取静态的 int 类型的数据 |
getUInt() | BigInteger |
获取静态的 uint 类型的数据 |
getBool() | boolean |
获取 bool 类型的数据 |
getIdentity() | Identity |
获取 identity 类型的数据 |
getString () | String |
获取 string 类型的数据 |
getBytes() | byte[] |
获取的 bytes 类型的数据 |
getBytesN() | byte[] |
获取 bytes 类型的数据 |
getIntArray() | List<BigInteger> |
获取 int 数组类型的数据 |
getUIntArray() | List<BigInteger> |
获取 uint 数组类型的数据 |
getBytesNArray() | byte[] value |
获取 bytes 数组类型的数据 |
getBooleanArray() | List<Boolean> |
获取 bool 数组类型的数据 |
EVM 的参数和返回值编码规则一致,都与 Solidity 合约一样。对于静态类型的变量,直接编码为 32 字节按顺序拼接。对应动态数据类型,则用一个 32 字节偏移量占住位置,所有动态数据类型的真实数据按顺序以 LV 的格式放在后面。其中 L 表示数据的实际长度,L 占用 32 字节;V 为实际数据。
下面通过示例进行详细说明。
类型 | 值 |
---|---|
uint | 100 |
String | “abc” |
String | “0123456789abcdefghijklmnopqrstuvwxyz” |
boolean | true |
Identity | “1e7d3e769f3f593dadcb8634cc5b09fc90dd3a61c4a06a79cb0923662fe6fae6b” |
0000000000000000000000000000000000000000000000000000000000000064
00000000000000000000000000000000000000000000000000000000000000a0
00000000000000000000000000000000000000000000000000000000000000e0
0000000000000000000000000000000000000000000000000000000000000001
e7d3e769f3f593dadcb8634cc5b09fc90dd3a61c4a06a79cb0923662fe6fae6b
0000000000000000000000000000000000000000000000000000000000000003
6162630000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000024
303132333435363738396162636465666768696a6b6c6d6e6f70717273747576
7778797a00000000000000000000000000000000000000000000000000000000
具体解析如下:
0000000000000000000000000000000000000000000000000000000000000064
为“100”的编码,uint 类型,定长 32 字节,是大端编码。00000000000000000000000000000000000000000000000000000000000000a0
“abc”为动态类型,这里的 a0 为其实际数据编码所处偏移位置。因为这里一共 5 个变量,每个变量占用 0x20 个字节,所以第一个动态类型的数据偏移位置就是 5*0x20=0xA0,偏移量的编码规则和 uint 一样。
000000000000000000000000000000000000000000000000000000000000000e0
“0123456789abcdefghijklmopqrstuvwxyz”是动态类型,这里e0
为其实际数据编码所处偏移位置。本数据在“abc”之后,由于“abc”的长度和数据各占 0x20 字节,所以本数据就在 0xA0+0x40=0xE0 的位置。
00000000000000000000000000000000000000000000000000000000000000001
“true”的编码,bool
型数据占用定长 32 字节,true 最后一个字节为 01,false 最后一个字节为 00。
1e7d3e769f3f593dadcb8634cc5b09fc90dd3a61c4a06a79cb0923662fe6fae6b
是一个”Identity”类型的编码,与源数据完全一致。
00000000000000000000000000000000000000000000000000000000000000003
“abc”的长度,编码规则和uint
一样。
61626300000000000000000000000000000000000000000000000000000000000
“abc”的实际数据,String
类型的数据占用长度为 32 的整数倍,实际数据靠左编码,后面填充 00。
00000000000000000000000000000000000000000000000000000000000000024
为“0123456789abcdefghijklmnopqrstuvwxyz”的长度为 36=0x24。
303132333435363738396162636465666768696a6b6c6d6e6f70717273747576
,7778797a00000000000000000000000000000000000000000000000000000000
为“0123456789abcdefghijklmnopqrstuvwxyz”的实际数据编码。
// 获取返回值解码示例
EVMOutput evmOutput = new EVMOutput(ByteUtils.toHexString(transactionReceipt.getOutput()));
//按顺序获得返回值
BigInteger bigInteger = evmOutput.getUint(); // 100
String string = evmOutput.getString(); // "abc"
// "0123456789abcdefghijklmnopqrstuvwxyz"
String string1 = evmOutput.getString();
boolean b = evmOutput.getBoolean(); // true
// "1e7d3e769f3f593dadcb8634cc5b09fc90dd3a61c4a06a79cb0923662fe6fae6b"
Identity id = evmOutput.getIdentity();
函数名称 | 参数类型 | 参数说明 |
---|---|---|
setMethodSignature() | String |
添加函数选择器,方法与参数列表构成的字符串。 |
getEncodedData() | String |
WASM 参数字节码 |
addInt8() | BigInteger |
添加静态的 int_8 类型的数据 |
addInt16() | BigInteger |
添加静态的 int_16 类型的数据 |
addInt32() | BigInteger |
添加静态的 int_32 类型的数据 |
addInt64() | BigInteger |
添加静态的 int_64 类型的数据 |
addUInt8() | BigInteger |
添加静态的 uint_8 类型的数据 |
addUInt16() | BigInteger |
添加静态的 uint_16 类型的数据 |
addUInt32() | BigInteger |
添加静态的 uint_32 类型的数据 |
addUInt64() | BigInteger |
添加静态的 uint_64 类型的数据 |
addBool() | boolean |
添加静态的 bool 类型的数据 |
addIdentity() | Identity |
添加静态的 identity 类型的数据 |
addString() | String |
添加动态的 string 类型的数据 |
addBytes() | byte[] |
添加动态的 bytes 类型的数据 |
addInt8Array() | List<BigInteger> |
添加动态的 int_8 数组类型的数据 |
addInt16Array() | List<BigInteger> |
添加动态的 int_16 数组类型的数据 |
addInt32Array() | List<BigInteger> |
添加动态的 int_32 数组类型的数据 |
addInt64Array() | List<BigInteger> |
添加动态的 int_64 数组类型的数据 |
addUInt8Array() | List<BigInteger> |
添加动态的 uint_8 数组类型的数据 |
addUInt16Array() | List<BigInteger> |
添加动态的 uint_16 数组类型的数据 |
addUInt32Array() | List<BigInteger> |
添加动态的 uint_32 数组类型的数据 |
addUInt64Array() | List<BigInteger> |
添加动态的 uint_64 数组类型的数据 |
addBooleanArray() | List<Boolean> |
添加动态的 bool 数组类型的数据 |
addUtfStringArray() | List<String> |
添加动态 String 数组的数据 |
WasmOutput,解析交易收据的 logData 和 output,可参考示例。
函数名称 | 参数类型 | 参数说明 |
---|---|---|
getInt8() | BigInteger |
获取静态的 int_8 类型的数据 |
getInt16() | BigInteger |
获取静态的 int_16 类型的数据 |
getInt32() | BigInteger |
获取静态的 int_32 类型的数据 |
getInt64() | BigInteger |
获取静态的 int_64 类型的数据 |
getUInt8() | BigInteger |
获取静态的 uint_8 类型的数据 |
getUInt16() | BigInteger |
获取静态的 uint_16 类型的数据 |
getUInt32() | BigInteger |
获取静态的 uint_32 类型的数据 |
getUInt64() | BigInteger |
获取静态的 uint_64 类型的数据 |
getBool() | boolean |
获取静态的 bool 类型的数据 |
getString() | String |
获取动态的 string 类型的数据 |
getBytes() | byte[] |
获取动态的 bytes 类型的数据 |
getIntAndUintDynamicArray(Class type) | <T extends Type> List<BigInteger> |
获取 int 或者 uint 的动态数组 |
getBooleanDynamicArray() | List<Boolean> |
获取 bool 的动态数组 |
getStringDynamicArray() | List<String> |
获取 String 的动态数组 |
C++ 合约中的 pack 函数按照下面的规则进行序列化:
编码表(字节序均为小端)
类型 | 编码 | 字节数 | 编码示例(编码后数据以 16 进制展示) | C++ 类型 | Java SDK/JS SDK 类型 |
---|---|---|---|---|---|
bool | 原码 | 1 | false =>00 true =>01 |
bool | Bool |
uint8 | 原码 | 1 | 123 =>7B |
uint8_t | Uint8 |
uint16 | 原码 | 2 | 12345 =>39,30 |
uint16_t | Uint16 |
uint32 | 原码 | 4 | 1234567890 =>D2,02,96,49 |
uint32_t | Uint32 |
uint64 | 原码 | 8 | 1234567890123ull =>CB,04,FB,71,1F,01,00,00 |
uint64_t | Uint64 |
int8 | 补码 | 1 | -123 =>85 |
int8_t | Int8 |
int16 | 补码 | 2 | -12345 =>C7,CF |
int16_t | Int16 |
int32 | 补码 | 4 | -1234567890 =>2E,FD,69,B6 |
int32_t | Int32 |
int64 | 补码 | 8 | -1234567890123 =>35,FB,04,8E,E0,FE,FF,FF |
int64_t | Int64 |
任何指针 | 编译时报错 | T * | |||
string,字符串,每个元素为字符类型 | 元素字符用 utf-8 编码 | 先入以 LEB128 编码的 uint32 表达元素个数,然后遍历放入元素。 | "hello世界" =>0B,68,65,6C,6C,6F,E4,B8,96,E7,95,8C |
std::string | Utf8String |
array,数组,元素必为上述内置整型或 string 类型 | 先入以 LEB128 编码的 uint32 表达元素个数,然后遍历放入元素。 | int32 数组:{10, 20, 30} =>03,0A,00,00,00,14,00,00,00,1E,00,00,00 string数组 {"hello", "smart", "world"} =>03,05,68,65,6C,6C,6F,05,73,6D,61,72,74,05,77,6F,72,6C,64 |
std::vector | DynamicArray | |
bytes,字节流, 操作接口和 array 一致 |
先入以 LEB128 编码的 uint32 表达元素个数,然后遍历放入元素。 | bytes:{10, 20, 30} =>03,0A,14,1E |
std::vector |
Bytes |
C++ 合约中可以使用SERIALIZE
宏将自定义数据类型(struct/class)序列化。
SERIALIZE(结构体名, (成员变量1)(成员变量2)...(成员变量n))
示例:
struct Foo {
int32_t x;
std::string y;
bool z;
int32_t tmp_value; //如果SERIALIZE中不写tmp_value, 则tmp_value不参与序列化
SERIALIZE(Foo, (y)(x)(z))
};
Foo f;
f.x = -1234567890;
f.y = "hello世界";
f.z = true;
基于 编码表 中对基本类型的编码,Foo 类型的 f 变量的编码相当于按照SERIALIZE
指定的顺序依次编码各成员,未声明的成员不参与编码。上述示例中,按 y—>x—>z 进行顺次编码,首尾相接,结果为0B,68,65,6C,6C,6F,E4,B8,96,E7,95,8C,2E,FD,69,B6,01
。
// 获取返回值解码示例,假设返回了“0B,68,65,6C,6C,6F,E4,B8,96,E7,95,8C,2E,FD,69,B6,01”
WASMOutput wasmOutput = new WASMOutput(ByteUtils.toHexString(transactionReceipt.getOutput()));
String string = wasmOutput.getString(); // "hello世界"
BigInteger integer1 = wasmOutput.getInt32(); // -1234567890
boolean b = wasmOutput.getBoolean(); // true
在文档使用中是否遇到以下问题
更多建议
匿名提交