获取账户的Noncepublic 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; }获取代币余额 方法二 (仅支持主链上的代币)String tokenBanceUrl = "https://api.etherscan.io/api?module=account&action=tokenbalance" + "&contractaddress=0x5aA8D6dE8CBf23DAC734E6f904B93bD056B15b81"//Token合约地址 + "&address=0xd4279e30e27f52ca60fac3cc9670c7b9b1eeefdc"//要查询额的账户余地址 + "&tag=latest&apikey=YourApiKeyToken"; String result = HttpRequestUtil.sendGet(tokenBanceUrl, ""); TokenBalanceResult tokenBalanceResult = JSON.parseObject(result, TokenBalanceResult.class); System.out.println(tokenBalanceResult.toString()); if (tokenBalanceResult.getStatus() == 1) { BigDecimal tokenCount = new BigDecimal(tokenBalanceResult.getResult()) .divide(new BigDecimal(10).pow(FinalValue.TOKEN_DECIMALS)); return tokenCount.floatValue(); }构造交易// 构造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"); } }转账ETHpublic 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 transferToken2(String fromAddr,String toAddr,String amount) { String contractAddress = "0xa22c2217e785f7796c9e8826c6be55c2e481f9f5"; Web3j web3j =MyWalletUtils.getWeb3j(); Credentials credentials = MyWalletUtils.getCredentials(); System.out.println("我的钱包地址："+credentials.getAddress()); try { EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount( fromAddr, DefaultBlockParameterName.LATEST).sendAsync().get(); BigInteger nonce = ethGetTransactionCount.getTransactionCount(); Function function = new Function( "transfer", Arrays.asList(new Address(toAddr), new Uint256(new BigInteger(amount))), Arrays.asList(new TypeReference<Type>() { })); String encodedFunction = FunctionEncoder.encode(function); RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, Convert.toWei("18", Convert.Unit.GWEI).toBigInteger(), Convert.toWei("100000", Convert.Unit.WEI).toBigInteger(), contractAddress, encodedFunction); byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); String hexValue = Numeric.toHexString(signedMessage); System.out.println("transfer hexValue:" + hexValue); EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get(); if (ethSendTransaction.hasError()) { System.out.println("transfer error:"+ ethSendTransaction.getError().getMessage()); return ethSendTransaction.getError().getMessage(); } else { String transactionHash = ethSendTransaction.getTransactionHash(); return ""; } } catch (Exception e) { e.printStackTrace(); return e.getMessage(); } }对交易签名，并发送交易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; // 主网是1 responst测试网是3 具体查看ChainId 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; }动态gas价格与限价在使用智能合约时，你可能需要根据调用函数指定不同的gas价格和最大值。你可以通过为智能合约封装包创建自己的ContractGasProvider来实现这一点。每一个生成的封装包都包含作为常量的所有智能合约方法名称，这有助于通过switch来进行编译时间匹配。例如，使用Greeter合约：Greeter greeter = new Greeter(...); greeter.setGasProvider(new DefaultGasProvider() { @Override public BigInteger getGasPrice(String contractFunc) { switch (contractFunc) { case Greeter.FUNC_GREET: return BigInteger.valueOf(22_000_000_000L); case Greeter.FUNC_KILL: return BigInteger.valueOf(44_000_000_000L); default: throw new NotImplementedException(); } } @Override public BigInteger getGasLimit(String contractFunc) { switch (contractFunc) { case Greeter.FUNC_GREET: return BigInteger.valueOf(4_300_000); case Greeter.FUNC_KILL: return BigInteger.valueOf(5_300_000); default: throw new NotImplementedException(); } } });如何加快以太坊交易确认被打包的的速度---gaspricehttps://ethgasstation.info/json/ethgasAPI.json结果:{ "average":25, //平均值(Gwei*10的结果) "fastestWait":0.5, "fastWait":0.7, "fast":36, //最快(Gwei*10的结果) "safeLowWait":1.2, "blockNum":6274955, "avgWait":1.2, "block_time":13.876288659793815, "speed":0.9481897143119544, "fastest":330, "safeLow":25 //安全最低值(Gwei*10的结果) } 发送交易平均正常速度被打包gasprice,单位是wei var average_gasprice_wei = average*10e8; 发送交易超快被打包的gasprice,单位是wei var fast_gasprice_wei = fast*10e8; 发送交易最慢被打包的gasprice,单位是wei var safeLow_gasprice_wei = safeLow*10e8;参考：https://www.jianshu.com/p/a63b0c86924d