to //对方地址
gasLimit //gas上限
gasPrice //gas价格
value //eth转账数量(单位 wei)
data //0x 普通转账用不到这个字段
to //合约地址
gasLimit //gas上限
gasPrice //gas价格
value //eth转账数量(单位 wei)
data //0x*** 合约方法ABI及参数
我们可以看到两种交易的本质不同是toAddress不同data不同
//token转账参数即data字段
String methodName = "transfer";
List<Type> inputParameters = new ArrayList<>();
List<TypeReference<?>> outputParameters = new ArrayList<>();
Address tAddress = new Address(toAddress);
Uint256 tokenValue = new Uint256(BigDecimal.valueOf(amount).multiply(BigDecimal.TEN.pow(decimals)).toBigInteger());
inputParameters.add(tAddress);
inputParameters.add(tokenValue);
TypeReference<Bool> typeReference = new TypeReference<Bool>() {
};
outputParameters.add(typeReference);
Function function = new Function(methodName, inputParameters, outputParameters);
String data = FunctionEncoder.encode(function);
RawTransaction rawTransaction = RawTransaction.createTransaction(
nonce,
gasPrice,
gasLimit,
to,
value,
data);
ECKeyPair ecKeyPair = ECKeyPair.create(new BigInteger(privateKey, 16));
Credentials credentials = Credentials.create(ecKeyPair);
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials;
String hexValue = Numeric.toHexString(signedMessage);
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(signedData).send();
System.out.println(ethSendTransaction.getTransactionHash());
调用
TokenERC20 contract = TokenERC20.load(contractAddress, web3j, credentials,
Convert.toWei("10", Convert.Unit.GWEI).toBigInteger(),
BigInteger.valueOf(100000));
String myAddress = null;
String toAddress = null;
BigInteger amount = BigInteger.ONE;
try {
TransactionReceipt receipt = contract.transfer(toAddress, amount).send();
} catch (Exception e) {
e.printStackTrace();
}
两种方法本质上是一样的,都是发送一笔带data参数的交易(或者查询)
第二种方法封装的更彻底,对于写代码的我们更容易理解,隐藏了data参数构建过程。
第一种方法的优势是可以快速更换合约地址,更改nonce,gasPrice,gasLimit的值。
所以在类交易所的平台场景下,需要对大量合约进行操作,但是调用的方法却不多(基本上都是ERC20的transfer方法),这时我们可以用第一种方法;在DAPP类的场景下,一个合约无论是游戏还是最近火爆的f3d,它并不通用没有与其他合约相同的接口,公共对外方法有很多。这时我们可以用第二种合约调用的方法来编写代码。