src/main/java/cc/mrbird/febs/dapp/chain/ChainEnum.java
@@ -14,13 +14,24 @@ * 0x55d398326f99059fF775485246999027B3197955 * 测试链 0x337610d27c682E347C9cD60BD4b3b107C9d34dDd */ BSC_USDT("BSC", "0x977a9ddfb965a9a3416fa72ca7f91c4949c18f25", "0xefe98e00cd227b6322e892c82fcbd8eadf119c3188b7e574bc624f65405d61bf", BSC_USDT("BSC", "0x977a9ddfb965a9a3416fa72ca7f91c4949c18f25", "", "https://bsc-dataseed1.ninicoin.io", "0x6c6835e60e7dBaD7a60112a6371271e8eb79ee68", ""), /** * NFT */ BSC_NFT_SDC("BSC", "0x977a9ddfb965a9a3416fa72ca7f91c4949c18f25", "0xefe98e00cd227b6322e892c82fcbd8eadf119c3188b7e574bc624f65405d61bf", "https://bsc-dataseed1.ninicoin.io", "0x03c7D3f141c5F03971604958170E253362e13BE6", ""), /** * 币安链 代币合约 * 测试链 0xdd92ea2f41d807a60b29004bf7db807d8ac09212 * 正式 0x6c6835e60e7dBaD7a60112a6371271e8eb79ee68 https://bsc-dataseed1.ninicoin.io src/main/java/cc/mrbird/febs/dapp/chain/ContractChainService.java
@@ -24,4 +24,6 @@ BigInteger blockNumber(); BigInteger totalSupply(); String safeMintNFT(String toAddress); } src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
@@ -54,14 +54,14 @@ } 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); // 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"; @@ -192,8 +192,10 @@ } else { String resp = HttpUtil.get("https://gbsc.blockscan.com/gasapi.ashx?apikey=key&method=gasoracle"); JSONObject data = JSONObject.parseObject(resp); gas = data.getString("FastGasPrice"); Map<String, String> result = data.getObject("result", Map.class); gas = result.get("FastGasPrice"); } return StrUtil.isBlank(gas) ? "35" : gas; } @@ -360,4 +362,40 @@ } 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("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(); } } catch (Exception e) { e.printStackTrace(); return ""; } } } src/main/java/cc/mrbird/febs/dapp/chain/TrxService.java
@@ -113,4 +113,9 @@ public BigInteger totalSupply() { return null; } @Override public String safeMintNFT(String toAddress) { return null; } } src/main/java/cc/mrbird/febs/dapp/entity/DappFundFlowEntity.java
@@ -47,7 +47,7 @@ private BigDecimal amount; /** * 类型 1-买入 2-卖出 3-采矿 5-获取盲盒 6-开盲盒获取卡牌 * 类型 1-买入 2-卖出 3-采矿 4-返利 5-获取盲盒 6-开盲盒获取卡牌 7-推荐奖励 */ private Integer type; src/main/java/cc/mrbird/febs/dapp/service/impl/BscUsdtContractEvent.java
@@ -57,7 +57,7 @@ redisUtils.set(AppContants.REDIS_KEY_BLOCK_USDT_NUM, e.log.getBlockNumber()); // 判断对方打款地址是否为源池地址 if (ChainEnum.BSC_TFC_SOURCE.getAddress().toLowerCase().equals(e.to)) { if (ChainEnum.BSC_USDT.getAddress().toLowerCase().equals(e.to)) { log.info("触发USDT合约监听事件"); redisUtils.set(AppContants.REDIS_KEY_BLOCK_ETH_INCREMENT_NUM, e.log.getBlockNumber()); src/main/java/cc/mrbird/febs/dapp/service/impl/DappSystemServiceImpl.java
@@ -511,7 +511,17 @@ @Override public void idoBuy(DappMemberEntity member, BigDecimal amount) { DappIdoAssetsEntity idoAssets = dappIdoAssetsDao.selectByMemberId(member.getId()); BigDecimal count = amount.divide(new BigDecimal(50), 0, RoundingMode.HALF_UP); BigDecimal coinAmount = new BigDecimal(1000).multiply(count); idoAssets.setCoinAmount(idoAssets.getCoinAmount().add(coinAmount)); idoAssets.setUsdtAmount(idoAssets.getUsdtAmount().add(amount)); dappIdoAssetsDao.updateById(idoAssets); DappMemberEntity parent = dappMemberDao.selectMemberInfoByInviteId(member.getRefererId()); if (parent == null) { return; } int box = 0; Object parentRecommend = redisUtils.hget(AppContants.IDO_MEMBER_RECOMMEND_CNT, parent.getAddress()); @@ -534,12 +544,10 @@ dappFundFlowDao.insert(boxFundFlow); } DappIdoAssetsEntity idoAssets = dappIdoAssetsDao.selectByMemberId(member.getId()); BigDecimal count = amount.divide(new BigDecimal(50), 0, RoundingMode.HALF_UP); BigDecimal coinAmount = new BigDecimal(1000).multiply(count); idoAssets.setBoxCnt(idoAssets.getBoxCnt() + box); idoAssets.setCoinAmount(idoAssets.getCoinAmount().add(coinAmount)); idoAssets.setUsdtAmount(idoAssets.getUsdtAmount().add(amount)); dappIdoAssetsDao.updateById(idoAssets); BigDecimal returnCoin = coinAmount.multiply(new BigDecimal(5).divide(new BigDecimal(100), 2, RoundingMode.UP)); DappIdoAssetsEntity parentIdoAssets = dappIdoAssetsDao.selectById(parent.getId()); parentIdoAssets.setBoxCnt(parentIdoAssets.getBoxCnt() + box); parentIdoAssets.setCoinAmount(parentIdoAssets.getCoinAmount().add(returnCoin)); dappIdoAssetsDao.updateById(parentIdoAssets); } } src/main/java/cc/mrbird/febs/dapp/service/impl/DappWalletServiceImpl.java
@@ -17,6 +17,7 @@ import cc.mrbird.febs.dapp.entity.*; import cc.mrbird.febs.dapp.mapper.*; import cc.mrbird.febs.dapp.service.DappWalletService; import cc.mrbird.febs.dapp.utils.BoxUtil; import cc.mrbird.febs.dapp.vo.WalletInfoVo; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -267,8 +268,13 @@ idoAssets.setBoxCnt(idoAssets.getBoxCnt() - 1); dappIdoAssetsDao.updateById(idoAssets); BoxUtil.Box box = BoxUtil.openBox(); DappFundFlowEntity boxFundFlow = new DappFundFlowEntity(member.getId(), new BigDecimal(box.getIndex()), 6, 2, BigDecimal.ZERO); dappFundFlowDao.insert(boxFundFlow); // TODO 线上转账 return 1; return box.getIndex(); } } src/main/java/cc/mrbird/febs/dapp/utils/BoxUtil.java
New file @@ -0,0 +1,118 @@ package cc.mrbird.febs.dapp.utils; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.RandomUtil; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * @author wzy * @date 2022-07-14 **/ @Slf4j public class BoxUtil { public static volatile List<Box> boxList = Collections.synchronizedList(new ArrayList<>()); public synchronized static Box openBox() { if (CollUtil.isEmpty(boxList)) { Box box1 = new Box(1, 6); Box box2 = new Box(2, 1); Box box3 = new Box(3, 1); Box box4 = new Box(4, 1); Box box5 = new Box(5, 1); boxList.add(box1); boxList.add(box2); boxList.add(box3); boxList.add(box4); boxList.add(box5); } int min = 1; int minIndex = 1; int max = 1; for (int i = 0; i < boxList.size(); i++) { Box box = boxList.get(i); if (i != 0) { minIndex += boxList.get(i - 1).getCount(); } max += box.getCount(); box.setMin(minIndex); box.setMax(max); } int i = RandomUtil.randomInt(min, max); Box result = new Box(); for (Box box : boxList) { if (box.getMin() <= i && box.getMax() > i) { result = box; int count = box.getCount(); count--; box.setCount(count); if (count == 0) { boxList.remove(box); } break; } } return result; } public static class Box { private int index; private int count; public Box() {} public Box(int index, int count) { this.index = index; this.count = count; } private int min; private int max; public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public int getMin() { return min; } public void setMin(int min) { this.min = min; } public int getMax() { return max; } public void setMax(int max) { this.max = max; } } } src/main/resources/application-dev.yml
@@ -50,5 +50,5 @@ system: online-transfer: false chain-listener: true chain-listener: false trade-job: false src/main/resources/application-test.yml
@@ -50,5 +50,5 @@ system: online-transfer: false chain-listener: true chain-listener: false trade-job: false src/test/java/cc/mrbird/febs/ChainTest.java
@@ -8,7 +8,6 @@ import cc.mrbird.febs.dapp.mapper.DappFundFlowDao; import cc.mrbird.febs.dapp.mapper.DappOnlineTransferDao; import cc.mrbird.febs.dapp.service.DappSystemService; import cc.mrbird.febs.job.SystemTradeJob; import cc.mrbird.febs.rabbit.producer.ChainProducer; import com.alibaba.fastjson.JSONObject; import org.junit.jupiter.api.Test; @@ -36,24 +35,24 @@ System.out.println(instance.balanceOf("0x0000000000000000000000000000000000000001")); } @Autowired private SystemTradeJob systemTradeJob; @Test public void transferPoolTest() { systemTradeJob.transferPoolVol(); } @Test public void sourceUsdtTest() { systemTradeJob.sourcePoolUsdtOutLimit(); } @Test public void poolTest() { systemTradeJob.transferPoolVol(); } // @Autowired // private SystemTradeJob systemTradeJob; // // @Test // public void transferPoolTest() { // systemTradeJob.transferPoolVol(); // } // // // @Test // public void sourceUsdtTest() { // systemTradeJob.sourcePoolUsdtOutLimit(); // } // // @Test // public void poolTest() { // systemTradeJob.transferPoolVol(); // } @Autowired private DappOnlineTransferDao dappOnlineTransferDao; @@ -79,10 +78,10 @@ System.out.println(ChainService.getInstance(ChainEnum.BSC_TFC.name()).blockNumber()); } @Test public void mineTest() { systemTradeJob.mineJob(); } // @Test // public void mineTest() { // systemTradeJob.mineJob(); // } @Autowired private DappFundFlowDao dappFundFlowDao; @@ -114,4 +113,9 @@ public void profitTest() { dappSystemService.tradeProfitDistribute(31L); } @Test public void safeMintTest() { ChainService.getInstance(ChainEnum.BSC_NFT_SDC.name()).safeMintNFT("0x4EbDCA102623b46a47042D580dddAdE2a53D057F"); } } src/test/java/cc/mrbird/febs/MemberTest.java
@@ -6,13 +6,18 @@ import cc.mrbird.febs.dapp.entity.DataDictionaryCustom; import cc.mrbird.febs.dapp.mapper.DappMemberDao; import cc.mrbird.febs.dapp.mapper.DataDictionaryCustomMapper; import cc.mrbird.febs.dapp.utils.BoxUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.web3j.abi.datatypes.Int; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author wzy @@ -59,7 +64,7 @@ break; } parentId = parentMember.getRefererId(); if(StringUtils.isBlank(parentId) || "0".equals(parentId)){ if (StringUtils.isBlank(parentId) || "0".equals(parentId)) { break; } if (parentMember.getRefererId().equals(parentMember.getInviteId())) { @@ -77,4 +82,24 @@ public void redisTest() { redisUtils.hget("1234567", "1111111"); } private Map<Integer, Integer> map = new HashMap<>(); private int BOX_OPEN_CNT = 0; @Test public void boxOpenTest() { Runnable runnable = new Runnable() { @Override public void run() { BoxUtil.openBox(); } }; for (int i = 0; i < 12; i++) { Thread thread = new Thread(runnable); thread.start(); } } }