From 61427d4fa770905fdba869971b49a78d91d08f3d Mon Sep 17 00:00:00 2001 From: zainali5120 <512061637@qq.com> Date: Fri, 09 Oct 2020 22:02:01 +0800 Subject: [PATCH] ROC提币修复 --- src/main/java/com/xcong/excoin/modules/Sms106Send.java | 4 src/main/java/com/xcong/excoin/modules/member/service/EthService.java | 290 ++++++++++++++++++++++++++++++++ src/main/java/com/xcong/excoin/modules/member/service/IMemberService.java | 3 src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java | 19 ++ src/main/java/com/xcong/excoin/modules/member/service/BigDecimalUtil.java | 190 +++++++++++++++++++++ src/main/java/com/xcong/excoin/modules/member/controller/MemberController.java | 3 pom.xml | 5 7 files changed, 509 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 1261d61..6c6c371 100644 --- a/pom.xml +++ b/pom.xml @@ -248,6 +248,11 @@ <artifactId>httpmime</artifactId> <version>4.3.5</version> </dependency> + <dependency> + <groupId>org.web3j</groupId> + <artifactId>core</artifactId> + <version>4.5.5</version> + </dependency> <!-- submail邮件 end --> </dependencies> diff --git a/src/main/java/com/xcong/excoin/modules/Sms106Send.java b/src/main/java/com/xcong/excoin/modules/Sms106Send.java index a213e6b..20f41ba 100644 --- a/src/main/java/com/xcong/excoin/modules/Sms106Send.java +++ b/src/main/java/com/xcong/excoin/modules/Sms106Send.java @@ -16,8 +16,8 @@ public class Sms106Send { private static final String URL = "http://www.qf106.com/sms.aspx"; - private static final String ID = "16580"; - private static final String ACCOUNT = "Biue"; + private static final String ID = "16606"; + private static final String ACCOUNT = "golden"; private static final String PASSWORD = "123456"; diff --git a/src/main/java/com/xcong/excoin/modules/member/controller/MemberController.java b/src/main/java/com/xcong/excoin/modules/member/controller/MemberController.java index 358a390..d0e42c6 100644 --- a/src/main/java/com/xcong/excoin/modules/member/controller/MemberController.java +++ b/src/main/java/com/xcong/excoin/modules/member/controller/MemberController.java @@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.Map; +import java.util.concurrent.ExecutionException; import javax.validation.Valid; import javax.validation.constraints.NotNull; @@ -217,7 +218,7 @@ */ @GetMapping("memberWithdrawCoinConfirm/{id}") @ControllerEndpoint(operation = "提币记录---确认", exceptionMessage = "划转失败") - public FebsResponse memberWithdrawCoinConfirm(@NotNull(message = "{required}") @PathVariable Long id) { + public FebsResponse memberWithdrawCoinConfirm(@NotNull(message = "{required}") @PathVariable Long id) throws ExecutionException, InterruptedException { return memberService.memberWithdrawCoinConfirm(id); } diff --git a/src/main/java/com/xcong/excoin/modules/member/service/BigDecimalUtil.java b/src/main/java/com/xcong/excoin/modules/member/service/BigDecimalUtil.java new file mode 100644 index 0000000..d76eceb --- /dev/null +++ b/src/main/java/com/xcong/excoin/modules/member/service/BigDecimalUtil.java @@ -0,0 +1,190 @@ +package com.xcong.excoin.modules.member.service; + + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; + +/** + * 数据计算工具类 + * + * @author cloud cloud + * @create 2017/10/11 + **/ +public class BigDecimalUtil { + + + /** + * 基本单位 + */ + private static final BigDecimal UNIT = new BigDecimal(100000000); + + /** + * 对double数据进行取精度. + * @param value double数据. + * @param scale 精度位数(保留的小数位数). + * @param roundingMode 精度取值方式. + * @return 精度计算后的数据. + */ + public static double round(double value, int scale, + int roundingMode) { + BigDecimal bd = new BigDecimal(value); + bd = bd.setScale(scale, roundingMode); + double d = bd.doubleValue(); + bd = null; + return d; + } + + /** + * 获取四位小数的字符串,小数位不够补充0 + * @param value + * @return X.0000 + */ + public static String getFourString(double value){ + DecimalFormat df = new DecimalFormat("0.0000"); + return df.format(value); + } + + + /** + * double 相加 + * @param d1 + * @param d2 + * @return + */ + public static double sum(Double d1,Double d2){ + BigDecimal bd1 = new BigDecimal(d1.toString()); + BigDecimal bd2 = new BigDecimal(d2.toString()); + return bd1.add(bd2).doubleValue(); + } + + public static double sum(String a,String b){ + BigDecimal pa = new BigDecimal(a); + BigDecimal pb = new BigDecimal(b); + return pa.add(pb).doubleValue(); + } + + + /** + * double 相减 + * @param d1 + * @param d2 + * @return + */ + public static double sub(double d1,double d2){ + BigDecimal bd1 = new BigDecimal(Double.toString(d1)); + BigDecimal bd2 = new BigDecimal(Double.toString(d2)); + return bd1.subtract(bd2).setScale(6,BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + /** + * double 乘法 + * @param d1 + * @param d2 + * @return + */ + public static double mul(double d1,double d2){ + BigDecimal bd1 = new BigDecimal(Double.toString(d1)); + BigDecimal bd2 = new BigDecimal(Double.toString(d2)); + return bd1.multiply(bd2).setScale(6,BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + + /** + * double 除法 + * @param d1 + * @param d2 + * @param scale 四舍五入 小数点位数 + * @return + */ + public static double div(double d1,double d2,int scale){ + // 当然在此之前,你要判断分母是否为0, + // 为0你可以根据实际需求做相应的处理 + + BigDecimal bd1 = new BigDecimal(Double.toString(d1)); + BigDecimal bd2 = new BigDecimal(Double.toString(d2)); + return bd1.divide + (bd2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + /** + * 长整数相乘 + * @param pa + * @param pb + * @return + */ + public static long longMul(long pa,long pb){ + BigDecimal b1 = new BigDecimal(pa); + BigDecimal b2 = new BigDecimal(pb); + return b1.multiply(b2).longValue(); + } + + public static long longMul(long pa ,Double rate){ + BigDecimal b1 = new BigDecimal(pa); + BigDecimal b2 = new BigDecimal(rate.toString()); + b2 = b2.setScale(6,BigDecimal.ROUND_HALF_UP); + return b1.multiply(b2).longValue(); + } + + public static long longMul(long pa ,String rate){ + BigDecimal b1 = new BigDecimal(pa); + BigDecimal b2 = new BigDecimal(rate); + return b1.multiply(b2).longValue(); + } + + /** + * 长整数相减 + * @param pa + * @param pb + * @return + */ + public static long longSub(long pa,long pb){ + BigDecimal b1 = new BigDecimal(pa); + BigDecimal b2 = new BigDecimal(pb); + return b1.subtract(b2).longValue(); + } + + /** + * 长整数相加 + * @param pa + * @param pb + * @return + */ + public static long longAdd(long pa,long pb){ + BigDecimal b1 = new BigDecimal(pa); + BigDecimal b2 = new BigDecimal(pb); + return b1.add(b2).longValue(); + } + + /** + * 入参转化 + * @param value + * @return + */ + public static long inputConvert(Double value){ + BigDecimal input = new BigDecimal(value.toString()); + return input.multiply(UNIT).longValue(); + } + + /** + * 输出转化 + * @param value + * @return + */ + public static double outputConvert(long value){ + BigDecimal output = new BigDecimal(value); + return output.divide(UNIT,6, RoundingMode.DOWN).doubleValue(); + } + + public static void main(String[] args) { + long res = longMul(100000000,0.000009999999); + System.out.println(res); + + } + + public static long sum(Long d1,String d2){ + BigDecimal bd1 = new BigDecimal(d1.toString()); + BigDecimal bd2 = new BigDecimal(d2); + return bd1.add(bd2).longValue(); + } +} diff --git a/src/main/java/com/xcong/excoin/modules/member/service/EthService.java b/src/main/java/com/xcong/excoin/modules/member/service/EthService.java new file mode 100644 index 0000000..115a8db --- /dev/null +++ b/src/main/java/com/xcong/excoin/modules/member/service/EthService.java @@ -0,0 +1,290 @@ +package com.xcong.excoin.modules.member.service; + +import org.apache.commons.lang3.StringUtils; +import org.web3j.abi.FunctionEncoder; +import org.web3j.abi.FunctionReturnDecoder; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.RawTransaction; +import org.web3j.crypto.TransactionEncoder; +import org.web3j.crypto.WalletUtils; +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.http.HttpService; +import org.web3j.utils.Convert; +import org.web3j.utils.Convert.Unit; +import org.web3j.utils.Numeric; + +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.*; +import java.util.concurrent.ExecutionException; + +/** + * ETH类,使用Web3j 下面为使用教程 + * https://kauri.io/article/925d923e12c543da9a0a3e617be963b4/manage-an-ethereum-account-with-java-and-web3js + * + * @author Administrator + * + */ + +public class EthService { + + private static String ethWalletPath = "/home/javaweb/webresource/eth"; + + + public static final String TOTAL_ADDRESS = "0x3d83A28B6C2d599d2B6D272c5DBcDC9c976d344F"; + public static final String TOTAL_PRIVATE_KEY = "4a1ce332133d8917360c5f3b194f703a0cf5b86c4eea319b1cd01197e68dad27"; + // private static String ethWalletPath="E://"; + private Web3j web3j; + // private Admin admin; + // private Parity parity; + /** + * 服务器地址 + */ + //private static final String ETH_UTL = "https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321"; + private static final String ETH_UTL = "http://120.55.86.146:8545"; + + public EthService() { + try { + HttpService service = new HttpService(ETH_UTL); + web3j = Web3j.build(service); + // parity = Parity.build(service); + // admin = Admin.build(service); + } catch (Exception e) { + System.out.println("liangjieshibao"); + // logger.error("==============虚拟币-以太坊链接获取失败!"); + e.printStackTrace(); + } + } + + /** + * 查询ETH余额 + * + * @param address + * @return + */ + public static BigDecimal getEthBlance(String address) { + Web3j web3 = Web3j.build(new HttpService(ETH_UTL)); + EthGetBalance balanceWei; + try { + balanceWei = web3.ethGetBalance(address, DefaultBlockParameterName.LATEST).send(); + if (balanceWei.getResult() == null) { + return null; + } + BigDecimal balanceInEther = Convert.fromWei(balanceWei.getBalance().toString(), Unit.ETHER); + return balanceInEther; + } catch (Exception e) { + System.out.println("ETH查询失败:" + address); + e.printStackTrace(); + } + return null; + + } + + /** + * 创建ETH钱包 + * + * @return + */ + public static Map<String, String> createEth() { + Map<String, String> wallet = new HashMap<String, String>(); + try { + String walletPassword = "secr3t"; + // 文件路径 + String walletDirectory = ethWalletPath; + + String walletName = WalletUtils.generateNewWalletFile(walletPassword, new File(walletDirectory)); + System.out.println("wallet location: " + walletDirectory + "/" + walletName); + Credentials credentials = WalletUtils.loadCredentials(walletPassword, walletDirectory + "/" + walletName); + String accountAddress = credentials.getAddress(); + String privateKey = credentials.getEcKeyPair().getPrivateKey().toString(16); + // 钱包地址 + wallet.put("address", accountAddress); + // 钱包私钥 + wallet.put("privateKey", privateKey); + // 产生的钱包文件地址 + wallet.put("walletLocation", walletDirectory + "/" + walletName); + } catch (Exception e) { + e.printStackTrace(); + } + return wallet; + } + + public boolean checkTransferResult(String hash) { + // 0xa3e6a0ccc3aac30d866a86ca9c0477dd58b7b061787ba40b16c3844803273816 交易hash + Request<?, EthGetTransactionReceipt> ethGetTransactionReceiptRequest = web3j.ethGetTransactionReceipt(hash); + EthGetTransactionReceipt send = null; + try { + send = ethGetTransactionReceiptRequest.send(); + if(send!=null){ + TransactionReceipt result = send.getResult(); + if(result!=null){ + String status = result.getStatus(); + System.out.println(status);//0x1 + if("0x1".equals(status)){ + return true; + }else{ + return false; + } + } + + } + + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return false; + } + + public static void main(String[] args) throws IOException, ExecutionException, InterruptedException { + HttpService service = new HttpService(ETH_UTL); + Web3j build = Web3j.build(service); + //Request<?, EthTransaction> ethTransactionRequest = build.ethGetTransactionByHash("0xa3e6a0ccc3aac30d866a86ca9c0477dd58b7b061787ba40b16c3844803273816"); +// Request<?, EthGetTransactionReceipt> ethGetTransactionReceiptRequest = build.ethGetTransactionReceipt("0xa3e6a0ccc3aac30d866a86ca9c0477dd58b7b061787ba40b16c3844803273816"); +// EthGetTransactionReceipt send = ethGetTransactionReceiptRequest.send(); +// String status = send.getResult().getStatus(); + //System.out.println(status);//0x1 +// EthTransaction send = ethTransactionRequest.send(); +// String input = send.getResult().getInput(); +// System.out.println(input); + EthService ethService = new EthService(); + String s = ethService.tokenSend("0x0cf5f120ea654f6806038daa6b021e83a9ab07c8", "1.0", null); + System.out.println(s); + } + + /** + * + * 方法描述:获取代币余额 + * + * @param fromAddress + * @param + * @param + * @return long + */ + public BigDecimal tokenGetBalance(String fromAddress) { + try { + if(StringUtils.isBlank(fromAddress)){ + fromAddress = TOTAL_ADDRESS; + } + // 合约地址 + String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7"; + int decimal = 6; + String methodName = "balanceOf"; + List<Type> inputParameters = new ArrayList<>(); + List<TypeReference<?>> outputParameters = new ArrayList<>(); + Address address = new Address(fromAddress); + inputParameters.add(address); + TypeReference<Uint256> typeReference = new TypeReference<Uint256>() { + }; + outputParameters.add(typeReference); + Function function = new Function(methodName, inputParameters, outputParameters); + String data = FunctionEncoder.encode(function); + Transaction transaction = Transaction.createEthCallTransaction(fromAddress, contractAddress, data); + + EthCall ethCall; + BigInteger balanceValue = BigInteger.ZERO; + try { + ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send(); + List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters()); + balanceValue = (BigInteger) results.get(0).getValue(); + } catch (IOException e) { + e.printStackTrace(); + } + double res = BigDecimalUtil.div(new BigDecimal(balanceValue).doubleValue(), Math.pow(10, decimal), 8); + if (res > 0) { + return new BigDecimal(res); + } + } catch (Exception e) { + // logger.error("==============以太坊代币链接获取失败!"); + e.printStackTrace(); + } + return BigDecimal.ZERO; + } + + // USDT + public String tokenSend( String toAddress, String amount,String gas) + throws InterruptedException, ExecutionException { + // Web3j web3j = Web3j.build(new + // HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321")); + String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7"; + Credentials credentials = Credentials.create(TOTAL_PRIVATE_KEY); + + EthGetTransactionCount ethGetTransactionCount = web3j + .ethGetTransactionCount(TOTAL_ADDRESS, DefaultBlockParameterName.LATEST).sendAsync().get(); + + BigInteger nonce = ethGetTransactionCount.getTransactionCount(); + + 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); + if(StringUtils.isBlank(gas)){ + gas = "70"; + } + RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, + Convert.toWei(gas, Unit.GWEI).toBigInteger(),// 给矿工开的转账单价 单价越高越快 + Convert.toWei("60000", Unit.WEI).toBigInteger(), contractAddress, encodedFunction);//里程上限 + // 10*80000/1000000000=0.0008 手续费 + + byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); + String hexValue = Numeric.toHexString(signedMessage); + + // log.debug("transfer hexValue:" + hexValue); + + EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get(); + + + if (ethSendTransaction.hasError()) { + // log.info("transfer error:", ethSendTransaction.getError().getMessage()); + return ""; + } else { + String transactionHash = ethSendTransaction.getTransactionHash(); + // log.info("Transfer transactionHash:" + transactionHash); + return transactionHash; + } + } + + public String ethSend(String privateKey, String fromAddress, String toAddress, String amount) + throws InterruptedException, ExecutionException { + // Web3j web3j = Web3j.build(new + // HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321")); + + Credentials credentials = Credentials.create(privateKey); + + EthGetTransactionCount ethGetTransactionCount = web3j + .ethGetTransactionCount(fromAddress, DefaultBlockParameterName.LATEST).sendAsync().get(); + + BigInteger nonce = ethGetTransactionCount.getTransactionCount(); + BigInteger value = Convert.toWei(amount, Unit.ETHER).toBigInteger(); + RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce, + Convert.toWei("50", Unit.GWEI).toBigInteger(), + Convert.toWei("60000", Unit.WEI).toBigInteger(), toAddress, value); + byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); + String hexValue = Numeric.toHexString(signedMessage); + + EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get(); + if (ethSendTransaction.hasError()) { + // log.info("transfer error:", ethSendTransaction.getError().getMessage()); + return ""; + } else { + String transactionHash = ethSendTransaction.getTransactionHash(); + // log.info("Transfer transactionHash:" + transactionHash); + return transactionHash; + } + } + + +} diff --git a/src/main/java/com/xcong/excoin/modules/member/service/IMemberService.java b/src/main/java/com/xcong/excoin/modules/member/service/IMemberService.java index d2c33b9..4cfc73a 100644 --- a/src/main/java/com/xcong/excoin/modules/member/service/IMemberService.java +++ b/src/main/java/com/xcong/excoin/modules/member/service/IMemberService.java @@ -1,6 +1,7 @@ package com.xcong.excoin.modules.member.service; import java.util.List; +import java.util.concurrent.ExecutionException; import javax.validation.Valid; import javax.validation.constraints.NotNull; @@ -46,7 +47,7 @@ IPage<MemberCoinWithdrawVo> findmemberWithdrawCoinListInPage(MemberCoinWithdrawEntity memberCoinWithdrawEntity, QueryRequest request); - FebsResponse memberWithdrawCoinConfirm(@NotNull(message = "{required}") Long id); + FebsResponse memberWithdrawCoinConfirm(@NotNull(message = "{required}") Long id) throws ExecutionException, InterruptedException; FebsResponse memberWithdrawCoinCancel(@NotNull(message = "{required}") Long id); diff --git a/src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java b/src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java index 940b8ca..b7c57c1 100644 --- a/src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java +++ b/src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java @@ -29,6 +29,7 @@ import com.xcong.excoin.modules.member.mapper.MemberMapper; import com.xcong.excoin.modules.member.mapper.MemberQuickBuySaleMapper; import com.xcong.excoin.modules.member.mapper.MemberWalletCoinMapper; +import com.xcong.excoin.modules.member.service.EthService; import com.xcong.excoin.modules.member.service.IMemberService; import com.xcong.excoin.modules.member.service.RocService; import com.xcong.excoin.modules.member.vo.MemberAuthenticationVo; @@ -49,6 +50,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ExecutionException; import javax.validation.Valid; import javax.validation.constraints.NotNull; @@ -452,7 +454,7 @@ @Override @Transactional(rollbackFor = Exception.class) - public FebsResponse memberWithdrawCoinConfirm(@NotNull(message = "{required}") Long id) { + public FebsResponse memberWithdrawCoinConfirm(@NotNull(message = "{required}") Long id) throws ExecutionException, InterruptedException { MemberCoinWithdrawEntity selectById = memberCoinWithdrawMapper.selectById(id); Long memberId = selectById.getMemberId(); @@ -531,6 +533,21 @@ if("ROC".equals(symbol)){ // 如果是ROC 则自动转 String transfer = RocService.transfer(amount, address, "ROC"); + }else if("USDT".equals(symbol) && !"Y".equals(selectById.getIsInside())){ + EthService ethService = new EthService(); + // 查询余额是否足够 + BigDecimal bigDecimal = ethService.tokenGetBalance(EthService.TOTAL_ADDRESS); + if(bigDecimal==null ||bigDecimal.compareTo(amount)<0 ){ + FebsResponse fail = new FebsResponse().fail(); + fail.message("总钱包余额不足"); + return fail; + } + amount = amount.multiply(new BigDecimal("1000000")); + String usdtStr = amount.toPlainString(); + if (usdtStr.contains(".")) { + usdtStr = usdtStr.substring(0, usdtStr.lastIndexOf(".")); + } + String s = ethService.tokenSend(address, usdtStr, null); } /** -- Gitblit v1.9.1