转账交易

转账交易的实现主要是TxService提供,主要有两个接口。

  1. Request<TxHashResponse> sendTx(Transaction transaction, int... nodeIds);
  2. Request<TxHashesResponse> sendBatchTxs(ArrayList<Transaction> transactions, ArrayList<String> methods, int... nodeIds);

分别绑定了TxHashResponseTxHashesResponse,当拿到这两个响应时调用polling()方法就可以获取真正的交易回执,前者返回ReceiptResponse,后者返回ArrayList<ReceiptResponse>。转账交易和合约接口类似,主要的不同在于交易体的创建,转账交易通过内部类Builder调用transfer()方法创建。

  1. class Builder {
  2. public Builder transfer(String to, long value);
  3. }
  4. // example:
  5. Transaction transaction = new Transaction.Builder(account.getAddress()).transfer("794BF01AB3D37DF2D1EA1AA4E6F4A0E988F4DEA5", 0).build();

创建交易体并调用服务的具体流程如下。

创建账户

这个过程分为两步,先创建AccountService对象,再利用该对象创建账户,示例如下:

  1. AccountService accountService = ServiceManager.getAccountService(providerManager);
  2. Account account = accountService.genAccount(Algo.SMRAW);

如第二章所说,创建Service对象需要指定ProviderManager对象,且使用genAccount()创建账户时需要指定加密算法,如示例中使用SMRAW算法(只有ECRAWSMRAW不需要密码参数,其余的加密算法需要手动设置password)。

AccountService提供的接口如下:

  1. public interface AccountService {
  2. Account genAccount(Algo algo);
  3. Account genAccount(Algo algo, String password);
  4. Account fromAccountJson(String accountJson);
  5. Account fromAccountJson(String accountJson, String password);
  6. Request<BalanceResponse> getBalance(String address, int... nodeIds);
  7. }

前四个接口是用于生成账户,而getBalance方法则可以查询该账户所有的余额,需要传一个合约地址为参数。

目前Account服务支持的所有加密算法如下:

  1. public enum Algo {
  2. ECDES("0x02"),
  3. ECRAW("0x03"),
  4. ECAES("0x04"),
  5. EC3DES("0x05"),
  6. SMSM4("0x11"),
  7. SMDES("0x12"),
  8. SMRAW("0x13"),
  9. SMAES("0x14"),
  10. SM3DES("0x15");
  11. }

交易体创建

LiteSDK使用Builder模式来负责对Transaction的创建,通过调用build()函数来获取到Transaction实例。HVM和EVM分别有各自的BuilderHVMBuilderEVMBuilder,继承同一个父类Builer。目前Builder模式提供了五种交易体的封装,分别对应部署合约、调用合约、升级合约、冻结合约、解冻合约,其中前两个服务的交易体分别定义在HVM、EVM各自的Builder子类中,后三者都是管理合约这一服务的子服务,定义在父类Builder中。

  1. class Builder {
  2. Builder upgrade(String contractAddress, String payload);
  3. Builder freeze(String contractAddress);
  4. Builder unfreeze(String contractAddress);
  5. Transaction build();
  6. }
  7. class HVMBuilder extends Builder {
  8. Builder deploy(InputStream fis);
  9. Builder invoke(String contractAddress, BaseInvoke baseInvoke);
  10. }
  11. class EVMBuilder extends Builder {
  12. // 当合约无构造参数时使用,不需abi参数
  13. Builder deploy(String bin);
  14. // 当合约需要提供abi解析构造方法参数时使用
  15. Builder deploy(String bin, Abi abi, FuncParams params);
  16. Builder invoke(String contractAddress, String methodName, Abi abi, FuncParams params);
  17. }

下面是创建各个服务的交易体Transaction的实例。

部署合约

HVM
  1. InputStream payload = FileUtil.readFileAsStream("hvm-jar/hvmbasic-1.0.0-student.jar");
  2. Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).deploy(payload).build();

创建交易体时需要指定要部署的jar包(封装成流)

EVM
  1. InputStream inputStream1 = FileUtil.readFileAsStream("solidity/sol2/TestContract_sol_TypeTestContract.bin");
  2. InputStream inputStream2 = FileUtil.readFileAsStream("solidity/sol2/TestContract_sol_TypeTestContract.abi");
  3. String bin = FileUtil.readFile(inputStream1);
  4. String abiStr = FileUtil.readFile(inputStream2);
  5. FuncParams params = new FuncParams();
  6. params.addParams("contract01");
  7. Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).deploy(bin, abi, params).build();
  8. // 如果要部署的合约无构造函数,则调用如下
  9. // Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).deploy(bin).build();

创建交易体时需要指定要部署的合约的bin、abi文件的字符串内容以及合约名

调用合约

HVM

hvm调用合约有两种方式:

  • invoke bean调用
  • 直接调用合约方法(类似evm)
  1. invoke bean调用如下:
  1. Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).invoke(receiptResponse.getContractAddress(), invoke).build();

创建交易体时需要指定合约地址invoke bean(HVM中新提出的概念,可点击该链接了解)。

  1. 直接调用合约方法如下:
  1. Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).invokeDirectly(receiptResponse.getContractAddress(), params).build();

params类型为InvokeDirectlyParams,具体的构造方式见附录。

EVM
  1. FuncParams params = new FuncParams();
  2. params.addParams("10".getBytes());
  3. Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).invoke(contractAddress, "TestBytes32(bytes1)", abi, params).build();

创建交易体时需要指定调用方法abi文件方法参数

升级合约

HVM
  1. Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).upgrade(contractAddress, payload).build();

创建交易体时需要指定合约地址读取新合约jar包得到的字符串

EVM
  1. Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).upgrade(contractAddress, payload).build();

创建交易体时需要指定合约地址升级的新合约的bin文件字符串

冻结合约

HVM
  1. Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).freeze(contractAddress).build();

创建交易体时需要指定合约地址

EVM
  1. Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).freeze(contractAddress).build();

创建交易体时需要指定合约地址

解冻合约

HVM
  1. Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).unfreeze(contractAddress).build();

创建交易体时需要指定合约地址

EVM
  1. Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).unfreeze(contractAddress).build();

创建交易体时需要指定合约地址