版权声明:学习中。。。 https://blog.csdn.net/fangdengfu123/article/details/82181091
获取账户的Nonce
public static BigInteger getNonce(Web3j web3j, String addr) {
try {
EthGetTransactionCount getNonce = web3j.ethGetTransactionCount(addr, DefaultBlockParameterName.PENDING).send();
if (getNonce == null){
throw new RuntimeException("net error");
}
return getNonce.getTransactionCount();
} catch (IOException e) {
throw new RuntimeException("net error");
}
}
获取ETH余额
public static BigDecimal getBalance(Web3j web3j, String address) {
try {
EthGetBalance ethGetBalance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send();
return Convert.fromWei(new BigDecimal(ethGetBalance.getBalance()),Convert.Unit.ETHER);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
获取代币余额
public static BigInteger getTokenBalance(Web3j web3j, String fromAddress, String contractAddress) {
String methodName = "balanceOf";
List<Type> inputParameters = new ArrayList<>();
List<TypeReference<?>> outputParameters = new ArrayList<>();
Address address = new Address(fromAddress);
inputParameters.add(address);
TypeReference<Uint256> typeReference = new TypeReference<Uint256>() {
};
outputParameters.add(typeReference);
Function function = new Function(methodName, inputParameters, outputParameters);
String data = FunctionEncoder.encode(function);
Transaction transaction = Transaction.createEthCallTransaction(fromAddress, contractAddress, data);
EthCall ethCall;
BigInteger balanceValue = BigInteger.ZERO;
try {
ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
balanceValue = (BigInteger) results.get(0).getValue();
} catch (IOException e) {
e.printStackTrace();
}
return balanceValue;
}
构造交易
// 构造eth交易
Transaction transaction = Transaction.createEtherTransaction(fromAddr, nonce, gasPrice, null, toAddr, value);
// 构造合约调用交易
Transaction transaction = Transaction.createFunctionCallTransaction(fromAddr, nonce, gasPrice, null, contractAddr, funcABI);
估算手续费上限
public static BigInteger getTransactionGasLimit(Web3j web3j, Transaction transaction) {
try {
EthEstimateGas ethEstimateGas = web3j.ethEstimateGas(transaction).send();
if (ethEstimateGas.hasError()){
throw new RuntimeException(ethEstimateGas.getError().getMessage());
}
return ethEstimateGas.getAmountUsed();
} catch (IOException e) {
throw new RuntimeException("net error");
}
}
转账ETH
public static String transferETH(Web3j web3j, String fromAddr, String privateKey, String toAddr, BigDecimal amount, String data){
// 获得nonce
BigInteger nonce = getNonce(web3j, fromAddr);
// value 转换
BigInteger value = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger();
// 构建交易
Transaction transaction = Transaction.createEtherTransaction(fromAddr, nonce, gasPrice, null, toAddr, value);
// 计算gasLimit
BigInteger gasLimit = getTransactionGasLimit(web3j, transaction);
// 查询调用者余额,检测余额是否充足
BigDecimal ethBalance = getBalance(web3j, fromAddr);
BigDecimal balance = Convert.toWei(ethBalance, Convert.Unit.ETHER);
// balance < amount + gasLimit ??
if (balance.compareTo(amount.add(new BigDecimal(gasLimit.toString()))) < 0) {
throw new RuntimeException("余额不足,请核实");
}
return signAndSend(web3j, nonce, gasPrice, gasLimit, toAddr, value, data, chainId, privateKey);
}
转账代币
public static String transferToken(Web3j web3j, String fromAddr, String privateKey, String toAddr, String contractAddr, long amount) {
BigInteger nonce = getNonce(web3j, fromAddr);
// 构建方法调用信息
String method = "transfer";
// 构建输入参数
List<Type> inputArgs = new ArrayList<>();
inputArgs.add(new Address(toAddr));
inputArgs.add(new Uint256(BigDecimal.valueOf(amount).multiply(BigDecimal.TEN.pow(18)).toBigInteger()));
// 合约返回值容器
List<TypeReference<?>> outputArgs = new ArrayList<>();
String funcABI = FunctionEncoder.encode(new Function(method, inputArgs, outputArgs));
Transaction transaction = Transaction.createFunctionCallTransaction(fromAddr, nonce, gasPrice, null, contractAddr, funcABI);
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, null, contractAddr, null, funcABI);
BigInteger gasLimit = getTransactionGasLimit(web3j, transaction);
// 获得余额
BigDecimal ethBalance = getBalance(web3j, fromAddr);
BigInteger tokenBalance = getTokenBalance(web3j, fromAddr, contractAddr);
BigInteger balance = Convert.toWei(ethBalance, Convert.Unit.ETHER).toBigInteger();
if (balance.compareTo(gasLimit) < 0) {
throw new RuntimeException("手续费不足,请核实");
}
if (tokenBalance.compareTo(BigDecimal.valueOf(amount).toBigInteger()) < 0) {
throw new RuntimeException("代币不足,请核实");
}
return signAndSend(web3j, nonce, gasPrice, gasLimit, contractAddr, BigInteger.ZERO, funcABI, chainId, privateKey);
}
对交易签名,并发送交易
public static String signAndSend(Web3j web3j, BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, BigInteger value, String data, byte chainId, String privateKey) {
String txHash = "";
RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, to, value, data);
if (privateKey.startsWith("0x")){
privateKey = privateKey.substring(2);
}
ECKeyPair ecKeyPair = ECKeyPair.create(new BigInteger(privateKey, 16));
Credentials credentials = Credentials.create(ecKeyPair);
byte[] signMessage;
if (chainId > ChainId.NONE){
signMessage = TransactionEncoder.signMessage(rawTransaction, chainId, credentials);
} else {
signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
}
String signData = Numeric.toHexString(signMessage);
if (!"".equals(signData)) {
try {
EthSendTransaction send = web3j.ethSendRawTransaction(signData).send();
txHash = send.getTransactionHash();
System.out.println(JSON.toJSONString(send));
} catch (IOException e) {
throw new RuntimeException("交易异常");
}
}
return txHash;
}
获取代理额度
public static BigInteger getAllowanceBalance(Web3j web3j, String fromAddr, String toAddr, String contractAddress) {
String methodName = "allowance";
List<Type> inputParameters = new ArrayList<>();
inputParameters.add(new Address(fromAddr));
inputParameters.add(new Address(toAddr));
List<TypeReference<?>> outputs = new ArrayList<>();
TypeReference<Uint256> typeReference = new TypeReference<Uint256>() {
};
outputs.add(typeReference);
Function function = new Function(methodName, inputParameters, outputs);
String data = FunctionEncoder.encode(function);
Transaction transaction = Transaction.createEthCallTransaction(fromAddr, contractAddress, data);
EthCall ethCall;
BigInteger balanceValue = BigInteger.ZERO;
try {
ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
List<Type> result = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
balanceValue = (BigInteger) result.get(0).getValue();
} catch (IOException e) {
e.printStackTrace();
}
return balanceValue;
}