KKSU
2024-06-06 424ad35dcd1fafb51a0ba77523b11e6871f2858c
src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
@@ -1,9 +1,10 @@
package cc.mrbird.febs.dapp.chain;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jcajce.provider.digest.SHA3;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
@@ -11,15 +12,12 @@
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.*;
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.EthCall;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.*;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;
@@ -28,10 +26,8 @@
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.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -55,6 +51,28 @@
        HttpService service = new HttpService(url);
        web3j = Web3j.build(service);
    }
    public static void main(String[] args) throws IOException {
        HttpService service = new HttpService("https://bsc-dataseed1.ninicoin.io");
        Web3j web3j = Web3j.build(service);
        long start = System.currentTimeMillis();
        Request<?, EthBlockNumber> request = web3j.ethBlockNumber();
        EthBlockNumber send = request.send();
        BigInteger bigInteger = Numeric.decodeQuantity(send.getResult());
        long end = System.currentTimeMillis();
        System.out.println(end - start);
//        String address = "0x971c09aa9735eb98459b17ec8b48932d24cbb931";
//        String nonce = "0x1d5f7444107bc02e980deda39d0fce21b06c9da4233a19cb11124cb5bfefc9ec";
//        String sign = "0x8f92cee24906122e26c3cc6cbd72f851cfe2c9574aa03bf3371e5d506fbec68b2ad22bbbc19b00ed21d26ab5a6871507831e2c902d8ed8c33301addc2b57a7731b";
//
//        String result = address + ":" + nonce + ":" + sign;
//        System.out.println(Hash.sha3(result));
//        Web3Sha3 send = web3j.web3Sha3(result).send();
//        System.out.println(1);
    }
    @Override
@@ -189,7 +207,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 "";
@@ -199,7 +217,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("."));
@@ -208,12 +226,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>() {
                }));
@@ -255,4 +314,115 @@
        JSONObject result = JSONObject.parseObject(jsonObject.getString("d"));
        return result.getIntValue("recordsTotal");
    }
    @Override
    public BigInteger blockNumber() {
        Request<?, EthBlockNumber> request = web3j.ethBlockNumber();
        EthBlockNumber send = null;
        try {
            send = request.send();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (send != null) {
            return Numeric.decodeQuantity(send.getResult());
        } else {
            throw new NullPointerException();
        }
    }
    @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;
    }
    @Override
    public BigInteger totalSupplyNFT() {
        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;
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return BigInteger.ZERO;
    }
    @Override
    public String safeMintNFT(String toAddress) {
        String gas = getGas();
        try {
            Credentials credentials = Credentials.create(privateKey);
            EthGetTransactionCount ethGetTransactionCount = web3j
                    .ethGetTransactionCount(ownerAddress, DefaultBlockParameterName.LATEST).sendAsync().get();
            BigInteger nonce = ethGetTransactionCount.getTransactionCount();
            Function function = new Function("safeMint",
                    Arrays.asList(new Address(toAddress)),
                    Arrays.asList(new TypeReference<Type>() {
                    }));
            String encodedFunction = FunctionEncoder.encode(function);
            RawTransaction rawTransaction = RawTransaction.createTransaction(nonce,
                    Convert.toWei(gas, Convert.Unit.GWEI).toBigInteger(),
                    Convert.toWei("1000000", 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();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}