From 5174f4b3f43f070dc26ff5c075813163ef8bb7ab Mon Sep 17 00:00:00 2001 From: Helius <wangdoubleone@gmail.com> Date: Mon, 20 Jul 2020 17:30:27 +0800 Subject: [PATCH] Merge branch 'master' of https://gitee.com/chonggaoxiao/new_excoin --- src/main/java/com/xcong/excoin/modules/blackchain/model/XrpTx.java | 69 ---- src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java | 10 src/main/java/com/xcong/excoin/modules/blackchain/service/EosService.java | 84 ++++++ src/main/java/com/xcong/excoin/modules/blackchain/model/EosResult.java | 28 ++ src/main/java/com/xcong/excoin/modules/blackchain/service/XrpService.java | 436 +------------------------------ src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java | 162 +++++++++++ src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java | 4 7 files changed, 312 insertions(+), 481 deletions(-) diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/model/EosResult.java b/src/main/java/com/xcong/excoin/modules/blackchain/model/EosResult.java new file mode 100644 index 0000000..ca0bd19 --- /dev/null +++ b/src/main/java/com/xcong/excoin/modules/blackchain/model/EosResult.java @@ -0,0 +1,28 @@ +package com.xcong.excoin.modules.blackchain.model; + +import lombok.Data; + +/** + * 数据样例 + * EosResult(quantity=2.0000 EOS, memo=aa, from=okbtothemoon, to=biueeostoken, accountActionSeq=2) + */ +@Data +public class EosResult { + /** + * 转账数量 + */ + private String quantity; + + /** + * 转账标记 + */ + private String memo; + private String from; + private String to; + + /** + * 这笔转账对应于这个账户的序号 + */ + private Integer accountActionSeq; + +} diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/model/XrpTx.java b/src/main/java/com/xcong/excoin/modules/blackchain/model/XrpTx.java index 513f593..9b7a883 100644 --- a/src/main/java/com/xcong/excoin/modules/blackchain/model/XrpTx.java +++ b/src/main/java/com/xcong/excoin/modules/blackchain/model/XrpTx.java @@ -1,63 +1,18 @@ package com.xcong.excoin.modules.blackchain.model; +import lombok.Data; + +@Data public class XrpTx { - private String TransactionType; - private Integer Flags; - private Integer Sequence; - private Integer DestinationTag; // 对应的用户标签 - private Integer Amount; // 金额 除以1000000 一百万 - private Integer Fee; // 手续费 - private String Account; // 转账人 - private String Destination; // 收款人(收款人是系统账户 说明是转入) + private String transactionType; + private Integer flags; + private Integer sequence; + private Integer destinationTag; // 对应的用户标签 + private Integer amount; // 金额 除以1000000 一百万 + private Integer fee; // 手续费 + private String account; // 转账人 + private String destination; // 收款人(收款人是系统账户 说明是转入) - public String getTransactionType() { - return TransactionType; - } - public void setTransactionType(String transactionType) { - TransactionType = transactionType; - } - public Integer getFlags() { - return Flags; - } - public void setFlags(Integer flags) { - Flags = flags; - } - public Integer getSequence() { - return Sequence; - } - public void setSequence(Integer sequence) { - Sequence = sequence; - } - public Integer getDestinationTag() { - return DestinationTag; - } - public void setDestinationTag(Integer destinationTag) { - DestinationTag = destinationTag; - } - public Integer getAmount() { - return Amount; - } - public void setAmount(Integer amount) { - Amount = amount; - } - public Integer getFee() { - return Fee; - } - public void setFee(Integer fee) { - Fee = fee; - } - public String getAccount() { - return Account; - } - public void setAccount(String account) { - Account = account; - } - public String getDestination() { - return Destination; - } - public void setDestination(String destination) { - Destination = destination; - } - + } diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/service/EosService.java b/src/main/java/com/xcong/excoin/modules/blackchain/service/EosService.java new file mode 100644 index 0000000..4aad013 --- /dev/null +++ b/src/main/java/com/xcong/excoin/modules/blackchain/service/EosService.java @@ -0,0 +1,84 @@ +package com.xcong.excoin.modules.blackchain.service; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.xcong.excoin.modules.blackchain.model.EosResult; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EosService { + // 正式网络 https://api-v2.eosasia.one https://proxy.eosnode.tools + // 测试网络 https://api-kylin.eosasia.one + // "eosqxyx11111", "5JJB2oiCXwASK9fumjyTgbtHcwDVedVRaZda1kBhFuQcmjnrDWB" + //private final static String account = "huobideposit"; + public final static String ACCOUNT = "biueeostoken"; + // private String account; + private final static String EOS_NAME = "EOS"; + public static final String K_mnemonic = "mnemonic"; + public static final String K_privateKey = "privateKey"; + public static final String K_publicKey = "publicKey"; + private static final String EOS_TOKEN = "eosio.token"; + private static final String ACTION_TRANSFER = "transfer"; + + + public static void main(String[] args) throws Exception { + + List<EosResult> actions = getActions(0, 3); + for(EosResult eosResult:actions){ + System.out.println(eosResult.toString()); + String quantity = eosResult.getQuantity(); + String amountStr = quantity.split("")[0]; + System.out.println(quantity); + System.out.println(new BigDecimal(amountStr)); + } + } + + + /** + * + * @param pos 从第几条开始(包括pos) + * @param offset 查询条数 + * @return + */ + public static List<EosResult> getActions(int pos, int offset) { + JSONObject param = new JSONObject(); + param.put("account_name", ACCOUNT); + param.put("pos", pos); + param.put("offset", offset); + Map<String, String> header = new HashMap<String, String>(); + header.put("content-type", "application/json"); + String res = HttpUtil.post("https://api.eosflare.io/v1/eosflare/get_actions", null, param.toJSONString(), header); + System.out.println(res); + List<EosResult> results = new ArrayList<>(); + try { + + JSONObject jsonObject = JSONObject.parseObject(res); + JSONArray actions = jsonObject.getJSONArray("actions"); + if (actions != null && actions.size() > 0) { + int size = actions.size(); + EosResult eosResult = null; + for (int i = 0; i < size; i++) { + JSONObject jsonObject1 = actions.getJSONObject(i); + // 当前交易序号 + Object account_action_seq = jsonObject1.get("account_action_seq"); + JSONObject action_trace = jsonObject1.getJSONObject("action_trace"); + JSONObject act = action_trace.getJSONObject("act"); + Object account = act.get("account"); + if (!EOS_TOKEN.equals(account)) { + continue; + } + eosResult = JSONObject.parseObject(act.getString("data"), EosResult.class); + eosResult.setAccountActionSeq((Integer) account_action_seq); + results.add(eosResult); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return results; + } +} diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/service/XrpService.java b/src/main/java/com/xcong/excoin/modules/blackchain/service/XrpService.java index 397ce7d..781eee7 100644 --- a/src/main/java/com/xcong/excoin/modules/blackchain/service/XrpService.java +++ b/src/main/java/com/xcong/excoin/modules/blackchain/service/XrpService.java @@ -24,7 +24,10 @@ public class XrpService { - // private //logger //logger = //logger.get//logger(getClass()); + /** + * 平台钱包地址 + */ + public final static String ACCOUNT="rKMGEyjXErL2dx9ck5QXFJVH8onSfHF5gn"; /** * 官方接口地址 */ @@ -32,65 +35,13 @@ private String postUrl = "https://s1.ripple.com:51234"; /** - * 本地nodejs创建钱包地址 + * 结果类型 */ - private static String localUrl = "http://121.40.86.163:1886"; - private String address; - private String password; - - private static final String gasFee = "100"; - private static final String COIN_XRP = "XRP"; - - private final static String RESULT = "result"; - private final static String SUCCESS = "success"; private final static String TES_SUCCESS = "tesSUCCESS"; - private final static String METHOD_GET_TRANSACTION = "/v2/accounts/{0}/transactions"; - private final static String METHOD_GET_BALANCE = "/v2/accounts/{0}/balances"; - private final static String METHOD_POST_SIGN = "sign"; - private final static String METHOD_POST_INDEX = "ledger_current"; - private final static String METHOD_POST_ACCOUNT_INFO = "account_info"; - private final static String METHOD_POST_SUBMIT = "submit"; - public XrpService(String address, String password) { - try { - this.address = address; - this.password = password; - } catch (Exception e) { - e.printStackTrace(); - } - } - public String getAddress() { - return address; - } - public static void main(String[] args) { - // 十分钟查一次 每次100条 - String result = HttpUtil.get("https://data.ripple.com/v2/accounts/rBEXvZL66VvaMzX5R2W5g5xC9Z3D81wkzb/transactions?start=2019-09-01T10:10:00Z"); - JSONObject json = JSONObject.parseObject(result); - XrpTransResult res = json.toJavaObject(XrpTransResult.class); - } - - /** - * 创建钱包 { "xAddress":"X7bpbHDKxS3Mr417RPtgS3TFFHwAHqULXJUVZntHWAKnccw", - * "secret":"snYpXT4wrhi8ve2miSUHUdn9wgzz7", - * "classicAddress":"rsJftGoh49zju51k2LdvUYrzLzJ44XJpXh", - * "address":"rsJftGoh49zju51k2LdvUYrzLzJ44XJpXh" } - * - * @return - */ - public static JSONObject createWallet() { - String res = HttpUtil.get(localUrl); - JSONObject obj = JSONObject.parseObject(res); - return obj; - } - - /** - * 查询交易记录 用于更新用户的余额 本系统的地址:X75MxY8sjcebBasymUXDYcYHWj6v8wqWLGmg9N3x65SXUJw - * https://data.ripple.com/v2/accounts/rBEXvZL66VvaMzX5R2W5g5xC9Z3D81wkzb/transactions - * https://data.ripple.com/v2/accounts/rBEXvZL66VvaMzX5R2W5g5xC9Z3D81wkzb/transactions?start=2019-09-01T10:10:00Z&limit=1 - */ /** * start YYYY-MM-DDThh:mm:ssZ String - Timestamp Start time of query range. The default is the @@ -109,379 +60,22 @@ * returned response. * * https://github.com/ripple/rippled-historical-database + * 接口文档:https://xrpl.org/data-api.html#get-account */ public static XrpTransResult getTransactions(Date start) { - // SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-DDThh:mm:ssZ"); - SimpleDateFormat formatDay = new SimpleDateFormat("YYYY-MM-dd"); - SimpleDateFormat formatHour = new SimpleDateFormat("hh:mm:ss"); - String startTime = formatDay.format(start)+"T"+formatHour.format(start)+"Z"; - String url ="https://data.ripple.com/v2/accounts/X75MxY8sjcebBasymUXDYcYHWj6v8wqWLGmg9N3x65SXUJw/transactions?start="+startTime+"&limit=1000"; - // 十分钟查一次 每次100条 - String result = HttpUtil.get(url); - try { - JSONObject json = JSONObject.parseObject(result); - XrpTransResult res = json.toJavaObject(XrpTransResult.class); - return res; - }catch(Exception e) { - e.printStackTrace(); - } - return null; - } - - /** - * XRP查询余额 - * - * @return - */ - public static double getBalance(String address) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + String startTime = dateFormat.format(start); + String url ="https://data.ripple.com/v2/accounts/"+ACCOUNT+"/transactions?type=Payment&result=tesSUCCESS&limit=100&start="+startTime; + // 十分钟查一次 每次100条 + String result = HttpUtil.get(url); try { - HashMap<String, String> params = new HashMap<String, String>(); - params.put("currency", COIN_XRP); - String re = HttpUtil.jsonGet(getUrl + MessageFormat.format(METHOD_GET_BALANCE, address), params); - if (!StringUtils.isEmpty(re)) { - JSONObject json = JSON.parseObject(re); - if (SUCCESS.equals(json.getString(RESULT))) { - JSONArray array = json.getJSONArray("balances"); - if (array != null && array.size() > 0) { - // 总余额 - double balance = array.getJSONObject(0).getDoubleValue("value"); - if (balance >= 20) { - // 可用余额 xrp会冻结20个币 - return BigDecimalUtil.sub(balance, 20); - } - } - } - } - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币getBalance失败!"); - e.printStackTrace(); - } - return 0.00; - } - - /** - * 发送交易 - * - * @param address - * @param value - * @return - */ - public synchronized String send(String toAddress, double value, String tag) { - try { - String txBlob = this.sign(toAddress, value, tag); - if (StringUtils.isEmpty(txBlob)) { - // logger.error("签名失败:{" + toAddress + "}"); - return null; - } - HashMap<String, Object> params = new HashMap<String, Object>(); - params.put("tx_blob", txBlob); - // 签名 - JSONObject json = doRequest(METHOD_POST_SUBMIT, params); - if (!isError(json)) { - // logger.error("============瑞波币XRP转账返回!json="+json); - JSONObject result = json.getJSONObject(RESULT); - if (result != null) { - if (TES_SUCCESS.equals(result.getString("engine_result"))) { - String hash = result.getJSONObject("tx_json").getString("hash"); - if (!StringUtils.isEmpty(hash)) { - // logger.error("转账成功:toAddress:{" + toAddress + "},value:{" + value + - // "},hash:{" + hash + "}"); - return hash; - } else { - // logger.error( - // "转账失败:toAddress:{" + toAddress + "},value:{" + value + "},hash:{" + hash + - // "}"); - } - } - } - } else { - // logger.error("============瑞波币XRP转账失败!json="+json); - } - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币send失败!"); + JSONObject json = JSONObject.parseObject(result); + XrpTransResult res = json.toJavaObject(XrpTransResult.class); + return res; + }catch(Exception e) { e.printStackTrace(); } return null; - } - - public synchronized String sendOnLine(String toAddress, double value, String tag) { - try { - String txBlob = this.signOnLine(toAddress, value, tag); - if (StringUtils.isEmpty(txBlob)) { - // logger.error("签名失败:{" + toAddress + "}"); - return null; - } - HashMap<String, Object> params = new HashMap<String, Object>(); - params.put("tx_blob", txBlob); - // 签名 - JSONObject json = doRequest(METHOD_POST_SUBMIT, params); - if (!isError(json)) { - // logger.error("============瑞波币XRP转账返回!json="+json); - JSONObject result = json.getJSONObject(RESULT); - if (result != null) { - if (TES_SUCCESS.equals(result.getString("engine_result"))) { - String hash = result.getJSONObject("tx_json").getString("hash"); - if (!StringUtils.isEmpty(hash)) { - // logger.error("转账成功:toAddress:{" + toAddress + "},value:{" + value + - // "},hash:{" + hash + "}"); - return hash; - } else { - // logger.error( - // "转账失败:toAddress:{" + toAddress + "},value:{" + value + "},hash:{" + hash + - // "}"); - } - } - } - } else { - // logger.error("==============瑞波币XRP转账失败!json="+json); - } - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币send失败!"); - e.printStackTrace(); - } - return null; - } - - @Deprecated - public String signOnLine(String toAddress, Double value, String tag) { - try { - // 瑞波币余额存储加六位长度 - value = BigDecimalUtil.mul(value, 1000000); - Integer vInteger = BigDecimal.valueOf(value).intValue(); - JSONObject txJson = new JSONObject(); - txJson.put("Account", address); - txJson.put("Amount", vInteger.toString()); - txJson.put("Destination", toAddress);// 标签 - txJson.put("TransactionType", "Payment"); - txJson.put("DestinationTag", tag); - HashMap<String, Object> params = new HashMap<String, Object>(); - params.put("secret", password); - params.put("tx_json", txJson); - params.put("offline", false); - // 签名 - JSONObject json = doRequest(METHOD_POST_SIGN, params); - if (!isError(json)) { - // logger.error("==============XRP签名返回:"+json); - JSONObject result = json.getJSONObject(RESULT); - if (result != null) { - if (SUCCESS.equals(result.getString("status"))) { - return result.getString("tx_blob"); - } - } - } else { - // logger.error("瑞波币XRP签名失败!json="+json); - } - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币signOnLine失败!"); - e.printStackTrace(); - } - return null; - } - - /** - * 签名 - * - * @param address - * @param value - * @return tx_blob - */ - public String sign(String toAddress, Double value, String tag) { - try { - value = BigDecimalUtil.mul(value, 1000000); - Integer vInteger = BigDecimal.valueOf(value).intValue(); - Map<String, String> map = getAccountSequenceAndLedgerCurrentIndex(); - Payment payment = new Payment(); - payment.as(AccountID.Account, address); - payment.as(AccountID.Destination, toAddress); - payment.as(UInt32.DestinationTag, tag); - payment.as(Amount.Amount, vInteger.toString()); - payment.as(UInt32.Sequence, map.get("accountSequence")); - payment.as(UInt32.LastLedgerSequence, map.get("ledgerCurrentIndex") + 4); - payment.as(Amount.Fee, gasFee); - SignedTransaction signed = payment.sign(password); - if (signed != null) { - return signed.tx_blob; - } - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币sign失败!"); - e.printStackTrace(); - } - return null; - } - - public Map<String, String> getAccountSequenceAndLedgerCurrentIndex() { - try { - HashMap<String, String> params = new HashMap<String, String>(); - params.put("account", address); - params.put("strict", "true"); - params.put("ledger_index", "current"); - params.put("queue", "true"); - JSONObject re = doRequest(METHOD_POST_ACCOUNT_INFO, params); - if (re != null) { - JSONObject result = re.getJSONObject("result"); - if (SUCCESS.equals(result.getString("status"))) { - Map<String, String> map = new HashMap<String, String>(); - map.put("accountSequence", result.getJSONObject("account_data").getString("Sequence")); - map.put("ledgerCurrentIndex", result.getString("ledger_current_index")); - return map; - } - } - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币getAccountSequenceAndLedgerCurrentIndex失败!"); - e.printStackTrace(); - } - return null; - } - - /** - * 获取用户交易序列号 - * - * @return - */ - public long getAccountSequence() { - try { - HashMap<String, String> params = new HashMap<String, String>(); - params.put("account", address); - params.put("strict", "true"); - params.put("ledger_index", "current"); - params.put("queue", "true"); - JSONObject re = doRequest(METHOD_POST_ACCOUNT_INFO, params); - if (re != null) { - JSONObject result = re.getJSONObject("result"); - if (SUCCESS.equals(result.getString("status"))) { - return result.getJSONObject("account_data").getLongValue("Sequence"); - } - } - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币getAccountSequence失败!"); - e.printStackTrace(); - } - return 0L; - } - - /** - * 获取最新序列 - * - * @return - */ - public long getLedgerIndex() { - try { - JSONObject re = doRequest(METHOD_POST_INDEX); - if (re != null) { - JSONObject result = re.getJSONObject("result"); - if (SUCCESS.equals(result.getString("status"))) { - return result.getLongValue("ledger_current_index"); - } - } - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币getLedgerIndex失败!"); - e.printStackTrace(); - } - return 0L; - } - - public String getTransaction(Date dateGMT, String limit) throws ParseException { - try { - HashMap<String, String> params = new HashMap<String, String>(); - params.put("start", DateUtil.formatDate(dateGMT, "yyyy-MM-dd'T'HH:mm:ss")); - params.put("result", "tesSUCCESS"); - params.put("type", "Payment"); - params.put("limit", limit); - return HttpUtil.jsonGet(getUrl + MessageFormat.format(METHOD_GET_TRANSACTION, address), params); - // {"result":"success","count":1,"transactions":[{"hash":"86859CBEFB870C941727E291BB13312BC3D6042D8DA08BF1DEDE6BB55F21B8EC","ledger_index":42268358,"date":"2018-10-16T06:49:30+00:00","tx":{"TransactionType":"Payment","Flags":2147483648,"Sequence":37996,"Amount":"29840000","Fee":"1000","SigningPubKey":"0279154FA62D1F28B6CB1F0264663F19EF3A1718D15363CAC1B47A9C6987231F94","TxnSignature":"304502210089F6526134F335C01C65D3E82284C06E22598A4EAD912604BF4FEAA42D5ACCE402203C044F32D399CEA6F4A16DD6DCBB339A7D0CF76E52C1AB090330A67EDFBABBE4","Account":"rH8yTBLm2SYgcL5HQGDznuNxMiy5ayYcmK","Destination":"raHb1tR1BcNB92nEqxiTuKsDap46szkJG2"},"meta":{"TransactionIndex":1,"AffectedNodes":[{"CreatedNode":{"LedgerEntryType":"AccountRoot","LedgerIndex":"56419B3209DA988033F6F0BD921806B4821A73EDF8C338FB5F06C785E527E967","NewFields":{"Sequence":1,"Balance":"29840000","Account":"raHb1tR1BcNB92nEqxiTuKsDap46szkJG2"}}},{"ModifiedNode":{"LedgerEntryType":"AccountRoot","PreviousTxnLgrSeq":42268355,"PreviousTxnID":"63D5A3121F2706099835D9A3A9E5DA574070A4E08FC70956DB1CC196DE6CDEFC","LedgerIndex":"7D2FC14FA2B344F41BB8A6E10B319301EA1C11705AE159B3E2FA82D9F3079E4C","PreviousFields":{"Sequence":37996,"Balance":"2051629511468"},"FinalFields":{"Flags":131072,"Sequence":37997,"OwnerCount":0,"Balance":"2051599670468","Account":"rH8yTBLm2SYgcL5HQGDznuNxMiy5ayYcmK"}}}],"TransactionResult":"tesSUCCESS","delivered_amount":"29840000"}}]} - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币getBalance失败!"); - e.printStackTrace(); - } - return null; - } - - public Long parseTransaction(String startTm) throws ParseException { - try { - HashMap<String, String> params = new HashMap<String, String>(); - if (!StringUtils.isEmpty(startTm)) { - Date d = new Date(BigDecimalUtil.longAdd(Long.parseLong(startTm), 1000L)); - params.put("start", DateUtil.formatDate(d, "yyyy-MM-dd'T'HH:mm:ss")); - } - params.put("result", "tesSUCCESS"); - params.put("type", "Payment"); - params.put("limit", "1"); - String re = HttpUtil.jsonGet(getUrl + MessageFormat.format(METHOD_GET_TRANSACTION, address), params); - if (!StringUtils.isEmpty(re)) { - JSONObject json = JSON.parseObject(re); - if (SUCCESS.equals(json.getString(RESULT))) { - // marker = json.getString("marker"); - JSONArray transactions = json.getJSONArray("transactions"); - if (transactions != null && transactions.size() > 0) { - for (Object object : transactions) { - JSONObject transaction = (JSONObject) object; - String hash = transaction.getString("hash"); - String dateString = transaction.getString("date"); - Date date = DateUtil.parseDate(dateString, "yyyy-MM-dd'T'HH:mm:ss"); - JSONObject tx = transaction.getJSONObject("tx"); - String destinationTag = tx.getString("DestinationTag"); - if (StringUtils.isEmpty(destinationTag)) { - // logger.info("非用户充值记录"); - return date.getTime(); - } - String to = tx.getString("Destination"); - if (!address.equals(to)) { - // logger.info("非用户充值记录,地址不一致"); - return date.getTime(); - } - // 校验用户是否存在 - /* - * UserEntity user = userService.getUserById(Integer.parseInt( destinationTag)); - * if (user == null) { //logger.info("用户不存在:{}",destinationTag); return - * date.getTime(); } - */ - double amount = tx.getDoubleValue("Amount"); - if (amount > 0) { - amount = BigDecimalUtil.div(amount, 1000000, 6); - } else { - // logger.error("交易金额异常:{" + amount + "}"); - return date.getTime(); - } - // 添加充值记录 - } - } - } - } - } catch (Exception e) { - // logger.error("==============虚拟币-瑞波币parseTransaction失败!"); - e.printStackTrace(); - } - return null; - } - - private boolean isError(JSONObject json) { - if (json == null || (!StringUtils.isEmpty(json.getString("error")) && json.get("error") != "null")) { - return true; - } - return false; - } - - private JSONObject doRequest(String method, Object... params) { - JSONObject param = new JSONObject(); - param.put("id", System.currentTimeMillis() + ""); - param.put("jsonrpc", "2.0"); - param.put("method", method); - if (params != null) { - param.put("params", params); - } - String creb = Base64.encodeBase64String((address + ":" + password).getBytes()); - Map<String, String> headers = new HashMap<>(2); - headers.put("Authorization", "Basic " + creb); - String resp = ""; - try { - resp = HttpUtil.jsonPost(postUrl, headers, param.toJSONString()); - } catch (Exception e) { - // logger.info(e.getMessage()); - if (e instanceof IOException) { - resp = "{}"; - } - } - return JSON.parseObject(resp); } } diff --git a/src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java b/src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java index 4944af5..e617f0a 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java +++ b/src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java @@ -10,4 +10,8 @@ public void updateBtc(); + public void updateEos(); + + public void updateXrp(); + } diff --git a/src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java b/src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java index 0fbce89..ba4e9ad 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java +++ b/src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java @@ -5,9 +5,11 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.xcong.excoin.common.enumerates.CoinTypeEnum; -import com.xcong.excoin.modules.blackchain.service.BtcService; -import com.xcong.excoin.modules.blackchain.service.EthService; -import com.xcong.excoin.modules.blackchain.service.UsdtService; +import com.xcong.excoin.modules.blackchain.model.EosResult; +import com.xcong.excoin.modules.blackchain.model.XrpTransResult; +import com.xcong.excoin.modules.blackchain.model.XrpTransactions; +import com.xcong.excoin.modules.blackchain.model.XrpTx; +import com.xcong.excoin.modules.blackchain.service.*; import com.xcong.excoin.modules.coin.service.BlockCoinService; import com.xcong.excoin.modules.member.dao.MemberCoinAddressDao; import com.xcong.excoin.modules.member.dao.MemberCoinChargeDao; @@ -18,17 +20,23 @@ import com.xcong.excoin.modules.member.entity.MemberEntity; import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity; import com.xcong.excoin.utils.LogRecordUtils; +import com.xcong.excoin.utils.RedisUtils; import com.xcong.excoin.utils.ThreadPoolUtils; import com.xcong.excoin.utils.dingtalk.DingTalkUtils; import com.xcong.excoin.utils.mail.Sms106Send; import com.xcong.excoin.utils.mail.SubMailSend; import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @@ -48,6 +56,13 @@ private MemberCoinChargeDao memberCoinChargeDao; @Resource private MemberWalletCoinDao memberWalletCoinDao; + + @Resource + private RedisUtils redisUtils; + + private final static String EOS_SEQ_KEY="eos_seq_key"; + + private final static String xrp_update_key = "xrp_update_key"; @Transactional(rollbackFor = Exception.class) @Override @@ -250,6 +265,147 @@ } } + @Override + public void updateEos() { + // 获取上次读取的序号 + int pos= 0; + //每次获取的条数 + int offset = 10; + + String eosSeq = redisUtils.getString(EOS_SEQ_KEY); + if(StringUtils.isNotBlank(eosSeq)){ + pos = Integer.valueOf(eosSeq); + } + // 记录最大的seq + int seq = pos; + List<EosResult> actions = EosService.getActions(pos, offset); + if(CollectionUtils.isNotEmpty(actions)){ + for(EosResult eosResult:actions){ + String to = eosResult.getTo(); + Integer accountActionSeq = eosResult.getAccountActionSeq(); + if(accountActionSeq>seq){ + seq = accountActionSeq; + } + if(!EosService.ACCOUNT.equals(to)){ + // 判断是否是收款 + continue; + } + // 处理收款 + String quantity = eosResult.getQuantity(); + String memo = eosResult.getMemo(); + if(StringUtils.isBlank(memo)){ + // 没有标记的跳过 + continue; + } + if(StringUtils.isNotBlank(quantity)){ + // 转账额 + String amountStr = quantity.split("")[0]; + BigDecimal amount = new BigDecimal(amountStr); + List<MemberCoinAddressEntity> memberCoinAddress = memberCoinAddressDao.selectAllBlockAddressBySymbolAndTag(CoinTypeEnum.EOS.name(), memo); + if(CollectionUtils.isNotEmpty(memberCoinAddress)){ + MemberCoinAddressEntity memberCoinAddressEntity = memberCoinAddress.get(0); + // 用户ID + Long memberId = memberCoinAddressEntity.getMemberId(); + MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, CoinTypeEnum.EOS.name()); + if(memberCoinAddressEntity!=null){ + memberWalletCoinDao.updateBlockBalance(memberWalletCoinEntity.getId(),amount,BigDecimal.ZERO,0); + // 添加冲币记录 + String orderNo = insertCoinCharge(EosService.ACCOUNT,memberId,amount,CoinTypeEnum.EOS.name(),memo,BigDecimal.ZERO); + LogRecordUtils.insertMemberAccountMoneyChange(memberId, "转入", amount, CoinTypeEnum.EOS.name(), 1, 1); + + ThreadPoolUtils.sendDingTalk(5); + MemberEntity member = memberDao.selectById(memberId); + if (StrUtil.isNotBlank(member.getPhone())) { + //String amountEos = amountStr + "EOS"; + Sms106Send.sendRechargeMsg(member.getPhone(), DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN), orderNo); + } else { + SubMailSend.sendRechargeMail(member.getEmail(), DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN), orderNo); + } + } + } + } + } + } + // 最后更新seq 即下次查询的起始位置 在本次最大的基础上加一 + if(seq>0 && seq>pos){ + redisUtils.set(EOS_SEQ_KEY,seq+1); + } + } + + public void updateXrp() { + // 首先去查redis上的上次同步时间 + Object lastUpdateTime = redisUtils.get(xrp_update_key); + SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd hh:mm:ss"); + Date start =null; + if(lastUpdateTime==null) { + // 没有 说明是第一次同步 此时从第一天开始同步2020 0716开始 + try { + start = format.parse("2020-07-16 12:00:00"); + } catch (ParseException e) { + e.printStackTrace(); + } + }else { + // 有上次时间 + try { + start = format.parse(lastUpdateTime.toString()); + } catch (ParseException e) { + e.printStackTrace(); + } + } + + // 去查询上次同步时间后的所有记录 + XrpTransResult result = XrpService.getTransactions(start); + // 写入本次更新时间 + String updateTime = format.format(new Date()); + redisUtils.set(xrp_update_key, updateTime); + // 判断有无 + List<XrpTransactions> list = result.getTransactions(); + if(CollectionUtils.isNotEmpty(list)) { + // 不为空 说明有转入记录 + for(XrpTransactions item:list) { + XrpTx data = item.getTx(); + Integer amountOld = data.getAmount(); + // 除以1000000 + BigDecimal amount = new BigDecimal(amountOld).divide(new BigDecimal(1000000)); + Integer memoInt = data.getDestinationTag(); + // 没有标签直接返回 + if(memoInt==null){ + continue; + } + String memo = memoInt.toString(); + String destination = data.getDestination(); + // 判断收款人是不是系统账号 + if(!XrpService.ACCOUNT.equals(destination)){ + continue; + } + List<MemberCoinAddressEntity> memberCoinAddress = memberCoinAddressDao.selectAllBlockAddressBySymbolAndTag(CoinTypeEnum.XRP.name(), memo); + if(CollectionUtils.isNotEmpty(memberCoinAddress)){ + MemberCoinAddressEntity memberCoinAddressEntity = memberCoinAddress.get(0); + // 用户ID + Long memberId = memberCoinAddressEntity.getMemberId(); + MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, CoinTypeEnum.XRP.name()); + if(memberCoinAddressEntity!=null){ + memberWalletCoinDao.updateBlockBalance(memberWalletCoinEntity.getId(),amount,BigDecimal.ZERO,0); + // 添加冲币记录 + String orderNo = insertCoinCharge(XrpService.ACCOUNT,memberId,amount,CoinTypeEnum.XRP.name(),memo,BigDecimal.ZERO); + LogRecordUtils.insertMemberAccountMoneyChange(memberId, "转入", amount, CoinTypeEnum.XRP.name(), 1, 1); + + ThreadPoolUtils.sendDingTalk(5); + MemberEntity member = memberDao.selectById(memberId); + if (StrUtil.isNotBlank(member.getPhone())) { + //String amountEos = amount + "XRP"; + Sms106Send.sendRechargeMsg(member.getPhone(), DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN), orderNo); + } else { + SubMailSend.sendRechargeMail(member.getEmail(), DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN), orderNo); + } + } + } + + } + } + + } + private String generateNo() { // 生成订单号 Long timestamp = System.currentTimeMillis(); diff --git a/src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java b/src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java index e68dd4c..4138bee 100644 --- a/src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java +++ b/src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java @@ -50,4 +50,14 @@ blockCoinService.updateBtc(); } + @Scheduled(cron = "0 4/20 * * * ? ") + public void eosUpdate() { + blockCoinService.updateEos(); + } + + @Scheduled(cron = "0 6/20 * * * ? ") + public void xrpUpdate() { + blockCoinService.updateXrp(); + } + } -- Gitblit v1.9.1