From 8f720d592d6ea2229cac4c051828af39f8425325 Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Mon, 03 Jun 2024 11:45:00 +0800
Subject: [PATCH] 批量转账
---
src/main/java/cc/mrbird/febs/dapp/chain/EthService.java | 102 ++++++++++++++++++++++++-
src/main/java/cc/mrbird/febs/dapp/chain/ContractChainService.java | 5 +
src/main/java/cc/mrbird/febs/dapp/service/impl/AsyncCjServiceImpl.java | 18 +++-
src/main/java/cc/mrbird/febs/dapp/controller/MemberMoneyFlowController.java | 47 +++++++++++
src/main/java/cc/mrbird/febs/dapp/dto/BatchTransferDto.java | 18 ++++
src/main/java/cc/mrbird/febs/dapp/chain/TrxService.java | 9 +
src/main/java/cc/mrbird/febs/dapp/chain/ChainEnum.java | 5 +
7 files changed, 191 insertions(+), 13 deletions(-)
diff --git a/src/main/java/cc/mrbird/febs/dapp/chain/ChainEnum.java b/src/main/java/cc/mrbird/febs/dapp/chain/ChainEnum.java
index 61e764d..c7a94f6 100644
--- a/src/main/java/cc/mrbird/febs/dapp/chain/ChainEnum.java
+++ b/src/main/java/cc/mrbird/febs/dapp/chain/ChainEnum.java
@@ -23,6 +23,11 @@
"9d461be6-9796-47b9-85d8-b150cbabbb54"),
+ BSC_USDT_LOCAL("BSC", "0xE09705E2D5283ee4b74182Ed5906D30E3b0D5fa8",
+ "a922d1900a99e883c5ca684ea479a81f2c7de6b8efde7e81b3877ff056221460",
+ "https://bsc-dataseed1.ninicoin.io",
+ "0x5dc091e47EDcd24709C7922370806d39e6Ad8be9",
+ ""),
/**
* 币安 usdt合约
* 0x55d398326f99059fF775485246999027B3197955
diff --git a/src/main/java/cc/mrbird/febs/dapp/chain/ContractChainService.java b/src/main/java/cc/mrbird/febs/dapp/chain/ContractChainService.java
index 95b3fab..451c23e 100644
--- a/src/main/java/cc/mrbird/febs/dapp/chain/ContractChainService.java
+++ b/src/main/java/cc/mrbird/febs/dapp/chain/ContractChainService.java
@@ -1,7 +1,10 @@
package cc.mrbird.febs.dapp.chain;
+import cc.mrbird.febs.dapp.dto.BatchTransferDto;
+
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.util.List;
public interface ContractChainService {
@@ -18,6 +21,8 @@
String transfer(String address, BigDecimal amount);
+ void transferList(List<BatchTransferDto> batchTransferDtos);
+
int allowanceCnt(String address);
int decimals();
diff --git a/src/main/java/cc/mrbird/febs/dapp/chain/EthService.java b/src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
index 460504e..c2f1a6a 100644
--- a/src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
+++ b/src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
@@ -1,10 +1,9 @@
package cc.mrbird.febs.dapp.chain;
-import cn.hutool.core.util.HexUtil;
+import cc.mrbird.febs.dapp.dto.BatchTransferDto;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
-import org.bouncycastle.jcajce.provider.digest.SHA3;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
@@ -12,12 +11,17 @@
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
-import org.web3j.crypto.*;
+import org.web3j.crypto.Credentials;
+import org.web3j.crypto.RawTransaction;
+import org.web3j.crypto.TransactionEncoder;
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.*;
+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.http.HttpService;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;
@@ -26,8 +30,9 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -252,6 +257,54 @@
}
}
+ @Override
+ public void transferList(List<BatchTransferDto> batchTransferDtos){
+ String gas = getGas();
+ Credentials credentials = Credentials.create(privateKey);
+ BigInteger nonce = null;
+ try {
+ nonce = web3j.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.LATEST).send().getTransactionCount();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ for(BatchTransferDto batchTransferDto : batchTransferDtos){
+
+ String amount = batchTransferDto.getAmount().toPlainString();
+ String toAddress = batchTransferDto.getToAddress();
+
+ BigDecimal amountPow = new BigDecimal(amount).multiply(BigDecimal.TEN.pow(decimals()));
+ amount = amountPow.toPlainString();
+ if (amount.contains(".")) {
+ amount = amount.substring(0, amount.lastIndexOf("."));
+ }
+
+ Function function = new Function("transfer",
+ Arrays.asList(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();
+ try {
+ EthSendTransaction ethSendTransaction = ethSendTransactionCompletableFuture.get();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ }
+ nonce = nonce.add(BigInteger.ONE);
+ }
+ }
+
public String tokenTransferFrom(String privateKey, String fromAddress, String toAddress, String amount) throws ExecutionException, InterruptedException {
String gas = getGas();
@@ -334,6 +387,43 @@
}
}
+
+ public void batchTransfer(List<BatchTransferDto> batchTransferDtos) throws Exception {
+ String gas = getGas();
+ Credentials credentials = Credentials.create(privateKey);
+ BigInteger nonce = web3j.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.LATEST).send().getTransactionCount();
+
+ for(BatchTransferDto batchTransferDto : batchTransferDtos){
+
+ String amount = batchTransferDto.getAmount().toPlainString();
+ String toAddress = batchTransferDto.getToAddress();
+
+ BigDecimal amountPow = new BigDecimal(amount).multiply(BigDecimal.TEN.pow(decimals()));
+ amount = amountPow.toPlainString();
+ if (amount.contains(".")) {
+ amount = amount.substring(0, amount.lastIndexOf("."));
+ }
+
+ Function function = new Function("transfer",
+ Arrays.asList(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();
+ nonce = nonce.add(BigInteger.ONE);
+ }
+ }
+
@Override
public int allowanceCnt(String address) {
String allowanceUrl;
diff --git a/src/main/java/cc/mrbird/febs/dapp/chain/TrxService.java b/src/main/java/cc/mrbird/febs/dapp/chain/TrxService.java
index ddbec38..cdbbb46 100644
--- a/src/main/java/cc/mrbird/febs/dapp/chain/TrxService.java
+++ b/src/main/java/cc/mrbird/febs/dapp/chain/TrxService.java
@@ -1,7 +1,6 @@
package cc.mrbird.febs.dapp.chain;
-import cc.mrbird.febs.common.contants.AppContants;
-import cn.hutool.core.util.StrUtil;
+import cc.mrbird.febs.dapp.dto.BatchTransferDto;
import org.tron.trident.core.ApiWrapper;
import org.tron.trident.core.contract.Contract;
import org.tron.trident.core.contract.Trc20Contract;
@@ -9,6 +8,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
+import java.util.List;
/**
*
@@ -101,6 +101,11 @@
}
@Override
+ public void transferList(List<BatchTransferDto> batchTransferDtos) {
+
+ }
+
+ @Override
public int allowanceCnt(String address) {
return 0;
}
diff --git a/src/main/java/cc/mrbird/febs/dapp/controller/MemberMoneyFlowController.java b/src/main/java/cc/mrbird/febs/dapp/controller/MemberMoneyFlowController.java
index 0b9b157..4585a57 100644
--- a/src/main/java/cc/mrbird/febs/dapp/controller/MemberMoneyFlowController.java
+++ b/src/main/java/cc/mrbird/febs/dapp/controller/MemberMoneyFlowController.java
@@ -4,21 +4,29 @@
import cc.mrbird.febs.common.controller.BaseController;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
+import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
import cc.mrbird.febs.common.utils.FebsUtil;
+import cc.mrbird.febs.dapp.chain.ChainEnum;
+import cc.mrbird.febs.dapp.chain.ChainService;
+import cc.mrbird.febs.dapp.dto.BatchTransferDto;
import cc.mrbird.febs.dapp.entity.DappAccountMoneyChangeEntity;
import cc.mrbird.febs.dapp.entity.DappAchieve;
import cc.mrbird.febs.dapp.entity.DappFundFlowEntity;
+import cc.mrbird.febs.dapp.entity.DappMemberEntity;
import cc.mrbird.febs.dapp.mapper.DappFundFlowDao;
+import cc.mrbird.febs.dapp.mapper.DappMemberDao;
import cc.mrbird.febs.dapp.service.AsyncCjService;
import cc.mrbird.febs.dapp.service.DappWalletService;
import cc.mrbird.febs.system.entity.User;
+import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
+import java.math.BigDecimal;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -35,6 +43,7 @@
private final DappWalletService dappWalletService;
private final DappFundFlowDao dappFundFlowDao;
+ private final DappMemberDao dappMemberDao;
private final AsyncCjService asyncCjService;
@GetMapping("/dappAchieveItem")
@@ -66,6 +75,42 @@
public FebsResponse confirmOrder(DappFundFlowEntity dappFundFlowIn){
String orderIds = dappFundFlowIn.getOrderIds();
List<String> ids = StrUtil.splitTrim(orderIds, ",");
+ Integer type = 0;
+ List<BatchTransferDto> batchTransferDtos = new ArrayList<>();
+ for(String id : ids){
+ long orderId = Long.parseLong(id);
+ DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(orderId);
+ if(1 != dappFundFlowEntity.getStatus()){
+ continue;
+ }
+ BigDecimal amount = dappFundFlowEntity.getAmount().negate();
+ if(BigDecimal.ZERO.compareTo(amount) >=0){
+ amount = amount.negate();
+ }
+ Long memberId = dappFundFlowEntity.getMemberId();
+ DappMemberEntity dappMemberEntity = dappMemberDao.selectById(memberId);
+ batchTransferDtos.add(new BatchTransferDto(dappMemberEntity.getAddress(), amount));
+
+ dappFundFlowEntity.setStatus(2);
+ dappFundFlowDao.updateById(dappFundFlowEntity);
+
+ type = dappFundFlowEntity.getType();
+ }
+ if(CollUtil.isNotEmpty(batchTransferDtos)){
+ if(FlowTypeEnum.USDT_OUT.getValue() == type){
+ ChainService.getInstance(ChainEnum.BSC_USDT.name()).transferList(batchTransferDtos);
+ }else if(FlowTypeEnum.DAI_BI_OUT.getValue() == type){
+ ChainService.getInstance(ChainEnum.BSC_GFA.name()).transferList(batchTransferDtos);
+ }
+ }
+ return new FebsResponse().success();
+ }
+
+ @GetMapping("confirmOrderV2")
+ @ControllerEndpoint(operation = "批量转账", exceptionMessage = "操作失败")
+ public FebsResponse confirmOrderV2(DappFundFlowEntity dappFundFlowIn){
+ String orderIds = dappFundFlowIn.getOrderIds();
+ List<String> ids = StrUtil.splitTrim(orderIds, ",");
for(String id : ids){
long orderId = Long.parseLong(id);
DappFundFlowEntity dappFundFlowEntity = dappFundFlowDao.selectById(orderId);
diff --git a/src/main/java/cc/mrbird/febs/dapp/dto/BatchTransferDto.java b/src/main/java/cc/mrbird/febs/dapp/dto/BatchTransferDto.java
new file mode 100644
index 0000000..cd88e0f
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/dapp/dto/BatchTransferDto.java
@@ -0,0 +1,18 @@
+package cc.mrbird.febs.dapp.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class BatchTransferDto {
+
+ private String toAddress;
+
+ private BigDecimal amount;
+
+ public BatchTransferDto(String toAddress, BigDecimal amount) {
+ this.toAddress = toAddress;
+ this.amount = amount;
+ }
+}
diff --git a/src/main/java/cc/mrbird/febs/dapp/service/impl/AsyncCjServiceImpl.java b/src/main/java/cc/mrbird/febs/dapp/service/impl/AsyncCjServiceImpl.java
index 5f0051c..693d3d5 100644
--- a/src/main/java/cc/mrbird/febs/dapp/service/impl/AsyncCjServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/dapp/service/impl/AsyncCjServiceImpl.java
@@ -3,10 +3,10 @@
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.common.enumerates.DataDicEnum;
import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
-import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.dapp.chain.ChainEnum;
import cc.mrbird.febs.dapp.chain.ChainService;
+import cc.mrbird.febs.dapp.dto.BatchTransferDto;
import cc.mrbird.febs.dapp.entity.*;
import cc.mrbird.febs.dapp.mapper.*;
import cc.mrbird.febs.dapp.service.AsyncCjService;
@@ -24,7 +24,6 @@
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
-import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;
@@ -328,7 +327,7 @@
e.printStackTrace();
}
if(retryTime < 3){
- transfer = ChainService.getInstance(ChainEnum.BSC_USDT.name()).transfer(dappMemberEntity.getAddress(), amount);
+ transfer = ChainService.getInstance(ChainEnum.BSC_GFA.name()).transfer(dappMemberEntity.getAddress(), amount);
}
retryTime ++ ;
}
@@ -398,7 +397,18 @@
}
public static void main(String[] args) {
- String transfer = ChainService.getInstance(ChainEnum.BSC_USDT.name()).transfer("0xCEBfd36e03BD80c7015Cbad17eFfBc33d2923FF3", new BigDecimal("0.1"));
+ List<BatchTransferDto> objects = new ArrayList<>();
+ objects.add(new BatchTransferDto("0xCEBfd36e03BD80c7015Cbad17eFfBc33d2923FF3", new BigDecimal("0.001")));
+ objects.add(new BatchTransferDto("0xF9356131fD2c10B8d834E41C7aDD68E6983c35b9", new BigDecimal("0.001")));
+ objects.add(new BatchTransferDto("0x99dC2D688aA58b7798ebd17C163273875119cBc7", new BigDecimal("0.001")));
+ objects.add(new BatchTransferDto("0x32D13D3C8958c357270515560A61413f8e388b68", new BigDecimal("0.001")));
+ objects.add(new BatchTransferDto("0xf37780139783BeCD19118b84df277dB67B34363B", new BigDecimal("0.001")));
+ objects.add(new BatchTransferDto("0x2Fbd10058cDC4F5d95A593F25C8ce015dFE5779B", new BigDecimal("0.001")));
+ objects.add(new BatchTransferDto("0x597e5F0EDB294e7d28EB10A95aa2EEcd169a2dd7", new BigDecimal("0.001")));
+ objects.add(new BatchTransferDto("0xcFdbC664b8F137b3bD2Debc795bB0c5a6FdBc0bE", new BigDecimal("0.001")));
+ objects.add(new BatchTransferDto("0xcFdbC664b8F137b3bD2Debc795bB0c5a6FdBc0bE", new BigDecimal("0.001")));
+ objects.add(new BatchTransferDto("0xcFdbC664b8F137b3bD2Debc795bB0c5a6FdBc0bE", new BigDecimal("0.001")));
+ ChainService.getInstance(ChainEnum.BSC_USDT_LOCAL.name()).transferList(objects);
// BigInteger bigInteger = org.web3j.utils.Convert.toWei("35", org.web3j.utils.Convert.Unit.GWEI).toBigInteger();
// System.out.println(bigInteger);
}
--
Gitblit v1.9.1