部署合约
deployContract
部署合约,同步方式调用。
函数原型
public MychainBaseResult<ReplyTransactionReceipt> deployContract(DeployContractRequest request)
请求参数
参数 | 必选 | 类型 | 说明 |
request | true | DeployContractRequest | 部署合约的请求 |
返回字段
返回字段 | 字段类型 | 说明 |
result | MychainBaseResult<ReplyTransactionReceipt> |
|
示例
// build params
MychainParams params = new MychainParams.Builder()
.gas(BigInteger.valueOf(4000000))
.privateKeyList(adminPrivateKeys)
.build();
ContractParameters contractParameters = new ContractParameters();
//deploy contract
MychainBaseResult<ReplyTransactionReceipt> result = sdk.getContractService().deployContract(
DeployContractRequest.build(
adminAccount.getIdentity(),
Utils.getIdentityByName(testContractId),
contractCode,
VMTypeEnum.EVM,
contractParameters,
BigInteger.ZERO,
params
)
);
asyncDeployContract
部署合约,异步方式调用。
函数原型
public MychainBaseResult<Response> asyncDeployContract(DeployContractRequest request, ICallback callback)
请求参数
参数 | 必选 | 类型 | 说明 |
request | true | DeployContractRequest | 部署合约的请求 |
callback | true | ICallback | 回调函数 |
返回字段
返回字段 | 字段类型 | 说明 |
result | MychainBaseResult<Response> |
|
示例
// build params
MychainParams params = new MychainParams.Builder()
.gas(BigInteger.valueOf(4000000))
.privateKeyList(adminPrivateKeys)
.build();
ContractParameters contractParameters = new ContractParameters();
//deploy contract
MychainBaseResult<Response> result = sdk.getContractService().asyncDeployContract(
DeployContractRequest.build(
adminAccount.getIdentity(),
Utils.getIdentityByName(testContractId),
contractCode,
VMTypeEnum.EVM,
contractParameters,
BigInteger.ZERO,
params
),
(txHash, response) -> {
System.out.println("async deploy contract, txHash:"+txHash+", result: "+ response.getErrorCode());
}
);
DeployContractRequest
下面是部署合约所需要的参数。
参数 | 类型 | 说明 |
acctId | Identity | 部署合约的账户 ID |
contractId | Identity | 合约 ID |
code | byte[] | 合约代码 |
vmTypeEnum | VMTypeEnum | 虚拟机类型,默认使用 EVM 虚拟机,后续将支持其它虚拟机类型。 |
parameters | Parameters | 合约参数 |
value | BigInteger | 合约金额 |
mychainParams | MychainParams | 接口通用扩展参数 |
调用合约
callContract
调用合约,同步方式调用。
函数原型
public MychainBaseResult<ReplyTransactionReceipt> callContract(CallContractRequest request)
请求参数
参数 | 必选 | 类型 | 说明 |
request | true | CallContractRequest | 调用合约的请求 |
返回字段
返回字段 | 字段类型 | 说明 |
result | MychainBaseResult<ReplyTransactionReceipt> |
|
示例
// build params
MychainParams params = new MychainParams.Builder()
.gas(BigInteger.valueOf(4000000))
.privateKeyList(adminPrivateKeys)
.build();
ContractParameters parameters = new ContractParameters("set(uint256)");
parameters.addUint(new BigInteger("100"));
BigInteger value = new BigInteger("0");
//call contract
MychainBaseResult<ReplyTransactionReceipt> replyTransactionReceipt = sdk.getContractService().callContract(
CallContractRequest.build(
adminAccount.getIdentity(),
Utils.getIdentityByName(testContractId),
parameters,
value,
params
)
);
asyncCallContract
调用合约,异步方式调用。
函数原型
public MychainBaseResult<Response> asyncCallContract(CallContractRequest request, ICallback callback)
请求参数
参数 | 必选 | 类型 | 说明 |
request | true | CallContractRequest | 调用合约的请求 |
callback | true | ICallback | 回调函数 |
返回字段
返回字段 | 字段类型 | 说明 |
result | MychainBaseResult<Response> |
|
示例
// build params
MychainParams params = new MychainParams.Builder()
.gas(BigInteger.valueOf(4000000))
.privateKeyList(adminPrivateKeys)
.build();
ContractParameters parameters = new ContractParameters("set(uint256)");
parameters.addUint(new BigInteger("100"));
// call contract
MychainBaseResult<Response> replyTransactionReceipt = sdk.getContractService().asyncCallContract(
CallContractRequest.build(
adminAccount.getIdentity(),
Utils.getIdentityByName(testContractId),
parameters,
value,
params
),
(txHash, response) -> {
System.out.println("async call contract, txHash:"+txHash+", result: "+ response.getErrorCode());
}
);
CallContractRequest
调用合约所需要的参数:
参数 | 类型 | 说明 |
acctId | Identity | 提交交易的账户 ID |
contractId | Identity | 合约 ID |
parameters | Parameters | 合约参数 |
value | BigInteger | 合约金额 |
mychainParams | MychainParams | 接口通用扩展参数 |
升级合约
updateContract
升级合约,同步方式调用。
函数原型
public MychainBaseResult<ReplyTransactionReceipt> updateContract(UpdateContractRequest request)
请求参数
参数 | 必选 | 类型 | 说明 |
request | true | UpdateContractRequest | 升级合约的请求 |
返回字段
返回字段 | 字段类型 | 说明 |
result | MychainBaseResult<ReplyTransactionReceipt> |
|
示例
// build params
MychainParams params = new MychainParams.Builder()
.gas(BigInteger.valueOf(40000))
.privateKeyList(adminPrivateKeys)
.build();
ContractParameters contractParameters = new ContractParameters();
//update contract
MychainBaseResult<ReplyTransactionReceipt> result = sdk.getContractService()
.updateContract(
UpdateContractRequest.build(Utils.getIdentityByName(testContractId), newContractCode, VMTypeEnum.EVM, params));
asyncUpdateContract
升级合约,异步方式调用。
函数原型
public MychainBaseResult<Response> asyncUpdateContract(UpdateContractRequest request, ICallback callback)
请求参数
参数 | 必选 | 类型 | 说明 |
request | true | UpdateContractRequest | 升级合约的请求 |
callback | true | ICallback | 回调函数 |
返回字段
返回字段 | 字段类型 | 说明 |
result | MychainBaseResult<Response> |
|
示例
// build params
// build params
MychainParams params = new MychainParams.Builder()
.gas(BigInteger.valueOf(40000))
.privateKeyList(adminPrivateKeys)
.build();
ContractParameters contractParameters = new ContractParameters();
//update contract
MychainBaseResult<Response> result = sdk.getContractService().asyncUpdateContract(
UpdateContractRequest.build(contractId, newContractCode, VMTypeEnum.EVM, params),
new ICallback() {
@Override
public void onResponse(String txHash, Response response) {
System.out.println("async update contract, txHash:" + txHash + ", result: "
+ response.getErrorCode());
assertTrue(response.isSuccess());
assertEquals("0", response.getErrorCode().getErrorCode());
}
});
UpdateContractRequest
升级合约所需要的参数:
参数 | 类型 | 说明 |
contractId | Identity | 合约 ID |
code |
| 目标合约的字节码,为 16 进制表示,无需“0x”作为前缀 |
vmTypeEnum | VMTypeEnum | 虚拟机类型 |
mychainParams | MychainParams | 接口通用扩展参数 |
说明:升级合约时,传入的 bytecode 字节码是 runtime 字节码,使用二进制 solc 编译工具的 —bin-runtime 参数可以直接得到,是正常 —bin 参数编译的字节码的子集。runtime 字节码通过本地执行合约部署操作也可获取到。
合约参数对象
参数对象,用于编码合约方法和参数。
EVM 合约参数对象
ContractParameters
函数名称 | 参数类型 | 参数说明 |
setMethodSignature() |
| 添加函数选择器,方法与参数列表构成的字符串。 |
getEncodedData() |
| EVM 参数字节码。 |
addInt() | BigInteger | 添加静态的 int 类型的数据。 |
addUInt() | BigInteger | 添加静态的 uint 类型的数据。 |
addBool() |
| 添加静态的 bool 类型的数据。 |
addIdentity() |
| 添加静态的 identity 类型的数据。 |
addString () |
| 添加动态的 string 类型的数据。 |
addBytes() |
| 添加动态的 bytes 类型的数据。 |
addBytesN() |
| 添加静态的 bytes 类型的数据。 |
addIntArray() |
| 添加动态的 int 数组类型的数据。 |
addUIntArray() |
| 添加动态的 uint 数组类型的数据。 |
addBytesNArray() |
| 添加动态的 bytes 数组类型的数据。 |
addBooleanArray() |
| 添加动态的 bool 数组类型的数据。 |
代码示例
//JAVA 示例代码 MychainParams params = new MychainParams(); params.setGas(BigInteger.valueOf(4000000)); params.setPrivateKeyList(adminPrivateKeys); BigInteger value = new BigInteger("0"); ContractParameters parameters = new ContractParameters("set(uint256)"); parameters.addUint(new BigInteger("100")); CallContractRequest request = CallContractRequest.build(adminAccount.getIdentity(), Utils.getIdentityByName(testContractId,env), parameters, value, params, 0, 0, BaseFixedSizeUnsignedInteger.Fixed64BitUnsignedInteger.valueOf(BigInteger.ONE)); assertNotNull(request); MychainBaseResult<ReplyTransactionReceipt> replyTransactionReceipt = sdk .getContractService().callContract(request);
EVM 数据解析
ContractReturnValues
函数名称 | 参数类型 | 参数说明 |
ContractReturnValues() |
| 虚拟机返回的字符串。 |
getInt() | BigInteger | 获取静态的 int 类型的数据。 |
getUInt() | BigInteger | 获取静态的 uint 类型的数据。 |
getBool() |
| 获取 bool 类型的数据。 |
getIdentity() |
| 获取 identity 类型的数据。 |
getString () |
| 获取 string 类型的数据。 |
getBytes() |
| 获取 bytes 类型的数据。 |
getBytesN() |
| 获取 bytes 类型的数据。 |
getIntArray() |
| 获取 int 数组类型的数据。 |
getUIntArray() |
| 获取 uint 数组类型的数据。 |
getBytesNArray() |
| 获取 bytes 数组类型的数据。 |
getBooleanArray() |
| 获取 bool 数组类型的数据。 |
EVM 合约编码说明
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”的实际数据编码。
// 获取返回值解码示例
ContractReturnValues contractReturnValues = new ContractReturnValues(ByteUtils.toHexString(replyTransactionReceipt.getData().getTransactionReceipt().getOutput()));
//按顺序获得返回值
BigInteger bigInteger = contractReturnValues.getUint(); // 100
String string = contractReturnValues.getString(); // "abc"
// "0123456789abcdefghijklmnopqrstuvwxyz"
String string1 = contractReturnValues.getString();
boolean b = contractReturnValues.getBoolean(); // true
// "1e7d3e769f3f593dadcb8634cc5b09fc90dd3a61c4a06a79cb0923662fe6fae6b"
Identity id = contractReturnValues.getIdentity();