package cc.mrbird.febs.mall.chain.service; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.mall.chain.dto.EthUsdtChargeDto; import cc.mrbird.febs.mall.chain.enums.CoinTypeEnum; import cc.mrbird.febs.mall.mapper.MemberCoinAddressDao; import cc.mrbird.febs.rabbit.producter.AgentProducer; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Service; import org.web3j.crypto.Credentials; import org.web3j.protocol.Web3j; import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.DefaultBlockParameterName; import org.web3j.protocol.core.DefaultBlockParameterNumber; import org.web3j.protocol.core.methods.request.EthFilter; import org.web3j.protocol.http.HttpService; import org.web3j.tx.gas.StaticGasProvider; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Service public class UsdtErc20UpdateService { @Resource private AgentProducer agentProducer; @Resource private MemberCoinAddressDao coinWalletDao; public final static List ALL_ADDRESS_LIST = new ArrayList<>(); public final static String ETH_USDT_BLOCK_NUM = "ETH_USDT_BLOCK_NUM"; private final static BigDecimal DIVIDE_USDT = new BigDecimal("1000000"); private static Web3j web3; private static Web3j getInstance() { if (web3 == null) { HttpService httpService = new HttpService(blockchainNode); web3 = Web3j.build(httpService); } return web3; } public static BigInteger GAS_PRICE = BigInteger.valueOf(45000000000L); //public static final BigInteger GAS_LIMIT = BigInteger.valueOf(4300000L); public static final BigInteger GAS_LIMIT = BigInteger.valueOf(2000000L); private static StaticGasProvider getStaticGasProvider(){ return new StaticGasProvider(GAS_PRICE,GAS_LIMIT); } private static Web3j getInstanceScope() { HttpService httpService = new HttpService(blockchainNode); return Web3j.build(httpService); } //private static String blockchainNode = "http://114.55.250.231:8545"; private static String blockchainNode = "https://bsc-dataseed1.ninicoin.io"; // private static String contractAddr = "0xdac17f958d2ee523a2206206994597c13d831ec7"; private static String contractAddr = "0x55d398326f99059ff775485246999027b3197955"; // 操作账号 private static String privateKey = "7761233246f68ab3d35eba04c2fbc794714652d2acc15ee5b27ecd1c4005d279"; @Resource private RedisUtils redisUtils; public void updateUsdt(){ // 首先查询所有的钱包地址 List tdCoinWallets = coinWalletDao.selectAllSymbolAddress(CoinTypeEnum.USDT.toString(),"ERC20"); if(tdCoinWallets!=null){ ALL_ADDRESS_LIST.addAll(tdCoinWallets); } // 获取最新区块 // String string = redisUtils.getString(ETH_USDT_BLOCK_NUM); String string = "24317595"; if(string==null){ string = "24317595"; } BigInteger blockNum = new BigInteger(string); Credentials credentials = Credentials.create(privateKey); EthUsdtContract contract = EthUsdtContract.load(contractAddr, getInstance(), credentials, getStaticGasProvider()); EthFilter filter = getFilter(blockNum,blockNum,contractAddr); Map map = new HashMap(); map.put("blockNum",blockNum); contract.transferEventFlowable(filter).subscribe(e->{ if(e!=null && StringUtils.isNotBlank(e.to) && e.log.getBlockNumber()!=null){ String transactionHash = e.log.getTransactionHash(); BigInteger blockNumber1 = e.log.getBlockNumber(); String toAddress = e.to; BigInteger tokenBalance = e.tokens; if(ALL_ADDRESS_LIST.contains(toAddress)){ System.out.println("存在本地的地址:"+toAddress); // 金额 BigDecimal divide = new BigDecimal(tokenBalance.toString()).divide(DIVIDE_USDT); // 发送消息队列 EthUsdtChargeDto dto = new EthUsdtChargeDto(toAddress,transactionHash,divide); dto.setSymbol(EthUsdtChargeDto.Symbol.USDT_ERC20); agentProducer.sendMsg(JSONObject.toJSONString(dto)); } if(map.get("blockNum").compareTo(blockNumber1)!=0){ redisUtils.set(ETH_USDT_BLOCK_NUM,blockNumber1.toString()); map.put("blockNum",blockNumber1); } } }); } private static EthFilter getFilter(BigInteger startBlock) { if (startBlock != null) { EthFilter filter = new EthFilter(new DefaultBlockParameterNumber(startBlock), DefaultBlockParameterName.LATEST, contractAddr); return filter; } else { return new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, contractAddr); } } private static EthFilter getFilter(BigInteger startBlock, BigInteger endBlock, String contractAddress) { DefaultBlockParameter startParameterName = null; DefaultBlockParameter endParameterName = null; if (startBlock != null) { startParameterName = new DefaultBlockParameterNumber(startBlock); } else { startParameterName = DefaultBlockParameterName.EARLIEST; } if (endBlock != null) { endParameterName = new DefaultBlockParameterNumber(endBlock); } else { endParameterName = DefaultBlockParameterName.LATEST; } return new EthFilter(startParameterName, endParameterName, contractAddress); } }