KKSU
2024-05-15 fa039ab4ede44c9ae3f07056bdcaa9cae8f94ad8
src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
@@ -27,10 +27,7 @@
import java.math.BigInteger;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -156,6 +153,43 @@
    }
    @Override
    public BigDecimal getPrice(String address) {
        BigInteger decimals = BigInteger.ZERO;
        try {
            String methodName = "getPrice";
            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;
            try {
                ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
                List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
                decimals = (BigInteger) results.get(0).getValue();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        /**
         * todo 修改了
         */
        int decimal = decimals();
//        int decimal = 8;
        double res = new BigDecimal(decimals).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<>();
@@ -187,16 +221,17 @@
    }
    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");
        }
        String gas = "1";
//        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;
    }
@@ -210,7 +245,7 @@
    @Override
    public String transfer(String address, BigDecimal amount) {
        try {
            return tokenTransferFrom(privateKey, address, ownerAddress, amount.toPlainString());
            return tokenTransfer(privateKey, ownerAddress, address, amount.toPlainString());
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return "";
@@ -220,7 +255,7 @@
    public String tokenTransferFrom(String privateKey, String fromAddress, String toAddress, String amount) throws ExecutionException, InterruptedException {
        String gas = getGas();
        BigDecimal amountPow = new BigDecimal(amount).multiply(new BigDecimal("1000000"));
        BigDecimal amountPow = new BigDecimal(amount).multiply(BigDecimal.TEN.pow(decimals()));
        amount = amountPow.toPlainString();
        if (amount.contains(".")) {
            amount = amount.substring(0, amount.lastIndexOf("."));
@@ -229,12 +264,53 @@
        Credentials credentials = Credentials.create(privateKey);
        EthGetTransactionCount ethGetTransactionCount = web3j
                .ethGetTransactionCount(toAddress, DefaultBlockParameterName.LATEST).sendAsync().get();
                .ethGetTransactionCount(fromAddress, 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();
        }
    }
    public String tokenTransfer(String privateKey, String fromAddress, String toAddress, String amount) throws ExecutionException, InterruptedException {
        String gas = getGas();
        BigDecimal amountPow = new BigDecimal(amount).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(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>() {
                }));
@@ -289,9 +365,37 @@
        if (send != null) {
            return Numeric.decodeQuantity(send.getResult());
        } else {
            throw new NullPointerException();
        }
        return new BigInteger("1");
    }
    @Override
    public BigInteger totalSupply() {
        try {
            String methodName = "totalSupply";
            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 totalSupply = BigInteger.ZERO;
            try {
                ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
                List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
                totalSupply = (BigInteger) results.get(0).getValue();
                return totalSupply.divide(BigInteger.TEN.pow(decimals()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return BigInteger.ZERO;
    }
}