转账交易
转账交易的实现主要是TxService提供,主要有两个接口。
Request<TxHashResponse> sendTx(Transaction transaction, int... nodeIds);
Request<TxHashesResponse> sendBatchTxs(ArrayList<Transaction> transactions, ArrayList<String> methods, int... nodeIds);
分别绑定了TxHashResponse
和TxHashesResponse
,当拿到这两个响应时调用polling()
方法就可以获取真正的交易回执,前者返回ReceiptResponse
,后者返回ArrayList<ReceiptResponse>
。转账交易和合约接口类似,主要的不同在于交易体的创建,转账交易通过内部类Builder
调用transfer()
方法创建。
class Builder {
public Builder transfer(String to, long value);
}
// example:
Transaction transaction = new Transaction.Builder(account.getAddress()).transfer("794BF01AB3D37DF2D1EA1AA4E6F4A0E988F4DEA5", 0).build();
创建交易体并调用服务的具体流程如下。
创建账户
这个过程分为两步,先创建AccountService
对象,再利用该对象创建账户,示例如下:
AccountService accountService = ServiceManager.getAccountService(providerManager);
Account account = accountService.genAccount(Algo.SMRAW);
如第二章所说,创建Service
对象需要指定ProviderManager
对象,且使用genAccount()
创建账户时需要指定加密算法,如示例中使用SMRAW算法(只有ECRAW、SMRAW不需要密码参数,其余的加密算法需要手动设置password)。
AccountService
提供的接口如下:
public interface AccountService {
Account genAccount(Algo algo);
Account genAccount(Algo algo, String password);
Account fromAccountJson(String accountJson);
Account fromAccountJson(String accountJson, String password);
Request<BalanceResponse> getBalance(String address, int... nodeIds);
}
前四个接口是用于生成账户,而getBalance
方法则可以查询该账户所有的余额,需要传一个合约地址为参数。
目前Account服务支持的所有加密算法如下:
public enum Algo {
ECDES("0x02"),
ECRAW("0x03"),
ECAES("0x04"),
EC3DES("0x05"),
SMSM4("0x11"),
SMDES("0x12"),
SMRAW("0x13"),
SMAES("0x14"),
SM3DES("0x15");
}
交易体创建
LiteSDK使用Builder模式来负责对Transaction
的创建,通过调用build()
函数来获取到Transaction
实例。HVM和EVM分别有各自的Builder:HVMBuilder
、EVMBuilder
,继承同一个父类Builer
。目前Builder模式提供了五种交易体的封装,分别对应部署合约、调用合约、升级合约、冻结合约、解冻合约,其中前两个服务的交易体分别定义在HVM、EVM各自的Builder
子类中,后三者都是管理合约这一服务的子服务,定义在父类Builder
中。
class Builder {
Builder upgrade(String contractAddress, String payload);
Builder freeze(String contractAddress);
Builder unfreeze(String contractAddress);
Transaction build();
}
class HVMBuilder extends Builder {
Builder deploy(InputStream fis);
Builder invoke(String contractAddress, BaseInvoke baseInvoke);
}
class EVMBuilder extends Builder {
// 当合约无构造参数时使用,不需abi参数
Builder deploy(String bin);
// 当合约需要提供abi解析构造方法参数时使用
Builder deploy(String bin, Abi abi, FuncParams params);
Builder invoke(String contractAddress, String methodName, Abi abi, FuncParams params);
}
下面是创建各个服务的交易体Transaction
的实例。
部署合约
HVM
InputStream payload = FileUtil.readFileAsStream("hvm-jar/hvmbasic-1.0.0-student.jar");
Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).deploy(payload).build();
创建交易体时需要指定要部署的jar包(封装成流)。
EVM
InputStream inputStream1 = FileUtil.readFileAsStream("solidity/sol2/TestContract_sol_TypeTestContract.bin");
InputStream inputStream2 = FileUtil.readFileAsStream("solidity/sol2/TestContract_sol_TypeTestContract.abi");
String bin = FileUtil.readFile(inputStream1);
String abiStr = FileUtil.readFile(inputStream2);
FuncParams params = new FuncParams();
params.addParams("contract01");
Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).deploy(bin, abi, params).build();
// 如果要部署的合约无构造函数,则调用如下
// Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).deploy(bin).build();
创建交易体时需要指定要部署的合约的bin、abi文件的字符串内容以及合约名。
调用合约
HVM
hvm调用合约有两种方式:
- invoke bean调用
- 直接调用合约方法(类似evm)
- invoke bean调用如下:
Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).invoke(receiptResponse.getContractAddress(), invoke).build();
创建交易体时需要指定合约地址和invoke bean(HVM中新提出的概念,可点击该链接了解)。
- 直接调用合约方法如下:
Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).invokeDirectly(receiptResponse.getContractAddress(), params).build();
params类型为InvokeDirectlyParams
,具体的构造方式见附录。
EVM
FuncParams params = new FuncParams();
params.addParams("10".getBytes());
Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).invoke(contractAddress, "TestBytes32(bytes1)", abi, params).build();
创建交易体时需要指定调用方法、abi文件和方法参数。
升级合约
HVM
Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).upgrade(contractAddress, payload).build();
创建交易体时需要指定合约地址和读取新合约jar包得到的字符串
EVM
Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).upgrade(contractAddress, payload).build();
创建交易体时需要指定合约地址和升级的新合约的bin文件字符串。
冻结合约
HVM
Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).freeze(contractAddress).build();
创建交易体时需要指定合约地址。
EVM
Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).freeze(contractAddress).build();
创建交易体时需要指定合约地址。
解冻合约
HVM
Transaction transaction = new Transaction.HVMBuilder(account.getAddress()).unfreeze(contractAddress).build();
创建交易体时需要指定合约地址。
EVM
Transaction transaction = new Transaction.EVMBuilder(account.getAddress()).unfreeze(contractAddress).build();
创建交易体时需要指定合约地址。