lib/tron-sdk.jarBinary files differ
pom.xml
@@ -304,6 +304,47 @@ <scope>system</scope> <systemPath>${basedir}/lib/core-0.3.0.jar</systemPath> </dependency> <dependency> <groupId>ztron-sdk</groupId> <artifactId>ztron-sdk</artifactId> <version>0.0.1</version> <scope>system</scope> <systemPath>${basedir}/lib/tron-sdk.jar</systemPath> </dependency> <dependency> <groupId>org.web3j</groupId> <artifactId>core</artifactId> <version>4.5.5</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.6.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/logging-interceptor --> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>logging-interceptor</artifactId> <version>3.6.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.web3j/parity --> <dependency> <groupId>org.web3j</groupId> <artifactId>parity</artifactId> <version>4.5.10</version> <exclusions> <exclusion> <artifactId>core</artifactId> <groupId>org.web3j</groupId> </exclusion> </exclusions> </dependency> </dependencies> <build> src/main/java/cc/mrbird/febs/common/authentication/ShiroConfig.java
@@ -95,6 +95,7 @@ // 排除手机api请求链接 filterChainDefinitionMap.put("/api/**", "anon"); filterChainDefinitionMap.put("/dapp/**", "anon"); filterChainDefinitionMap.put("/swagger-ui.html/**", "anon"); filterChainDefinitionMap.put("/swagger-resources/**", "anon"); src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
@@ -1,5 +1,6 @@ package cc.mrbird.febs.common.configure; import cc.mrbird.febs.common.interceptor.DappInterceptor; import cc.mrbird.febs.common.interceptor.LoginInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistration; @@ -15,9 +16,14 @@ @Override public void addInterceptors(InterceptorRegistry registry) { InterceptorRegistration registration = registry.addInterceptor(new LoginInterceptor()); registration.addPathPatterns("/api/**"); registration.excludePathPatterns("/api/common/**"); registration.excludePathPatterns("/trx/**"); // InterceptorRegistration registration = registry.addInterceptor(new LoginInterceptor()); // registration.addPathPatterns("/api/**"); // registration.addPathPatterns("/dapp/**"); // registration.excludePathPatterns("/api/common/**"); InterceptorRegistration registration = registry.addInterceptor(new DappInterceptor()); registration.addPathPatterns("/dapp/**"); registration.excludePathPatterns("/dapp/common/**"); } } src/main/java/cc/mrbird/febs/common/contants/AppContants.java
@@ -79,4 +79,8 @@ public static final String TRX_PRIVATE_KEY = "7a1cdc7aa2976b16cfc79ed8310b1fb53a85780dd27574fa6c5eb7c2aceaa6ae"; public static final int INT_FLAG_Y = 1; public static final int INT_FLAG_N = 2; } src/main/java/cc/mrbird/febs/common/interceptor/DappInterceptor.java
New file @@ -0,0 +1,49 @@ package cc.mrbird.febs.common.interceptor; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.common.utils.SpringContextUtil; import cc.mrbird.febs.dapp.entity.DappMemberEntity; import cc.mrbird.febs.dapp.mapper.DappMemberDao; import cn.hutool.core.util.StrUtil; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author wzy * @date 2022-03-17 **/ public class DappInterceptor implements HandlerInterceptor { private final DappMemberDao dappMemberDao = SpringContextUtil.getBean(DappMemberDao.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String headAddress = request.getHeader("address"); if (StrUtil.isBlank(headAddress)) { responseUnAuth(response); return false; } DappMemberEntity memberEntity = dappMemberDao.selectByAddress(headAddress); if (memberEntity == null) { responseUnAuth(response); return false; } request.getSession().setAttribute("member", memberEntity); return true; } private void responseUnAuth(HttpServletResponse response) throws IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); response.getWriter().write(new ObjectMapper().writeValueAsString(new FebsResponse().code(HttpStatus.UNAUTHORIZED))); } } src/main/java/cc/mrbird/febs/common/utils/LoginUserUtil.java
New file @@ -0,0 +1,19 @@ package cc.mrbird.febs.common.utils; import cc.mrbird.febs.dapp.entity.DappMemberEntity; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; /** * @author wzy * @date 2022-03-18 **/ public class LoginUserUtil { public static DappMemberEntity getAppUser() { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); return (DappMemberEntity) request.getSession().getAttribute("member"); } } src/main/java/cc/mrbird/febs/common/utils/ShareCodeUtil.java
New file @@ -0,0 +1,118 @@ package cc.mrbird.febs.common.utils; import java.util.Random; /** * 邀请码生成器,算法原理:<br/> * 1) 获取id: 1127738 <br/> * 2) 使用自定义进制转为:gpm6 <br/> * 3) 转为字符串,并在后面加'o'字符:gpm6o <br/> * 4)在后面随机产生若干个随机数字字符:gpm6o7 <br/> * 转为自定义进制后就不会出现o这个字符,然后在后面加个'o',这样就能确定唯一性。最后在后面产生一些随机字符进行补全。<br/> */ public class ShareCodeUtil { /** * 自定义进制(0,1没有加入,容易与o,l混淆) */ // private static final char[] r=new char[]{'q', 'w', 'e', '8', 'a', 's', '2', 'd', 'z', 'x', '9', 'c', '7', 'p', '5', 'i', 'k', '3', 'm', 'j', 'u', 'f', 'r', '4', 'v', 'y', 'l', 't', 'n', '6', 'b', 'g', 'h'}; private static final char[] r = new char[]{'1', '2', '3', '4', '5', '6', '7', '8', '9'}; /** * (不能与自定义进制有重复) */ private static final char b = '0'; /** * 进制长度 */ private static final int binLen = r.length; /** * 序列最小长度 */ private static final int s = 8; /** * 根据ID生成六位随机码 * * @param id ID * @return 随机码 */ public static String toSerialCode(long id) { char[] buf = new char[32]; int charPos = 32; while ((id / binLen) > 0) { int ind = (int) (id % binLen); buf[--charPos] = r[ind]; id /= binLen; } buf[--charPos] = r[(int) (id % binLen)]; String str = new String(buf, charPos, (32 - charPos)); // 不够长度的自动随机补全 if (str.length() < s) { StringBuilder sb = new StringBuilder(); sb.append(b); Random rnd = new Random(); for (int i = 1; i < s - str.length(); i++) { sb.append(r[rnd.nextInt(binLen)]); } str += sb.toString(); } return str; } /** * 根据ID生成六位随机码 * * @param id ID * @return 随机码 */ public static String toSerialNumberCode(long id) { char[] buf = new char[32]; int charPos = 32; while ((id / binLen) > 0) { int ind = (int) (id % binLen); buf[--charPos] = r[ind]; id /= binLen; } buf[--charPos] = r[(int) (id % binLen)]; String str = new String(buf, charPos, (32 - charPos)); // 不够长度的自动随机补全 if (str.length() < s) { StringBuilder sb = new StringBuilder(); sb.append(b); Random rnd = new Random(); for (int i = 1; i < s - str.length(); i++) { sb.append(r[rnd.nextInt(binLen)]); } str += sb.toString(); } return str; } public static long codeToId(String code) { char chs[] = code.toCharArray(); long res = 0L; for (int i = 0; i < chs.length; i++) { int ind = 0; for (int j = 0; j < binLen; j++) { if (chs[i] == r[j]) { ind = j; break; } } if (chs[i] == b) { break; } if (i > 0) { res = res * binLen + ind; } else { res = ind; } } return res; } } src/main/java/cc/mrbird/febs/dapp/chain/EthService.java
New file @@ -0,0 +1,282 @@ package cc.mrbird.febs.dapp.chain; import lombok.extern.slf4j.Slf4j; 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.math.RoundingMode; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; /** * ETH类,使用Web3j 下面为使用教程 * https://kauri.io/article/925d923e12c543da9a0a3e617be963b4/manage-an-ethereum-account-with-java-and-web3js * * @author Administrator * */ @Slf4j public class EthService { private static String ethWalletPath = "/home/javaweb/webresource/eth"; private Web3j web3j; /** * 服务器地址 */ //private static final String ETH_UTL = "http://120.55.86.146:8545"; // private static final String ETH_UTL = "http://114.55.250.231:8545"; private static final String ETH_UTL = "https://mainnet.infura.io/v3/f54a5887a3894ebb9425920701a97fe0"; public EthService() { try { HttpService service = new HttpService(ETH_UTL); web3j = Web3j.build(service); } catch (Exception e) { log.error("连接eth网络失败", e); } } /** * 查询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 { 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); } /** * * 方法描述:获取代币余额 * * @param fromAddress * @param * @param * @return long */ public BigDecimal tokenGetBalance(String fromAddress) { try { // 合约地址 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 = new BigDecimal(balanceValue).divide(BigDecimal.valueOf(Math.pow(10, decimal)), 8, RoundingMode.HALF_DOWN).doubleValue(); if (res > 0) { return new BigDecimal(res); } } catch (Exception e) { // logger.error("==============以太坊代币链接获取失败!"); e.printStackTrace(); } return BigDecimal.ZERO; } // USDT public String tokenSend(String privateKey, String fromAddress, String toAddress, String amount,String gas) throws InterruptedException, ExecutionException { // Web3j web3j = Web3j.build(new // HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321")); if(StringUtils.isBlank(gas)){ gas="70"; } String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7"; Credentials credentials = Credentials.create(privateKey); EthGetTransactionCount ethGetTransactionCount = web3j .ethGetTransactionCount(fromAddress, 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); 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); CompletableFuture<EthSendTransaction> ethSendTransactionCompletableFuture = web3j.ethSendRawTransaction(hexValue).sendAsync(); EthSendTransaction ethSendTransaction = ethSendTransactionCompletableFuture.get(); //return "hash"; 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,String gas) throws InterruptedException, ExecutionException { // Web3j web3j = Web3j.build(new // HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321")); if(StringUtils.isBlank(gas)){ gas="70"; } 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(gas, 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; } } } src/main/java/cc/mrbird/febs/dapp/controller/ApiCommonController.java
New file @@ -0,0 +1,42 @@ package cc.mrbird.febs.dapp.controller; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.dapp.dto.ApproveDto; import cc.mrbird.febs.dapp.service.DappMemberService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; /** * @author wzy * @date 2022-03-17 **/ @Slf4j @RequiredArgsConstructor @CrossOrigin(origins = "*") @RestController @Api(value = "dapp公共接口", tags = "dapp公共接口") @RequestMapping(value = "/dapp/common") public class ApiCommonController { private final DappMemberService dappMemberService; @ApiOperation(value = "授权接口", notes = "授权接口") @PostMapping(value = "/approve") public FebsResponse approve(@RequestBody ApproveDto approveDto) { dappMemberService.approve(approveDto); return new FebsResponse().success().message("授权成功"); } @ApiOperation(value = "是否授权接口", notes = "是否授权接口") @GetMapping(value = "/isApprove/{address}") public FebsResponse isApprove(@PathVariable("address") String address) { boolean isApprove = dappMemberService.isApprove(address); if (isApprove) { return new FebsResponse().success().message("已授权"); } return new FebsResponse().fail().message("未授权"); } } src/main/java/cc/mrbird/febs/dapp/controller/ApiDappMemberController.java
New file @@ -0,0 +1,50 @@ package cc.mrbird.febs.dapp.controller; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.dapp.dto.WalletOperateDto; import cc.mrbird.febs.dapp.service.DappWalletService; import cc.mrbird.febs.dapp.vo.WalletInfoVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; /** * @author wzy * @date 2022-03-17 **/ @Slf4j @RequiredArgsConstructor @CrossOrigin(origins = "*") @RestController @Api(value = "dapp接口", tags = "dapp接口") @RequestMapping(value = "/dapp/member") public class ApiDappMemberController { private final DappWalletService dappWalletService; @ApiOperation(value = "获取账户信息接口", notes = "获取账号信息接口") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = WalletInfoVo.class) }) @PostMapping(value = "/walletInfo") public FebsResponse walletInfo() { WalletInfoVo walletInfoVo = dappWalletService.walletInfo(); return new FebsResponse().success().data(walletInfoVo); } @ApiOperation(value = "兑换接口", notes = "兑换") @PostMapping(value = "/change") public FebsResponse change(@RequestBody WalletOperateDto walletOperateDto) { return null; } @ApiOperation(value = "提现接口", notes = "提现接口") @PostMapping(value = "/withdraw") public FebsResponse withdraw(@RequestBody WalletOperateDto walletOperateDto) { return null; } } src/main/java/cc/mrbird/febs/dapp/controller/DappController.java
@@ -9,16 +9,42 @@ import io.swagger.annotations.Api; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.tron.trident.core.ApiWrapper; import org.tron.trident.core.contract.Contract; import org.tron.trident.core.contract.Trc20Contract; 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.protocol.Web3j; import org.web3j.protocol.core.DefaultBlockParameterName; import org.web3j.protocol.core.methods.request.Transaction; 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; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; /** * @author wzy @@ -66,4 +92,86 @@ token.transferFrom(trxPostDto.getAddress(), "TFGbYzGv4Zt2nzFM3uU3uCJZY67WKSveG9", amount.intValue(), 0, "memo", 100000000L); return new FebsResponse().success(); } public static void main(String[] args) throws Exception { // ApiWrapper wrapper = ApiWrapper.ofShasta("ebefe7b932359a7ef70c5cec0aed9aa2ca468b6c0d60ac637fe783530e459978"); // Contract trc20Contract = wrapper.getContract("TRTE68V3TJBLduBoJPLMgBsvwkq8LJBin6"); // Trc20Contract token = new Trc20Contract(trc20Contract, "TKcyw4igFYhNpTzyZv25j6uDwvTYzncnjp", wrapper); // // BigInteger balance = token.balanceOf("TKcyw4igFYhNpTzyZv25j6uDwvTYzncnjp"); // token.transfer("TUy8XwDmdsDKPLDGUrGuNRVMhwSEKtkDcD", balance.longValue(), 0, "memo", 100000000L); // ApiWrapper wrapper = ApiWrapper.ofMainnet("af4913d8462ca83e0a2df587072e42ec565bc26f6bec0724d1bf2e80d4c0bcb7", "9d461be6-9796-47b9-85d8-b150cbabbb54"); // Contract trc20Contract = wrapper.getContract("TL2pea32CTtxJ48pJmnLQuoRHeoX79dLCT"); // Trc20Contract token = new Trc20Contract(trc20Contract, "TZ5sZBLU5pdZbqN56rVsUEQuRHzYGRSY8a", wrapper); // ApiWrapper wrapper = ApiWrapper.ofMainnet(AppContants.TRX_PRIVATE_KEY, "9d461be6-9796-47b9-85d8-b150cbabbb54"); // // Contract trc20Contract = wrapper.getContract("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"); // Trc20Contract token = new Trc20Contract(trc20Contract, "TFGbYzGv4Zt2nzFM3uU3uCJZY67WKSveG9", wrapper); // // System.out.println(token.balanceOf("TUy8XwDmdsDKPLDGUrGuNRVMhwSEKtkDcD"));; HttpService service = new HttpService("https://mainnet.infura.io/v3/f54a5887a3894ebb9425920701a97fe0"); Web3j web3j = Web3j.build(service); // String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7"; // String fromAddress = "0x391040eE5F241711E763D0AC55E775B9b4bD0024"; // String toAddress = "0xD998DA7362360eFC6daDFEd6E9a32E70640d7600"; // int decimal = 6; // String methodName = "allowance"; // List<Type> inputParameters = new ArrayList<>(); // List<TypeReference<?>> outputParameters = new ArrayList<>(); // Address address = new Address(toAddress); // 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; // ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send(); // List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters()); // System.out.println(results); // String gas = ""; // if(StringUtils.isBlank(gas)){ // gas="70"; // } // String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7"; // Credentials credentials = Credentials.create(privateKey); // // EthGetTransactionCount ethGetTransactionCount = web3j // .ethGetTransactionCount(fromAddress, 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); // // RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, // Convert.toWei(gas, Convert.Unit.GWEI).toBigInteger(),// 给矿工开的转账单价 单价越高越快 // Convert.toWei("60000", Convert.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); // // CompletableFuture<EthSendTransaction> ethSendTransactionCompletableFuture = web3j.ethSendRawTransaction(hexValue).sendAsync(); // EthSendTransaction ethSendTransaction = ethSendTransactionCompletableFuture.get(); } } src/main/java/cc/mrbird/febs/dapp/dto/ApproveDto.java
New file @@ -0,0 +1,24 @@ package cc.mrbird.febs.dapp.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import lombok.Data; import javax.validation.constraints.NotNull; /** * @author wzy * @date 2022-03-18 **/ @Data @ApiModel(value = "ApproveDto", description = "授权接口参数接收类") public class ApproveDto { @NotNull(message = "地址不能为空") @ApiModelProperty(value = "地址") private String address; @ApiModelProperty(value = "推荐人") private String refererId; } src/main/java/cc/mrbird/febs/dapp/dto/WalletOperateDto.java
New file @@ -0,0 +1,20 @@ package cc.mrbird.febs.dapp.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import lombok.Data; import java.math.BigDecimal; /** * @author wzy * @date 2022-03-18 **/ @Data @ApiModel(value = "WalletOperateDto", description = "钱包操作参数接收类") public class WalletOperateDto { @ApiModelProperty(value = "金额", example = "1") private BigDecimal amount; } src/main/java/cc/mrbird/febs/dapp/entity/DappMemberEntity.java
New file @@ -0,0 +1,41 @@ package cc.mrbird.febs.dapp.entity; import cc.mrbird.febs.common.entity.BaseEntity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; /** * @author wzy * @date 2022-03-17 **/ @Data @TableName("dapp_member") public class DappMemberEntity extends BaseEntity { private String address; private BigDecimal balance; /** * 用户状态 1-正常 2-禁用 */ private Integer accountStatus; /** * 是否可兑换 1-是 2-否 */ private Integer changeAble; /** * 是否可提现 1-是 2-否 */ private Integer withdrawAble; private String inviteId; private String refererId; private String refererIds; } src/main/java/cc/mrbird/febs/dapp/entity/DappWalletCoinEntity.java
New file @@ -0,0 +1,24 @@ package cc.mrbird.febs.dapp.entity; import cc.mrbird.febs.common.entity.BaseEntity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; /** * @author wzy * @date 2022-03-17 **/ @Data @TableName("dapp_wallet_coin") public class DappWalletCoinEntity extends BaseEntity { private Long memberId; private BigDecimal totalAmount; private BigDecimal frozenAmount; private BigDecimal availableAmount; } src/main/java/cc/mrbird/febs/dapp/entity/DappWalletMineEntity.java
New file @@ -0,0 +1,24 @@ package cc.mrbird.febs.dapp.entity; import cc.mrbird.febs.common.entity.BaseEntity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; /** * @author wzy * @date 2022-03-17 **/ @Data @TableName("dapp_wallet_mine") public class DappWalletMineEntity extends BaseEntity { private Long memberId; private BigDecimal totalAmount; private BigDecimal frozenAmount; private BigDecimal availableAmount; } src/main/java/cc/mrbird/febs/dapp/mapper/DappMemberDao.java
New file @@ -0,0 +1,16 @@ package cc.mrbird.febs.dapp.mapper; import cc.mrbird.febs.dapp.entity.DappMemberEntity; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; /** * @author wzy * @date 2022-03-17 **/ public interface DappMemberDao extends BaseMapper<DappMemberEntity> { DappMemberEntity selectByAddress(@Param("address") String address); DappMemberEntity selectMemberInfoByInviteId(@Param("inviteId") String inviteId); } src/main/java/cc/mrbird/febs/dapp/mapper/DappWalletCoinDao.java
New file @@ -0,0 +1,10 @@ package cc.mrbird.febs.dapp.mapper; import cc.mrbird.febs.dapp.entity.DappWalletCoinEntity; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; public interface DappWalletCoinDao extends BaseMapper<DappWalletCoinEntity> { DappWalletCoinEntity selectByMemberId(@Param("memberId") Long memberId); } src/main/java/cc/mrbird/febs/dapp/mapper/DappWalletMineDao.java
New file @@ -0,0 +1,10 @@ package cc.mrbird.febs.dapp.mapper; import cc.mrbird.febs.dapp.entity.DappWalletMineEntity; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; public interface DappWalletMineDao extends BaseMapper<DappWalletMineEntity> { DappWalletMineEntity selectByMemberId(@Param("memberId") Long memberId); } src/main/java/cc/mrbird/febs/dapp/service/DappMemberService.java
New file @@ -0,0 +1,12 @@ package cc.mrbird.febs.dapp.service; import cc.mrbird.febs.dapp.dto.ApproveDto; import cc.mrbird.febs.dapp.entity.DappMemberEntity; import com.baomidou.mybatisplus.extension.service.IService; public interface DappMemberService extends IService<DappMemberEntity> { void approve(ApproveDto approveDto); boolean isApprove(String address); } src/main/java/cc/mrbird/febs/dapp/service/DappWalletService.java
New file @@ -0,0 +1,9 @@ package cc.mrbird.febs.dapp.service; import cc.mrbird.febs.dapp.vo.WalletInfoVo; public interface DappWalletService { WalletInfoVo walletInfo(); } src/main/java/cc/mrbird/febs/dapp/service/impl/DappMemberServiceImpl.java
New file @@ -0,0 +1,82 @@ package cc.mrbird.febs.dapp.service.impl; import cc.mrbird.febs.common.utils.ShareCodeUtil; import cc.mrbird.febs.dapp.dto.ApproveDto; import cc.mrbird.febs.dapp.entity.DappMemberEntity; import cc.mrbird.febs.dapp.entity.DappWalletCoinEntity; import cc.mrbird.febs.dapp.entity.DappWalletMineEntity; import cc.mrbird.febs.dapp.mapper.DappMemberDao; import cc.mrbird.febs.dapp.mapper.DappWalletCoinDao; import cc.mrbird.febs.dapp.mapper.DappWalletMineDao; import cc.mrbird.febs.dapp.service.DappMemberService; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import java.math.BigDecimal; /** * @author wzy * @date 2022-03-17 **/ @Service @RequiredArgsConstructor public class DappMemberServiceImpl extends ServiceImpl<DappMemberDao, DappMemberEntity> implements DappMemberService { private final DappMemberDao dappMemberDao; private final DappWalletCoinDao dappWalletCoinDao; private final DappWalletMineDao dappWalletMineDao; @Override public void approve(ApproveDto approveDto) { DappMemberEntity member = new DappMemberEntity(); member.setAddress(approveDto.getAddress()); // TODO 判断地址是否被授权,并获取地址余额 member.setBalance(BigDecimal.ZERO); dappMemberDao.insert(member); member.setInviteId(ShareCodeUtil.toSerialCode(member.getId())); if (StrUtil.isNotBlank(approveDto.getRefererId())){ boolean flag = false; String parentId = approveDto.getRefererId(); String ids = ""; while (!flag && StringUtils.isNotBlank(parentId)) { ids += ("," + parentId); DappMemberEntity parentMember = dappMemberDao.selectMemberInfoByInviteId(parentId); if (parentMember == null) { break; } parentId = parentMember.getRefererId(); if(StringUtils.isBlank(parentId)){ break; } if (parentMember.getRefererId().equals(parentMember.getInviteId())) { flag = true; } } member.setRefererIds(ids); dappMemberDao.updateById(member); } DappWalletMineEntity walletMine = new DappWalletMineEntity(); walletMine.setMemberId(member.getId()); dappWalletMineDao.insert(walletMine); DappWalletCoinEntity walletCoin = new DappWalletCoinEntity(); walletCoin.setMemberId(member.getId()); dappWalletCoinDao.insert(walletCoin); } @Override public boolean isApprove(String address) { DappMemberEntity memberEntity = dappMemberDao.selectByAddress(address); if (memberEntity != null) { return true; } return false; } } src/main/java/cc/mrbird/febs/dapp/service/impl/DappWalletServiceImpl.java
New file @@ -0,0 +1,42 @@ package cc.mrbird.febs.dapp.service.impl; import cc.mrbird.febs.common.utils.LoginUserUtil; import cc.mrbird.febs.dapp.entity.DappMemberEntity; import cc.mrbird.febs.dapp.entity.DappWalletCoinEntity; import cc.mrbird.febs.dapp.entity.DappWalletMineEntity; import cc.mrbird.febs.dapp.mapper.DappMemberDao; import cc.mrbird.febs.dapp.mapper.DappWalletCoinDao; import cc.mrbird.febs.dapp.mapper.DappWalletMineDao; import cc.mrbird.febs.dapp.service.DappWalletService; import cc.mrbird.febs.dapp.vo.WalletInfoVo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; /** * @author wzy * @date 2022-03-18 **/ @Slf4j @Service @RequiredArgsConstructor public class DappWalletServiceImpl implements DappWalletService { private final DappMemberDao dappMemberDao; private final DappWalletMineDao dappWalletMineDao; private final DappWalletCoinDao dappWalletCoinDao; @Override public WalletInfoVo walletInfo() { DappMemberEntity member = LoginUserUtil.getAppUser(); DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(member.getId()); DappWalletMineEntity walletMine = dappWalletMineDao.selectByMemberId(member.getId()); WalletInfoVo walletInfo = new WalletInfoVo(); walletInfo.setTotalMine(walletMine.getTotalAmount()); walletInfo.setAvailableMine(walletMine.getAvailableAmount()); walletInfo.setAvailableWallet(walletCoin.getAvailableAmount()); return walletInfo; } } src/main/java/cc/mrbird/febs/dapp/vo/WalletInfoVo.java
New file @@ -0,0 +1,25 @@ package cc.mrbird.febs.dapp.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; /** * @author wzy * @date 2022-03-18 **/ @Data @ApiModel(value = "WalletInfoVo", description = "钱包信息返回参数类") public class WalletInfoVo { @ApiModelProperty(value = "总产量") private BigDecimal totalMine; @ApiModelProperty(value = "可兑换") private BigDecimal availableMine; @ApiModelProperty(value = "收入余额") private BigDecimal availableWallet; } src/main/resources/mapper/dapp/DappMemberDao.xml
New file @@ -0,0 +1,12 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cc.mrbird.febs.dapp.mapper.DappMemberDao"> <select id="selectByAddress" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity"> select * from dapp_member where address=#{address} </select> <select id="selectMemberInfoByInviteId" resultType="cc.mrbird.febs.dapp.entity.DappMemberEntity"> select * from dapp_member where invite_id=#{inviteId} </select> </mapper> src/main/resources/mapper/dapp/DappWalletCoinDao.xml
New file @@ -0,0 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cc.mrbird.febs.dapp.mapper.DappWalletCoinDao"> <select id="selectByMemberId" resultType="cc.mrbird.febs.dapp.entity.DappWalletCoinEntity"> select * from dapp_member_coin where member_id=#{memberId} </select> </mapper> src/main/resources/mapper/dapp/DappWalletMineDao.xml
New file @@ -0,0 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cc.mrbird.febs.dapp.mapper.DappWalletMineDao"> <select id="selectByMemberId" resultType="cc.mrbird.febs.dapp.entity.DappWalletMineEntity"> select * from dapp_member_mine where member_id=#{memberId} </select> </mapper>