合约接口

案例合约

pragma solidity ^0.6.4;
pragma experimental ABIEncoderV2;

contract arrTest
{

  、、、、、、、、、、、、、、、、、、

  function createArrayInt(int[] memory source)
    public
    pure
    returns (int[] memory)
  {
    int[] memory data=source;
    return data;
  }

}

部署合约

deployContract

部署合约,同步方式调用。

说明

请确保在部署合约时使用的是编译器正常编译后生成的合约字节码,避免使用其他渠道获得的合约字节码,以免部署时出现合约校验失败的问题。

  • 函数原型

public DeployContractResponse deployContract(DeployContractRequest request)
  • 请求参数

参数

必选

类型

说明

request

true

DeployContractRequest

部署合约的请求

DeployContractRequest,具体参数见下表。

参数

必选

类型

说明

acctId

true

Identity

部署合约的账户 ID

contractId

true

Identity

合约 ID

code

true

byte[]

合约代码

vmTypeEnum

true

VMTypeEnum

虚拟机类型:

  • NATIVE(0, "NATIVE CONTRACT")

  • EVM(1, "EVM CONTRACT")

  • WASM(2, "WASM CONTRACT")

  • DCVM(4, "DATA CONTRACT")

  • NATIVE_PRECOMPILE(-2, "NATIVE PRECOMPILE")

parameters

true

Parameters

合约参数

value

false

BigInteger

合约金额

  • 返回字段

返回字段

字段类型

说明

response

DeployContractResponse

部署合约的响应

DeployContractResponse,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

TransactionReceipt,具体参数见下表。

参数

类型

说明

result

long

交易执行结果,0 代表成功,其他值代表失败

gasUsed

BigInteger

交易执行所花费的gas费用

logs

List<logEntry>

交易结果日志输出

output

byte[]

交易的输出,此处为虚拟机的执行结果

LogEntry,具体参数见下表。

参数

类型

说明

from

Identity

交易结果日志中的字段,代表交易发送者

to

Identity

交易结果日志中的字段,代表交易j接收者

topics

List<String>

交易结果日志中的字段,交易执行的事件主题

logData

byte[]

交易结果日志中的字段,交易执行中的日志数据

  • 示例

public void deployContract() {
        String contractName = "contractName";
        String accountName = "tester";
        EVMParameter evmParameter = new EVMParameter();
        String contractCodeString = "608060405234801561001057600080fd5b50610c73806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806361df56c8146100465780636767574a14610076578063a61eed31146100a6575b600080fd5b610060600480360381019061005b91906102cd565b6100d6565b60405161006d91906104d7565b60405180910390f35b610090600480360381019061008b919061034f565b6100e5565b60405161009d91906104f9565b60405180910390f35b6100c060048036038101906100bb919061030e565b61010a565b6040516100cd91906104f9565b60405180910390f35b60608082905080915050919050565b60608082816000815181106100f657fe5b602002602001018190525080915050919050565b60608082905080915050919050565b600082601f83011261012a57600080fd5b813561013d61013882610548565b61051b565b9150818183526020840193506020810190508385602084028201111561016257600080fd5b60005b8381101561019257816101788882610210565b845260208401935060208301925050600181019050610165565b5050505092915050565b600082601f8301126101ad57600080fd5b81356101c06101bb82610570565b61051b565b9150818183526020840193506020810190508360005b8381101561020657813586016101ec8882610225565b8452602084019350602083019250506001810190506101d6565b5050505092915050565b60008135905061021f816106db565b92915050565b600082601f83011261023657600080fd5b813561024961024482610598565b61051b565b9150808252602083016020830185838301111561026557600080fd5b610270838284610688565b50505092915050565b600082601f83011261028a57600080fd5b813561029d610298826105c4565b61051b565b915080825260208301602083018583830111156102b957600080fd5b6102c4838284610688565b50505092915050565b6000602082840312156102df57600080fd5b600082013567ffffffffffffffff8111156102f957600080fd5b61030584828501610119565b91505092915050565b60006020828403121561032057600080fd5b600082013567ffffffffffffffff81111561033a57600080fd5b6103468482850161019c565b91505092915050565b60006020828403121561036157600080fd5b600082013567ffffffffffffffff81111561037b57600080fd5b61038784828501610279565b91505092915050565b600061039c838361048f565b60208301905092915050565b60006103b4838361049e565b905092915050565b60006103c782610610565b6103d1818561064b565b93506103dc836105f0565b8060005b8381101561040d5781516103f48882610390565b97506103ff83610631565b9250506001810190506103e0565b5085935050505092915050565b60006104258261061b565b61042f818561065c565b93508360208202850161044185610600565b8060005b8581101561047d578484038952815161045e85826103a8565b94506104698361063e565b925060208a01995050600181019050610445565b50829750879550505050505092915050565b6104988161067e565b82525050565b60006104a982610626565b6104b3818561066d565b93506104c3818560208601610697565b6104cc816106ca565b840191505092915050565b600060208201905081810360008301526104f181846103bc565b905092915050565b60006020820190508181036000830152610513818461041a565b905092915050565b6000604051905081810181811067ffffffffffffffff8211171561053e57600080fd5b8060405250919050565b600067ffffffffffffffff82111561055f57600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561058757600080fd5b602082029050602081019050919050565b600067ffffffffffffffff8211156105af57600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156105db57600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000819050919050565b82818337600083830152505050565b60005b838110156106b557808201518184015260208101905061069a565b838111156106c4576000848401525b50505050565b6000601f19601f8301169050919050565b6106e48161067e565b81146106ef57600080fd5b5056fea467616e74696e666f7905327b22636f6d6d656e7473223a22222c22636f6d70696c6572223a7b2276657273696f6e223a22302e362e342b636f6d6d69742e3831323031373135227d2c22636f6e74726163745f6769745f6964223a22222c22636f6e74726163745f76657273696f6e223a302c226c616e6775616765223a22536f6c6964697479222c226f7574707574223a7b22616269223a5b7b22696e70757473223a5b7b22696e7465726e616c54797065223a22737472696e675b5d222c226e616d65223a22736f75726365222c2274797065223a22737472696e675b5d227d5d2c226e616d65223a226372656174654172726179222c226f757470757473223a5b7b22696e7465726e616c54797065223a22737472696e675b5d222c226e616d65223a22222c2274797065223a22737472696e675b5d227d5d2c2273746174654d75746162696c697479223a2270757265222c2274797065223a2266756e6374696f6e227d2c7b22696e70757473223a5b7b22696e7465726e616c54797065223a22696e743235365b5d222c226e616d65223a22736f75726365222c2274797065223a22696e743235365b5d227d5d2c226e616d65223a226372656174654172726179496e74222c226f757470757473223a5b7b22696e7465726e616c54797065223a22696e743235365b5d222c226e616d65223a22222c2274797065223a22696e743235365b5d227d5d2c2273746174654d75746162696c697479223a2270757265222c2274797065223a2266756e6374696f6e227d2c7b22696e70757473223a5b7b22696e7465726e616c54797065223a22737472696e67222c226e616d65223a2273222c2274797065223a22737472696e67227d5d2c226e616d65223a226372656174654172726179537472696e67222c226f757470757473223a5b7b22696e7465726e616c54797065223a22737472696e675b5d222c226e616d65223a22222c2274797065223a22737472696e675b5d227d5d2c2273746174654d75746162696c697479223a2270757265222c2274797065223a2266756e6374696f6e227d5d2c22646576646f63223a7b226d6574686f6473223a7b7d7d2c2275736572646f63223a7b226d6574686f6473223a7b7d7d7d2c2273657474696e6773223a7b22636f6d70696c6174696f6e546172676574223a7b222f686f6d652f646174612f636f6e74726163742f736f6c69646974792f617272546573742e736f6c223a2261727254657374227d2c2265766d56657273696f6e223a22697374616e62756c222c226c6962726172696573223a7b7d2c226d65746164617461223a7b2262797465636f646548617368223a2269706673227d2c226f7074696d697a6572223a7b22656e61626c6564223a66616c73652c2272756e73223a3230307d2c2272656d617070696e6773223a5b5d7d2c22736f7572636573223a7b222f686f6d652f646174612f636f6e74726163742f736f6c69646974792f617272546573742e736f6c223a7b226b656363616b323536223a22307864373632383864613062313266336164626531396338623731393166663432643939316539373361333338373132646430383030373431653239656566336531222c2275726c73223a5b22627a7a2d7261773a2f2f37366363643566636536333831613765313365366433666265663065303362303035623436393866646666613634653933313830323738363766383063666138222c22647765623a2f697066732f516d6477684e367532597a333567536135694b6b7a507532465741725550475954514b55715a72566b704461597a225d7d7d2c2276657273696f6e223a317d646970667358221220839707e4119966fc9ac4ac6ddcc048f1a4a30c2bb25ce57c5e640f920614904864736f6c63430006046b636f6d70696c655f6d6f646130057e";

        DeployContractRequest deployContractRequest = new DeployContractRequest(Utils.getIdentityByName(accountName), Utils.getIdentityByName(contractName), ByteUtils.hexStringToBytes(contractCodeString), VMTypeEnum.EVM, evmParameter, BigInteger.ZERO);
        DeployContractResponse deployContractResponse = sdk.getContractService().deployContract(deployContractRequest);
        if (!deployContractResponse.isSuccess()) {
            logger.error("deployContract failed, errorCode :{}, errorDesc: {}", deployContractResponse.getErrorCode().getErrorCode(), deployContractResponse.getErrorCode().getErrorDesc());
        } else {
            // 交易收据
            TransactionReceipt transactionReceipt = deployContractResponse.getTransactionReceipt();
            if (transactionReceipt.getResult() != 0) {
                logger.error("deployContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
            } else {
                logger.info("deployContract success.返回信息: {}", transactionReceipt.toString());
            }
        }
    }

asyncDeployContract

部署合约,异步方式调用。

  • 函数原型

public int asyncDeployContract(DeployContractRequest request, IAsyncCallback callback)
  • 请求参数

参数

必选

类型

说明

request

true

DeployContractRequest

部署合约的请求

callback

true

IAsyncCallback

回调函数

DeployContractRequest,具体参数见下表。

参数

必选

类型

说明

acctId

true

Identity

部署合约的账户 ID

contractId

true

Identity

合约 ID

code

true

byte[]

合约代码

vmTypeEnum

true

VMTypeEnum

虚拟机类型:

  • NATIVE(0, "NATIVE CONTRACT")

  • EVM(1, "EVM CONTRACT")

  • WASM(2, "WASM CONTRACT")

  • DCVM(4, "DATA CONTRACT")

  • NATIVE_PRECOMPILE(-2, "NATIVE PRECOMPILE")

parameters

true

Parameters

合约参数

value

false

BigInteger

合约金额

  • 同步返回字段

返回字段

字段类型

说明

result

int

发送返回值

  • 异步返回字段

返回字段

字段类型

说明

errorCode

int

SDK发送消息返回的错误码,success时为0。

response

Response

平台返回的响应,其中 response.getErrorCode()是平台返回的错误码。

(DeployContractResponse)Response,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

  • 示例

public void asyncDeployContract() {
        String contractName = "contractName";
        String accountName = "tester";
        EVMParameter evmParameter = new EVMParameter();
        String contractCodeString = "608060405234801561001057600080fd5b50610c73806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806361df56c8146100465780636767574a14610076578063a61eed31146100a6575b600080fd5b610060600480360381019061005b91906102cd565b6100d6565b60405161006d91906104d7565b60405180910390f35b610090600480360381019061008b919061034f565b6100e5565b60405161009d91906104f9565b60405180910390f35b6100c060048036038101906100bb919061030e565b61010a565b6040516100cd91906104f9565b60405180910390f35b60608082905080915050919050565b60608082816000815181106100f657fe5b602002602001018190525080915050919050565b60608082905080915050919050565b600082601f83011261012a57600080fd5b813561013d61013882610548565b61051b565b9150818183526020840193506020810190508385602084028201111561016257600080fd5b60005b8381101561019257816101788882610210565b845260208401935060208301925050600181019050610165565b5050505092915050565b600082601f8301126101ad57600080fd5b81356101c06101bb82610570565b61051b565b9150818183526020840193506020810190508360005b8381101561020657813586016101ec8882610225565b8452602084019350602083019250506001810190506101d6565b5050505092915050565b60008135905061021f816106db565b92915050565b600082601f83011261023657600080fd5b813561024961024482610598565b61051b565b9150808252602083016020830185838301111561026557600080fd5b610270838284610688565b50505092915050565b600082601f83011261028a57600080fd5b813561029d610298826105c4565b61051b565b915080825260208301602083018583830111156102b957600080fd5b6102c4838284610688565b50505092915050565b6000602082840312156102df57600080fd5b600082013567ffffffffffffffff8111156102f957600080fd5b61030584828501610119565b91505092915050565b60006020828403121561032057600080fd5b600082013567ffffffffffffffff81111561033a57600080fd5b6103468482850161019c565b91505092915050565b60006020828403121561036157600080fd5b600082013567ffffffffffffffff81111561037b57600080fd5b61038784828501610279565b91505092915050565b600061039c838361048f565b60208301905092915050565b60006103b4838361049e565b905092915050565b60006103c782610610565b6103d1818561064b565b93506103dc836105f0565b8060005b8381101561040d5781516103f48882610390565b97506103ff83610631565b9250506001810190506103e0565b5085935050505092915050565b60006104258261061b565b61042f818561065c565b93508360208202850161044185610600565b8060005b8581101561047d578484038952815161045e85826103a8565b94506104698361063e565b925060208a01995050600181019050610445565b50829750879550505050505092915050565b6104988161067e565b82525050565b60006104a982610626565b6104b3818561066d565b93506104c3818560208601610697565b6104cc816106ca565b840191505092915050565b600060208201905081810360008301526104f181846103bc565b905092915050565b60006020820190508181036000830152610513818461041a565b905092915050565b6000604051905081810181811067ffffffffffffffff8211171561053e57600080fd5b8060405250919050565b600067ffffffffffffffff82111561055f57600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561058757600080fd5b602082029050602081019050919050565b600067ffffffffffffffff8211156105af57600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156105db57600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000819050919050565b82818337600083830152505050565b60005b838110156106b557808201518184015260208101905061069a565b838111156106c4576000848401525b50505050565b6000601f19601f8301169050919050565b6106e48161067e565b81146106ef57600080fd5b5056fea467616e74696e666f7905327b22636f6d6d656e7473223a22222c22636f6d70696c6572223a7b2276657273696f6e223a22302e362e342b636f6d6d69742e3831323031373135227d2c22636f6e74726163745f6769745f6964223a22222c22636f6e74726163745f76657273696f6e223a302c226c616e6775616765223a22536f6c6964697479222c226f7574707574223a7b22616269223a5b7b22696e70757473223a5b7b22696e7465726e616c54797065223a22737472696e675b5d222c226e616d65223a22736f75726365222c2274797065223a22737472696e675b5d227d5d2c226e616d65223a226372656174654172726179222c226f757470757473223a5b7b22696e7465726e616c54797065223a22737472696e675b5d222c226e616d65223a22222c2274797065223a22737472696e675b5d227d5d2c2273746174654d75746162696c697479223a2270757265222c2274797065223a2266756e6374696f6e227d2c7b22696e70757473223a5b7b22696e7465726e616c54797065223a22696e743235365b5d222c226e616d65223a22736f75726365222c2274797065223a22696e743235365b5d227d5d2c226e616d65223a226372656174654172726179496e74222c226f757470757473223a5b7b22696e7465726e616c54797065223a22696e743235365b5d222c226e616d65223a22222c2274797065223a22696e743235365b5d227d5d2c2273746174654d75746162696c697479223a2270757265222c2274797065223a2266756e6374696f6e227d2c7b22696e70757473223a5b7b22696e7465726e616c54797065223a22737472696e67222c226e616d65223a2273222c2274797065223a22737472696e67227d5d2c226e616d65223a226372656174654172726179537472696e67222c226f757470757473223a5b7b22696e7465726e616c54797065223a22737472696e675b5d222c226e616d65223a22222c2274797065223a22737472696e675b5d227d5d2c2273746174654d75746162696c697479223a2270757265222c2274797065223a2266756e6374696f6e227d5d2c22646576646f63223a7b226d6574686f6473223a7b7d7d2c2275736572646f63223a7b226d6574686f6473223a7b7d7d7d2c2273657474696e6773223a7b22636f6d70696c6174696f6e546172676574223a7b222f686f6d652f646174612f636f6e74726163742f736f6c69646974792f617272546573742e736f6c223a2261727254657374227d2c2265766d56657273696f6e223a22697374616e62756c222c226c6962726172696573223a7b7d2c226d65746164617461223a7b2262797465636f646548617368223a2269706673227d2c226f7074696d697a6572223a7b22656e61626c6564223a66616c73652c2272756e73223a3230307d2c2272656d617070696e6773223a5b5d7d2c22736f7572636573223a7b222f686f6d652f646174612f636f6e74726163742f736f6c69646974792f617272546573742e736f6c223a7b226b656363616b323536223a22307864373632383864613062313266336164626531396338623731393166663432643939316539373361333338373132646430383030373431653239656566336531222c2275726c73223a5b22627a7a2d7261773a2f2f37366363643566636536333831613765313365366433666265663065303362303035623436393866646666613634653933313830323738363766383063666138222c22647765623a2f697066732f516d6477684e367532597a333567536135694b6b7a507532465741725550475954514b55715a72566b704461597a225d7d7d2c2276657273696f6e223a317d646970667358221220839707e4119966fc9ac4ac6ddcc048f1a4a30c2bb25ce57c5e640f920614904864736f6c63430006046b636f6d70696c655f6d6f646130057e";

        DeployContractRequest deployContractRequest = new DeployContractRequest(Utils.getIdentityByName(accountName), Utils.getIdentityByName(contractName), ByteUtils.hexStringToBytes(contractCodeString), VMTypeEnum.EVM, evmParameter, BigInteger.ZERO);
        int result = sdk.getContractService().asyncDeployContract(deployContractRequest, new IAsyncCallback() {
            @Override
            public void onResponse(int errorCode, Response response) {
                // 请参考错误信息章节,检查返回的数据
                DeployContractResponse deployContractResponse = (DeployContractResponse) response;
                if (!deployContractResponse.isSuccess()) {
                    logger.error("deployContract failed, errorCode :{}, errorDesc: {}", deployContractResponse.getErrorCode().getErrorCode(), deployContractResponse.getErrorCode().getErrorDesc());
                } else {
                    // 交易收据
                    TransactionReceipt transactionReceipt = deployContractResponse.getTransactionReceipt();
                    if (transactionReceipt.getResult() != 0) {
                        logger.error("deployContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
                    } else {
                        logger.info("deployContract success.返回信息: {}", transactionReceipt.toString());
                    }
                }
            }
        });
    }

调用合约

callContract

调用合约,同步方式调用。

  • 函数原型

public CallContractResponse callContract(CallContractRequest request)
  • 请求参数

参数

必选

类型

说明

request

true

CallContractRequest

调用合约的请求

CallContractRequest

调用合约的参数:

参数

必选

类型

说明

acctId

true

Identity

提交交易的账户 ID

contractId

true

Identity

合约 ID

parameters

true

Parameters

合约参数

vmTypeEnum

true

VMTypeEnum

虚拟机类型:

NATIVE(0, "NATIVE CONTRACT")

EVM(1, "EVM CONTRACT")

WASM(2, "WASM CONTRACT")

DCVM(4, "DATA CONTRACT")

NATIVE_PRECOMPILE(-2, "NATIVE PRECOMPILE")

value

false

BigInteger

合约金额

  • 返回字段

返回字段

字段类型

说明

result

CallContractResponse

调用合约的响应

CallContractResponse,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

  • 示例

public void callContract() {
        String contractName = "contractName";
        String accountName = "tester";
        EVMParameter parameters = new EVMParameter("createArrayInt(int256[])");
        // 检查参数是否错误
        DynamicArray<Int> dynamicArray = new DynamicArray<Int>(new Int(BigInteger.valueOf(1)), new Int(BigInteger.valueOf(2)), new Int(BigInteger.valueOf(3)));
        parameters.addArray(dynamicArray);
        // build CallContractRequest
        CallContractRequest request = new CallContractRequest(Utils.getIdentityByName(accountName), Utils.getIdentityByName(contractName), parameters, BigInteger.ZERO, VMTypeEnum.EVM);

        CallContractResponse callContractResponse = sdk.getContractService().callContract(request);
        if (!callContractResponse.isSuccess()) {
            logger.error("callContract failed, errorCode :{}, errorDesc: {}", callContractResponse.getErrorCode().getErrorCode(), callContractResponse.getErrorCode().getErrorDesc());
        } else {
            // 交易收据
            TransactionReceipt transactionReceipt = callContractResponse.getTransactionReceipt();
            if (transactionReceipt.getResult() != 0) {
                logger.error("callContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
            } else {
                logger.info("callContract success.返回信息: {}", transactionReceipt.toString());
                // 手动抛出的错误可在evmOutput中查看
                EVMOutput evmOutput = new EVMOutput(Hex.toHexString(transactionReceipt.getOutput()));
                //获取要解析的类型
                logger.info("callContract success.返回信息:{}", evmOutput.getIntDynamicArray().toString());
            }
        }
    }

asyncCallContract

调用合约,异步方式调用。

  • 函数原型

public int asyncCallContract(CallContractRequest request, IAsyncCallback callback)
  • 请求参数

参数

必选

类型

说明

request

true

CallContractRequest

调用合约的请求

callback

true

IAsyncCallback

回调函数

CallContractRequest,具体参数见下表。

参数

必选

类型

说明

acctId

true

Identity

提交交易的账户 ID

contractId

true

Identity

合约 ID

parameters

true

Parameters

合约参数

vmTypeEnum

true

VMTypeEnum

虚拟机类型:

  • NATIVE(0, "NATIVE CONTRACT")

  • EVM(1, "EVM CONTRACT")

  • WASM(2, "WASM CONTRACT")

  • DCVM(4, "DATA CONTRACT")

  • NATIVE_PRECOMPILE(-2, "NATIVE PRECOMPILE")

value

false

BigInteger

合约金额

  • 同步返回字段

返回字段

字段类型

说明

result

int

发送返回值

  • 异步返回字段

返回字段

字段类型

说明

errorCode

int

SDK发送消息返回的错误码,success时为0。

response

Response

平台返回的响应,其中 response.getErrorCode()是平台返回的错误码。

(CallContractResponse)Response,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

  • 示例

public void asyncCallContract() {
        String contractName = "contractName";
        String accountName = "tester";
        EVMParameter parameters = new EVMParameter("createArrayInt(int256[])");
        // 检查参数是否错误
        DynamicArray<Int> dynamicArray = new DynamicArray<Int>(new Int(BigInteger.valueOf(1)), new Int(BigInteger.valueOf(2)), new Int(BigInteger.valueOf(3)));
        parameters.addArray(dynamicArray);
        // build CallContractRequest
        CallContractRequest request = new CallContractRequest(Utils.getIdentityByName(accountName), Utils.getIdentityByName(contractName), parameters, BigInteger.ZERO, VMTypeEnum.EVM);
        int result = sdk.getContractService().asyncCallContract(request, new IAsyncCallback() {
            @Override
            public void onResponse(int errorCode, Response response) {
                // 请参考错误信息章节,检查返回的数据
                CallContractResponse callContractResponse = (CallContractResponse) response;
                if (!callContractResponse.isSuccess()) {
                    logger.error("callContract failed, errorCode :{}, errorDesc: {}", callContractResponse.getErrorCode().getErrorCode(), callContractResponse.getErrorCode().getErrorDesc());
                } else {
                    // 交易收据
                    TransactionReceipt transactionReceipt = callContractResponse.getTransactionReceipt();
                    if (transactionReceipt.getResult() != 0) {
                        logger.error("callContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
                    } else {
                        logger.info("callContract success.返回信息: {}", transactionReceipt.toString());
                        // 手动抛出的错误可在evmOutput中查看
                        EVMOutput evmOutput = new EVMOutput(Hex.toHexString(transactionReceipt.getOutput()));
                        //获取要解析的类型
                        logger.info("callContract success.返回信息:{},", evmOutput.getIntDynamicArray().toString());
                    }
                }
            }
        });
    }

升级合约

updateContract

升级合约,同步方式调用。

  • 函数原型

public UpdateContractResponse updateContract(UpdateContractRequest request)
  • 请求参数

参数

必选

类型

说明

request

true

UpdateContractRequest

升级合约的请求

UpdateContractRequest,具体参数见下表。

参数

必选

类型

说明

contractId

true

Identity

合约 ID

code

true

byte[]

目标合约的字节码,采用 16 进制表示,无需“0x”作为前缀。

vmTypeEnum

true

VMTypeEnum

虚拟机类型:

  • NATIVE(0, "NATIVE CONTRACT")

  • EVM(1, "EVM CONTRACT")

  • WASM(2, "WASM CONTRACT")

  • DCVM(4, "DATA CONTRACT")

  • NATIVE_PRECOMPILE(-2, "NATIVE PRECOMPILE")

说明

升级合约时,传入的 bytecode 字节码为 runtime 字节码。如果使用二进制 solc 编译工具,可直接获取 --bin-runtime 参数,即正常 --bin 参数编译的字节码的子集。runtime 字节码也可通过本地执行合约部署操作来获取。

  • 返回字段

返回字段

字段类型

说明

response

UpdateContractResponse

升级合约的响应

UpdateContractResponse,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

  • 示例

public void updateContract() {
        String contractName = "contractName";
        UpdateContractRequest updateContractRequest = new UpdateContractRequest(Utils.getIdentityByName(contractName), ByteUtils.hexStringToBytes(contractCodeString), VMTypeEnum.EVM);
        UpdateContractResponse updateContractResponse = sdk.getContractService().updateContract(updateContractRequest);
        if (!updateContractResponse.isSuccess()) {
            logger.error("updateContract failed, errorCode :{}, errorDesc: {}", updateContractResponse.getErrorCode().getErrorCode(), updateContractResponse.getErrorCode().getErrorDesc());
        } else {
            // 交易收据
            TransactionReceipt transactionReceipt = updateContractResponse.getTransactionReceipt();
            if (transactionReceipt.getResult() != 0) {
                logger.error("updateContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
            } else {
                logger.info("updateContract success.返回信息: {}", transactionReceipt.toString());
            }
        }
    }

asyncUpdateContract

升级合约,异步方式调用。

  • 函数原型

public int asyncUpdateContract(UpdateContractRequest request, IAsyncCallback callback)
  • 请求参数

参数

必选

类型

说明

request

true

UpdateContractRequest

升级合约的请求

callback

true

IAsyncCallback

回调函数

UpdateContractRequest,具体参数见下表。

参数

必选

类型

说明

contractId

true

Identity

合约 ID

code

true

byte[]

目标合约的字节码,采用 16 进制表示,无需“0x”作为前缀。

vmTypeEnum

true

VMTypeEnum

虚拟机类型:

  • NATIVE(0, "NATIVE CONTRACT")

  • EVM(1, "EVM CONTRACT")

  • WASM(2, "WASM CONTRACT")

  • DCVM(4, "DATA CONTRACT")

  • NATIVE_PRECOMPILE(-2, "NATIVE PRECOMPILE")

说明

升级合约时,传入的 bytecode 字节码为 runtime 字节码。如果使用二进制 solc 编译工具,可直接获取 --bin-runtime 参数,即正常 --bin 参数编译的字节码的子集。runtime 字节码也可通过本地执行合约部署操作来获取。

  • 同步返回字段

返回字段

字段类型

说明

result

int

发送返回值

  • 异步返回字段

返回字段

字段类型

说明

errorCode

int

SDK发送消息返回的错误码,success时为0。

response

Response

平台返回的响应,其中 response.getErrorCode()是平台返回的错误码。

(UpdateContractResponse)Response,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

  • 示例

public void asyncUpdateContract() {
        String contractName = "contractName";
        UpdateContractRequest updateContractRequest = new UpdateContractRequest(Utils.getIdentityByName(contractName), ByteUtils.hexStringToBytes(contractCodeString), VMTypeEnum.EVM);
        int result = sdk.getContractService().asyncUpdateContract(updateContractRequest, new IAsyncCallback() {
            @Override
            public void onResponse(int errorCode, Response response) {
                // 请参考错误信息章节,检查返回的数据
                UpdateContractResponse updateContractResponse = (UpdateContractResponse) response;
                if (!updateContractResponse.isSuccess()) {
                    logger.error("updateContract failed, errorCode :{}, errorDesc: {}", updateContractResponse.getErrorCode().getErrorCode(), updateContractResponse.getErrorCode().getErrorDesc());
                } else {
                    // 交易收据
                    TransactionReceipt transactionReceipt = updateContractResponse.getTransactionReceipt();
                    if (transactionReceipt.getResult() != 0) {
                        logger.error("updateContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
                    } else {
                        logger.info("updateContract success.返回信息: {}", transactionReceipt.toString());
                    }
                }
            }
        });
    }

冻结合约

freezeContract

冻结合约,同步方式调用。

  • 函数原型

public FreezeContractResponse freezeContract(FreezeContractRequest request)
  • 请求参数

参数

必选

类型

说明

request

true

FreezeContractRequest

冻结合约的请求

FreezeContractRequest,具体参数见下表。

参数

必选

类型

说明

from

true

Identity

冻结合约的操作者id(admin或者是合约本身)

to

true

Identity

待冻结的合约 ID

  • 返回字段

返回字段

字段类型

说明

response

FreezeContractResponse

冻结合约的响应

FreezeContractResponse,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

  • 示例

public void freezeContract() {
        String contractName = "contractName";
        FreezeContractRequest freezeContractRequest = new FreezeContractRequest(Utils.getIdentityByName("Administrator"), Utils.getIdentityByName(contractName));

        FreezeContractResponse freezeContractResponse = sdk.getContractService().freezeContract(freezeContractRequest);
        if (!freezeContractResponse.isSuccess()) {
            logger.error("freezeContract failed, errorCode :{}, errorDesc: {}", freezeContractResponse.getErrorCode().getErrorCode(), freezeContractResponse.getErrorCode().getErrorDesc());
        } else {
            // 交易收据
            TransactionReceipt transactionReceipt = freezeContractResponse.getTransactionReceipt();
            if (transactionReceipt.getResult() != 0) {
                logger.error("freezeContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
            } else {
                logger.info("freezeContract success.返回信息: {}", transactionReceipt.toString());
            }
        }
    }

asyncFreezeContract

冻结合约,异步方式调用。

  • 函数原型

public int asyncFreezeContract(FreezeContractRequest request,IAsyncCallback callback)
  • 请求参数

参数

必选

类型

说明

request

true

FreezeContractRequest

冻结合约的请求

callback

true

IAsyncCallback

回调函数

FreezeContractRequest,具体参数见下表。

参数

必选

类型

说明

from

true

Identity

冻结合约的操作者id(admin或者是合约本身)

to

true

Identity

待冻结的合约 ID

  • 同步返回字段

返回字段

字段类型

说明

result

int

发送返回值

  • 异步返回字段

返回字段

字段类型

说明

errorCode

int

SDK发送消息返回的错误码,success时为0。

response

Response

平台返回的响应,其中 response.getErrorCode()是平台返回的错误码。

(FreezeContractResponse)Response,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

  • 示例

public void asyncFreezeContract() {
        String contractName = "contractName";
        FreezeContractRequest freezeContractRequest = new FreezeContractRequest(Utils.getIdentityByName("Administrator"), Utils.getIdentityByName(contractName));

        int result = sdk.getContractService().asyncFreezeContract(freezeContractRequest, new IAsyncCallback() {
            @Override
            public void onResponse(int errorCode, Response response) {
                // 请参考错误信息章节,检查返回的数据
                FreezeContractResponse freezeContractResponse = (FreezeContractResponse) response;
                if (!freezeContractResponse.isSuccess()) {
                    logger.error("freezeContract failed, errorCode :{}, errorDesc: {}", freezeContractResponse.getErrorCode().getErrorCode(), freezeContractResponse.getErrorCode().getErrorDesc());
                } else {
                    // 交易收据
                    TransactionReceipt transactionReceipt = freezeContractResponse.getTransactionReceipt();
                    if (transactionReceipt.getResult() != 0) {
                        logger.error("freezeContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
                    } else {
                        logger.info("freezeContract success.返回信息: {}", transactionReceipt.toString());
                    }
                }
            }
        });
    }

解冻合约

unFreezeContract

解除冻结合约,同步方式调用。

  • 函数原型

public UnFreezeContractResponse unFreezeContract(UnFreezeContractRequest request)

  • 请求参数

参数

必选

类型

说明

request

true

UnFreezeContractRequest

解除冻结合约的请求

UnfreezeContractRequest,具体参数见下表。

参数

必选

类型

说明

from

true

Identity

解冻合约的操作者(必须为admin)

to

true

Identity

待解冻的合约 ID

  • 返回字段

返回字段

字段类型

说明

response

UnFreezeContractResponse

解除冻结合约的响应

UnFreezeContractResponse,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

  • 示例

public void unFreezeContract() {
        String contractName = "contractName";
        UnFreezeContractRequest unFreezeContractRequest = new UnFreezeContractRequest(Utils.getIdentityByName("Administrator"), Utils.getIdentityByName(contractName));

        UnFreezeContractResponse unFreezeContractResponse = sdk.getContractService().unFreezeContract(unFreezeContractRequest);
        if (!unFreezeContractResponse.isSuccess()) {
            logger.error("unFreezeContract failed, errorCode :{}, errorDesc: {}", unFreezeContractResponse.getErrorCode().getErrorCode(), unFreezeContractResponse.getErrorCode().getErrorDesc());
        } else {
            // 交易收据
            TransactionReceipt transactionReceipt = unFreezeContractResponse.getTransactionReceipt();
            if (transactionReceipt.getResult() != 0) {
                logger.error("unFreezeContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
            } else {
                logger.info("unFreezeContract success.返回信息: {}", transactionReceipt.toString());
            }
        }
    }

asyncUnFreezeContract

解除冻结合约,异步方式调用。

  • 函数原型

public int asyncUnFreezeContract(UnFreezeContractRequest request,IAsyncCallback callback)
  • 请求参数

参数

必选

类型

说明

request

true

UnFreezeContractRequest

解除冻结合约的请求

callback

true

IAsyncCallback

回调函数

UnfreezeContractRequest,具体参数见下表。

参数

必选

类型

说明

from

true

Identity

解冻合约的操作者 (必须为admin)

to

true

Identity

待解冻的合约 ID

  • 同步返回字段

返回字段

字段类型

说明

result

int

发送返回值

  • 异步返回字段

返回字段

字段类型

说明

errorCode

int

SDK发送消息返回的错误码,success时为0。

response

Response

平台返回的响应,其中 response.getErrorCode()是平台返回的错误码。

(UnFreezeContractResponse)Response,具体参数见下表。

参数

类型

说明

transactionReceipt

TransactionReceipt

交易收据

blockNumber

BigInteger

区块号

txIndex

int

交易偏移量

txHash

Hash

交易hash

isLocalTransaction

boolean

是否为本地交易

  • 示例

public void asyncUnFreezeContract() {
        String contractName = "contractName";
        UnFreezeContractRequest unFreezeContractRequest = new UnFreezeContractRequest(Utils.getIdentityByName("Administrator"), Utils.getIdentityByName(contractName));
        int result = sdk.getContractService().asyncUnFreezeContract(unFreezeContractRequest, new IAsyncCallback() {
            @Override
            public void onResponse(int errorCode, Response response) {
                // 请参考错误信息章节,检查返回的数据
                UnFreezeContractResponse unFreezeContractResponse = (UnFreezeContractResponse) response;
                if (!unFreezeContractResponse.isSuccess()) {
                    logger.error("unFreezeContract failed, errorCode :{}, errorDesc: {}", unFreezeContractResponse.getErrorCode().getErrorCode(), unFreezeContractResponse.getErrorCode().getErrorDesc());
                } else {
                    // 交易收据
                    TransactionReceipt transactionReceipt = unFreezeContractResponse.getTransactionReceipt();
                    if (transactionReceipt.getResult() != 0) {
                        logger.error("unFreezeContract failed, errorCode :{}, errorDesc: {}", ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorCode(), ErrorCode.valueOf((int) transactionReceipt.getResult()).getErrorDesc());
                    } else {
                        logger.info("unFreezeContract success.返回信息: {}", transactionReceipt.toString());
                    }
                }
            }
        });
    }

获取数据合约Schema

getContractSchema

调用 getContractSchema 接口获取数据合约的Schema,同步方式调用。

  • 函数原型

public GetContractSchemaResponse getContractSchema(GetContractSchemaRequest request)
  • 请求参数

参数

必选

类型

说明

request

true

GetContractSchemaRequest

获取数据合约的请求

GetContractSchemaRequest,具体参数见下表。

参数

必选

类型

说明

acctId

true

Identity

发起交易的账户id

contractId

true

Identity

被调用的数据合约id

vmTypeEnum

true

VMTypeEnum

合约类型(VMTypeEnum.DCVM)

  • 返回字段

返回字段

字段类型

说明

response

GetContractSchemaResponse

获取数据合约的响应

说明

GetContractSchemaResponse,无参数,通过方法获取值,请参考示例中的写法。

  • 示例

    @Test
    public void testgetContractSchemaTest() throws IOException {
        // byte[] schema = IOUtil.inputStreamToByte(ContractServiceTest.class.getResourceAsStream("/contract_schema"));
       //部署数据合约
        //schema内容,请根据实际项目中业务场景赋值
        byte[] schema = new byte[]{1, 2, 3, 4, 5, 6, 7};
        DeployContractRequest deployContractRequest = new DeployContractRequest(yourAccount.getIdentity(),
                Utils.getIdentityByName(yourTestDCVMContractId), schema,
                VMTypeEnum.DCVM);
        DeployContractResponse result = sdk.getContractService().deployContract(deployContractRequest);
        assertTrue(result.isSuccess());
        assertEquals(0, result.getTransactionReceipt().getResult());

        //设置合约访问权限
        ContractAccessControl acl = new ContractAccessControl(yourAccount.getIdentity());
        acl.setDataRead(true);
        acl.setSchemaRead(true);
        List<ContractAccessControl> contractAccessControls = new ArrayList<>();
        contractAccessControls.add(acl);

        SetContractAccessControlRequest setContractAccessControlRequest =
                new SetContractAccessControlRequest(Utils.getIdentityByName(yourTestDCVMContractId), contractAccessControls);
        SetContractAccessControlResponse setContractAccessControlResponse =
                sdk.getContractService().setContractAccessControl(setContractAccessControlRequest);
        assertTrue(setContractAccessControlResponse.isSuccess());

        //查询合约访问权限
        List<Identity> identities = Arrays.asList(yourAccount.getIdentity());
        GetContractAccessControlRequest getContractAccessControlRequest = new GetContractAccessControlRequest(Utils.getIdentityByName(yourTestDCVMContractId), identities);
        GetContractAccessControlResponse getContractAccessControlResponse = sdk.getContractService().getContractAccessControl(getContractAccessControlRequest);
        assertTrue(getContractAccessControlResponse.isSuccess());
        assertEquals(getContractAccessControlRequest.getSequenceId(), getContractAccessControlResponse.getSequenceId());
        assertEquals(getContractAccessControlResponse.getTransactionReceipt().getResult(), 0);
        assertNull(getContractAccessControlResponse.getContractAccessControls(identities).getSecond());
        List<ContractAccessControl> aclResult = getContractAccessControlResponse.getContractAccessControls(identities).getFirst();
        assertTrue(aclResult.size() > 0);
        assertTrue(aclResult.get(0).isDataRead());
        assertFalse(aclResult.get(0).isDataWrite());
        assertTrue(aclResult.get(0).isSchemaRead());
        assertFalse(aclResult.get(0).isSchemaWrite());

        //获取Schema
        GetContractSchemaRequest getContractSchemaRequest = new GetContractSchemaRequest(yourAccount.getIdentity(),
                Utils.getIdentityByName(yourTestDCVMContractId), VMTypeEnum.DCVM);
        GetContractSchemaResponse getContractSchemaResponse = sdk.getContractService().getContractSchema(getContractSchemaRequest);
        assertTrue(getContractSchemaResponse.isSuccess());
        assertEquals(getContractSchemaResponse.getSequenceId(), getContractSchemaRequest.getSequenceId());
        assertEquals(getContractSchemaResponse.getTransactionReceipt().getResult(), 0);
        if(getContractSchemaResponse.getContractSchema().getFirst()!=null) {
            String schemaString = getContractSchemaResponse.getContractSchema().getFirst();
            assertEquals(ByteUtils.toHexString(schema), schemaString);
        }else{
            fail();
        }

        //更新合约
        //schema内容,请根据实际项目中业务场景赋值
        schema = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        UpdateContractRequest updateContractRequest = new UpdateContractRequest(Utils.getIdentityByName(yourTestDCVMContractId), schema, VMTypeEnum.DCVM);
        UpdateContractResponse updateContractResponse = sdk.getContractService().updateContract(updateContractRequest);
        assertTrue(updateContractResponse.isSuccess());
        assertEquals(updateContractResponse.getSequenceId(), updateContractRequest.getSequenceId());
        assertEquals(updateContractResponse.getTransactionReceipt().getResult(), 0);

        //重新获取合约Schema
        getContractSchemaRequest = new GetContractSchemaRequest(yourAccount.getIdentity(),
                Utils.getIdentityByName(yourTestDCVMContractId),  VMTypeEnum.DCVM);
        getContractSchemaResponse = sdk.getContractService().getContractSchema(getContractSchemaRequest);
        assertTrue(getContractSchemaResponse.isSuccess());
        assertEquals(getContractSchemaResponse.getSequenceId(), getContractSchemaRequest.getSequenceId());
        assertEquals(getContractSchemaResponse.getTransactionReceipt().getResult(), 0);
        if(getContractSchemaResponse.getContractSchema().getFirst()!=null) {
            String schemaString = getContractSchemaResponse.getContractSchema().getFirst();
            assertEquals(ByteUtils.toHexString(schema), schemaString);
        }else{
            fail();
        }
    }

asyncGetContractSchema

调用 asyncGetContractSchema 接口获取数据合约的Schema,异步方式调用。

  • 函数原型

public int asyncGetContractSchema(GetContractSchemaRequest request, IAsyncCallback callback)
  • 请求参数

参数

必选

类型

说明

request

true

GetContractSchemaRequest

获取数据合约的请求

callback

true

IAsyncCallback

回调函数

GetContractSchemaRequest,具体参数见下表。

参数

必选

类型

说明

acctId

true

Identity

发起交易的账户id

contractId

true

Identity

被调用的数据合约id

vmTypeEnum

true

VMTypeEnum

合约类型(VMTypeEnum.DCVM)

  • 同步返回字段

返回字段

字段类型

说明

result

int

发送返回值,success时为0

  • 异步返回字段

返回字段

字段类型

说明

errorCode

int

SDK发送消息返回的错误码,success时为0。

response

GetContractSchemaResponse

平台返回的响应,其中 response.getErrorCode()是平台返回的错误码。

说明

GetContractSchemaResponse,无参数,通过方法获取值,请参考示例中的写法。

  • 示例

   public void testAsyncGetContractSchemaTest() throws IOException, InterruptedException {
        // byte[] schema = IOUtil.inputStreamToByte(ContractServiceTest.class.getResourceAsStream("/contract_schema_random"));
        //部署合约
        //schema内容,请根据实际项目中业务场景赋值
        final byte[] schema = new byte[]{1, 2, 3, 4, 5, 6, 7};
        DeployContractRequest deployContractRequest = new DeployContractRequest(yourAccount.getIdentity(),
                Utils.getIdentityByName(testDCVMContractId), schema,
                VMTypeEnum.DCVM);
        final CountDownLatch deployCountDownLatch = new CountDownLatch(1);
        int returnCode = sdk.getContractService().asyncDeployContract(deployContractRequest, new IAsyncCallback() {
            @Override
            public void onResponse(int errorCode, Response response) {
                if (errorCode == 0 && response instanceof DeployContractResponse)
                    assertTrue(response.isSuccess());
                assertEquals(0, ((DeployContractResponse) response).getTransactionReceipt().getResult());
                deployCountDownLatch.countDown();
            }
        });
        assertEquals(returnCode, 0);
        assertTrue(deployCountDownLatch.await(5, TimeUnit.SECONDS));

        //设置合约访问权限
        ContractAccessControl acl = new ContractAccessControl(yourAccount.getIdentity());
        acl.setDataRead(true);
        acl.setSchemaRead(true);
        List<ContractAccessControl> contractAccessControls = new ArrayList<>();
        contractAccessControls.add(acl);
        final CountDownLatch countDownLatch = new CountDownLatch(1);
        SetContractAccessControlRequest setContractAccessControlRequest =
                new SetContractAccessControlRequest(Utils.getIdentityByName(testDCVMContractId), contractAccessControls);
        returnCode =
                sdk.getContractService().asyncSetContractAccessControl(setContractAccessControlRequest, new IAsyncCallback() {
                    @Override
                    public void onResponse(int errorCode, Response response) {
                        if (errorCode == 0 && response instanceof SetContractAccessControlResponse) {
                            assertTrue(((SetContractAccessControlResponse) response).isSuccess());
                            countDownLatch.countDown();
                        }
                    }
                });
        assertEquals(returnCode, 0);
        assertTrue(countDownLatch.await(5, TimeUnit.SECONDS));


        //查询合约访问权限
        final List<Identity> identities = Arrays.asList(yourAccount.getIdentity());
        final GetContractAccessControlRequest getContractAccessControlRequest = new GetContractAccessControlRequest(
                Utils.getIdentityByName(testDCVMContractId), identities);
        final CountDownLatch getContractAccessControlCountDownLatch = new CountDownLatch(1);
        returnCode = sdk.getContractService().
                asyncGetContractAccessControlResponse(getContractAccessControlRequest, new IAsyncCallback() {
                    @Override
                    public void onResponse(int errorCode, Response response) {
                        if (errorCode == 0 && response instanceof GetContractAccessControlResponse) {
                            assertTrue(((GetContractAccessControlResponse) response).isSuccess());
                            assertEquals(((GetContractAccessControlResponse) response).getSequenceId(), getContractAccessControlRequest.getSequenceId());
                            assertEquals(((GetContractAccessControlResponse) response).getTransactionReceipt().getResult(), 0);
                            assertNull(((GetContractAccessControlResponse) response).getContractAccessControls(identities).getSecond());
                            List<ContractAccessControl> aclResult = ((GetContractAccessControlResponse) response).getContractAccessControls(identities).getFirst();
                            assertTrue(aclResult.size() > 0);
                            assertTrue(aclResult.get(0).isDataRead());
                            assertFalse(aclResult.get(0).isDataWrite());
                            assertTrue(aclResult.get(0).isSchemaRead());
                            assertFalse(aclResult.get(0).isSchemaWrite());
                            getContractAccessControlCountDownLatch.countDown();
                        }
                    }
                });
        assertEquals(returnCode, 0);
        assertTrue(getContractAccessControlCountDownLatch.await(5, TimeUnit.SECONDS));


        //获取合约Schema
        final GetContractSchemaRequest callContractRequest = new GetContractSchemaRequest(yourAccount.getIdentity(),
                Utils.getIdentityByName(testDCVMContractId),  VMTypeEnum.DCVM);
        final CountDownLatch getSchemaCountDownLatch = new CountDownLatch(1);
        returnCode = sdk.getContractService().asyncGetContractSchema(callContractRequest, new IAsyncCallback() {
            @Override
            public void onResponse(int errorCode, Response response) {
                if (errorCode == 0 && response instanceof GetContractSchemaResponse) {
                    GetContractSchemaResponse getContractSchemaResponse = (GetContractSchemaResponse)response;
                    assertTrue(getContractSchemaResponse.isSuccess());
                    assertEquals(getContractSchemaResponse.getSequenceId(), callContractRequest.getSequenceId());
                    assertEquals(getContractSchemaResponse.getTransactionReceipt().getResult(), 0);
                    String schemaString = getContractSchemaResponse.getContractSchema().getFirst();
                    assertEquals(ByteUtils.toHexString(schema), schemaString);
                    getSchemaCountDownLatch.countDown();
                }
            }
        });
        assertEquals(returnCode, 0);
        assertTrue(getSchemaCountDownLatch.await(5, TimeUnit.SECONDS));

        //更新合约
        //schema内容,请根据实际项目中业务场景赋值
        final byte[] schema2 = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        final UpdateContractRequest updateContractRequest = new UpdateContractRequest(
                Utils.getIdentityByName(testDCVMContractId), schema2, VMTypeEnum.DCVM);
        final CountDownLatch updateContractCountDownLatch = new CountDownLatch(1);
        returnCode = sdk.getContractService().asyncUpdateContract(updateContractRequest,
                new IAsyncCallback() {
                    @Override
                    public void onResponse(int errorCode, Response response) {
                        if (errorCode == 0 && response instanceof UpdateContractResponse) {
                            assertTrue(((UpdateContractResponse) response).isSuccess());
                            assertEquals(((UpdateContractResponse) response).getSequenceId(), updateContractRequest.getSequenceId());
                            assertEquals(((UpdateContractResponse) response).getTransactionReceipt().getResult(), 0);
                            updateContractCountDownLatch.countDown();
                        }
                    }
                });
        assertEquals(returnCode, 0);
        assertTrue(updateContractCountDownLatch.await(5, TimeUnit.SECONDS));


        //重新获取合约Schema
        final GetContractSchemaRequest callContractRequest3 = new GetContractSchemaRequest(yourAccount.getIdentity(),
                Utils.getIdentityByName(testDCVMContractId),  VMTypeEnum.DCVM);
        final CountDownLatch getSchema2 = new CountDownLatch(1);
        returnCode = sdk.getContractService().asyncGetContractSchema(callContractRequest3, new IAsyncCallback() {
            @Override
            public void onResponse(int errorCode, Response response) {
                if (errorCode == 0 && response instanceof GetContractSchemaResponse) {
                    GetContractSchemaResponse getContractSchemaResponse = (GetContractSchemaResponse)response;
                    assertTrue(getContractSchemaResponse.isSuccess());
                    assertEquals(getContractSchemaResponse.getSequenceId(), callContractRequest3.getSequenceId());
                    assertEquals(getContractSchemaResponse.getTransactionReceipt().getResult(), 0);
                    String schemaString = getContractSchemaResponse.getContractSchema().getFirst();
                    assertEquals(ByteUtils.toHexString(schema2), schemaString);
                    getSchema2.countDown();
                }
            }
        });
        assertEquals(returnCode, 0);
        assertTrue(getSchema2.await(5, TimeUnit.SECONDS));
    }

合约参数对象

参数对象用于编码合约方法和参数。

EVM 合约参数对象

  • EVMParameter

函数名称

参数类型

参数说明

setMethodSignature()

String

添加函数选择器,即方法与参数列表构成的字符串

getEncodedData()

-

-

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 数组类型的数据

addBooleanArray()

List<Boolean>

添加动态的 bool 数组类型的数据

getMethodSignature()

-

-

addStruct()

Struct

添加Struct类型参数,类似于Java集合中的List

addArray()

DynamicArray

添加动态数组

addIdentityArray()

List<byte[]>

添加Indentity的byte[]集合

addBytes32Array()

List<byte[]>

添加32位的byte[]集合

addBytes32()

byte[]

添加32位的byte[],必须为32位

说明

其中addBytesN() 已废弃,但仍可以继续使用。

EVM 数据解析

EVMOutput,解析交易收据的 logData 和 output,可参考 EVM 合约编码说明 中的脚本示例。

函数名称

参数类型

参数说明

getInt()

BigInteger

获取静态的 int 类型的数据

getUInt()

BigInteger

获取静态的 uint 类型的数据

getIdentity()

Identity

获取 identity 类型的数据

getString ()

String

获取 string 类型的数据

getBytes()

byte[]

获取的 bytes 类型的数据

getBytesN()

byte[]

获取 bytes 类型的数据

evmRevertDecoder()

byte[]

添加针对result=10201时,output转换为String的解码器

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。

    • 303132333435363738396162636465666768696a6b6c6d6e6f707172737475767778797a00000000000000000000000000000000000000000000000000000000 为“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();

WASM 合约参数对象

  • WASMParameter

函数名称

参数类型

参数说明

setMethodSignature()

String

添加函数选择器,方法与参数列表构成的字符串。

getEncodedData()

String

WASM 参数字节码

addInt8()

BigInteger

添加静态的 int_8 类型的数据

addInt16()

BigInteger

添加静态的 int_16 类型的数据

addInt32()

BigInteger

添加静态的 int_32 类型的数据

addInt64()

BigInteger

添加静态的 int_64 类型的数据

addInt128()

BigInteger

添加静态的 int_128 类型的数据

addUInt8()

BigInteger

添加静态的 uint_8 类型的数据

addUInt16()

BigInteger

添加静态的 uint_16 类型的数据

addUInt32()

BigInteger

添加静态的 uint_32 类型的数据

addUInt64()

BigInteger

添加静态的 uint_64 类型的数据

addUInt128()

BigInteger

添加静态的 uint_128 类型的数据

addBool()

boolean

添加静态的 bool 类型的数据

addIdentity()

Hash

添加静态的 Hash 类型的数据

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 数组类型的数据

addInt128Array()

List<BigInteger>

添加动态的 int_128 数组类型的数据

addUInt8Array()

List<BigInteger>

添加动态的 uint_8 数组类型的数据

addUInt16Array()

List<BigInteger>

添加动态的 uint_16 数组类型的数据

addUInt32Array()

List<BigInteger>

添加动态的 uint_32 数组类型的数据

addUInt64Array()

List<BigInteger>

添加动态的 uint_64 数组类型的数据

addUint128Array()

List<BigInteger>

添加动态的 uint_128 数组类型的数据

addBooleanArray()

List<Boolean>

添加动态的 bool 数组类型的数据

addUtfStringArray()

List<String>

添加动态 String 数组的数据

WASM 数据解析

WasmOutput,解析交易收据的 logData 和 output,可参考示例。

函数名称

参数类型

参数说明

getInt8()

BigInteger

获取静态的 int_8 类型的数据

getInt16()

BigInteger

获取静态的 int_16 类型的数据

getInt32()

BigInteger

获取静态的 int_32 类型的数据

getInt64()

BigInteger

获取静态的 int_64 类型的数据

getInt128()

BigInteger

获取静态的 int_128 类型的数据

getUInt8()

BigInteger

获取静态的 uint_8 类型的数据

getUInt16()

BigInteger

获取静态的 uint_16 类型的数据

getUInt32()

BigInteger

获取静态的 uint_32 类型的数据

getUInt64()

BigInteger

获取静态的 uint_64 类型的数据

getUint128()

BigInteger

获取静态的 uint_128 类型的数据

getString()

String

获取动态的 string 类型的数据

getBytes()

byte[]

获取动态的 bytes 类型的数据

getIntAndUintDynamicArray(Class type)

<T extends Type> List<BigInteger>

获取 int 或者 uint 的动态数组

getBooleanDynamicArray()

List<Boolean>

获取 bool 的动态数组

getStringDynamicArray()

List<String>

获取 String 的动态数组

WASM 合约编码说明

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