去除定时器上链代码

pull/1/head
luojianheng 5 years ago
parent 9c9fe6075c
commit 4fb4f8915a
  1. 53
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/util/BtcAddressSetRedisUtils.java
  2. 43
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/util/BtcBlockRedisUtils.java
  3. 35
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/mapper/BtcBlockNumberMapper.java
  4. 14
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/mapper/BtcWalletKeyMapper.java
  5. 44
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/rpc/BtcOmniRpcClient.java
  6. 553
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/rpc/BtcUtils.java
  7. 113
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/rpc/UsdtUtils.java
  8. 280
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/scheduleTask/RechargeBtcAndUsdtBlockTimer.java
  9. 86
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/scheduleTask/WallertTimerTask.java
  10. 40
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/service/BtcBlockNumberService.java
  11. 7
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/service/BtcWalletKeyService.java
  12. 10
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/service/BtcWalletTransferService.java
  13. 68
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/service/impl/BtcBlockNumberServiceImpl.java
  14. 33
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/service/impl/BtcWalletKeyServiceImpl.java
  15. 29
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/service/impl/BtcWalletServiceImpl.java
  16. 39
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/service/impl/BtcWalletTransferServiceImpl.java
  17. 27
      blockchain-server/blockchain-server-btc/src/main/resources/mapper/BtcBlockNumberMapper.xml
  18. 11
      blockchain-server/blockchain-server-btc/src/main/resources/mapper/BtcWalletKeyMapper.xml
  19. 178
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/common/util/EosUtil.java
  20. 66
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/mapper/BlockNumberMapper.java
  21. 6
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/mapper/TokenMapper.java
  22. 13
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/mapper/WalletInMapper.java
  23. 54
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/scheduleTask/TransferDisposeTimerTask.java
  24. 64
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/scheduleTask/WallertTimerTask.java
  25. 59
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/EosBlockNumberService.java
  26. 6
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/EosTokenService.java
  27. 13
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/EosWalletInService.java
  28. 31
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/EosWalletService.java
  29. 47
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/EosWalletTransferService.java
  30. 48
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/EosWalletUtilService.java
  31. 2
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/impl/EosApplicationServiceImpl.java
  32. 201
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/impl/EosBlockNumberServiceImpl.java
  33. 12
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/impl/EosTokenServiceImpl.java
  34. 56
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/impl/EosWalletInServiceImpl.java
  35. 73
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/impl/EosWalletServiceImpl.java
  36. 96
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/impl/EosWalletTransferServiceImpl.java
  37. 109
      blockchain-server/blockchain-server-eos/src/main/java/com/blockchain/server/eos/service/impl/EosWalletUtilServiceImpl.java
  38. 55
      blockchain-server/blockchain-server-eos/src/main/resources/mapper/BlockNumberMapper.xml
  39. 4
      blockchain-server/blockchain-server-eos/src/main/resources/mapper/TokenMapper.xml
  40. 14
      blockchain-server/blockchain-server-eos/src/main/resources/mapper/WalletInMapper.xml
  41. 9
      blockchain-server/blockchain-server-eos/src/main/resources/mapper/WalletMapper.xml
  42. 141
      blockchain-server/blockchain-server-eth/src/main/java/com/blockchain/server/eth/scheduleTask/EthTxInTimerTask.java
  43. 116
      blockchain-server/blockchain-server-eth/src/main/java/com/blockchain/server/eth/scheduleTask/EthWallertTimerTask.java
  44. 80
      blockchain-server/blockchain-server-eth/src/main/java/com/blockchain/server/eth/service/IEthBlockNumberService.java
  45. 205
      blockchain-server/blockchain-server-eth/src/main/java/com/blockchain/server/eth/service/impl/EthBlockNumberServiceImpl.java
  46. 27
      blockchain-server/blockchain-server-eth/src/main/resources/mapper/EthBlockNumberMapper.xml

@ -1,53 +0,0 @@
package com.blockchain.server.btc.common.util;
import com.blockchain.server.btc.common.constants.BtcAddressConstans;
import com.blockchain.server.btc.service.BtcWalletService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Set;
@Component
public class BtcAddressSetRedisUtils {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private BtcWalletService btcWalletService;
/**
* 保存地址集合到redis
*
* @param address 新增地址
*/
public void insert(String address) {
redisTemplate.opsForSet().add(BtcAddressConstans.BTC_ADDRESS_KEY, address);
}
/**
* 从redis中获取地址集合
*
* @return
*/
public Set<String> get() {
return redisTemplate.opsForSet().members(BtcAddressConstans.BTC_ADDRESS_KEY);
}
/**
* 判断缓存中是否存在该地址
*
* @param addr 地址
* @return
*/
public boolean isExistsAddr(String addr) {
Set<String> addressSet = get();
if (addressSet == null || addressSet.size() == 0) {
addressSet = btcWalletService.getAllWalletAddr();
redisTemplate.opsForSet().add(BtcAddressConstans.BTC_ADDRESS_KEY, addressSet.toArray());
}
return addressSet.contains(addr);
}
}

@ -1,43 +0,0 @@
package com.blockchain.server.btc.common.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class BtcBlockRedisUtils {
@Autowired
private RedisTemplate redisTemplate;
private static final String ETH_BLOCKCHAIN_OPT_HASH = "btc:blockchain:opt:block";
/**
* 根据区块高度获取爬取的次数
*
* @param blockHeight 区块高度
* @return
*/
public int getBlockOptMapCount(int blockHeight) {
Integer val = (Integer) redisTemplate.opsForHash().get(ETH_BLOCKCHAIN_OPT_HASH, blockHeight);
return val != null ? val : 0;
}
/**
* 爬取次数加1
*
* @param blockHeight 区块高度
*/
public void incrementBlockOptMapCount(int blockHeight) {
redisTemplate.opsForHash().increment(ETH_BLOCKCHAIN_OPT_HASH, blockHeight, 1);
}
/**
* 移除区块的爬取记录
*
* @param blockHeight 区块高度
*/
public void delBlockOptMapCount(int blockHeight) {
redisTemplate.opsForHash().delete(ETH_BLOCKCHAIN_OPT_HASH, blockHeight);
}
}

@ -1,35 +0,0 @@
package com.blockchain.server.btc.mapper;
import com.blockchain.server.btc.dto.BtcBlockNumberDTO;
import com.blockchain.server.btc.entity.BtcBlockNumber;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
/**
* BtcBlockNumberMapper 数据访问类
*
* @version 1.0
* @date 2019-02-16 15:08:16
*/
@Repository
public interface BtcBlockNumberMapper extends Mapper<BtcBlockNumber> {
/**
* 查询已经同步的最大区块号
*
* @return
*/
Integer selectBigest();
/**
* 根据状态获取同步区块
*
* @param status 状态
* @return
*/
List<BtcBlockNumberDTO> listByStatus(@Param("status") String status);
}

@ -1,14 +0,0 @@
package com.blockchain.server.btc.mapper;
import com.blockchain.server.btc.entity.BtcWalletKey;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
/**
* BtcWalletKeyMapper 数据访问类
* @date 2019-02-16 15:08:16
* @version 1.0
*/
@Repository
public interface BtcWalletKeyMapper extends Mapper<BtcWalletKey> {
}

@ -1,44 +0,0 @@
package com.blockchain.server.btc.rpc;
import com.googlecode.jsonrpc4j.JsonRpcHttpClient;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
/**
* @author hugq
* @date 2019/2/16 15:54
*/
@Component
public class BtcOmniRpcClient {
private Logger LOG = LoggerFactory.getLogger(getClass());
@Value("${btc.rpc.user}")
public String RPC_USER; //验证用户名
@Value("${btc.rpc.password}")
public String RPC_PASSWORD; //验证密码
@Value("${btc.rpc.url}")
public String RPC_URL; //验证地址
// 比特币RPC身份认证
public JsonRpcHttpClient getClient() {
JsonRpcHttpClient client = null;
try {
String cred = new Base64().encodeToString((RPC_USER + ":" + RPC_PASSWORD).getBytes("UTF-8"));
Map<String, String> headers = new HashMap<String, String>(1);
headers.put("Authorization", "Basic " + cred);
client = new JsonRpcHttpClient(new URL(RPC_URL), headers);
} catch (Exception e) {
LOG.info("=== getClient:{} btc client !===", e.getMessage(), e);
}
return client;
}
}

@ -1,553 +0,0 @@
package com.blockchain.server.btc.rpc;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.server.btc.common.enums.BtcEnums;
import com.blockchain.server.btc.common.exception.BtcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* @author hugq
* @date 2019/2/16 15:54
*/
@Component
public class BtcUtils {
private Logger LOG = LoggerFactory.getLogger(getClass());
@Autowired
private BtcOmniRpcClient client;
/**
* 生成新的钱包地址
*
* @return
* @throws Exception
*/
public String getNewAddress() throws Exception {
try {
return client.getClient().invoke("getnewaddress", null, String.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.getNewAddress(String):{} ===", e.getMessage(), e);
throw new BtcException(BtcEnums.GET_NEW_ADDRESS_ERROR);
}
}
/**
* 获取地址的未花费列表
*
* @param address 地址
* @return
* @throws Exception
*/
public JSONArray listUnspent(String address) throws Exception {
try {
return client.getClient().invoke("listunspent", new Object[]{1, Integer.MAX_VALUE, new Object[]{address}}, JSONArray.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.listUnspent(String):{} ===", e.getMessage(), e);
throw new BtcException(BtcEnums.LIST_UNSPENT_ERROR);
}
}
/**
* 验证是否有效地址
*
* @param address 地址
* @return
* @throws Exception
*/
public JSONObject validateAddress(String address) throws Exception {
try {
return client.getClient().invoke("validateaddress", new Object[]{address}, JSONObject.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.validateAddress(String):{} ===", e.getMessage(), e);
throw new BtcException(BtcEnums.ADDRESS_ERROR);
}
}
/**
* 获取指定账户/整个钱包BTC余额
*
* @param account 账户名为空则获取整个钱包余额
* @return
* @throws Exception
*/
public double getBalance(String account) throws Exception {
double balance;
try {
if (!StringUtils.isEmpty(account)) {
balance = client.getClient().invoke("getbalance", new Object[]{account}, Double.class);
} else {
balance = client.getClient().invoke("getbalance", new Object[]{}, Double.class);
}
} catch (Throwable e) {
LOG.info("=== BtcUtils.getBalance(String...):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: account=%s", account));
}
return balance;
}
/**
* 从钱包内向指定的地址发送指定数量的比特币简单交易钱包内随机指定或创建地址作为发送地址找零地址
*
* @param toAddress 地址
* @param amount 数量
* @return 交易ID
* @throws Exception
*/
public String sendToAddress(String toAddress, String amount) throws Exception {
try {
return client.getClient().invoke("sendtoaddress", new Object[]{toAddress, amount}, String.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.sendtoaddress(String, double):{} ===", e.getMessage(), e);
throw new BtcException(BtcEnums.SENDTOADDRESS_ERROR);
}
}
public Object sendMany(String fromaccount, Object target) throws Exception {
try {
String txId = client.getClient().invoke("sendmany", new Object[]{fromaccount, target}, Object.class).toString();
return txId;
} catch (Throwable e) {
LOG.info("=== BtcUtils.signSendToAddress(String, double):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: fromaccount=%s,target=%s", fromaccount, target));
}
}
public Object getRawTransaction(String txId, int verbose) throws Exception {
try {
return client.getClient().invoke("getrawtransaction", new Object[]{txId, verbose}, Object.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.getRawTransaction(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: txId=%s", txId));
}
}
/**
* 获取指定钱包内交易的详细信息
*
* @param txId 交易ID
* @return
* @throws Exception
*/
public JSONObject getTransaction(String txId) throws Exception {
try {
return client.getClient().invoke("gettransaction", new Object[]{txId}, JSONObject.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.getTransaction(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: txId=%s", txId));
}
}
public Object setAccount(String address, String account) throws Exception {
try {
return client.getClient().invoke("setaccount", new Object[]{address, account}, Object.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.setAccount(String, String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: address=%s,account=%s", address, account));
}
}
/**
* 调用返回各地址收到的比特币数量
*
* @param minconf 计入统计结果的交易所需的最小确认数默认值1
* @return
* @throws Exception
*/
public Object listReceivedByAddress(int minconf) throws Exception {
try {
return client.getClient().invoke("listreceivedbyaccount", new Object[]{minconf}, Object.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.listReceivedByAddress(int minconf):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: minconf=%s", minconf));
}
}
/**
* 调用设置钱包交易支付时采用的每千字节手续费率
*
* @param account 每千字节的手续费
* @return true
* @throws Exception
*/
public boolean setTxFee(double account) throws Exception {
try {
return client.getClient().invoke("settxfee", new Object[]{account + ""}, Boolean.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.settxfee(double):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: account=%s", account));
}
}
public Object encryptWallet(String passphrase) throws Exception {
try {
return client.getClient().invoke("encryptwallet", new Object[]{passphrase}, Object.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.encryptwallet(String) ===", e.getMessage(), e);
throw new Exception(e.getMessage());
}
}
public Object walletPassphrase(String passphrase, int timeout) throws Exception {
try {
return client.getClient().invoke("walletpassphrase", new Object[]{passphrase, timeout}, Object.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.walletpassphrase(String, int):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: passphrase=%s,timeout=%s", passphrase, timeout));
}
}
/**
* 调用可以将钱包文件wallet.data安全地拷贝到指定文件或目录
*
* @param destination 备份文件路径名称
* @return 成功时返回null
* @throws Exception
*/
public boolean backupWallet(String destination) throws Exception {
try {
Object obj = client.getClient().invoke("backupwallet ", new Object[]{destination}, Object.class);
return obj == null;
} catch (Throwable e) {
LOG.info("=== BtcUtils.backupWallet(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: destination=%s", destination));
}
}
/**
* 调用可以导入钱包转储文件通过dumpwallet调用获得该文件中的私钥将添加到节点钱包中由于加入了新的私钥该调用可能 需要重新扫描区块链
*
* @param filename 要导入的钱包转储文件名
* @return
* @throws Exception
*/
public boolean importWallet(String filename) throws Exception {
try {
Object obj = client.getClient().invoke("importwallet ", new Object[]{filename}, Object.class);
return obj == null;
} catch (Throwable e) {
LOG.info("=== BtcUtils.importWallet(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: filename=%s", filename));
}
}
/**
* 创建一个未签名的裸交易
*
* @param utxo 交易输入数组,成员对象的结构: UTXO的交易id, UTXO的输出序号
* @param toAddress 交易输出对象键为地址
* @param amonut 交易输出对象值为金额
* @return 返回生成的未签名交易的序列化字符串
* @throws Exception
*/
public String createRawTransaction(Object utxo, String toAddress, double amonut) throws Exception {
String _amount = String.valueOf(amonut);
Map<String, String> outputs = new HashMap();
outputs.put(toAddress, _amount);
try {
return client.getClient().invoke("createrawtransaction", new Object[]{utxo, outputs}, String.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.createRawTransaction(Object):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: inputs=%s,outputs=%s", utxo.toString(), outputs.toString()));
}
}
/**
* 为裸交易交易增加输入主要用于指定找零地址
*
* @param hexString 裸交易字符串
* @param address 额外的可选项结构: changeAddress找零地址如果不设置则自动从地址池中选择一个新地址
* @return 返回更新后的交易信息
* @throws Exception
*/
public String fundRawTransaction(String hexString, String address) throws Exception {
Map<String, String> outputs = new HashMap();
outputs.put("changeAddress", address);
try {
JSONObject jsonObject = client.getClient().invoke("fundrawtransaction", new Object[]{hexString, outputs}, JSONObject.class);
return jsonObject.getString("hex");
} catch (Throwable e) {
LOG.info("=== BtcUtils.fundRawTransaction(Object):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: hexString=%s,outputs=%s", hexString, outputs.toString()));
}
}
/**
* 签名交易
*
* @param hexString 交易串
* @return
* @throws Exception
*/
public String signRawTransaction(String hexString) throws Exception {
try {
JSONObject jsonObject = client.getClient().invoke("signrawtransaction", new Object[]{hexString}, JSONObject.class);
return jsonObject.getString("hex");
} catch (Throwable e) {
LOG.info("=== BtcUtils.signrawTransaction(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: hexstring=%s", hexString));
}
}
/**
* 调用验证指定交易并将其广播到P2P网络中
*
* @param hexHash 序列化的交易码流
* @return
* @throws Exception
*/
public String sendRawTransaction(String hexHash) throws Exception {
try {
return client.getClient().invoke("sendrawtransaction", new Object[]{hexHash}, String.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.sendRawTransaction(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: hexHash=%s", hexHash));
}
}
/**
* 调用将一个序列化的交易字符串解码为JSON对象
*
* @param hex 要解码的裸交易字符串
* @return
* @throws Exception
*/
public JSONObject decodeRawTransaction(String hex) throws Exception {
try {
return client.getClient().invoke("decoderawtransaction", new Object[]{hex}, JSONObject.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.decoderawtransaction(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: hex=%s", hex));
}
}
/**
* 通过区块高度获取该区块hash
*
* @param index
* @return
* @throws Exception
*/
public String getBlockHash(int index) throws Exception {
try {
return client.getClient().invoke("getblockhash", new Object[]{index}, String.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.getBlockHash(int):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: index=%s", index));
}
}
/**
* 获取最新区块高度
*
* @return
* @throws Exception
*/
public Integer getBlockCount() throws Exception {
try {
return client.getClient().invoke("getblockcount", null, Integer.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.getBlockHeader():{} ===", e.getMessage(), e);
throw new Exception(e.getMessage());
}
}
/**
* 获取区块内交易id列表集合
*
* @param blockHash 区块hash
* @return
* @throws Exception
*/
public ArrayList<String> getBlock(String blockHash) throws Exception {
try {
JSONObject blockJson = client.getClient().invoke("getblock", new Object[]{blockHash}, JSONObject.class);
return (ArrayList<String>) blockJson.get("tx");
} catch (Throwable e) {
LOG.info("=== BtcUtils.getblock(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: blockHash=%s", blockHash));
}
}
/**
* 通过地址获取私钥
*
* @param address 地址
* @return
* @throws Exception
*/
public String getPrivateKeyByAddress(String address) throws Exception {
try {
return client.getClient().invoke("dumpprivkey", new Object[]{address}, String.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.getPrivateKeyByAddress(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: blockHash=%s", address));
}
}
/**
* 通过区块hash获取区块高度
*
* @param headerHash 区块hash
* @return
* @throws Exception
*/
public int getBlockHeader(String headerHash) throws Exception {
try {
JSONObject blockObject = client.getClient().invoke("getblockheader", new Object[]{headerHash}, JSONObject.class);
return blockObject.getInteger("height");
} catch (Throwable e) {
LOG.info("=== BtcUtils.getBlockHeader(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: headerHash=%s", headerHash));
}
}
/**
* 调用返回指定区块之后发生的与钱包相关的所有交易
*
* @param headerHash 区块hash
* @return
* @throws Exception
*/
public JSONArray listSinceBlock(String headerHash) throws Exception {
try {
JSONObject blockObject = client.getClient().invoke("listsinceblock", new Object[]{headerHash}, JSONObject.class);
return blockObject.getJSONArray("transactions");
} catch (Throwable e) {
LOG.info("=== BtcUtils.listSinceBlock(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: headerHash=%s", headerHash));
}
}
/**
* 用裸交易方式进行转账可以指定找零地址没有指定则默认输出地址
*
* @param fromAddress 输出地址
* @param toAddress 收入地址
* @param amonut 数量
* @param changeAddress 找零地址
* @return
* @throws Exception
*/
public String sendWithRaw(String fromAddress, String toAddress, double amonut, String changeAddress) throws Exception {
String txId = "";
//如果没指定找零地址则默认输出地址
if (StringUtils.isEmpty(changeAddress)) {
changeAddress = fromAddress;
}
try {
//获取输出地址的UTXO
JSONArray UTXOArr = listUnspent(fromAddress);
//创建裸交易
String hexString = createRawTransaction(UTXOArr, toAddress, amonut);
//指定找零地址
String fundHexString = fundRawTransaction(hexString, changeAddress);
//签名交易
String signHex = signRawTransaction(fundHexString);
//广播交易
txId = sendRawTransaction(signHex);
} catch (Throwable e) {
LOG.info("=== BtcUtils.sendWithRaw(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: fromAddress=%s,toAddress=%s,amonut=%s,changeAddress=%s", fromAddress, toAddress, amonut, changeAddress));
}
return txId;
}
/**
* 调用返回节点钱包中未确认总余额
*
* @return
* @throws Exception
*/
public double getUnconfirmedBalance() throws Exception {
try {
return client.getClient().invoke("getunconfirmedbalance", null, Double.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.getUnconfirmedBalance():{} ===", e.getMessage(), e);
throw new Exception(e.getMessage());
}
}
/**
* 调用按地址分组显示余额信息
*
* @return
* @throws Exception
*/
public JSONArray listAddressGroupings() throws Exception {
try {
return client.getClient().invoke("listaddressgroupings", null, JSONArray.class);
} catch (Throwable e) {
LOG.info("=== BtcUtils.listaddressgroupings():{} ===", e.getMessage(), e);
throw new Exception(e.getMessage());
}
}
/**
* 通过地址获取BTC余额
*
* @param addr 地址
* @return
* @throws Exception
*/
public double getBalanceByAddr(String addr) throws Exception {
try {
JSONArray jsonArray = listAddressGroupings();
for (int i = 0; i < jsonArray.size(); i++) {
JSONArray groupArr = jsonArray.getJSONArray(i);
for (int j = 0; j < groupArr.size(); j++) {
JSONArray addrArr = groupArr.getJSONArray(j);
String addrThis = addrArr.getString(0);
if (addr.equals(addrThis)) {
return addrArr.getDoubleValue(1);
}
}
}
return 0.0;
// double balance = 0;
// JSONArray jsonArray = listUnspent(addr);
// int len = jsonArray.size();
// for (int i = 0; i < len; i++) {
// JSONObject jsonObject = jsonArray.getJSONObject(i);
// balance += jsonObject.getDoubleValue("amount");
// }
// return balance;
} catch (Throwable e) {
LOG.info("=== BtcUtils.getBalanceByAddr(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: addr=%s", addr));
}
}
/**
* 调用暂时锁定/解锁指定的交易输出一个被锁定的交易输出将不会被自动选中作为交易输入锁定仅保持在内存中因此节点重新启动后将自动解除锁定
*
* @return
* @throws Exception
*/
public void unLockUnspent() throws Exception {
try {
//调用返回当前暂时不可用(锁定)的UTXO清单
JSONArray jsonArray = client.getClient().invoke("listlockunspent", null, JSONArray.class);
if (jsonArray.size() > 0) {
//解锁之前被锁定的交易输出项,设置为true解锁交易输出,否则加锁
client.getClient().invoke("lockunspent", new Object[]{true, jsonArray});
}
} catch (Throwable e) {
LOG.info("=== BtcUtils.unLockUnspent():{} ===", e.getMessage(), e);
throw new Exception(e.getMessage());
}
}
}

@ -1,113 +0,0 @@
package com.blockchain.server.btc.rpc;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.server.btc.common.constants.UsdtConstans;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author hugq
* @date 2019/2/16 15:54
*/
@Component
public class UsdtUtils {
private Logger LOG = LoggerFactory.getLogger(getClass());
@Autowired
private BtcOmniRpcClient client;
/**
* 创建并广播发送一个简单usdt交易
*
* @param fromAddress 发起地址
* @param toAddress 接受地址
* @param amount 数量
* @return 返回结果为16进制字符串表示的交易哈希
* @throws Exception
*/
public String send(String fromAddress, String toAddress, double amount) throws Exception {
String _amount = String.valueOf(amount);
try {
return client.getClient().invoke("omni_send", new Object[]{fromAddress, toAddress, UsdtConstans.USDT_PROPERTY_ID, _amount}, String.class);
} catch (Throwable e) {
LOG.info("=== BtcOmniUtils.send(String fromAddress, String toAddress, double amount):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: fromAddress=%s,toAddress=%s,amount=%s", fromAddress, toAddress, _amount));
}
}
/**
* 创建并广播发送一个简单usdt交易指定支付手续费地址
*
* @param fromAddress 发起地址
* @param toAddress 接受地址
* @param amount 数量
* @param feeAddress 支付手续费的地址
* @return 返回结果为16进制字符串表示的交易哈希
* @throws Exception
*/
public String fundedSend(String fromAddress, String toAddress, double amount, String feeAddress) throws Exception {
String _amount = String.valueOf(amount);
try {
return client.getClient().invoke("omni_funded_send", new Object[]{fromAddress, toAddress, UsdtConstans.USDT_PROPERTY_ID, _amount, feeAddress}, String.class);
} catch (Throwable e) {
LOG.info("=== BtcOmniUtils.fundedSend(String fromAddress, String toAddress, double amount, String feeaddress):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: fromAddress=%s,toAddress=%s,propertyId=%s,amount=%s,feeaddress=%s", fromAddress, toAddress, UsdtConstans.USDT_PROPERTY_ID, amount, feeAddress));
}
}
/**
* 调用创建并广播一个交易将所有可用代币转入指定生态系统中的接收地址
*
* @param fromAddress 发起地址
* @param toAddress 接受地址
* @param ecosystem 生态系统编码数值1 - 主生态2 - 测试生态
* @param feeaddress 支付手续费的地址
* @return 返回结果为16进制字符串表示的交易哈希
* @throws Exception
*/
public String fundedSendAll(String fromAddress, String toAddress, int ecosystem, String feeaddress) throws Exception {
try {
return client.getClient().invoke("omni_funded_sendall", new Object[]{fromAddress, toAddress, ecosystem, feeaddress}, String.class);
} catch (Throwable e) {
LOG.info("=== BtcOmniUtils.fundedSendAll(String fromAddress, String toAddress, int ecosystem, String feeaddress):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: fromAddress=%s,toAddress=%s,ecosystem=%s,feeaddress=%s", fromAddress, toAddress, ecosystem, feeaddress));
}
}
/**
* 调用返回指定地址和资产的代币余额
*
* @param address 地址
* @return
* @throws Exception
*/
public double getBalance(String address) throws Exception {
try {
JSONObject balanceJson = client.getClient().invoke("omni_getbalance", new Object[]{address, UsdtConstans.USDT_PROPERTY_ID}, JSONObject.class);
return balanceJson.getDoubleValue("balance");
} catch (Throwable e) {
LOG.info("=== BtcOmniUtils.getBalance(String address):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: address=%s", address));
}
}
/**
* 获取指定Omni交易的详细信息
*
* @param txId 交易哈希
* @return
* @throws Exception
*/
public JSONObject getTransaction(String txId) throws Exception {
try {
return client.getClient().invoke("omni_gettransaction", new Object[]{txId}, JSONObject.class);
} catch (Throwable e) {
LOG.info("=== BtcOmniUtils.getTransaction(String):{} ===", e.getMessage(), e);
throw new Exception(e.getMessage() + String.format("[params]: txId=%s", txId));
}
}
}

@ -1,280 +0,0 @@
package com.blockchain.server.btc.scheduleTask;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.server.btc.common.constants.BtcBlockNumberConstans;
import com.blockchain.server.btc.common.constants.BtcConstans;
import com.blockchain.server.btc.common.constants.BtcTransferConstans;
import com.blockchain.server.btc.common.constants.UsdtConstans;
import com.blockchain.server.btc.common.util.BtcAddressSetRedisUtils;
import com.blockchain.server.btc.common.util.BtcBlockRedisUtils;
import com.blockchain.server.btc.dto.BtcBlockNumberDTO;
import com.blockchain.server.btc.entity.BtcWalletTransfer;
import com.blockchain.server.btc.rpc.BtcUtils;
import com.blockchain.server.btc.rpc.UsdtUtils;
import com.blockchain.server.btc.service.BtcBlockNumberService;
import com.blockchain.server.btc.service.BtcWalletTransferService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.UUID;
//@Component
public class RechargeBtcAndUsdtBlockTimer {
@Autowired
private BtcAddressSetRedisUtils btcAddressSetRedisUtils;
@Autowired
private BtcBlockRedisUtils btcBlockRedisUtils;
@Autowired
private BtcUtils btcUtils;
@Autowired
private UsdtUtils usdtUtils;
@Autowired
private BtcBlockNumberService btcBlockNumberService;
@Autowired
private BtcWalletTransferService btcWalletTransferService;
/**
* 查询区块链充值信息
*/
@Scheduled(cron = "0/30 * * * * ?") //30秒每次
public void rechargeBtcAndUsdtBlock() {
//获取已经同步的最大区块号
int bigestBlock = btcBlockNumberService.selectBigest();
//区块链最新区块高度
int blockHeightRpc = 0;
//获取该区块hash
String blockHash = "";
//交易信息
JSONArray transferArr = null;
try {
blockHeightRpc = btcUtils.getBlockCount();
//是否已经同步到最新区块
if (bigestBlock >= blockHeightRpc) {
return;
}
// //判断是否有未确认交易
// if (btcUtils.getUnconfirmedBalance() != 0) {
// return;
// }
blockHash = btcUtils.getBlockHash(bigestBlock);
transferArr = btcUtils.listSinceBlock(blockHash);
} catch (Exception e) {
return;
}
//区块号自增
bigestBlock++;
//保存已经同步区块高度的到数据库
btcBlockNumberService.insertBlockNumber(bigestBlock, BtcBlockNumberConstans.STATUS_W);
int transferArrLen = transferArr.size();
for (int i = 0; i < transferArrLen; i++) {
JSONObject transferObj = transferArr.getJSONObject(i);
if ("receive".equals(transferObj.getString("category"))) {
String toAddr = transferObj.getString("address");
if (btcAddressSetRedisUtils.isExistsAddr(toAddr)) {
String txId = transferObj.getString("txid");
try {
//先用usdt解析,如果不能解析,则用btc解析
JSONObject transferUsdt = usdtUtils.getTransaction(txId);
try {
//修改该usdt钱包余额,并插入一条充值记录
parseUsdtTransfer(transferUsdt, txId);
} catch (Exception e) {
return;
}
} catch (Exception e) {
//btc解析
try {
JSONObject transferBtc = btcUtils.getTransaction(txId);
parseBtcTransfer(transferBtc, txId);
} catch (Exception e1) {
return;
}
}
}
}
}
//修改区块同步状态
btcBlockNumberService.updateStatus(bigestBlock, BtcBlockNumberConstans.STATUS_Y);
}
/**
* 查询区块链遗漏的充值信息
*/
@Scheduled(cron = "0 0/2 * * * ?") //2分钟每次
public void crawlOmitTxIn() {
long nowTime = System.currentTimeMillis();
//获取等待区块列表
List<BtcBlockNumberDTO> blockNumberDTOList = btcBlockNumberService.listByStatus(BtcBlockNumberConstans.STATUS_W);
for (BtcBlockNumberDTO blockNumberDTO : blockNumberDTOList) {
//判断时间差
if (nowTime - blockNumberDTO.getCreateTime().getTime() < BtcBlockNumberConstans.TIME_DIFFERENCE) {
continue;
}
//获取爬取次数
int count = btcBlockRedisUtils.getBlockOptMapCount(blockNumberDTO.getBlockNumber());
if (count >= 5) { // 爬取次数超过五次跳出
//删除缓存
btcBlockRedisUtils.delBlockOptMapCount(blockNumberDTO.getBlockNumber());
//记录改为失败
btcBlockNumberService.updateStatus(blockNumberDTO.getBlockNumber(), BtcBlockNumberConstans.STATUS_N);
continue;
}
try {
//本区块hash
String thisBlockHash = btcUtils.getBlockHash(blockNumberDTO.getBlockNumber());
//上一个区块hash
String previousBlockHash = btcUtils.getBlockHash(blockNumberDTO.getBlockNumber() - 1);
//交易数组
JSONArray transferArr = btcUtils.listSinceBlock(previousBlockHash);
int transferArrLen = transferArr.size();
for (int i = 0; i < transferArrLen; i++) {
JSONObject transferObj = transferArr.getJSONObject(i);
//不为本次区块交易,不需要解析
if (!thisBlockHash.equals(transferObj.getString("blockhash"))) {
continue;
}
if ("receive".equals(transferObj.getString("category"))) {
String toAddr = transferObj.getString("address");
if (btcAddressSetRedisUtils.isExistsAddr(toAddr)) {
String txId = transferObj.getString("txid");
try {
//先用usdt解析,如果不能解析,则用btc解析
JSONObject transferUsdt = usdtUtils.getTransaction(txId);
try {
//修改该usdt钱包余额,并插入一条充值记录
parseUsdtTransfer(transferUsdt, txId);
} catch (Exception e) {
continue;
}
} catch (Exception e) {
//btc解析
try {
JSONObject transferBtc = btcUtils.getTransaction(txId);
parseBtcTransfer(transferBtc, txId);
} catch (Exception e1) {
continue;
}
}
}
}
}
} catch (Exception e) {
continue;
}
//爬取次数加1
btcBlockRedisUtils.incrementBlockOptMapCount(blockNumberDTO.getBlockNumber());
try {
//修改区块同步状态
btcBlockNumberService.updateStatus(blockNumberDTO.getBlockNumber(), BtcBlockNumberConstans.STATUS_Y);
//删除缓存
btcBlockRedisUtils.delBlockOptMapCount(blockNumberDTO.getBlockNumber());
} catch (Exception e) {
}
}
}
/**
* 解析btc交易
*
* @param transferBtc btc交易
* @param txId 交易id
*/
private void parseBtcTransfer(JSONObject transferBtc, String txId) {
//交易金额,正数表示该交易增加钱包余额,负数表示该交易减少钱包余额
if (transferBtc.getDouble("amount") <= 0) {
return;
}
JSONArray details = transferBtc.getJSONArray("details");
String toAddr = null;
String fromAddr = null;
double amount = 0;
double fee = 0;
for (int i = 0; i < details.size(); i++) {
JSONObject jsonObject = details.getJSONObject(i); // 遍历 jsonarray 数组,把每一个对象转成 json 对象
String category = jsonObject.getString("category");
if ("receive".equals(category)) {
toAddr = jsonObject.getString("address");
amount = jsonObject.getDouble("amount");
} else if ("send".equals(category)) {
fromAddr = jsonObject.getString("address");
fee = Math.abs(jsonObject.getDouble("fee"));
}
}
if (btcAddressSetRedisUtils.isExistsAddr(toAddr)) {
//修改该钱包余额,并插入一条充值记录
BtcWalletTransfer btcWalletTransfer = new BtcWalletTransfer();
btcWalletTransfer.setId(UUID.randomUUID().toString());
btcWalletTransfer.setHash(txId);
btcWalletTransfer.setFromAddr(fromAddr);
btcWalletTransfer.setToAddr(toAddr);
btcWalletTransfer.setAmount(Math.abs(amount));
btcWalletTransfer.setGasPrice(fee);
btcWalletTransfer.setTokenId(BtcConstans.BTC_PROPERTY_ID);
btcWalletTransfer.setTokenSymbol(BtcConstans.BTC_SYMBOL);
btcWalletTransfer.setTransferType(BtcTransferConstans.TYPE_IN);
btcWalletTransfer.setStatus(BtcTransferConstans.STATUS_SUCCESS);
btcWalletTransfer.setCreateTime(new Date());
btcWalletTransfer.setUpdateTime(btcWalletTransfer.getCreateTime());
btcWalletTransferService.handleBlockRecharge(btcWalletTransfer);
}
}
/**
* 解析usdt交易
*
* @param transferUsdt usdt交易
* @param txId 交易id
*/
private void parseUsdtTransfer(JSONObject transferUsdt, String txId) {
//交易是否有效交易
if (transferUsdt.getBoolean("valid")) {
//是否USDT交易
if (transferUsdt.getInteger("propertyid") == UsdtConstans.USDT_PROPERTY_ID) {
//是否充值到本地钱包地址
String toAddr = transferUsdt.getString("referenceaddress");
if (btcAddressSetRedisUtils.isExistsAddr(toAddr)) {
//修改该钱包余额,并插入一条充值记录
BtcWalletTransfer btcWalletTransfer = new BtcWalletTransfer();
btcWalletTransfer.setId(UUID.randomUUID().toString());
btcWalletTransfer.setHash(txId);
btcWalletTransfer.setFromAddr(transferUsdt.getString("sendingaddress"));
btcWalletTransfer.setToAddr(toAddr);
btcWalletTransfer.setAmount(Math.abs(transferUsdt.getDouble("amount")));
btcWalletTransfer.setGasPrice(transferUsdt.getDouble("fee"));
btcWalletTransfer.setTokenId(UsdtConstans.USDT_PROPERTY_ID);
btcWalletTransfer.setTokenSymbol(UsdtConstans.USDT_SYMBOL);
btcWalletTransfer.setTransferType(BtcTransferConstans.TYPE_IN);
btcWalletTransfer.setStatus(BtcTransferConstans.STATUS_SUCCESS);
btcWalletTransfer.setCreateTime(new Date());
btcWalletTransfer.setUpdateTime(btcWalletTransfer.getCreateTime());
btcWalletTransferService.handleBlockRecharge(btcWalletTransfer);
}
}
}
}
}

@ -1,86 +0,0 @@
package com.blockchain.server.btc.scheduleTask;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.server.btc.common.constants.BtcConstans;
import com.blockchain.server.btc.common.constants.BtcTransferConstans;
import com.blockchain.server.btc.entity.BtcWalletTransfer;
import com.blockchain.server.btc.rpc.BtcUtils;
import com.blockchain.server.btc.rpc.UsdtUtils;
import com.blockchain.server.btc.service.BtcWalletService;
import com.blockchain.server.btc.service.BtcWalletTransferService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 钱包业务处理的定时器
*/
//@Component
public class WallertTimerTask {
// 钱包提现处理
private static ExecutorService txOutExecutorService = Executors.newSingleThreadExecutor();
// 日志
private static final Logger LOG = LoggerFactory.getLogger(WallertTimerTask.class);
@Autowired
BtcWalletTransferService walletTransferService;
@Autowired
BtcWalletService btcWalletService;
@Autowired
BtcUtils btcUtils;
@Autowired
UsdtUtils usdtUtils;
@Scheduled(cron = "0/30 * * * * ?")
public void crawlTxOut() {
txOutExecutorService.execute(new Runnable() {
@Override
public void run() {
crawlTxOutDispose(); // 爬取提现记录
}
});
}
void crawlTxOutDispose() {
// 查询提现的未处理的数据
List<BtcWalletTransfer> txs = walletTransferService.selectByTxTypeAndStatus(BtcTransferConstans.TYPE_OUT,
BtcTransferConstans.STATUS_ALREADY_OUT, 0, 99);
for (BtcWalletTransfer tx : txs) {
try {
if (BtcConstans.BTC_SYMBOL.equalsIgnoreCase(tx.getTokenSymbol())) {
JSONObject obj = btcUtils.getTransaction(tx.getHash());
int confirmations = new Integer(obj.get("confirmations").toString()).intValue();
if (confirmations >= 1) {
btcWalletService.updateTxOutSuccess(tx);
}else{
btcWalletService.updateTxOutError(tx);
}
} else {
JSONObject obj = usdtUtils.getTransaction(tx.getHash());
int confirmations = new Integer(obj.get("confirmations").toString()).intValue();
boolean valid = Boolean.getBoolean(obj.get("valid").toString());
if (!valid) {
btcWalletService.updateTxOutError(tx);
} else if (valid && confirmations >= 1) {
btcWalletService.updateTxOutSuccess(tx);
}
}
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
}

@ -1,40 +0,0 @@
package com.blockchain.server.btc.service;
import com.blockchain.server.btc.dto.BtcBlockNumberDTO;
import java.util.List;
public interface BtcBlockNumberService {
/**
* 新增已经同步的区块不成功报异常
*
* @param blockNumber 区块高度
* @param status 状态
* @return
*/
void insertBlockNumber(int blockNumber, String status);
/**
* 修改区块装填不成功报异常
*
* @param blockNumber 区块高度
* @return
*/
void updateStatus(int blockNumber, String status);
/**
* 根据状态获取同步区块
*
* @param status 状态
* @return
*/
List<BtcBlockNumberDTO> listByStatus(String status);
/**
* 查询已经同步的最大区块号
*
* @return
*/
int selectBigest();
}

@ -1,7 +0,0 @@
package com.blockchain.server.btc.service;
public interface BtcWalletKeyService {
void insertWalletKey(String address, String privateKey);
}

@ -46,14 +46,6 @@ public interface BtcWalletTransferService {
*/
Boolean isNotExistsTransferIn(String txId);
/**
* 处理同步区块充值
*
* @param btcWalletTransfer 记录信息
* @return
*/
void handleBlockRecharge(BtcWalletTransfer btcWalletTransfer);
/**
* 处理CCT交易可用冻结余额加减
*
@ -91,7 +83,7 @@ public interface BtcWalletTransferService {
* @param pageSize 页数展示条数
* @return
*/
List<BtcWalletTransfer> selectByTxTypeAndStatus(String transferType, int Status, int pageNum, int pageSize);
// List<BtcWalletTransfer> selectByTxTypeAndStatus(String transferType, int Status, int pageNum, int pageSize);
/**
* 修改记录状态

@ -1,68 +0,0 @@
package com.blockchain.server.btc.service.impl;
import com.blockchain.server.btc.common.constants.BtcBlockNumberConstans;
import com.blockchain.server.btc.common.enums.BtcEnums;
import com.blockchain.server.btc.common.exception.BtcException;
import com.blockchain.server.btc.dto.BtcBlockNumberDTO;
import com.blockchain.server.btc.entity.BtcBlockNumber;
import com.blockchain.server.btc.mapper.BtcBlockNumberMapper;
import com.blockchain.server.btc.rpc.BtcUtils;
import com.blockchain.server.btc.service.BtcBlockNumberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service
public class BtcBlockNumberServiceImpl implements BtcBlockNumberService {
@Autowired
private BtcBlockNumberMapper btcBlockNumberMapper;
@Autowired
private BtcUtils btcUtils;
@Override
public void insertBlockNumber(int blockNumber, String status) {
BtcBlockNumber btcBlockNumber = new BtcBlockNumber();
btcBlockNumber.setBlockNumber(blockNumber);
btcBlockNumber.setStatus(status);
btcBlockNumber.setCreateTime(new Date());
btcBlockNumber.setUpdateTime(btcBlockNumber.getCreateTime());
int count = btcBlockNumberMapper.insertSelective(btcBlockNumber);
if (count != 1) {
throw new BtcException(BtcEnums.INSERT_BLOCKNUMBER_ERROR);
}
}
@Override
public void updateStatus(int blockNumber, String status) {
BtcBlockNumber btcBlockNumber = new BtcBlockNumber();
btcBlockNumber.setBlockNumber(blockNumber);
btcBlockNumber.setStatus(status);
btcBlockNumber.setUpdateTime(new Date());
int countRow = btcBlockNumberMapper.updateByPrimaryKeySelective(btcBlockNumber);
if (countRow != 1) {
throw new BtcException(BtcEnums.UPDATE_BLOCK_NUMBER_STATUS_ERROR);
}
}
@Override
public List<BtcBlockNumberDTO> listByStatus(String status) {
return btcBlockNumberMapper.listByStatus(status);
}
@Override
public int selectBigest() {
Integer blockNumber = btcBlockNumberMapper.selectBigest();
if (blockNumber == null) {
try {
blockNumber = btcUtils.getBlockCount();
this.insertBlockNumber(blockNumber, BtcBlockNumberConstans.STATUS_Y);
} catch (Exception e) {
e.printStackTrace();
}
}
return blockNumber;
}
}

@ -1,33 +0,0 @@
package com.blockchain.server.btc.service.impl;
import com.blockchain.server.btc.common.enums.BtcEnums;
import com.blockchain.server.btc.common.exception.BtcException;
import com.blockchain.server.btc.common.util.BtcRASUtils;
import com.blockchain.server.btc.entity.BtcWalletKey;
import com.blockchain.server.btc.mapper.BtcWalletKeyMapper;
import com.blockchain.server.btc.service.BtcWalletKeyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BtcWalletKeyServiceImpl implements BtcWalletKeyService {
@Autowired
private BtcWalletKeyMapper btcWalletKeyMapper;
@Override
public void insertWalletKey(String address, String privateKey) {
BtcWalletKey btcWalletKey = new BtcWalletKey();
btcWalletKey.setAddr(address);
try {
privateKey = BtcRASUtils.encrypt(privateKey);
} catch (Exception e) {
throw new BtcException(BtcEnums.CREATE_WALLET_ERROR);
}
btcWalletKey.setPrivateKey(privateKey);
int countIw = btcWalletKeyMapper.insertSelective(btcWalletKey);
if (countIw != 1) {
throw new BtcException(BtcEnums.CREATE_WALLET_ERROR);
}
}
}

@ -3,7 +3,6 @@ package com.blockchain.server.btc.service.impl;
import com.blockchain.server.btc.common.constants.BtcTransferConstans;
import com.blockchain.server.btc.common.enums.BtcEnums;
import com.blockchain.server.btc.common.exception.BtcException;
import com.blockchain.server.btc.common.util.BtcAddressSetRedisUtils;
import com.blockchain.server.btc.dto.BtcApplicationDTO;
import com.blockchain.server.btc.dto.BtcTokenDTO;
import com.blockchain.server.btc.dto.BtcWalletDTO;
@ -13,7 +12,6 @@ import com.blockchain.server.btc.entity.BtcWalletTransfer;
import com.blockchain.server.btc.entity.WalletInitConfig;
import com.blockchain.server.btc.mapper.BtcWalletMapper;
import com.blockchain.server.btc.mapper.WalletInitConfigMapper;
import com.blockchain.server.btc.rpc.BtcUtils;
import com.blockchain.server.btc.service.BtcApplicationService;
import com.blockchain.server.btc.service.BtcTokenService;
import com.blockchain.server.btc.service.BtcWalletService;
@ -30,15 +28,10 @@ import java.util.UUID;
@Service
public class BtcWalletServiceImpl<psvm> implements BtcWalletService {
@Autowired
private BtcUtils btcUtils;
@Autowired
private BtcWalletTransferService btcWalletTransferService;
@Autowired
private BtcAddressSetRedisUtils btcAddressSetRedisUtils;
@Autowired
private BtcWalletMapper btcWalletMapper;
@ -47,9 +40,6 @@ public class BtcWalletServiceImpl<psvm> implements BtcWalletService {
@Autowired
private BtcTokenService btcTokenService;
@Autowired
private BtcWalletKeyServiceImpl btcWalletKeyService;
@Autowired
private WalletInitConfigMapper walletInitConfigMapper;
@ -120,6 +110,7 @@ public class BtcWalletServiceImpl<psvm> implements BtcWalletService {
public Set<String> getAllWalletAddr() {
return btcWalletMapper.getAllWalletAddr();
}
@Override
@Transactional
public void updateTxOutError(BtcWalletTransfer btcWalletTransfer) {
@ -127,7 +118,7 @@ public class BtcWalletServiceImpl<psvm> implements BtcWalletService {
Date date = new Date();
// 业务操作(1)- 恢复提现余额,扣除手续费
Double amount = btcWalletTransfer.getAmount();
this.updateBalanceByAddrInRowLock(wallet.getAddr(), wallet.getTokenId(), amount, amount * -1, Double.valueOf(0),date);
this.updateBalanceByAddrInRowLock(wallet.getAddr(), wallet.getTokenId(), amount, amount * -1, Double.valueOf(0), date);
// 业务操作(2)- 修改记录状态
btcWalletTransferService.updateStatus(btcWalletTransfer.getId(), BtcTransferConstans.STATUS_FILE, date);
}
@ -139,19 +130,19 @@ public class BtcWalletServiceImpl<psvm> implements BtcWalletService {
Date date = new Date();
// 业务操作(1)- 恢复提现余额,扣除手续费
Double amount = btcWalletTransfer.getAmount();
this.updateBalanceByAddrInRowLock(wallet.getAddr(), wallet.getTokenId(), Double.valueOf(0), amount * -1, amount * -1,date);
this.updateBalanceByAddrInRowLock(wallet.getAddr(), wallet.getTokenId(), Double.valueOf(0), amount * -1, amount * -1, date);
// 业务操作(2)- 修改记录状态
btcWalletTransferService.updateStatus(btcWalletTransfer.getId(), BtcTransferConstans.STATUS_SUCCESS, date);
}
@Override
public BtcWallet findWallet(String userId,String walletType, String coinName) {
public BtcWallet findWallet(String userId, String walletType, String coinName) {
BtcWallet wallet = new BtcWallet();
wallet.setWalletType(walletType);
wallet.setTokenSymbol(coinName);
wallet.setUserOpenId(userId);
BtcWallet btcWallet = btcWalletMapper.selectOne(wallet);
if(btcWallet == null) {
if (btcWallet == null) {
throw new BtcException(BtcEnums.INEXISTENCE_WALLET);
}
return btcWallet;
@ -166,8 +157,8 @@ public class BtcWalletServiceImpl<psvm> implements BtcWalletService {
btcApplicationService.checkWalletType(fromType);
btcApplicationService.checkWalletType(toType);
BtcToken btcToken = btcTokenService.selectByTokenName(coinName);
BtcWallet fromWallet = this.findWallet(userId,fromType,coinName);
BtcWallet toWallet = this.findWallet(userId,toType,coinName);
BtcWallet fromWallet = this.findWallet(userId, fromType, coinName);
BtcWallet toWallet = this.findWallet(userId, toType, coinName);
//该用户减去提现可用余额、总额
int countUb = this.updateBalanceByAddrInRowLock(fromWallet.getAddr(), fromWallet.getTokenId(), -amount, 0.0, -amount, end);
if (countUb != 1) {
@ -195,7 +186,7 @@ public class BtcWalletServiceImpl<psvm> implements BtcWalletService {
if (countIt != 1) {
throw new BtcException(BtcEnums.WITHDRAW_ERROR);
}
return btcWalletTransfer;
return btcWalletTransfer;
}
@Override
@ -205,10 +196,10 @@ public class BtcWalletServiceImpl<psvm> implements BtcWalletService {
walletInitConfig.setCoin(tokenId);
walletInitConfig.setWalletType(walletType);
WalletInitConfig config = walletInitConfigMapper.selectOne(walletInitConfig);
if(config==null || config.getBalance()==null){
if (config == null || config.getBalance() == null) {
throw new BtcException(BtcEnums.RESET_ERROR);
}
btcWalletMapper.updateWalletBalanceByUserOpenId(config.getBalance(),userOpenId,tokenId,walletType,new Date());
btcWalletMapper.updateWalletBalanceByUserOpenId(config.getBalance(), userOpenId, tokenId, walletType, new Date());
return 1;
}

@ -1,26 +1,17 @@
package com.blockchain.server.btc.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.common.base.constant.BaseConstant;
import com.blockchain.common.base.dto.GasDTO;
import com.blockchain.common.base.dto.ResultDTO;
import com.blockchain.common.base.dto.WalletChangeDTO;
import com.blockchain.common.base.dto.WalletOrderDTO;
import com.blockchain.common.base.exception.RPCException;
import com.blockchain.server.btc.common.constants.BtcTransferConstans;
import com.blockchain.server.btc.common.constants.UsdtConstans;
import com.blockchain.server.btc.common.enums.BtcEnums;
import com.blockchain.server.btc.common.exception.BtcException;
import com.blockchain.server.btc.common.util.CheckEthFeginResult;
import com.blockchain.server.btc.dto.BtcWalletDTO;
import com.blockchain.server.btc.dto.BtcWalletTransferDTO;
import com.blockchain.server.btc.entity.BtcWalletTransfer;
import com.blockchain.server.btc.entity.WalletInitConfig;
import com.blockchain.server.btc.feign.EthServerFegin;
import com.blockchain.server.btc.feign.UserServerFegin;
import com.blockchain.server.btc.mapper.BtcWalletTransferMapper;
import com.blockchain.server.btc.mapper.WalletInitConfigMapper;
import com.blockchain.server.btc.rpc.BtcUtils;
import com.blockchain.server.btc.service.*;
import com.codingapi.tx.annotation.ITxTransaction;
import com.codingapi.tx.annotation.TxTransaction;
@ -49,20 +40,12 @@ public class BtcWalletTransferServiceImpl implements BtcWalletTransferService, I
@Autowired
private BtcTokenService btcTokenService;
@Autowired
private BtcUtils btcUtils;
@Autowired
private ConfigWalletParamService walletParamService;
@Autowired
private EthServerFegin ethServerFegin;
@Autowired
private UserServerFegin userServerFegin;
@Autowired
private BtcWalletTransferService btcWalletTransferService;
@Override
public Integer insertTransfer(BtcWalletTransfer btcWalletTransfer) {
return btcWalletTransferMapper.insertSelective(btcWalletTransfer);
@ -93,24 +76,6 @@ public class BtcWalletTransferServiceImpl implements BtcWalletTransferService, I
return StringUtils.isEmpty(id);
}
@Override
@Transactional
public void handleBlockRecharge(BtcWalletTransfer btcWalletTransfer) {
if (isNotExistsTransferIn(btcWalletTransfer.getHash())) {
//插入充值记录
int countIt = insertTransfer(btcWalletTransfer);
if (countIt != 1) {
throw new BtcException(BtcEnums.PARSE_TRANSFER_IN_ERROR);
}
//增加钱包可用余额、总额
int countUb = btcWalletService.updateBalanceByAddrInRowLock(btcWalletTransfer.getToAddr(), btcWalletTransfer.getTokenId(),
btcWalletTransfer.getAmount(), 0.0, btcWalletTransfer.getAmount(), btcWalletTransfer.getCreateTime());
if (countUb != 1) {
throw new BtcException(BtcEnums.PARSE_TRANSFER_IN_ERROR);
}
}
}
@Override
@Transactional
@TxTransaction
@ -316,14 +281,14 @@ public class BtcWalletTransferServiceImpl implements BtcWalletTransferService, I
return btcWalletService.selectByAddr(fromAddress, tokenId, walletType);
}
@Override
/*@Override
public List<BtcWalletTransfer> selectByTxTypeAndStatus(String transferType, int Status, int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize); // 分页处理
BtcWalletTransfer where = new BtcWalletTransfer();
where.setTransferType(transferType);
where.setStatus(Status);
return btcWalletTransferMapper.select(where);
}
}*/
@Override
@Transactional

@ -1,27 +0,0 @@
<?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="com.blockchain.server.btc.mapper.BtcBlockNumberMapper">
<resultMap id="BtcBlockNumberMap" type="com.blockchain.server.btc.dto.BtcBlockNumberDTO">
<result property="createTime" column="create_time"/>
<result property="blockNumber" column="block_number"/>
<result property="updateTime" column="update_time"/>
<result property="status" column="status"/>
</resultMap>
<sql id="tableName">dapp_btc_block_number</sql>
<select id="selectBigest" resultType="java.lang.Integer">
SELECT MAX(block_number)
FROM <include refid="tableName"/>
</select>
<select id="listByStatus" resultMap="BtcBlockNumberMap">
SELECT block_number, create_time
FROM <include refid="tableName"/>
WHERE status = #{status}
order by block_number asc
</select>
</mapper>

@ -1,11 +0,0 @@
<?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="com.blockchain.server.btc.mapper.BtcWalletKeyMapper">
<resultMap id="BtcWalletKeyMap" type="com.blockchain.server.btc.dto.BtcWalletKeyDTO">
<result property="privateKey" column="private_key"/>
<result property="addr" column="addr"/>
</resultMap>
</mapper>

@ -1,178 +0,0 @@
package com.blockchain.server.eos.common.util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.server.eos.common.constant.EosConstant;
import com.blockchain.server.eos.common.enums.EosWalletEnums;
import com.blockchain.server.eos.common.exception.EosWalletException;
import com.blockchain.server.eos.dto.WalletInDTO;
import com.blockchain.server.eos.entity.Wallet;
import com.blockchain.server.eos.entity.WalletTransfer;
import com.blockchain.server.eos.service.EosWalletService;
import com.blockchain.server.eos.service.EosWalletTransferService;
import com.blockchain.server.eos.service.EosWalletUtilService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* @author Harvey Luo
* @date 2019/5/27 10:54
*/
@Component
public class EosUtil {
@Autowired
private EosWalletService eosWalletService;
@Autowired
private EosWalletTransferService eosWalletTransferService;
@Autowired
private EosWalletUtilService eosWalletUtilService;
// 日志
private static final Logger LOG = LoggerFactory.getLogger(EosUtil.class);
/**
* 递归方式判断查询返回账户历史数据
*
* @param walletInDTO
* @param offset
* @return
*/
public JSONArray recursion(WalletInDTO walletInDTO, Integer offset) {
JSONObject bodyBody = eosWalletUtilService.getActions(walletInDTO.getAccountName(), offset.toString());
if (bodyBody == null) return null;
JSONArray actions = bodyBody.getJSONArray("actions");
BigInteger blockNumber = walletInDTO.getBlockNumber();
if (actions.size() > 0) {
JSONObject job = actions.getJSONObject(0);
JSONObject action_trace = job.getJSONObject("action_trace");
BigInteger blockNum = action_trace.getBigInteger("block_num");
if (blockNum.compareTo(blockNumber) <= 0 || offset.equals(EosConstant.RPCConstant.OFFSET_MAX))
return actions;
else {
return recursion(walletInDTO, offset + EosConstant.RPCConstant.ADD_OFFSET);
}
}
return null;
}
/**
* 分析账户历史记录
*
* @param actions
* @param tokenName
* @param walletInDTO
*/
public void handTransaction(JSONArray actions, String tokenName, WalletInDTO walletInDTO) {
if (actions.size() > 0) {
for (int i = 0; i < actions.size(); i++) {
JSONObject job = actions.getJSONObject(i);
JSONObject action_trace = job.getJSONObject("action_trace");
JSONObject act = action_trace.getJSONObject("act");
String token = act.getObject("account", String.class);
// 判断币种地址
if (!token.equalsIgnoreCase(tokenName)) continue;
JSONObject data = act.getJSONObject("data");
String to = data.getObject("to", String.class);
// 判断资金账户
if (to == null || !walletInDTO.getAccountName().equalsIgnoreCase(to)) continue;
// 判断是否为本地钱包
String memo = data.getObject("memo", String.class);
Integer walletId = null;
try {
walletId = Integer.parseInt(memo.trim());
} catch (Exception e) {
continue;
}
Wallet wallet = eosWalletService.selectWalletById(walletId.toString());
if (wallet == null) continue;
// 获取充值金额和币种符号
String quantity = data.getObject("quantity", String.class);
String[] quantitys = quantity.split(" ");
String amount = quantitys[0];
String symbol = quantitys[1];
if (!wallet.getTokenSymbol().equalsIgnoreCase(symbol)) continue;
String hash = action_trace.getString("trx_id");
// 判断数据库是否存在该记录
Integer row = eosWalletTransferService.countByHashAndTransferType(hash, EosConstant.TransferType.TRANSFER_IN);
if (row != 0) continue;
String from = data.getObject("from", String.class);
BigInteger blockNum = action_trace.getBigInteger("block_num");
// 修改钱包插入充值记录
eosWalletTransferService.handleWalletAndWalletTransfer(hash,
wallet.getId(),
null,
EosConstant.TransferType.TRANSFER_IN,
new BigDecimal(quantitys[0]),
tokenName,
quantitys[1],
memo,
blockNum);
LOG.info("************************充值成功: hash值 ==》 " + hash + " + 币种名称 ==》 " + tokenName + " + 钱包地址 ==》 " + wallet.getId() + " + 金额 ==》" + quantity + "************************");
// System.out.println("hashId ===>" + hash);
// System.out.println("blockNum ===>" + blockNum);
// System.out.println("amount ==> " + amount);
// System.out.println("symbol ==> " + symbol);
// System.out.println("from ==> " + from);
// System.out.println("to ==> " + to);
// System.out.println("quantity ==> " + quantity);
// System.out.println("memo ==> " + memo);
}
}
}
/**
* 解析eos查询交易信息状态
*
* @param blockNum
* @param hashId
* @param walletTransfer
* @return
*/
public Boolean getTransactions(String blockNum, String hashId, WalletTransfer walletTransfer) {
JSONObject body = eosWalletUtilService.getTransaction(blockNum, hashId);
if (body == null || "".equalsIgnoreCase(body.toString())) {
LOG.info("************************出币失败:区块高度" + blockNum + "交易hash:" + hashId + "************************");
return false;
}
JSONObject action = null;
JSONObject data = null;
try {
// 返回结果分析出币信息
JSONObject trx = body.getJSONObject("trx");
JSONObject trx1 = trx.getJSONObject("trx");
JSONArray actions = trx1.getJSONArray("actions");
action = actions.getJSONObject(0);
data = action.getJSONObject("data");
if (null == data || "".equalsIgnoreCase(data.toString())) {
LOG.info("************************出币失败:区块高度" + blockNum + "交易hash:" + hashId + "************************");
return false;
} else {
// 支付人地址:
// String from = data.getObject("from", String.class);
// 收款人地址:
String to = data.getObject("to", String.class);
// 提现由系统账户转账到用户提供账户
// 判断to是否为用户提供的地址名称
if (to.equalsIgnoreCase(walletTransfer.getAccountName())) return true;
else {
LOG.info("************************出币失败:区块高度" + blockNum + "交易hash:" + hashId + "************************");
throw new EosWalletException(EosWalletEnums.CURRENCY_FAILURE_ERROR);
}
}
} catch (Exception e) {
LOG.info("************************出币失败:区块高度" + blockNum + "交易hash:" + hashId + "************************");
// TODO 出币失败是否抛出错误
// throw new EosWalletException(EosWalletEnums.CURRENCY_FAILURE_ERROR);
return false;
}
}
}

@ -1,66 +0,0 @@
package com.blockchain.server.eos.mapper;
import com.blockchain.server.eos.dto.BlockNumberDTO;
import com.blockchain.server.eos.entity.BlockNumber;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
import java.math.BigInteger;
import java.util.List;
/**
* BlockNumberMapper 数据访问类
* @date 2018-11-05 15:10:47
* @version 1.0
*/
@Repository
public interface BlockNumberMapper extends Mapper<BlockNumber> {
/**
* 查询最旧区块
* @return
*/
BigInteger selectMinBlockNum();
/**
* 查询最大的区块号
* @return
*/
BigInteger selectMaxBlockNum();
/**
* 查询是否存在区块
* @param blockNum
* @return
*/
BlockNumberDTO selectBlockNumIsExist(@Param("blockNum") BigInteger blockNum);
/**
* 查找当前区块状态
* @param blockNum
* @return
*/
Character selectBlockNumStatusByBlockNum(@Param("blockNum") BigInteger blockNum);
/**
* 根据区块状态获取区块
* @param status
* @return
*/
List<BigInteger> listBlockNumberByStatus(@Param("status") Character status);
/**
* 更新处理区块状态
* @param blockNum
* @param status
* @return
*/
int updateBlockNumberByStatus(@Param("blockNum") BigInteger blockNum, @Param("status") Character status);
/**
*
* @param blockNumber
* @return
*/
int insertSelectiveIgnore(BlockNumber blockNumber);
}

@ -16,12 +16,6 @@ import java.util.HashSet;
@Repository
public interface TokenMapper extends Mapper<Token> {
/**
* 查询所有代币名称
* @return
*/
HashSet<String> listTokenNameAll();
/**
* 根据代币名称查询代币信息
* @param tokenName

@ -17,9 +17,6 @@ import java.util.List;
@Repository
public interface WalletInMapper extends Mapper<WalletIn> {
// WalletInDTO selectWalletInAccount(String tokenName, Integer eosWalletInUsable);
/**
* 查询对应的代币名称充值账户
* @param tokenName
@ -28,14 +25,4 @@ public interface WalletInMapper extends Mapper<WalletIn> {
*/
WalletInDTO selectWalletInAccount(@Param("tokenName") String tokenName, @Param("status") Integer status);
List<WalletInDTO> listWalletInByAccountName(@Param("to") String to);
/**
* 修改区块字段
* @param accountName
* @param blockNum
* @return
*/
Integer updateWalletInBlockNumber(@Param("accountName") String accountName, @Param("blockNum") BigInteger blockNum);
}

@ -1,54 +0,0 @@
package com.blockchain.server.eos.scheduleTask;
import com.blockchain.server.eos.service.EosTokenService;
import com.blockchain.server.eos.service.EosWalletInService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//@Component
public class TransferDisposeTimerTask {
@Autowired
private EosTokenService tokenService;
@Autowired
private EosWalletInService eosWalletInService;
private static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
// 日志
private static final Logger LOG = LoggerFactory.getLogger(TransferDisposeTimerTask.class);
/**
* 查eos区块信息
*/
@Scheduled(cron = "0/10 * * * * ?") //5秒钟执行一次 */5 * * * * ? 5分钟执行一次 0 */5 * * * ?
public void selectTxStatus() {
LOG.info("************************eos交易记录爬取的定时任务************************");
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
dispose(); //查询eos账户历史充值信息
}
});
}
public void dispose() {
// Token查询所有代币
HashSet<String> listTokenName = tokenService.listTokenNameAll();
try {
// 充值处理方法
eosWalletInService.handleAccountBlockTransactions(listTokenName);
} catch (Exception e) {
e.printStackTrace();
LOG.error("************************ 充值处理异常 ************************");
}
}
}

@ -1,64 +0,0 @@
package com.blockchain.server.eos.scheduleTask;
import com.blockchain.server.eos.common.constant.EosConstant;
import com.blockchain.server.eos.entity.WalletTransfer;
import com.blockchain.server.eos.eos4j.Rpc;
import com.blockchain.server.eos.service.EosWalletService;
import com.blockchain.server.eos.service.EosWalletTransferService;
import com.blockchain.server.eos.service.EosWalletUtilService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 钱包业务处理的定时器
*/
//@Component
public class WallertTimerTask {
// 钱包提现处理
private static ExecutorService txOutExecutorService = Executors.newSingleThreadExecutor();
// 日志
private static final Logger LOG = LoggerFactory.getLogger(WallertTimerTask.class);
@Autowired
EosWalletTransferService walletTransferService;
@Autowired
EosWalletService walletService;
@Scheduled(cron = "0/5 * * * * ?")
public void crawlTxOut() {
txOutExecutorService.execute(new Runnable() {
@Override
public void run() {
crawlTxOutDispose(); // 爬取提现记录
}
});
}
void crawlTxOutDispose() {
// 查询提现的未处理的数据
List<WalletTransfer> txs = walletTransferService.selectByTxTypeAndStatus(EosConstant.TransferType.TRANSFER_OUT, EosConstant.TransferStatus.YI_CHU_BI, 0, 99);
for (WalletTransfer tx : txs) {
try {
Boolean status = walletService.getTransaction(tx.getBlockNumber(), tx.getHash());
// 修改失败状态
if (!status) walletService.updateTxOutError(tx);
// 修改余额改变成功状态
else walletService.updateTxOutSuccess(tx);
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
}

@ -1,59 +0,0 @@
package com.blockchain.server.eos.service;
import com.blockchain.server.eos.dto.BlockNumberDTO;
import com.blockchain.server.eos.entity.BlockNumber;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.List;
/**
* @author Harvey
* @date 2019/2/16 17:45
* @user WIN10
*/
public interface EosBlockNumberService {
/**
* 查询最大区块
* @return
*/
BigInteger selectCurrentBlockNum();
/**
* 添加区块交易信息
* @param nowBlock
* @param listTokenAddr
*/
void handleBlockTransactions(BigInteger nowBlock, HashSet<String> listTokenAddr);
/**
* 添加
* @param blockNumber
* @return
*/
int insertBlockNumber(BlockNumber blockNumber);
/**
* 插入区块处理状态
* @param nowBlock
* @param status
* @return
*/
int insertBlockNumberByStatus(BigInteger nowBlock, Character status);
/**
* 根据区块状态获取区块
* @param eosBlockNumberWait
* @return
*/
List<BigInteger> listBlockNumberByStatus(Character eosBlockNumberWait);
/**
* 更新处理区块状态
* @param blockNum
* @param status
* @return
*/
int updateBlockNumberByStatus(BigInteger blockNum, Character status);
}

@ -20,12 +20,6 @@ public interface EosTokenService {
*/
TokenDTO selectEosTokenByTokenName(String tokenName);
/**
* 查询所有代币地址
* @return
*/
HashSet<String> listTokenNameAll();
/**
* 查找eos所有币种信息
* @return

@ -19,17 +19,4 @@ public interface EosWalletInService {
*/
WalletInDTO selectWalletInAccount(String tokenName);
/**
* 查询充值资金账户
* @param to
* @return
*/
List<WalletInDTO> listWalletInByAccountName(String to);
/**
* 充值方法
* @param listTokenName
*/
void handleAccountBlockTransactions(HashSet<String> listTokenName);
}

@ -17,16 +17,6 @@ import java.util.List;
*/
public interface EosWalletService {
/**
* 通过
*
* @param walletId
* @return
*/
Wallet selectWalletById(String walletId);
Wallet selectWalletByIdAndTokenName(Integer walletId,String tokenName);
/**
* 用户充值修改钱包金额
*
@ -107,27 +97,6 @@ public interface EosWalletService {
*/
WalletDTO selectWalletByTokenSymbol(String userId, String tokenSymbol, String walletType);
/**
* 查询eos出块
* @param bolckNum
* @param hashId
* @return
*/
Boolean getTransaction(String bolckNum, String hashId);
/**
* 提现失败处理
*
* @param tx
*/
void updateTxOutError(WalletTransfer tx);
/**
* 提现成功处理
* @param tx
*/
void updateTxOutSuccess(WalletTransfer tx);
/**
* 根据用户ID,钱包类型币种名称查询钱包信息

@ -15,19 +15,6 @@ import java.util.List;
*/
public interface EosWalletTransferService {
/**
* 添加记录并修改账户金额
* @param hash
* @param transferType
* @param amount
* @param tokenName
* @param tokenSymbol
* @param memo
* @param accountId
* @return
*/
int handleWalletAndWalletTransfer(String hash, Integer accountId, String accountName, String transferType, BigDecimal amount, String tokenName, String tokenSymbol, String memo, BigInteger blockNumber);
/**
* 插入记录
* @param walletTransfer
@ -43,38 +30,4 @@ public interface EosWalletTransferService {
* @return
*/
List<WalletTransferDTO> listWalletTransfer(String userOpenId, String tokenName, String walletType);
/**
* 根据记录类型与记录状态查询记录
*
* @param transferType 记录类型
* @param Status 记录状态
* @param pageNum 当前页数
* @param pageSize 页数展示条数
* @return
*/
List<WalletTransfer> selectByTxTypeAndStatus(String transferType, int Status, Integer pageNum, Integer pageSize);
/**
* 更新状态
* @param id
* @param status
* @param date
*/
void updateStatus(String id, int status, Date date);
/**
* 根据hash查询交易记录
* @param hashId
* @return
*/
WalletTransfer selectByHashId(String hashId);
/**
* 根据hash查询是否存在数据
* @param hash
* @param transferType
* @return
*/
Integer countByHashAndTransferType(String hash, String transferType);
}

@ -1,48 +0,0 @@
package com.blockchain.server.eos.service;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.server.eos.dto.BlockNumberDTO;
import java.math.BigInteger;
/**
* @author Harvey
* @date 2019/2/18 13:57
* @user WIN10
*/
public interface EosWalletUtilService {
/**
* 获取最新区块
* @return
*/
BigInteger getEosBlock();
/**
* 获取区块交易记录
* @param nowBlock
* @return
*/
JSONObject listBlockTransaction(BigInteger nowBlock);
/**
* 获取区块高度
* @return
*/
BlockNumberDTO getBlockNum();
/**
* 获取出币信息
* @param blockNum
* @param hashId
* @return
*/
JSONObject getTransaction(String blockNum, String hashId);
/**
* 获取账户历史交易信息
* @param accountName
* @return
*/
JSONObject getActions(String accountName, String offset);
}

@ -22,6 +22,7 @@ public class EosApplicationServiceImpl implements EosApplicationService {
/**
* 查询是否存在该应用钱包
*
* @param walletType
* @return
*/
@ -33,6 +34,7 @@ public class EosApplicationServiceImpl implements EosApplicationService {
/**
* 查找所有应用信息
*
* @return
*/
@Override

@ -1,201 +0,0 @@
package com.blockchain.server.eos.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.common.base.util.ExceptionPreconditionUtils;
import com.blockchain.server.eos.common.constant.EosConstant;
import com.blockchain.server.eos.common.util.RedisUtil;
import com.blockchain.server.eos.dto.WalletInDTO;
import com.blockchain.server.eos.entity.BlockNumber;
import com.blockchain.server.eos.entity.Wallet;
import com.blockchain.server.eos.mapper.BlockNumberMapper;
import com.blockchain.server.eos.mapper.WalletInMapper;
import com.blockchain.server.eos.scheduleTask.TransferDisposeTimerTask;
import com.blockchain.server.eos.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
/**
* @author Harvey
* @date 2019/2/16 17:49
* @user WIN10
*/
@Service
public class EosBlockNumberServiceImpl implements EosBlockNumberService {
@Autowired
private BlockNumberMapper blockNumberMapper;
@Autowired
private EosWalletUtilService eosWalletUtilService;
@Autowired
private EosWalletService eosWalletService;
@Autowired
private EosWalletTransferService eosWalletTransferService;
@Autowired
private EosWalletInService eosWalletInService;
@Autowired
private RedisTemplate redisTemplate;
// 日志
private static final Logger LOG = LoggerFactory.getLogger(TransferDisposeTimerTask.class);
/**
* 查询最大区块
*
* @return
*/
@Override
public BigInteger selectCurrentBlockNum() {
BigInteger current = RedisUtil.getCurrentBlock(redisTemplate);
if (current == null) current = blockNumberMapper.selectMaxBlockNum();
return current;
}
/**
* 添加区块交易信息
*
* @param nowBlock 区块号
* @param listTokenAddr 所有系统代币地址
*/
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void handleBlockTransactions(BigInteger nowBlock, HashSet<String> listTokenAddr) {
ExceptionPreconditionUtils.notEmpty(nowBlock);
ExceptionPreconditionUtils.notEmpty(listTokenAddr);
if (EosConstant.BlockNumber.EOS_BLOCK_NUMBER_WAIT.equals(blockNumberMapper.selectBlockNumStatusByBlockNum(nowBlock))) {
// 查询eos此区块所有交易信息
JSONObject resultData = eosWalletUtilService.listBlockTransaction(nowBlock);
if (resultData != null) {
JSONArray transactions = resultData.getJSONArray("transactions");
if (transactions.size() > 0) {
for (int i = 0; i < transactions.size(); i++) {
// 遍历 jsonarray 数组,把每一个对象转成 json 对象
JSONObject job = transactions.getJSONObject(i);
JSONObject trx = null;
try {
trx = job.getJSONObject("trx");
} catch (Exception e) {
continue;
}
String hash = trx.getObject("id", String.class);
JSONObject transaction = trx.getJSONObject("transaction");
if (transaction.size() > 0) {
JSONArray actions = transaction.getJSONArray("actions");
JSONObject action = actions.getJSONObject(0);
// System.out.println("action: " + action);
JSONObject data = null;
try {
data = action.getJSONObject("data");
} catch (Exception e) {
continue;
}
if (null != data && !"".equals(data)) {
// 解析收款地址是否平台收款地址
String to = data.getObject("to", String.class);
if(to == null) continue;
List<WalletInDTO> walletInDTOS = eosWalletInService.listWalletInByAccountName(to);
if (walletInDTOS != null && walletInDTOS.size() > 0) {
// 解析区块信息,获取充值记录
String from = data.getObject("from", String.class);
String tokenName = action.getObject("account", String.class);
// String hexData = action.getObject("hex_data", String.class);
String quantity = data.getObject("quantity", String.class);
String[] quantitys = null;
if (null != quantity && quantity.length() > 0) quantitys = quantity.split(" ");
// 备注格式为备注 钱包地址
String memo = data.getObject("memo", String.class).trim();
for (WalletInDTO walletInDTO : walletInDTOS) {
// 判断代币地址
if (tokenName.equals(walletInDTO.getTokenName())) {
Wallet wallet = eosWalletService.selectWalletById(memo);
if (null != wallet) {
// 判断token_name 和 token_symbol
if (wallet.getTokenName().equals(tokenName) && wallet.getTokenSymbol().equals(quantitys[1])) {
// 添加充值记录
eosWalletTransferService.handleWalletAndWalletTransfer(hash,
wallet.getId(),
null,
EosConstant.TransferType.TRANSFER_IN,
new BigDecimal(quantitys[0]),
tokenName,
quantitys[1],
memo,
nowBlock);
LOG.info("************************充值成功:" + hash + " + " + wallet.getId() + " + " + quantity + " + " + memo + "************************");
}
}
}
}
}
}
}
}
}
}
}
}
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public int insertBlockNumber(BlockNumber blockNumber) {
// System.out.println("添加区块高度");
return blockNumberMapper.insertSelectiveIgnore(blockNumber);
}
/**
* 插入区块处理状态
*
* @param nowBlock
* @param status
* @return
*/
@Override
@Transactional
public int insertBlockNumberByStatus(BigInteger nowBlock, Character status) {
BlockNumber blockNumber = new BlockNumber();
blockNumber.setBlockNumber(nowBlock);
blockNumber.setStatus(status);
blockNumber.setCreateTime(new Date());
return this.insertBlockNumber(blockNumber);
}
/**
* 根据区块状态获取区块
*
* @param status
* @return
*/
@Override
public List<BigInteger> listBlockNumberByStatus(Character status) {
return blockNumberMapper.listBlockNumberByStatus(status);
}
/**
* 更新处理区块状态
*
* @param blockNum
* @param status
* @return
*/
@Override
@Transactional
public int updateBlockNumberByStatus(BigInteger blockNum, Character status) {
return blockNumberMapper.updateBlockNumberByStatus(blockNum, status);
}
}

@ -8,7 +8,6 @@ import com.blockchain.server.eos.service.EosTokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
/**
@ -24,6 +23,7 @@ public class EosTokenServiceImpl implements EosTokenService {
/**
* 根据币种名称查询币种信息
*
* @param tokenName
* @return
*/
@ -33,17 +33,9 @@ public class EosTokenServiceImpl implements EosTokenService {
return tokenMapper.selectEosTokenByTokenName(tokenName);
}
/**
* 查询所有代币名称
* @return
*/
@Override
public HashSet<String> listTokenNameAll() {
return tokenMapper.listTokenNameAll();
}
/**
* 查找所有币种信息
*
* @return
*/
@Override

@ -1,20 +1,12 @@
package com.blockchain.server.eos.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.common.base.util.ExceptionPreconditionUtils;
import com.blockchain.server.eos.common.constant.EosConstant;
import com.blockchain.server.eos.common.util.EosUtil;
import com.blockchain.server.eos.dto.WalletInDTO;
import com.blockchain.server.eos.mapper.WalletInMapper;
import com.blockchain.server.eos.service.EosWalletInService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.List;
/**
* @author Harvey
@ -26,11 +18,10 @@ public class EosWalletInServiceImpl implements EosWalletInService {
@Autowired
private WalletInMapper walletInMapper;
@Autowired
private EosUtil eosUtil;
/**
* 查询对应的代币名称充值账户
*
* @param tokenName
* @return
*/
@ -40,50 +31,5 @@ public class EosWalletInServiceImpl implements EosWalletInService {
return walletInMapper.selectWalletInAccount(tokenName, EosConstant.WalletInStatus.EOS_WALLET_IN_USABLE);
}
/**
* 查询充值资金账户
* @param to
* @return
*/
@Override
public List<WalletInDTO> listWalletInByAccountName(String to) {
ExceptionPreconditionUtils.notEmpty(to);
return walletInMapper.listWalletInByAccountName(to);
}
/**
* 充值方法
*
* @param listTokenName
*/
@Override
@Transactional
public void handleAccountBlockTransactions(HashSet<String> listTokenName) {
for (String tokenName : listTokenName) {
WalletInDTO walletInDTO = this.selectWalletInAccount(tokenName);
JSONArray actions = eosUtil.recursion(walletInDTO, EosConstant.RPCConstant.OFFSET);
if (actions == null) return;
Integer row = updateWalletInBlockNumber(walletInDTO, actions);
if (row != 1) return;
eosUtil.handTransaction(actions, tokenName, walletInDTO);
}
}
/**
* 修改资金账户区块字段
*
* @param walletInDTO
* @param actions
* @return
*/
private Integer updateWalletInBlockNumber(WalletInDTO walletInDTO, JSONArray actions) {
JSONObject job = actions.getJSONObject(actions.size() - 1);
JSONObject action_trace = job.getJSONObject("action_trace");
BigInteger blockNum = action_trace.getBigInteger("block_num");
return walletInMapper.updateWalletInBlockNumber(walletInDTO.getAccountName(), blockNum);
}
}

@ -10,7 +10,6 @@ import com.blockchain.common.base.util.ExceptionPreconditionUtils;
import com.blockchain.server.eos.common.constant.EosConstant;
import com.blockchain.server.eos.common.enums.EosWalletEnums;
import com.blockchain.server.eos.common.exception.EosWalletException;
import com.blockchain.server.eos.common.util.EosUtil;
import com.blockchain.server.eos.dto.WalletDTO;
import com.blockchain.server.eos.entity.*;
import com.blockchain.server.eos.feign.UserServerFegin;
@ -52,32 +51,9 @@ public class EosWalletServiceImpl implements EosWalletService, ITxTransaction {
private EosTokenService eosTokenService;
@Autowired
private UserServerFegin userServerFegin;
@Autowired
private EosUtil eosUtil;
@Autowired
private WalletInitConfigMapper walletInitConfigMapper;
/**
* 通过id查询钱包
*
* @param walletId
* @return
*/
@Override
public Wallet selectWalletById(String walletId) {
return walletMapper.selectByPrimaryKey(walletId);
}
@Override
public Wallet selectWalletByIdAndTokenName(Integer walletId, String tokenName) {
// 数据验证
Wallet where = new Wallet();
where.setId(walletId);
where.setTokenName(tokenName);
Wallet wallet = walletMapper.selectOne(where);
if (wallet == null) throw new EosWalletException(EosWalletEnums.EOSWALLET_GETWALLET_ERROR);
return wallet;
}
/**
* 用户充值修改钱包金额
@ -329,50 +305,13 @@ public class EosWalletServiceImpl implements EosWalletService, ITxTransaction {
}
@Override
public Boolean getTransaction(String blockNum, String hashId) {
ExceptionPreconditionUtils.notEmpty(blockNum);
ExceptionPreconditionUtils.notEmpty(hashId);
WalletTransfer walletTransfer = eosWalletTransferService.selectByHashId(hashId);
// 调用接口查询出币信息
return eosUtil.getTransactions(blockNum, hashId, walletTransfer);
}
@Override
@Transactional
public void updateTxOutError(WalletTransfer tx) {
Wallet wallet = this.selectWalletByIdAndTokenName(tx.getFromId(), tx.getTokenName());
Date date = new Date();
// 业务操作(1)- 恢复提现余额
BigDecimal amount = tx.getAmount();
int row = walletMapper.updateWalletAllBalanceInRowLock(BigDecimal.ZERO, amount, amount.negate(), wallet.getUserOpenId(), wallet.getTokenName(), wallet.getWalletType(), date);
if (row == 0) throw new EosWalletException(EosWalletEnums.GET_PUBLICKEY_ERROR);
// 业务操作(2)- 修改记录状态
eosWalletTransferService.updateStatus(tx.getId(), EosConstant.TransferStatus.DEFEATED, date);
}
@Override
@Transactional
public void updateTxOutSuccess(WalletTransfer tx) {
// 数据验证
Wallet wallet = this.selectWalletByIdAndTokenName(tx.getFromId(), tx.getTokenName());
Date date = new Date();
// 业务操作(1)- 扣除提现余额
BigDecimal amount = tx.getAmount();
int row = walletMapper.updateWalletAllBalanceInRowLock(amount.negate(), BigDecimal.ZERO, amount.negate(), wallet.getUserOpenId(), wallet.getTokenName(), wallet.getWalletType(), date);
if (row == 0) throw new EosWalletException(EosWalletEnums.GET_PUBLICKEY_ERROR);
// 业务操作(2)- 修改记录状态
eosWalletTransferService.updateStatus(tx.getId(), EosConstant.TransferStatus.SUCCESS, date);
}
@Override
public Wallet findWallet(String userId,String walletType, String coinName) {
public Wallet findWallet(String userId, String walletType, String coinName) {
Wallet where = new Wallet();
where.setWalletType(walletType);
where.setTokenSymbol(coinName);
where.setUserOpenId(userId);
Wallet wallet = walletMapper.selectOne(where);
if(wallet == null) {
if (wallet == null) {
throw new EosWalletException(EosWalletEnums.INEXISTENCE_WALLET);
}
return wallet;
@ -389,8 +328,8 @@ public class EosWalletServiceImpl implements EosWalletService, ITxTransaction {
count = eosApplicationService.selectWalletCountByWalletType(toType);
if (count < 1) throw new EosWalletException(EosWalletEnums.EOSWALLET_GETWALLET_ERROR);
Token token = eosTokenService.selectByTokenSymbol(coinName);
Wallet fromWallet = this.findWallet(userOpenId,fromType,coinName);
Wallet toWallet = this.findWallet(userOpenId,toType,coinName);
Wallet fromWallet = this.findWallet(userOpenId, fromType, coinName);
Wallet toWallet = this.findWallet(userOpenId, toType, coinName);
//该用户减去提现可用余额、总额
count = walletMapper.updateWalletAllBalanceInRowLock(amount.negate(),
amount.negate(),
@ -439,11 +378,11 @@ public class EosWalletServiceImpl implements EosWalletService, ITxTransaction {
walletInitConfig.setWalletType(walletType);
WalletInitConfig config = walletInitConfigMapper.selectOne(walletInitConfig);
if(config==null || config.getBalance()==null){
if (config == null || config.getBalance() == null) {
throw new EosWalletException(EosWalletEnums.RESET_ERROR);
}
// 修改钱包插入充值记录
walletMapper.updateWalletBalanceByUserOpenId(config.getBalance(),userOpenId,tokenId,walletType,new Date());
walletMapper.updateWalletBalanceByUserOpenId(config.getBalance(), userOpenId, tokenId, walletType, new Date());
}
}

@ -1,27 +1,17 @@
package com.blockchain.server.eos.service.impl;
import com.blockchain.common.base.util.ExceptionPreconditionUtils;
import com.blockchain.server.eos.common.constant.EosConstant;
import com.blockchain.server.eos.common.enums.EosWalletEnums;
import com.blockchain.server.eos.common.exception.EosWalletException;
import com.blockchain.server.eos.dto.WalletDTO;
import com.blockchain.server.eos.dto.WalletTransferDTO;
import com.blockchain.server.eos.entity.WalletTransfer;
import com.blockchain.server.eos.mapper.WalletTransferMapper;
import com.blockchain.server.eos.service.EosWalletService;
import com.blockchain.server.eos.service.EosWalletTransferService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* @author Harvey
@ -36,45 +26,6 @@ public class EosWalletTransferServiceImpl implements EosWalletTransferService {
@Autowired
private WalletTransferMapper walletTransferMapper;
/**
* 添加记录并修改账户金额
*
* @param hash
* @param transferType
* @param amount
* @param tokenName
* @param tokenSymbol
* @param memo
* @param accountId
* @return
*/
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public int handleWalletAndWalletTransfer(String hash, Integer accountId, String accountName, String transferType, BigDecimal amount, String tokenName, String tokenSymbol, String memo, BigInteger blockNumber) {
Date now = new Date();
WalletTransfer walletTransfer = new WalletTransfer();
walletTransfer.setId(UUID.randomUUID().toString());
walletTransfer.setRemark(memo);
walletTransfer.setTimestamp(now);
walletTransfer.setBlockNumber(blockNumber.toString());
// 充值保存数据
if (EosConstant.TransferType.TRANSFER_IN.equals(transferType)) {
walletTransfer.setHash(hash);
walletTransfer.setAmount(amount);
walletTransfer.setTokenName(tokenName);
walletTransfer.setTokenSymbol(tokenSymbol);
walletTransfer.setToId(accountId);
walletTransfer.setTransferType(EosConstant.TransferType.TRANSFER_IN);
}
walletTransfer.setStatus(EosConstant.TransferStatus.SUCCESS);
this.insertWalletTransfer(walletTransfer);
// 添加一条交易记录
// 修改账户金额
return eosWalletService.updateWalletBalanceByIdInRowLock(amount, accountId, now);
}
/**
* 插入交易记录
*
@ -103,51 +54,4 @@ public class EosWalletTransferServiceImpl implements EosWalletTransferService {
return walletTransferMapper.listWalletTransfer(walletId, tokenName);
}
@Override
public List<WalletTransfer> selectByTxTypeAndStatus(String transferType, int Status, Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
WalletTransfer where = new WalletTransfer();
where.setTransferType(transferType);
where.setStatus(Status);
return walletTransferMapper.select(where);
}
@Override
@Transactional
public void updateStatus(String id, int status, Date date) {
WalletTransfer ethWalletTransfer = walletTransferMapper.selectByPrimaryKey(id);
ExceptionPreconditionUtils.checkNotNull(ethWalletTransfer, new EosWalletException(EosWalletEnums.INEXISTENCE_TX));
ethWalletTransfer.setStatus(status);
ethWalletTransfer.setTimestamp(date);
// 失败抛出异常
int row = walletTransferMapper.updateByPrimaryKeySelective(ethWalletTransfer);
if (row == 0) throw new EosWalletException(EosWalletEnums.GET_PUBLICKEY_ERROR);
}
/**
* 根据hash查询交易记录
* @param hashId
* @return
*/
@Override
public WalletTransfer selectByHashId(String hashId) {
WalletTransfer example = new WalletTransfer();
example.setHash(hashId);
return walletTransferMapper.selectOne(example);
}
/**
* 根据hash查询是否存在数据
* @param hash
* @param transferType
* @return
*/
@Override
public Integer countByHashAndTransferType(String hash, String transferType) {
ExceptionPreconditionUtils.notEmpty(hash);
ExceptionPreconditionUtils.notEmpty(transferType);
return walletTransferMapper.countByHashAndTransferType(hash, transferType);
}
}

@ -1,109 +0,0 @@
package com.blockchain.server.eos.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.blockchain.server.eos.dto.BlockNumberDTO;
import com.blockchain.server.eos.eos4j.Rpc;
import com.blockchain.server.eos.eos4j.api.vo.ChainInfo;
import com.blockchain.server.eos.service.EosBlockNumberService;
import com.blockchain.server.eos.service.EosWalletUtilService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.math.BigInteger;
/**
* @author Harvey
* @date 2019/2/18 13:57
* @user WIN10
*/
@Service
public class EosWalletUtilServiceImpl implements EosWalletUtilService {
@Autowired
private EosBlockNumberService eosBlockNumberService;
private Rpc eosRpc = null;
@Value("${rpc_url}")
private String RPC_URL;
@Value("${get_block_url}")
private String GET_BLOCK_URL;
@Value("${get_transaction}")
private String GET_TRANSACTION_URL;
@Value("${get_actions}")
private String GET_ACTIONS;
@Override
public BigInteger getEosBlock() {
eosRpc = new Rpc(RPC_URL);
ChainInfo chainInfo = eosRpc.getChainInfo();
String headBlockNum = chainInfo.getHeadBlockNum();
return new BigInteger(headBlockNum);
}
/**
* 获取区块交易信息
*
* @param nowBlock
* @return
*/
@Override
public JSONObject listBlockTransaction(BigInteger nowBlock) {
eosRpc = new Rpc(RPC_URL);
String url = RPC_URL + GET_BLOCK_URL;
ResponseEntity<JSONObject> body = eosRpc.get_block(url, nowBlock);
if (body != null) return body.getBody();
return null;
}
@Override
public BlockNumberDTO getBlockNum() {
BigInteger newstBlock = this.getEosBlock(); //最新区块
// 从redis获取区块信息
// 当前区块高度
BigInteger current = eosBlockNumberService.selectCurrentBlockNum();
if (current == null) current = newstBlock;
// 判断当前区块是否大于最新区块
if (current.compareTo(newstBlock) > 0) newstBlock = this.getEosBlock(); //最新区块
BlockNumberDTO blockNumberDTO = new BlockNumberDTO();
blockNumberDTO.setCurrentBlock(current);
blockNumberDTO.setNewBlock(newstBlock);
return blockNumberDTO;
}
/**
* 获取出币信息
*
* @param blockNum
* @param hashId
* @return
*/
@Override
public JSONObject getTransaction(String blockNum, String hashId) {
eosRpc = new Rpc(RPC_URL);
String url = RPC_URL + GET_TRANSACTION_URL;
ResponseEntity<JSONObject> body = eosRpc.getTransaction(url, blockNum, hashId);
if (body != null) return body.getBody();
return null;
}
/**
* 获取账户历史交易信息
*
* @param accountName
* @return
*/
@Override
public JSONObject getActions(String accountName, String offset) {
eosRpc = new Rpc(RPC_URL);
String url = RPC_URL + GET_ACTIONS;
ResponseEntity<JSONObject> body = eosRpc.getActions(url, accountName, offset);
if (body != null) return body.getBody();
return null;
}
}

@ -1,55 +0,0 @@
<?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="com.blockchain.server.eos.mapper.BlockNumberMapper">
<resultMap id="BlockNumber" type="com.blockchain.server.eos.dto.BlockNumberDTO">
<result property="blockNumber" column="block_number"/>
<result property="endBlockNumber" column="end_block_number"/>
<result property="createTime" column="create_time"/>
</resultMap>
<sql id="tableName">dapp_eos_block_number</sql>
<select id="selectMinBlockNum" resultType="java.math.BigInteger">
select block_number from <include refid="tableName"/>
order by block_number asc limit 0, 1
</select>
<select id="selectMaxBlockNum" resultType="java.math.BigInteger">
select block_number from <include refid="tableName"/>
order by block_number desc limit 0, 1
</select>
<select id="selectBlockNumIsExist" resultType="java.math.BigInteger" resultMap="BlockNumber">
select block_number, create_time from <include refid="tableName"/>
where block_number = #{blockNum}
</select>
<select id="selectBlockNumStatusByBlockNum" parameterType="java.math.BigInteger" resultType="java.lang.Character">
select status
from <include refid="tableName"/>
where block_number = #{blockNum}
</select>
<!-- 该方法为查漏区块方法,此处的100为查询最高区块下面的区块,防止重复处理最新区块-->
<select id="listBlockNumberByStatus" parameterType="java.lang.Character" resultType="java.math.BigInteger">
SELECT block_number FROM <include refid="tableName"/>
WHERE status = #{status}
AND block_number &lt; (SELECT block_number
FROM <include refid="tableName"/> ORDER BY block_number desc LIMIT 1) - 100
</select>
<update id="updateBlockNumberByStatus">
update <include refid="tableName"/>
set status = #{status}
where block_number = #{blockNum}
</update>
<insert id="insertSelectiveIgnore" parameterType="com.blockchain.server.eos.entity.BlockNumber">
insert ignore into <include refid="tableName"/>
(block_number, status, create_time)
value (#{blockNumber}, #{status}, #{createTime})
</insert>
</mapper>

@ -13,10 +13,6 @@
</resultMap>
<sql id="tableName">dapp_eos_token</sql>
<select id="listTokenNameAll" resultType="java.lang.String">
select token_name from <include refid="tableName"/>
</select>
<select id="selectEosTokenByTokenName" parameterType="java.lang.String" resultMap="WalletTokenMap">
select token_name, token_symbol, issue_time, total_supply, total_circulation, descr from <include refid="tableName"/>

@ -14,12 +14,6 @@
</resultMap>
<sql id="tableName">dapp_eos_wallet_in</sql>
<select id="listWalletInByAccountName" parameterType="java.lang.String" resultMap="walletInMap">
select id, account_name, token_name, token_symbol, remark, status, block_number
from <include refid="tableName"/>
where account_name = #{to}
</select>
<select id="selectWalletInAccount" resultMap="walletInMap">
select id, account_name, token_name, token_symbol, remark, status, block_number
@ -28,12 +22,4 @@
and status = #{status}
</select>
<update id="updateWalletInBlockNumber">
update
<include refid="tableName"/>
set
block_number = #{blockNum}
where account_name = #{accountName}
</update>
</mapper>

@ -31,15 +31,6 @@
wallet.id = #{id}
</update>
<select id="selectWalletByUserOpenId" parameterType="java.lang.String" resultMap="walletMap">
select id, token_name, user_open_id, token_symbol, balance, free_balance, freeze_balance, create_time,
update_time, wallet_type
from
<include refid="tableName"/>
where user_open_id = #{userOpenId}
and token_name = #{tokenName}
</select>
<update id="updateWalletAllBalanceInRowLock">
UPDATE <include refid="tableName"/> wallet
SET

@ -1,141 +0,0 @@
package com.blockchain.server.eth.scheduleTask;
import com.blockchain.server.eth.common.constants.EthWalletConstants;
import com.blockchain.server.eth.common.util.RedisBlockUtil;
import com.blockchain.server.eth.entity.EthBlockNumber;
import com.blockchain.server.eth.entity.EthToken;
import com.blockchain.server.eth.service.IEthBlockNumberService;
import com.blockchain.server.eth.service.IEthTokenService;
import com.blockchain.server.eth.service.IEthWalletKeyService;
import com.blockchain.server.eth.web3j.IWalletWeb3j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 充值记录爬取的定时器
*/
//@Component
public class EthTxInTimerTask {
static ExecutorService singleThreadExecutorNormal = Executors.newSingleThreadExecutor();
static ExecutorService singleThreadExecutorOmit = Executors.newSingleThreadExecutor();
// 日志
static final Logger LOG = LoggerFactory.getLogger(EthTxInTimerTask.class);
// 区块与当前爬取区块的偏差量
static final BigInteger BIAS_CURRENT = BigInteger.valueOf(20);
// 规定遗漏爬取区块的时间差
static final long TIME_DIFFERENCE = 60;
@Autowired
IEthBlockNumberService ethBlockNumberService;
@Autowired
IWalletWeb3j walletWeb3j;
@Autowired
IEthWalletKeyService ethWalletKeyService;
@Autowired
IEthTokenService ethTokenService;
@Autowired
RedisTemplate redisTemplate;
/**
* 充值记录爬取
*/
@Scheduled(cron = "0/10 * * * * ?")
public void crawlTxIn() {
singleThreadExecutorNormal.execute(new Runnable() {
@Override
public void run() {
crawlTxInDispose(); // 爬取充值记录
}
});
}
/**
* 查询以太坊遗漏的以太坊数据
*/
@Scheduled(cron = "0/30 * * * * ?")
public void crawlOmitTxIn() {
singleThreadExecutorOmit.execute(new Runnable() {
@Override
public void run() {
crawlOmitTxInDispose(); // 爬取遗漏数据的业务逻辑
}
});
}
/**
* 充值记录爬取处理方法
*/
void crawlTxInDispose() {
BigInteger newestBlock = ethBlockNumberService.selectNewest(); // 获取最新区块
BigInteger currentBlock = ethBlockNumberService.selectCurrent(); //当前区块
// 缓冲区块差为10个,不足退出
if (newestBlock.compareTo(currentBlock.add(BIAS_CURRENT)) < 0) return;
Map<String, EthToken> coinAddrs = ethTokenService.selectMaps(); // 获取所有币种地址
Set<String> adds = ethWalletKeyService.selectAddrs(); // 获取所有用户钱包地址
// 遍历爬取区块
for (int i = 0; i < 10; i++) {
currentBlock = currentBlock.add(BigInteger.ONE);
try {
// 插入当前区块号
ethBlockNumberService.insert(currentBlock, EthWalletConstants.StatusType.BLOCK_WAIT);
// 插入区块号的充值数据,修改区块状态
ethBlockNumberService.handleBlockTxIn(currentBlock, coinAddrs, adds);
} catch (Exception e) {
}
RedisBlockUtil.setBlockCurrent(currentBlock, redisTemplate);
}
}
/**
* 充值记录遗漏爬取的处理方法
*/
void crawlOmitTxInDispose() {
Map<String, EthToken> coinAddrs = ethTokenService.selectMaps(); // 获取所有币种地址
Set<String> adds = ethWalletKeyService.selectAddrs(); // 获取所有用户钱包地址
BigInteger currentBlock = ethBlockNumberService.selectCurrent(); // 当前区块
// 获取当前区块的创建时间
long currentBlockTime = ethBlockNumberService.selectByBlockNumber(currentBlock).getCreateTime().getTime();
List<EthBlockNumber> blockWaits = ethBlockNumberService.selectWaitBlocks(); // 获取等待区块列表
for (EthBlockNumber row : blockWaits) {
long rowTime = row.getCreateTime().getTime(); // 获取等待区块的时间
long diffTime = (currentBlockTime - rowTime) / 1000; // 获取时间差
if (diffTime <= TIME_DIFFERENCE) return; // 区块时间未超过一分钟,跳出处理
int count = RedisBlockUtil.getBlockOptMapCount(row.getBlockNumber(), redisTemplate); // 获取爬取次数
if (count >= 5) { // 爬取次数超过五次跳出
RedisBlockUtil.delBlockOptMapCount(row.getBlockNumber(), redisTemplate);
ethBlockNumberService.updateByBlockNumber(row.getBlockNumber(),
EthWalletConstants.StatusType.BLOCK_ERROR);
return;
}
// 爬取次数 + 1
RedisBlockUtil.incrementBlockOptMapCount(row.getBlockNumber(), redisTemplate);
try {
// 插入区块号的充值数据,修改区块状态
ethBlockNumberService.handleBlockTxIn(row.getBlockNumber(), coinAddrs, adds);
RedisBlockUtil.delBlockOptMapCount(row.getBlockNumber(), redisTemplate);
} catch (Exception e) {
}
}
}
}

@ -1,116 +0,0 @@
package com.blockchain.server.eth.scheduleTask;
import com.blockchain.server.eth.common.constants.EthWalletConstants;
import com.blockchain.server.eth.common.util.RedisBlockUtil;
import com.blockchain.server.eth.entity.EthToken;
import com.blockchain.server.eth.entity.EthWalletTransfer;
import com.blockchain.server.eth.service.*;
import com.blockchain.server.eth.web3j.IWalletWeb3j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 钱包业务处理的定时器
*/
//@Component
public class EthWallertTimerTask {
// 钱包充值处理
private static ExecutorService txInExecutorService = Executors.newSingleThreadExecutor();
// 钱包提现处理
private static ExecutorService txOutExecutorService = Executors.newSingleThreadExecutor();
// 日志
private static final Logger LOG = LoggerFactory.getLogger(EthWallertTimerTask.class);
@Autowired
IEthWalletService ethWalletService;
@Autowired
IEthWalletTransferService ethWalletTransferService;
@Autowired
IWalletWeb3j walletWeb3j;
@Scheduled(cron = "0/10 * * * * ?")
public void crawlTxIn() {
txInExecutorService.execute(new Runnable() {
@Override
public void run() {
crawlTxInDispose(); // 爬取充值记录
}
});
}
@Scheduled(cron = "0/10 * * * * ?")
public void crawlTxOut() {
txOutExecutorService.execute(new Runnable() {
@Override
public void run() {
crawlTxOutDispose(); // 爬取提现记录
}
});
}
void crawlTxInDispose() {
// 查询充值的未处理的数据
List<EthWalletTransfer> txs =
ethWalletTransferService.selectByTxTypeAndStatus(EthWalletConstants.TransferType.IN,
EthWalletConstants.StatusType.IN_LOAD, 0, 99);
// 查询记录打包状态
for (EthWalletTransfer tx : txs) {
try {
tx = ethWalletTransferService.updateGas(tx); // 修改记录的旷工费用
if (tx.getStatus() == EthWalletConstants.StatusType.IN_SUCCESS) {
// 修改余额改变成功状态
ethWalletService.updateBlanceTxIn(tx);
} else if (tx.getStatus() == EthWalletConstants.StatusType.IN_ERROR) {
// 修改失败状态
ethWalletTransferService.updateStatus(tx);
}
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
void crawlTxOutDispose() {
// 查询提现的未处理的数据
List<EthWalletTransfer> txs =
ethWalletTransferService.selectByTxTypeAndStatus(EthWalletConstants.TransferType.OUT,
EthWalletConstants.StatusType.OUT_LOAD4, 0, 99);
// 查询记录打包状态
for (EthWalletTransfer tx : txs) {
try {
tx = ethWalletTransferService.updateGas(tx); // 修改记录的旷工费用
if (tx.getStatus() == EthWalletConstants.StatusType.IN_ERROR) {
// 修改失败状态
ethWalletService.updateTxOutError(tx);
} else if (tx.getStatus() == EthWalletConstants.StatusType.IN_SUCCESS) {
// 修改余额改变成功状态
ethWalletService.updateTxOutSuccess(tx);
}
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
}

@ -1,80 +0,0 @@
package com.blockchain.server.eth.service;
import com.blockchain.server.eth.entity.EthBlockNumber;
import com.blockchain.server.eth.entity.EthToken;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 以太坊区块高度记录表业务接口
*
* @author YH
* @date 2019年2月16日17:09:19
*/
public interface IEthBlockNumberService {
/**
* 插入一个区块
*
* @param blockNumber 区块号
* @param status 状态
*/
void insert(BigInteger blockNumber, char status);
/**
* 插入一个区块的状态
*
* @param blockNumber 区块号
* @param status 状态
*/
void updateByBlockNumber(BigInteger blockNumber, char status);
/**
* 查询区块是否存在
*
* @param bigInteger 区块
* @return true存在false不存在
*/
boolean isBlock(BigInteger bigInteger);
/**
* 查询区块信息
*
* @param blockNumber
* @return
*/
EthBlockNumber selectByBlockNumber(BigInteger blockNumber);
/**
* 查询最大的区块号
*
* @return
*/
BigInteger selectCurrent();
/**
* 查询最新的区块号
*
* @return
*/
BigInteger selectNewest();
/**
* 获取查询等待中的区块号
*
* @return
*/
List<EthBlockNumber> selectWaitBlocks();
/**
* 插入该区块所有的平台用户充值记录
*
* @param blockNumber 区块号
*/
void handleBlockTxIn(BigInteger blockNumber, Map<String, EthToken> coinAddrs, Set<String> adds);
}

@ -1,205 +0,0 @@
package com.blockchain.server.eth.service.impl;
import com.blockchain.server.eth.common.constants.EthWalletConstants;
import com.blockchain.server.eth.common.util.DataCheckUtil;
import com.blockchain.server.eth.common.util.RedisBlockUtil;
import com.blockchain.server.eth.dto.Web3jTransferDTO;
import com.blockchain.server.eth.entity.EthBlockNumber;
import com.blockchain.server.eth.entity.EthToken;
import com.blockchain.server.eth.entity.EthWalletTransfer;
import com.blockchain.server.eth.mapper.EthBlockNumberMapper;
import com.blockchain.server.eth.service.*;
import com.blockchain.server.eth.web3j.IWalletWeb3j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.web3j.protocol.core.methods.response.EthBlock;
import org.web3j.protocol.core.methods.response.Transaction;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 以太坊区块高度记录表业务接口
*
* @author YH
* @date 2019年2月16日17:09:19
*/
@Service
public class EthBlockNumberServiceImpl implements IEthBlockNumberService {
static final String GAS_TOKENADDR = "eth"; // 默认手续费币种
static final String REGEX = "^0xa9059cbb.+"; // 转账正则判断
static final Pattern PATTERN = Pattern.compile("^(.+)(.{64})(.{64}$)"); // input 数据解析
static final BigInteger BIAS_CURRENT = BigInteger.valueOf(20);
@Autowired
EthBlockNumberMapper ethBlockNumberMapper;
@Autowired
IEthWalletKeyService ethWalletKeyService;
@Autowired
IEthTokenService ethTokenService;
@Autowired
IEthWalletTransferService ethWalletTransferService;
@Autowired
IEthGasWalletService ethGasWalletService;
@Autowired
IWalletWeb3j walletWeb3j;
@Autowired
RedisTemplate redisTemplate;
@Override
@Transactional
public void insert(BigInteger blockNumber, char status) {
Date date = new Date();
EthBlockNumber ethBlockNumber = new EthBlockNumber();
ethBlockNumber.setBlockNumber(blockNumber);
ethBlockNumber.setCreateTime(date);
ethBlockNumber.setUpdateTime(date);
ethBlockNumber.setStatus(status);
ethBlockNumberMapper.insertSelective(ethBlockNumber);
}
@Override
@Transactional
public void updateByBlockNumber(BigInteger blockNumber, char status) {
EthBlockNumber ethBlockNumber = ethBlockNumberMapper.selectByPrimaryKey(blockNumber);
if (ethBlockNumber == null) {
insert(blockNumber, status);
} else {
Date date = new Date();
ethBlockNumber.setUpdateTime(date);
ethBlockNumber.setStatus(status);
ethBlockNumberMapper.updateByPrimaryKeySelective(ethBlockNumber);
}
}
@Override
public boolean isBlock(BigInteger bigInteger) {
EthBlockNumber ethBlockNumber = ethBlockNumberMapper.selectByPrimaryKey(bigInteger);
return ethBlockNumber != null;
}
@Override
public EthBlockNumber selectByBlockNumber(BigInteger blockNumber) {
return ethBlockNumberMapper.selectByPrimaryKey(blockNumber);
}
@Override
public BigInteger selectCurrent() {
BigInteger current = RedisBlockUtil.getBlockCurrent(redisTemplate);
if (current == null) {
current = ethBlockNumberMapper.selectMaxBlockNumber();
if(current == null){
current = walletWeb3j.getEthBlock();
}
RedisBlockUtil.setBlockCurrent(current, redisTemplate);
}
return current;
}
@Override
public BigInteger selectNewest() {
BigInteger newest = RedisBlockUtil.getBlockNewest(redisTemplate);
if (newest == null || newest.compareTo(selectCurrent().add(BIAS_CURRENT)) <= 0) {
newest = walletWeb3j.getEthBlock();
RedisBlockUtil.setBlockNewest(newest, redisTemplate);
}
return newest;
}
@Override
public List<EthBlockNumber> selectWaitBlocks() {
EthBlockNumber ethBlockNumber = new EthBlockNumber();
ethBlockNumber.setStatus(EthWalletConstants.StatusType.BLOCK_WAIT);
return ethBlockNumberMapper.select(ethBlockNumber);
}
@Override
@Transactional
public void handleBlockTxIn(BigInteger blockNumber, Map<String, EthToken> coinAddrs, Set<String> adds) {
// 查询该区块的所有交易记录
List<EthBlock.TransactionResult> txResults = walletWeb3j.getTokenTransactionList(blockNumber);
for (EthBlock.TransactionResult<Transaction> txResult : txResults) {
Transaction tx = txResult.get();
// 忽略打油费的钱包的充值
if(ethGasWalletService.isGasWallet(tx.getFrom())){
continue;
}
if (coinAddrs.containsKey(tx.getTo())) { // 充值ETH代币
if (!tx.getInput().matches(REGEX)) continue;
Web3jTransferDTO transferDTO = getTokenWalletDto(tx, coinAddrs.get(tx.getTo()));
if (adds.contains(transferDTO.getToAddr())) {
// 插入ETH代币钱包充值记录
ethWalletTransferService.insert(transferDTO.getHash(), transferDTO.getFromAddr(),
transferDTO.getToAddr(), transferDTO.getAmount(), transferDTO.getGasPrice(),
coinAddrs.get(tx.getTo()),
coinAddrs.get(GAS_TOKENADDR),
EthWalletConstants.TransferType.IN, EthWalletConstants.StatusType.IN_LOAD, new Date());
}
} else if (adds.contains(tx.getTo())) { // 充值ETH
Web3jTransferDTO transferDTO = getWalletDto(tx);
// 插入ETH钱包充值记录
ethWalletTransferService.insert(transferDTO.getHash(), transferDTO.getFromAddr(),
transferDTO.getToAddr(), transferDTO.getAmount(), transferDTO.getGasPrice(),
coinAddrs.get(GAS_TOKENADDR),
coinAddrs.get(GAS_TOKENADDR),
EthWalletConstants.TransferType.IN, EthWalletConstants.StatusType.IN_LOAD, new Date());
}
}
// 修改当前区块为成功
updateByBlockNumber(blockNumber, EthWalletConstants.StatusType.BLOCK_SUCCESS);
}
/**
* 代币数据DTO
*
* @param transaction 数据信息
* @return
*/
private Web3jTransferDTO getTokenWalletDto(Transaction transaction, EthToken coin) {
Matcher matcher = PATTERN.matcher(transaction.getInput());
matcher.matches();
String toAddr = matcher.group(2).replaceAll(".+(.{40})", "0x$1");
BigInteger amount = new BigInteger(matcher.group(3).replaceAll("0+(.+)", "$1"), 16);
Web3jTransferDTO transferDTO = new Web3jTransferDTO();
transferDTO.setHash(transaction.getHash());
transferDTO.setFromAddr(transaction.getFrom());
transferDTO.setToAddr(toAddr);
transferDTO.setTokenAddr(transaction.getTo());
transferDTO.setGasPrice(new BigDecimal(transaction.getGasPrice()));
transferDTO.setAmount(DataCheckUtil.bitToBigDecimal(amount, coin.getTokenDecimals()));
return transferDTO;
}
/**
* eth数据DTO
*
* @param transaction
* @return
*/
private Web3jTransferDTO getWalletDto(Transaction transaction) {
Web3jTransferDTO transferDTO = new Web3jTransferDTO();
transferDTO.setHash(transaction.getHash());
transferDTO.setFromAddr(transaction.getFrom());
transferDTO.setToAddr(transaction.getTo());
transferDTO.setTokenAddr(GAS_TOKENADDR);
transferDTO.setAmount(DataCheckUtil.bitToBigDecimal(transaction.getValue()));
transferDTO.setGasPrice(new BigDecimal(transaction.getGasPrice()));
return transferDTO;
}
}

@ -1,27 +0,0 @@
<?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="com.blockchain.server.eth.mapper.EthBlockNumberMapper">
<resultMap id="EthBlockNumberMap" type="com.blockchain.server.eth.entity.EthBlockNumber">
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="blockNumber" column="block_number"/>
<result property="status" column="status"/>
</resultMap>
<sql id="tableName">dapp_eth_block_number</sql>
<select id="selectMaxBlockNumber" resultType="BigInteger">
SELECT block_number FROM
<include refid="tableName"/>
ORDER BY block_number DESC LIMIT 1
</select>
<select id="selectMinBlockNumber" resultType="BigInteger">
SELECT block_number FROM
<include refid="tableName"/>
ORDER BY block_number ASC LIMIT 1
</select>
</mapper>
Loading…
Cancel
Save