From 7a447492f1bf8ac6849166f9345f176ebad02c4b Mon Sep 17 00:00:00 2001 From: Helius <wangdoubleone@gmail.com> Date: Fri, 03 Jul 2020 12:19:01 +0800 Subject: [PATCH] modify --- /dev/null | 11 -- src/main/java/com/xcong/excoin/modules/member/dao/MemberCoinChargeDao.java | 4 + src/main/resources/mapper/member/MemberCoinChargeDao.xml | 11 ++ src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java | 29 ++++++ src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java | 160 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 201 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/UsdtEthService.java b/src/main/java/com/xcong/excoin/modules/blackchain/UsdtEthService.java deleted file mode 100644 index 0041fef..0000000 --- a/src/main/java/com/xcong/excoin/modules/blackchain/UsdtEthService.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.xcong.excoin.modules.blackchain; - -import org.springframework.stereotype.Component; - -/** - * @author wzy - * @date 2020-07-03 - **/ -@Component -public class UsdtEthService { -} diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java b/src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java new file mode 100644 index 0000000..7e42b08 --- /dev/null +++ b/src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java @@ -0,0 +1,160 @@ +package com.xcong.excoin.modules.blackchain.service; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.xcong.excoin.common.enumerates.CoinTypeEnum; +import com.xcong.excoin.modules.member.dao.MemberCoinAddressDao; +import com.xcong.excoin.modules.member.dao.MemberCoinChargeDao; +import com.xcong.excoin.modules.member.dao.MemberDao; +import com.xcong.excoin.modules.member.dao.MemberWalletCoinDao; +import com.xcong.excoin.modules.member.entity.MemberCoinAddressEntity; +import com.xcong.excoin.modules.member.entity.MemberCoinChargeEntity; +import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * @author wzy + * @date 2020-07-03 + **/ +@Slf4j +@Component +public class UsdtEthService { + + private static final BigDecimal LIMIT = new BigDecimal("50"); + private static final BigDecimal LIMIT_ETH = new BigDecimal("0.2"); + private static final BigDecimal FEE = new BigDecimal("0.0032"); + private static final BigDecimal ETH_TR_FEE = new BigDecimal("0.0032"); + + public static String ETH_FEE = "0.0032"; + + public static final String TOTAL_ADDRESS = "0x067b4bE5d7B05560AE539Fc8f10597D854ae056D"; + public static final String TOTAL_PRIVATE = "1fb7288c8c88c37d6f79e9617822bffc8d3635bf2d808c5f6afdee9bb326e49c"; + + @Resource + private MemberCoinChargeDao memberCoinChargeDao; + @Resource + private MemberCoinAddressDao memberCoinAddressDao; + @Resource + private MemberWalletCoinDao memberWalletCoinDao; + + public void pool() throws ExecutionException, InterruptedException { + List<MemberCoinChargeEntity> list = memberCoinChargeDao.selectAllBySymbolAndTag(CoinTypeEnum.USDT.name(), "ERC20", 1); + if (CollUtil.isNotEmpty(list)) { + EthService ethService = new EthService(); + + for (MemberCoinChargeEntity coinCharge : list) { + // 首先根据每个地址查询其是否有ETH 如果没有就充值ETH并设置1 表示初始状态 status=2(待充值)3:表示已提过 + String address = coinCharge.getAddress(); + Long memberId = coinCharge.getMemberId(); + BigDecimal lastAmount = coinCharge.getLastAmount(); + if (lastAmount == null || lastAmount.compareTo(LIMIT) < 0) { + continue; + } + + BigDecimal usdt = ethService.tokenGetBalance(address); + log.info("地址:{}, 金额:{}", address, usdt); + if (usdt != null && usdt.compareTo(LIMIT) > 0) { + usdt = usdt.subtract(new BigDecimal("0.01")); + + // 查询eth是否足够 + BigDecimal eth = EthService.getEthBlance(address); + log.info("地址:{}, ETH:{}", address, eth); + if (eth != null && eth.compareTo(FEE) >= 0) { + MemberCoinAddressEntity memberCoinAddressEntity = memberCoinAddressDao.selectBlockAddressWithTag(memberId, CoinTypeEnum.USDT.name(), "ERC20"); + if (memberCoinAddressEntity == null) { + continue; + } + + String privateKey = memberCoinAddressEntity.getPrivateKey(); + + usdt = usdt.multiply(new BigDecimal("1000000")); + String usdtStr = usdt.toPlainString(); + if (usdtStr.contains(".")) { + usdtStr = usdtStr.substring(0, usdtStr.lastIndexOf(".")); + } + + String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr); + log.info("归集:{}", hash); + if (StrUtil.isNotBlank(hash)) { + // 归集成功更新状态 先保存本次的hash值,待交易成功后再更新 + coinCharge.setHash(hash); + memberCoinChargeDao.updateById(coinCharge); + } + } else { + String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE); + log.info("转手续费:{}", hash); + } + } + } + } + } + + + public void ethPool() throws ExecutionException, InterruptedException { + List<MemberCoinChargeEntity> list = memberCoinChargeDao.selectAllBySymbolAndTag(CoinTypeEnum.ETH.name(), null, 1); + if (CollUtil.isNotEmpty(list)) { + EthService ethService = new EthService(); + for (MemberCoinChargeEntity coinCharge : list) { + String address = coinCharge.getAddress(); + Long memberId = coinCharge.getMemberId(); + MemberWalletCoinEntity walletCoin = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, CoinTypeEnum.ETH.name()); + if (walletCoin == null) { + continue; + } + + BigDecimal earlyBalance = walletCoin.getEarlyBalance(); + + if (earlyBalance == null || earlyBalance.compareTo(LIMIT_ETH) < 0) { + continue; + } + + BigDecimal eth = EthService.getEthBlance(address); + if (eth != null && eth.compareTo(LIMIT_ETH) >= 0) { + MemberCoinAddressEntity coinAddress = memberCoinAddressDao.selectBlockAddressWithTag(memberId, CoinTypeEnum.ETH.name(), null); + String privateKey = coinAddress.getPrivateKey(); + + BigDecimal tr = eth.subtract(ETH_TR_FEE); + String hash = ethService.ethSend(privateKey, address, TOTAL_ADDRESS, tr.toPlainString()); + if (StrUtil.isNotBlank(hash)) { + coinCharge.setHash(hash); + coinCharge.setLastAmount(new BigDecimal("0.0001")); + coinCharge.setStatus(3); + memberCoinChargeDao.updateById(coinCharge); + } + } + } + } + } + + /** + * 定时查询该归集转账交易是否成功 + */ + public void usdtEthPoolCheck() { + // 首先查询需要确认的交易 + List<MemberCoinChargeEntity> list = memberCoinChargeDao.selectAllBySymbolAndTag(CoinTypeEnum.USDT.name(), "ERC20", null); + EthService ethService = new EthService(); + + if (CollectionUtils.isNotEmpty(list)) { + for (MemberCoinChargeEntity appeal : list) { + String hash = appeal.getHash(); + boolean b = ethService.checkTransferResult(hash); + if (b) { + appeal.setStatus(3); + appeal.setLastAmount(new BigDecimal("0.0001")); + + // 表示这笔归集转账已经成功 + // 更新状态 + memberCoinChargeDao.updateById(appeal); + } + } + } + } + +} diff --git a/src/main/java/com/xcong/excoin/modules/member/dao/MemberCoinChargeDao.java b/src/main/java/com/xcong/excoin/modules/member/dao/MemberCoinChargeDao.java index 94d25f2..c35bdb0 100644 --- a/src/main/java/com/xcong/excoin/modules/member/dao/MemberCoinChargeDao.java +++ b/src/main/java/com/xcong/excoin/modules/member/dao/MemberCoinChargeDao.java @@ -4,8 +4,12 @@ import com.xcong.excoin.modules.member.entity.MemberCoinChargeEntity; import org.apache.ibatis.annotations.Param; +import java.util.List; + public interface MemberCoinChargeDao extends BaseMapper<MemberCoinChargeEntity> { public MemberCoinChargeEntity selectNewestChargeRecord(@Param("memberId") Long memberId, @Param("symbol") String symbol, @Param("tag") String tag); + List<MemberCoinChargeEntity> selectAllBySymbolAndTag(@Param("symbol") String symbol, @Param("tag") String tag, @Param("status") Integer status); + } diff --git a/src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java b/src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java index 40a0def..75f36ad 100644 --- a/src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java +++ b/src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java @@ -1,8 +1,13 @@ package com.xcong.excoin.quartz.job; +import com.xcong.excoin.modules.blackchain.service.UsdtEthService; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.concurrent.ExecutionException; /** * 归集定时任务 @@ -11,22 +16,40 @@ * @date 2020-07-02 **/ +@Slf4j @Component @ConditionalOnProperty(prefix = "app", name = "block-job", havingValue = "true") public class NotionalPoolingJob { + @Resource + private UsdtEthService usdtEthService; + + /** + * 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 * * * ? ") 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); + } } } diff --git a/src/main/resources/mapper/member/MemberCoinChargeDao.xml b/src/main/resources/mapper/member/MemberCoinChargeDao.xml index 3f6faae..e875705 100644 --- a/src/main/resources/mapper/member/MemberCoinChargeDao.xml +++ b/src/main/resources/mapper/member/MemberCoinChargeDao.xml @@ -12,4 +12,15 @@ order by create_time desc limit 1 </select> + <select id="selectAllBySymbolAndTag" resultType="com.xcong.excoin.modules.member.entity.MemberCoinChargeEntity"> + select * from member_coin_charge + where symbol=#{symbol} + <if test="tag !=null and tag != ''"> + and tag = #{tag} + </if> + <if test="status !=null and status != ''"> + and status = #{status} + </if> + </select> + </mapper> \ No newline at end of file -- Gitblit v1.9.1