BTC 比特币自动充值从公链拉去交易 本地保存区块高度

版权声明:望支持~~~ https://blog.csdn.net/u011663149/article/details/85296858

本地数据库保存区块高度:


@Order(value = 1)
@Service
public class BtcoinChargeServiceImpl implements BtcoinChargeService, CommandLineRunner {
	
	private Logger LOG = LoggerFactory.getLogger("btcoin");
	
	private static final String RECHARSTATE = "0";
	private static final String CURRENTTYPE = "BTC";
 
	
	@Value("${btcoin.block.confirm}")
	public int confirm;
	
	
	@Transactional(noRollbackFor = CoinException.class, rollbackFor = Exception.class)
	@Override
	public Object rechargeRecordByBlcokTx(String tx) throws CoinException {
		try {
			Map transaction = (Map) btcService.getTrawtransaction(tx, 1);
			if (null != transaction && !transaction.isEmpty()) {
				JSONObject info = JSONObject.parseObject(JSON.toJSONString(transaction));
				Integer confirms = info.getInteger("confirmations");
				if(confirms >= confirm){
					Long time = info.getLong("time");
					Long blocktime = info.getLong("blocktime");
					String txId = info.getString("txid");
					String blockHash = info.getString("blockhash");
					Map blockInfo = (Map) btcService.getblock(blockHash);
					JSONObject block = JSONObject.parseObject(JSON.toJSONString(blockInfo));
					Integer height = block.getInteger("height");
					// vin
					double sumvin = 0;
					double sumvout = 0;
					List<String> formAddress = new ArrayList<>();
					JSONArray vins = JSONArray.parseArray(info.getString("vin"));
					for (int z = 0, lenz = vins.size(); z < lenz; z++) {
						JSONObject vin = JSONObject.parseObject(vins.getString(z));
						String txid = vin.getString("txid");
						Integer vinN = vin.getInteger("vout");
						LOG.info("=== [BTC-Supple] search txid:{} trawtransaction! ===", txid);
						Map parentTransaction = (Map) btcService.getTrawtransaction(txid, 1);
						JSONObject parentInfo = JSONObject.parseObject(JSON.toJSONString(parentTransaction));
						JSONArray vouts = JSONArray.parseArray(parentInfo.getString("vout"));
						for (int j = 0, leg = vouts.size(); j < leg; j++) {
							JSONObject vout = vouts.getJSONObject(j);
							Integer n = vout.getInteger("n");
							if (n == vinN) { // 收款金额
								sumvin += vout.getDouble("value");
								JSONObject scriptPubKey = vout.getJSONObject("scriptPubKey");
								JSONArray addresses = scriptPubKey.getJSONArray("addresses");
								formAddress.add(addresses.getString(0));
							}
						}
					}
					
					// vout
					JSONArray vouts = JSONArray.parseArray(info.getString("vout"));
					for (int x = 0, lenx = vouts.size(); x < lenx; x++) {
						JSONObject vout = JSONObject.parseObject(vouts.getString(x));
						Integer n = vout.getInteger("n");
						JSONObject scriptPubKey = vout.getJSONObject("scriptPubKey");
						String hex = scriptPubKey.getString("hex");
						JSONArray addresses = scriptPubKey.getJSONArray("addresses");
						String receviceAddr = addresses.getString(0);
						if (n == 0) { // recharge = 0 , utxo
							// user addres from accout
							UserAccount user = userAccountMapper.selectAccountByAddress(receviceAddr, CURRENTTYPE);
							if (null != user) {
								Long userId = user.getUserId();
								String userAddress = user.getUserAddress();
								if (userAddress.equals(receviceAddr)) {
									double amount = vout.getDouble("value");
									if (amount > 0) {
										// count fee
										for (int w = 0, lenw = vouts.size(); w < lenw; w++) {
											JSONObject feevout = JSONObject.parseObject(vouts.getString(x));
											sumvout += feevout.getDouble("value");
										}
										try {
											LOG.info("=== [BTC-Supple] handling transaction data entry and storage !!! ===");
											//可以处理入库
											return;
										} catch (Exception e) {
											//可以处理入库
											LOG.info("===[BTC-Supple] record user recharge exception:{}  ===", e.getMessage(), e);
										}
									}
								}
							}
						}
					}
				}
			}
		} catch (CoinException e) {
			LOG.info("=== com.wallet.bit.service.btc.impl.BtcoinChargeServiceImpl.rechargeRecordByBlcokTx(String):{} ===", e.getMessage(), e);
			throw new CoinException(e.getMessage());
		}
		return false;
	}
	
	@Transactional(rollbackFor = CoinException.class)
	@Override
	public Object rechargeRecordFromBlockTx(List<UserAccount> userList) throws CoinException {
		Map<Object, Object> result = new HashMap<Object, Object>();
		try {
			// current block from mysql
			CoinBlockInfo blockInfo = blockMapper.selectByCoinType("BTC");
			int parseBlockCount = blockInfo.getBlockHeight(); 
			int blockCount = (int) btcService.getBlockCount(); 
			String blockHash = null;
			if (parseBlockCount > 0) {
				LOG.info("=== [BTC] the current BTC block height is {}, and the processing block height is {}. ===", blockCount, parseBlockCount);
				if (blockCount > parseBlockCount) {
					int current = parseBlockCount + 1;
					if ((blockCount - parseBlockCount) >= confirm) {
						try {
							blockHash = btcService.getBlockHash(current).toString();
							//LOG.info("=== [BTC] scan block [\theight:{}\t], [\thash:{}\t] begins !!! ===", current, blockHash);
							if (parseTransactionInfo(userList, blockHash, current)) {
								 LOG.info("=== [BTC] end of scan block [\theight:{}\t], [\thash:{}\t] !!! ===", current, blockHash);
								/* current height */
								blockInfo.setBlockHeight(current);
								blockInfo.setBlockHash(blockHash);
								blockInfo.setUpdateTime(new Date());
								if (blockMapper.updateByPrimaryKeySelective(blockInfo) > 0 ? true : false) {
									LOG.info("=== [BTC-LOCAL] current block height: {}, previous block height: {} ===", current, parseBlockCount);
								}
								current++;
							} /*else {
								break;
							}*/
						} catch (CoinException e) {
							LOG.info("=== [BTC] getting block information failed through block height.reason:{} ===", e.getMessage(), e);
							throw new CoinException(e.getMessage());
						}
					}
			/*	 if (current == blockCount) {
						// all block deal flish
						blockInfo.setBlockHeight(current);
						blockInfo.setBlockHash(blockHash);
						blockInfo.setUpdateTime(new Date());
						if (blockMapper.updateByPrimaryKeySelective(blockInfo) > 0 ? true : false) {
							LOG.info("=== [BTC-LOCAL] current block height: {}, previous block height: {} ===", current, parseBlockCount);
						}
					} else {
						int index = current - 1;
						blockInfo.setBlockHeight(index);
						blockInfo.setBlockHash(blockHash);
						blockInfo.setUpdateTime(new Date());
						if (blockMapper.updateByPrimaryKeySelective(blockInfo) > 0 ? true : false) {
							LOG.info("=== [BTC-LOCAL] current block height: {}, previous block height: {} ===", index, parseBlockCount);
						}
					}*/
				}
			}
		} catch (CoinException e) {
			LOG.info("=== com.wallet.bit.service.btc.impl.BtcoinChargeServiceImpl.rechargeRecordFromBlockTx(List<UserAccount>):{} ===", e.getMessage(), e);
			throw new CoinException(e.getMessage());
		}
		return result;
	}

	private boolean parseTransactionInfo(List<UserAccount> userList, String blockHash, int current) throws CoinException {
		Map block = (Map) btcService.getblock(blockHash);
		JSONObject blocks = JSONObject.parseObject(JSON.toJSONString(block));
		if (isError(blocks)) {
			LOG.info("=== [BTC] handling blockTransactions data errors !! ===");
			return false;
		}
		JSONArray txs = JSONArray.parseArray(blocks.getString("tx"));
		LOG.info("=== [BTC] scan block [\theight:{}\t], [\thash:{}\t], [\ttotal transactions:{}\t] begins !!! ===", current, blockHash, txs.size());
		for (int i = 0, len = txs.size(); i < len; i++) {
			String txId = txs.getString(i);
			// deal block
			//LOG.info("=== [BTC] scan block [\theight:{}\t], [\thash:{}\t], [\ttx:{}\t] begins !!! ===", current, blockHash, txId);
			parseBlockInfoByTxId(userList, txId, current);
			// LOG.info("=== [BTC] current blockheight:{},blockhash:{},txhash:{} operation completion!!", current, blockHash, txId);
		}
		return true;
	}
	/**
	 * @throws CoinException
	 * @Title: parseBlockInfoByTxId @param @param userList @param @param txId @param @throws CoinException 参数 @return void 返回类型 @throws
	 */
	private boolean parseBlockInfoByTxId(List<UserAccount> userList, String txId, int height) throws CoinException {
		try {
			Map transaction = (Map) btcService.getTrawtransaction(txId, 1);
			JSONObject info = JSONObject.parseObject(JSON.toJSONString(transaction));
			Integer confirm = info.getInteger("confirmations");
			Long time = info.getLong("time");
			Long blocktime = info.getLong("blocktime");
			// vin
			JSONArray vins = JSONArray.parseArray(info.getString("vin"));
			double sumvin = 0;
			double sumvout = 0;
			List<String> formAddress = new ArrayList<>();
			for (int z = 0, lenz = vins.size(); z < lenz; z++) {
				JSONObject vin = JSONObject.parseObject(vins.getString(z));
				String txid = vin.getString("txid");
				if (null != txid) {
					Integer vinN = vin.getInteger("vout");
	//				LOG.info("=== [BTC] search vins txid:{} trawtransaction! ===", txid);
					Map parentTransaction = (Map) btcService.getTrawtransaction(txid, 1);
					JSONObject parentInfo = JSONObject.parseObject(JSON.toJSONString(parentTransaction));
					JSONArray vouts = JSONArray.parseArray(parentInfo.getString("vout"));
					for (int j = 0, leg = vouts.size(); j < leg; j++) {
						JSONObject vout = vouts.getJSONObject(j);
						Integer n = vout.getInteger("n");
						if (n == vinN) { // 收款金额
							sumvin += vout.getDouble("value");
							JSONObject scriptPubKey = vout.getJSONObject("scriptPubKey");
							JSONArray addresses = scriptPubKey.getJSONArray("addresses");
							formAddress.add(addresses.getString(0));
						}
					}
				}
			}
			// vout
			JSONArray vouts = JSONArray.parseArray(info.getString("vout"));
			for (int x = 0, lenx = vouts.size(); x < lenx; x++) {
				JSONObject vout = JSONObject.parseObject(vouts.getString(x));
				Integer n = vout.getInteger("n");
				JSONObject scriptPubKey = vout.getJSONObject("scriptPubKey");
				String hex = scriptPubKey.getString("hex");
				String type = scriptPubKey.getString("type");// usdt charge
				if (!type.equals("nulldata")) {
					if (n == 0) { // recharge = 0 , utxo
						JSONArray addresses = scriptPubKey.getJSONArray("addresses");
						String receviceAddr = addresses.getString(0);
						for (UserAccount user : userList) {
							Long userId = user.getUserId();
							String userAddress = user.getUserAddress();
							if (userAddress.equals(receviceAddr)) {
								double amount = vout.getDouble("value");
								if (amount > 0) {
									// count fee
									for (int w = 0, lenw = vouts.size(); w < lenw; w++) {
										JSONObject feevout = JSONObject.parseObject(vouts.getString(x));
										sumvout += feevout.getDouble("value");
									}
									try {
										LOG.info("=== [BTC] handling transaction data entry and storage !!! ===");
										 //可以处理入库
									} catch (Exception e) {
										 //可以处理入库
										LOG.info("=== [BTC] record user recharge exception:{}  ===", e.getMessage(), e);
									}
								}
							}
						}
					}
				}
			}
		} catch (CoinException e) {
			LOG.info("=== com.wallet.bit.service.btc.impl.BtcoinChargeServiceImpl.parseBlockInfoByTxId(List<UserAccount>, String, int):{} ===", e.getMessage(), e);
			throw new CoinException(e.getMessage());
		}
		return false;
	}

  
	
	private boolean isError(JSONObject json) {
		if (json == null || (StringUtils.isNotEmpty(json.getString("error")) && json.get("error") != "null")) {
			return true;
		}
		return false;
	}
	
	@Override
	public void run(String... arg0) throws Exception {
		CoinBlockInfo blockInfo = blockMapper.selectByCoinType("BTC");
		if (null == blockInfo || blockInfo.getBlockHeight() == 0) {
			int blockCount = (int) btcService.getBlockCount();
			String blockHash = btcService.getBlockHash(blockCount).toString();
			LOG.info("=== [BTC] init block height is : {} and block hash is :{} start !! ===", blockCount, blockHash);
			CoinBlockInfo blockInfos = new CoinBlockInfo();
			blockInfos.setBlockHeight(blockCount);
			blockInfos.setBlockHash(blockHash);
			blockInfos.setCoinType("BTC");
			blockInfos.setCreateTime(new Date());
			blockInfos.setRemark("first record");
			boolean res = blockMapper.insert(blockInfos) > 0 ? true : false;
			if (res)
				LOG.info("=== [BTC] init block success !!");
		}
	}
	
 
}

猜你喜欢

转载自blog.csdn.net/u011663149/article/details/85296858