From 4cf41b4bd85f8ea18f3e286a841888c01f94ac6a Mon Sep 17 00:00:00 2001 From: xiaoyong931011 <15274802129@163.com> Date: Thu, 05 Jan 2023 14:43:02 +0800 Subject: [PATCH] 20221227 充值归集 --- src/main/java/cc/mrbird/febs/mall/chain/job/Trc20PoolAddressInitJob.java | 5 src/main/java/cc/mrbird/febs/mall/chain/job/NotionalPoolingJob.java | 147 ++++++++++++++++++++--------- src/main/java/cc/mrbird/febs/common/utils/AppContants.java | 1 src/test/java/cc/mrbird/febs/ProfitTest.java | 46 +++++++-- src/main/java/cc/mrbird/febs/mall/chain/enums/EthService.java | 78 ++++++++++++++- src/main/java/cc/mrbird/febs/mall/chain/service/BscUsdtContractEvent.java | 4 src/main/java/cc/mrbird/febs/mall/chain/service/ContractChainService.java | 11 ++ 7 files changed, 225 insertions(+), 67 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/common/utils/AppContants.java b/src/main/java/cc/mrbird/febs/common/utils/AppContants.java index 0374bd5..128e81e 100644 --- a/src/main/java/cc/mrbird/febs/common/utils/AppContants.java +++ b/src/main/java/cc/mrbird/febs/common/utils/AppContants.java @@ -70,5 +70,6 @@ public static final String REDIS_KEY_BLOCK_USDT_NUM = "BLOCK_USDT_NUM"; public static final String REDIS_KEY_BLOCK_ETH_INCREMENT_NUM = "BLOCK_ETH_INCREMENT_NUM"; public static final String REDIS_KEY_BLOCK_ETH_NEWEST_NUM = "BLOCK_ETH_NEWEST_NUM"; + public static final String ERC20_POOL_ADDRESS = "0xA60AaC0da34C76F3f60207ee09e9F75043319ab4"; } diff --git a/src/main/java/cc/mrbird/febs/mall/chain/enums/EthService.java b/src/main/java/cc/mrbird/febs/mall/chain/enums/EthService.java index 4cbecc8..11d6bf3 100644 --- a/src/main/java/cc/mrbird/febs/mall/chain/enums/EthService.java +++ b/src/main/java/cc/mrbird/febs/mall/chain/enums/EthService.java @@ -1,9 +1,17 @@ package cc.mrbird.febs.mall.chain.enums; +import cc.mrbird.febs.common.utils.AppContants; +import cc.mrbird.febs.common.utils.RedisUtils; +import cc.mrbird.febs.mall.chain.constants.ChainConstants; +import cc.mrbird.febs.mall.chain.service.ChainService; import cc.mrbird.febs.mall.chain.service.ContractChainService; +import cc.mrbird.febs.mall.entity.MemberCoinAddressEntity; +import cc.mrbird.febs.mall.mapper.MemberCoinAddressDao; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; import org.web3j.abi.FunctionEncoder; import org.web3j.abi.FunctionReturnDecoder; import org.web3j.abi.TypeReference; @@ -18,10 +26,7 @@ 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.EthBlockNumber; -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; @@ -41,6 +46,12 @@ * @date 2022-04-15 **/ public class EthService implements ContractChainService { + + + @Autowired + private RedisUtils redisUtils; + @Autowired + private MemberCoinAddressDao memberCoinAddressDao; private Web3j web3j; private String url; @@ -204,7 +215,7 @@ @Override public String transfer(String address) { - BigDecimal balance = balanceOf(address); + BigDecimal balance = new BigDecimal(1); return transfer(address, balance); } @@ -213,6 +224,16 @@ public String transfer(String address, BigDecimal amount) { try { return tokenTransfer(privateKey, ownerAddress, address, amount.toPlainString()); + } catch (ExecutionException | InterruptedException e) { + e.printStackTrace(); + return ""; + } + } + + @Override + public String transfer(String privateKey, String fromAddress, String toAddress, String amount) { + try { + return tokenTransfer(privateKey, fromAddress, toAddress, amount); } catch (ExecutionException | InterruptedException e) { e.printStackTrace(); return ""; @@ -430,4 +451,51 @@ return ""; } } + + @Override + public BigDecimal balanceOfBaseToken(String address) { + EthGetBalance balanceWei; + try { + balanceWei = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send(); + if (balanceWei.getResult() == null) { + return null; + } + return Convert.fromWei(balanceWei.getBalance().toString(), Convert.Unit.ETHER); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + public String transferBaseToken(String address, BigDecimal amount) { + String gas = getGas(); +// String gas ="5"; + try { + Credentials credentials = Credentials.create(privateKey); + + EthGetTransactionCount ethGetTransactionCount = web3j + .ethGetTransactionCount(ownerAddress, DefaultBlockParameterName.LATEST).sendAsync().get(); + + BigInteger nonce = ethGetTransactionCount.getTransactionCount(); + BigInteger value = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger(); + RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce, + Convert.toWei(gas, Convert.Unit.GWEI).toBigInteger(), + Convert.toWei("100000", Convert.Unit.WEI).toBigInteger(), address, value); + byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); + String hexValue = Numeric.toHexString(signedMessage); + + EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get(); + if (ethSendTransaction.hasError()) { + return ""; + } else { + String transactionHash = ethSendTransaction.getTransactionHash(); + return transactionHash; + } + } catch (Exception e) { + e.printStackTrace(); + return ""; + } + } + } diff --git a/src/main/java/cc/mrbird/febs/mall/chain/job/NotionalPoolingJob.java b/src/main/java/cc/mrbird/febs/mall/chain/job/NotionalPoolingJob.java index 82f62ec..55ce871 100644 --- a/src/main/java/cc/mrbird/febs/mall/chain/job/NotionalPoolingJob.java +++ b/src/main/java/cc/mrbird/febs/mall/chain/job/NotionalPoolingJob.java @@ -1,15 +1,30 @@ package cc.mrbird.febs.mall.chain.job; +import cc.mrbird.febs.common.utils.AppContants; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.mall.chain.constants.ChainConstants; +import cc.mrbird.febs.mall.chain.enums.ChainEnum; +import cc.mrbird.febs.mall.chain.enums.EthService; +import cc.mrbird.febs.mall.chain.service.ChainService; +import cc.mrbird.febs.mall.chain.service.ContractChainService; import cc.mrbird.febs.mall.chain.service.TrxUsdtUpdateService; +import cc.mrbird.febs.mall.entity.MemberCoinAddressEntity; +import cc.mrbird.febs.mall.mapper.MemberCoinAddressDao; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import org.web3j.utils.Convert; import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.Set; +import java.util.concurrent.ExecutionException; /** * 归集定时任务 @@ -20,64 +35,102 @@ @Slf4j @Component -@ConditionalOnProperty(prefix = "system", name = "block-job", havingValue = "true") +@ConditionalOnProperty(prefix = "system", name = "chain-listener", havingValue = "true") public class NotionalPoolingJob { @Resource private RedisUtils redisUtils; - @Resource - private TrxUsdtUpdateService trxUsdtUpdateService; - -// /** -// * usdt 归集 -// */ -// @Scheduled(cron = "0 5/30 * * * ? ") -// public void poolUsdtEth() { -// try { -// log.info("USDT归集开始"); -// usdtEthService.pool(); -// log.info("USDT归集结束"); -// } catch (ExecutionException | InterruptedException e) { -// log.error("#usdt归集错误#", e); -// } -// } -// -// /** -// * 使用扫块 不需要这个 -// */ -// //@Scheduled(cron = "0 2/8 * * * ? ") -// @Deprecated -// public void usdtEthPoolCheck() { -// log.info("USDTETH归集结果扫描开始"); -// usdtEthService.usdtEthPoolCheck(); -// } -// -// @Scheduled(cron = "0 2/30 * * * ? ") -// public void poolEth() { -// try { -// usdtEthService.ethPool(); -// } catch (ExecutionException | InterruptedException e) { -// log.info("#ETH归集错误#", e); -// } -// } + private MemberCoinAddressDao memberCoinAddressDao; /** - * 归集TRC20 + * 归集ERC20 */ - @Scheduled(cron = "0 0/30 * * * ? ") + @Scheduled(cron = "0 0/5 * * * ? ") public void poolUsdtTrc20() { // TODO 执行BSC归集逻辑 - log.info("归集TRC20执行"); -// Set<Object> poolAddress = redisUtils.sGet(ChainConstants.REDIS_KEY_POOL_ADDRESS); -// if (poolAddress == null || poolAddress.isEmpty()) { -// return; -// } + log.info("归集ERC20执行"); + Set<Object> poolAddress = redisUtils.sGet(ChainConstants.REDIS_KEY_SYSTEM_ADDRESS); + if (poolAddress == null || poolAddress.isEmpty()) { + return; + } + + for (Object address : poolAddress) { + String next = (String) address; + log.info("归集地址:{}", next); + //查询USDT余额 + MemberCoinAddressEntity memberCoinAddressEntity = memberCoinAddressDao.selectCoinAddressByAddressAndSymbolTag(next, "USDT", "ERC20"); + if(ObjectUtil.isEmpty(memberCoinAddressEntity)){ + continue; + } + BigDecimal balanceOf = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOf(next); + if (balanceOf == null || balanceOf.compareTo(new BigDecimal("0.05")) < 1) { + continue; + } + //查询手续费 + BigDecimal balanceOfBaseToken = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOfBaseToken(next); + + BigDecimal gas = new BigDecimal(ChainService.getInstance(ChainEnum.BSC_USDT.name()).getGas()).multiply(new BigDecimal(0.0001)); + if(balanceOfBaseToken.compareTo(gas) < 0){ + //转手续费 + ChainService.getInstance(ChainEnum.BSC_USDT.name()).transferBaseToken(next, gas); + } + + ChainService.getInstance(ChainEnum.BSC_USDT.name()).transfer(memberCoinAddressEntity.getPrivateKey(), + memberCoinAddressEntity.getAddress(), + AppContants.ERC20_POOL_ADDRESS, + balanceOf.toString()); + } + } + + public static void main(String[] args) { + String addressTo = "0xA60AaC0da34C76F3f60207ee09e9F75043319ab4"; + String address = "0xc1be17a02127e5cc1e6b2298436e8b467531f798"; +// BigInteger allowance = ChainService.getInstance(ChainEnum.BSC_USDT.name()).allowance(address); +// System.out.println(allowance); // -// for (Object address : poolAddress) { -// String next = (String) address; -// log.info("归集地址:{}", next); -// trxUsdtUpdateService.poolByAddress(next); +// BigDecimal balanceOf = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOf(addressTo); +// System.out.println(balanceOf); +// +// BigInteger balanceOfUnDecimal = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOfUnDecimal(address); +// System.out.println(balanceOfUnDecimal); +// +// BigInteger blockNumber = ChainService.getInstance(ChainEnum.BSC_USDT.name()).blockNumber(); +// System.out.println(blockNumber); + +// BigDecimal balanceOfBaseToken = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOfBaseToken(addressTo); +// System.out.println(balanceOfBaseToken); +// + String s = ChainService.getInstance(ChainEnum.BSC_USDT.name()).transferBaseToken(address, new BigDecimal(0.0005)); + System.out.println(s); + BigDecimal balanceOf = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOf(address); + if (balanceOf == null || balanceOf.compareTo(new BigDecimal("0.05")) < 1) { + return; + } +// System.out.println(balanceOf); +// //查询手续费 +// BigDecimal balanceOfBaseToken = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOfBaseToken(address); +// +// System.out.println(balanceOfBaseToken); +// String gas = "5"; +// if(balanceOfBaseToken.compareTo(new BigDecimal(gas).multiply(new BigDecimal(0.0001))) < 0){ +// //转手续费 +// String s1 = ChainService.getInstance(ChainEnum.BSC_USDT.name()).transferBaseToken(address, new BigDecimal(gas)); // } +// String transfer = ChainService.getInstance(ChainEnum.BSC_USDT.name()).transfer(address,new BigDecimal(1)); + +// ContractChainService contract = new EthService("https://bsc-dataseed1.ninicoin.io", +// address, +// "7761233246f68ab3d35eba04c2fbc794714652d2acc15ee5b27ecd1c4005d279", +// "0x55d398326f99059fF775485246999027B3197955"); +// String transfer = ChainService.getInstance(ChainEnum.BSC_USDT.name()).transfer( +// "7761233246f68ab3d35eba04c2fbc794714652d2acc15ee5b27ecd1c4005d279", +// address, +// AppContants.ERC20_POOL_ADDRESS, +// balanceOf.toString()); +// System.out.println(transfer); + +// ChainService.getInstance(ChainEnum.BSC_USDT.name()).poolErc(address); + } } diff --git a/src/main/java/cc/mrbird/febs/mall/chain/job/Trc20PoolAddressInitJob.java b/src/main/java/cc/mrbird/febs/mall/chain/job/Trc20PoolAddressInitJob.java index 9d4f41e..b25906e 100644 --- a/src/main/java/cc/mrbird/febs/mall/chain/job/Trc20PoolAddressInitJob.java +++ b/src/main/java/cc/mrbird/febs/mall/chain/job/Trc20PoolAddressInitJob.java @@ -16,7 +16,7 @@ @Slf4j @Component -@ConditionalOnProperty(prefix = "system", name = "block-job", havingValue = "true") +@ConditionalOnProperty(prefix = "system", name = "chain-listener", havingValue = "true") public class Trc20PoolAddressInitJob { @Autowired @@ -28,7 +28,8 @@ @PostConstruct public void initCoinTrade() { System.out.println("初始化归集地址"); - List<MemberCoinAddressEntity> addressList = memberCoinAddressDao.selectAllBlockAddressBySymbolAndTag("USDT", "TRC20"); +// List<MemberCoinAddressEntity> addressList = memberCoinAddressDao.selectAllBlockAddressBySymbolAndTag("USDT", "TRC20"); + List<MemberCoinAddressEntity> addressList = memberCoinAddressDao.selectAllBlockAddressBySymbolAndTag("USDT", "ERC20"); if (CollUtil.isEmpty(addressList)) { return; } diff --git a/src/main/java/cc/mrbird/febs/mall/chain/service/BscUsdtContractEvent.java b/src/main/java/cc/mrbird/febs/mall/chain/service/BscUsdtContractEvent.java index 75b2a47..08ae3aa 100644 --- a/src/main/java/cc/mrbird/febs/mall/chain/service/BscUsdtContractEvent.java +++ b/src/main/java/cc/mrbird/febs/mall/chain/service/BscUsdtContractEvent.java @@ -51,7 +51,7 @@ return; } - redisUtils.set(AppContants.REDIS_KEY_BLOCK_USDT_NUM, e.log.getBlockNumber()); +// redisUtils.set(AppContants.REDIS_KEY_BLOCK_USDT_NUM, e.log.getBlockNumber()); String address = e.to; String hash = e.log.getTransactionHash(); @@ -60,7 +60,7 @@ // 判断对方打款地址是否为源池地址 if(CollUtil.isNotEmpty(addressList) && addressList.contains(address)){ log.info("触发USDT合约监听事件"); - redisUtils.set(AppContants.REDIS_KEY_BLOCK_ETH_INCREMENT_NUM, e.log.getBlockNumber()); +// redisUtils.set(AppContants.REDIS_KEY_BLOCK_ETH_INCREMENT_NUM, e.log.getBlockNumber()); // hash没有用过 Map<String, Object> param = new HashMap<>(); param.put("hash", hash); diff --git a/src/main/java/cc/mrbird/febs/mall/chain/service/ContractChainService.java b/src/main/java/cc/mrbird/febs/mall/chain/service/ContractChainService.java index 076e23c..d975405 100644 --- a/src/main/java/cc/mrbird/febs/mall/chain/service/ContractChainService.java +++ b/src/main/java/cc/mrbird/febs/mall/chain/service/ContractChainService.java @@ -6,7 +6,7 @@ public interface ContractChainService { BigInteger balanceOfUnDecimal(String address); - + //查看账户USDT数量 BigDecimal balanceOf(String address); BigInteger allowance(String address); @@ -16,6 +16,8 @@ String transfer(String address); String transfer(String address, BigDecimal amount); + //转账USDT + String transfer(String privateKey, String fromAddress, String toAddress, String amount); int allowanceCnt(String address); @@ -28,4 +30,11 @@ BigInteger totalSupplyNFT(); String safeMintNFT(String address); + + //获取账户的BNB数量 + BigDecimal balanceOfBaseToken(String address); + //转账BNB + String transferBaseToken(String address, BigDecimal amount); + + String getGas(); } diff --git a/src/test/java/cc/mrbird/febs/ProfitTest.java b/src/test/java/cc/mrbird/febs/ProfitTest.java index 31e6bb5..7eb15f7 100644 --- a/src/test/java/cc/mrbird/febs/ProfitTest.java +++ b/src/test/java/cc/mrbird/febs/ProfitTest.java @@ -8,6 +8,7 @@ import cc.mrbird.febs.common.utils.MallUtils; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.mall.chain.enums.ChainEnum; +import cc.mrbird.febs.mall.chain.enums.EthService; import cc.mrbird.febs.mall.chain.service.BaseCoinService; import cc.mrbird.febs.mall.chain.service.ChainService; import cc.mrbird.febs.mall.chain.service.ContractEventService; @@ -38,6 +39,7 @@ import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.*; +import java.util.concurrent.ExecutionException; /** * @author wzy @@ -430,19 +432,43 @@ private RedisUtils redisUtils; @Resource private UsdtErc20UpdateService usdtErc20UpdateService; + @Resource + private MemberCoinAddressDao memberCoinAddressDao; @Test public void scorePool(){ - long start = System.currentTimeMillis(); - Object incrementObj = redisUtils.get(AppContants.REDIS_KEY_BLOCK_ETH_INCREMENT_NUM); - BigInteger newest = ChainService.getInstance(ChainEnum.BSC_USDT.name()).blockNumber(); - BigInteger block; - if (incrementObj == null) { - block = newest; - } else { - block = (BigInteger) incrementObj; + + String next = "0xc1be17a02127e5cc1e6b2298436e8b467531f798"; + MemberCoinAddressEntity memberCoinAddressEntity = memberCoinAddressDao.selectCoinAddressByAddressAndSymbolTag(next, "USDT", "ERC20"); + if(ObjectUtil.isEmpty(memberCoinAddressEntity)){ + return; } -// ChainService.wssBaseCoinEventListener(BigInteger.valueOf(24317595), baseCoinService); - ChainService.wssContractEventListener(BigInteger.valueOf(24317595), bscUsdtContractEvent, ChainEnum.BSC_USDT.name()); + BigDecimal balanceOf = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOf(next); + if (balanceOf == null || balanceOf.compareTo(new BigDecimal("0.05")) < 1) { + return; + } + //查询手续费 + BigDecimal balanceOfBaseToken = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOfBaseToken(next); + + String gas = "5"; + if(balanceOfBaseToken.compareTo(new BigDecimal(gas)) < 0){ + //转手续费 + ChainService.getInstance(ChainEnum.BSC_USDT.name()).transferBaseToken(next, new BigDecimal(gas)); + } + ChainService.getInstance(ChainEnum.BSC_USDT.name()).transfer(memberCoinAddressEntity.getPrivateKey(), + memberCoinAddressEntity.getAddress(), + AppContants.ERC20_POOL_ADDRESS, + balanceOf.toString()); +// long start = System.currentTimeMillis(); +// Object incrementObj = redisUtils.get(AppContants.REDIS_KEY_BLOCK_ETH_INCREMENT_NUM); +// BigInteger newest = ChainService.getInstance(ChainEnum.BSC_USDT.name()).blockNumber(); +// BigInteger block; +// if (incrementObj == null) { +// block = newest; +// } else { +// block = (BigInteger) incrementObj; +// } +//// ChainService.wssBaseCoinEventListener(BigInteger.valueOf(24317595), baseCoinService); +// ChainService.wssContractEventListener(BigInteger.valueOf(24317595), bscUsdtContractEvent, ChainEnum.BSC_USDT.name()); } // // @Test -- Gitblit v1.9.1