波场(Tron)监听区块交易(TRX,USDT)

 前言说明:

        本篇文章参考GitHub一位伙伴的代码,再代码基础上优化改良以后的结果,但是一下找不到那位大佬的GitHub链接了,如有侵权请联系作者调整文章,让跟多人收益。谢谢。

实现思路:

           波场链是一条很新奇的链,他提供了专门的http api相关链接,我们可以通过链接去获取区块上面的事件,同时解析数据来判定交易流水以及方向,再结合业务从而实现我们系统的充值转账等操作。缺点就是他只提供了根据区块号取单个区块的交易数据(目前结合文档看只能单个单个区块的取)。并且容易触发限流控制。

           首先会获取最新区块号,放入缓存Redis里面,定时任务每10秒执行一次,获取上次Redis缓存区块和本次最新区块号对比,开始遍历每个区块获取节点数据(数据获取到了以后就解析处理数据),获取到数据的区块将区块号跟新到Redis里面去。

技术准备:

              先去这个网站申请一个api keys吧,地址 ,申请的key每天可以调用50万次的,完全够用了,这个就很好,如果有更高需求的话可以付费升级的。如果不申请的话很可能会触发RQS限制。

导入依赖:

<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.7</version>
</dependency>

实现代码:

package com.app.web.task;import com.app.web.trx.TrxEventDataService;
import com.app.web.web3.Erc20Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import javax.annotation.Resource;/*** 用户冲提币监听*/
@Slf4j
@Component
public class Web3Task {@Resourceprivate TrxEventDataService trxEventDataService;/*** 监听入账数据*/@Scheduled(initialDelay = 20_000, fixedDelay = 10_000)public void exec() {//我们需要监听的是TRX链代币USDT    所以这里是USDT的合约地址String contractUsdt = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";String url = "https://api.trongrid.io";// 设置API key,设置自己的,要不然会触发RQS限制// https://www.trongrid.io/ 申请下欧~String apiKey = "填入申请的key";trxEventDataService.exec(contractUsdt,url,apiKey);System.out.printf("同步完成-------------");}}

注意事项:

                备注都有应该都可以看懂吧,下面获取区块高度我是用的gethub大佬jar包里面的,所以这一块需要大家下载一下jar包导入自己的项目里面引用,当然也可以自己写一个获取区块高度的代码也行,比导入jar方便实在的多。这里给你们提供一下文档自己去看下 HTTP API - Java Tron ,我也写了,但是没有测试就不贴代码出来了。

package com.app.web.trx;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.app.common.util.RedisUtil;
import org.springframework.stereotype.Service;
import tron_scan.ScanBlock;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** TRX同步线上数据*/
@Service
public class TrxEventDataService {// 初始化扫描器   一定要全局哟  这个包需要我们将下面的jar包导入我们项目里面才能引入进来private static final ScanBlock scan = new ScanBlock();//缓存的最新区块号keypublic static String REDIS_BLOCK_NUM = "REDIS_BLOCK_NUM";/*** 监听的合约地址,本方法经过测试以及很稳定了,可以直接用的* 需要注意的是建议项目别停止太久,这个方法基本1秒同步一个区块,而区块3秒才生成一个,差的不多能快速追上的* @param contractUsdt   USDT合约地址* @param url            tron api的URL地址* @param apiKey         我们申请的key*/public void exec(String contractUsdt,String url,String apiKey){scan.set_api_key(apiKey);// 设置主节点scan.set_uri(url);// 获取最新的区块号String endNumStr = scan.GetNowBlockNum();String startNumber = RedisUtil.get(REDIS_BLOCK_NUM);if(startNumber == null){RedisUtil.set(REDIS_BLOCK_NUM,endNumStr);startNumber = endNumStr;}Integer start = Integer.parseInt(startNumber);Integer end = Integer.parseInt(endNumStr);// 执行任务for (int i = start + 1; i < end; i++) {final int index = i;String return_str = this.sendPost(url+"/walletsolidity/getblockbynum","{\"num\":" + i + "}",apiKey);if (JSON.isValid(return_str)) {JSONObject Json = JSON.parseObject(return_str);if(Json.size() == 0){//取不到数据,我们这里休息30秒重试,有可能是被封了,或者取出来的区块里面还没有写入数据,我们等等就好了try {System.out.printf("取不到数据,我们这里休息30秒重试-----------------\n");Thread.sleep(30000L);//休息完以后我们重新获取一下上次没有获取到的区块数据return_str = this.sendPost(url,"{\"num\":" + i + "}",apiKey);Json = JSON.parseObject(return_str);} catch (InterruptedException var7) {}}if (Json.containsKey("blockID")) {if (Json.containsKey("transactions")) {String value = AnalysisOt.getTransferEvent(Json.getJSONArray("transactions").toJSONString(), i+"");//获取出来的数据我们解析一下数据就好啦processTransferData(value,contractUsdt);}//防止内存使用太大,我们GC清理一下System.gc();}}//区块的数据我们获取到了,将本次的区块高度更新到Redis吧RedisUtil.set(REDIS_BLOCK_NUM,index+"");System.out.printf("本次执行的区块是:"+ i+"休眠一秒再继续执行-----------------\n");try {//这里一定需要休眠,不然会被封掉无法获取到数据的Thread.sleep(1000L);} catch (InterruptedException var7) {}}}// 回调 转账信息private void processTransferData(String allData,String contractUsdt) {JSONArray jsonArray = JSON.parseArray(allData);for (int i = 0; i < jsonArray.size(); i++) {JSONObject transfer = jsonArray.getJSONObject(i);if ("SUCCESS".equals(transfer.getString("contractRet"))) {String type = transfer.getString("type");BigDecimal amount = new BigDecimal(transfer.getString("amount"));BigDecimal divisor = new BigDecimal("1000000");String formattedAmount = amount.divide(divisor, 6, BigDecimal.ROUND_HALF_UP).toString();if ("TriggerSmartContract".equals(type) && contractUsdt.toLowerCase().equals(transfer.getString("contract_address").toLowerCase())) {//这个是USDT代币的交易流水System.out.println("USDT transfer: " +transfer.getString("from_address") + " -> " +transfer.getString("to_address") + " -> " +formattedAmount + " -> " +transfer.getString("txID"));} else if ("TransferContract".equals(type)) {//这里是TRX交易的流水System.out.println("TRX transfer: " +transfer.getString("from_address") + " -> " +transfer.getString("to_address") + " -> " +formattedAmount + " -> " +transfer.getString("txID"));}}}}public String sendPost(String url, String json,String apiKey) {StringBuilder response = new StringBuilder();try {URL requestUrl = new URL(url);HttpURLConnection connection = (HttpURLConnection)requestUrl.openConnection();connection.setRequestMethod("POST");connection.setConnectTimeout(10000);connection.setReadTimeout(10000);connection.setRequestProperty("accept", "application/json");connection.setRequestProperty("TRON-PRO-API-KEY", apiKey);connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0");connection.setDoOutput(true);connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");Throwable var6 = null;BufferedReader in = null;try {OutputStream outputStream = connection.getOutputStream();try {byte[] requestData = json.getBytes(StandardCharsets.UTF_8);outputStream.write(requestData, 0, requestData.length);outputStream.flush();} finally {if (outputStream != null) {outputStream.close();}}} catch (Throwable var17) {if (var6 == null) {var6 = var17;} else if (var6 != var17) {var6.addSuppressed(var17);}throw var6;}int responseCode = connection.getResponseCode();if (responseCode == 200) {in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;while((line = in.readLine()) != null) {response.append(line);}in.close();}} catch (Throwable var18) {}System.gc();return response.toString();}}

这里是下载jar包的链接,或者你们私信作者发你们也行的。

https://download.csdn.net/download/qq_38935605/89712274

如果这篇文章在你一筹莫展的时候帮助到了你,可以请作者吃个棒棒糖🙂,如果有啥疑问或者需要完善的地方欢迎大家在下面留言或者私信作者优化改进。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1523605.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Nexus配置npm私服

1&#xff0c;配置npm-hub 2&#xff0c;配置proxy-npm 3&#xff0c;配置group-npm 4&#xff0c;配置local-npm 5&#xff0c;配置淘宝

[overleaf] 论文中含有中文字符导致编译失败

解决方案分为两步&#xff1a; 1. 加入package&#xff1a; UTF8或者xeCJK \usepackage[UTF8]{ctex}二选一 \usepackage{xeCJK} 2. 修改编译方式&#xff1a; Menu -> Setting -> Compiler -> XeLatex

MyPrint打印设计器(七)svg篇-二阶贝塞尔曲线

svg-二阶贝塞尔曲线 介绍一款强大的svg操作库&#xff0c;能够通过简单的代码&#xff0c;实现svg绘制与操纵&#xff0c;实现拖拽等功能 代码仓库 在线体验 代码仓库&#xff1a;github 代码仓库&#xff1a;gitee 实战项目&#xff1a;MyPrint 操作简单&#xff0c;组件丰富…

Ovirt-Engine(4.3.10 )备份恢复

介绍如何进行 oVirt Engine 的备份、恢复以及相关操作&#xff0c;包括自动备份脚本、手动备份步骤、托管引擎的恢复流程&#xff0c;以及恢复后的配置和验证步骤。 1. Engine 备份部分 1.1 备份使用的脚本 以下是一个用于自动备份 oVirt Engine 的 Bash 脚本&#xff1a; …

标签中的ref属性

之前说过了 ref() 函数&#xff0c;现在说的标签中的 ref 属性 和 ref() 函数也存在一定关联。 2、 标签中的 ref 属性分为两种情况&#xff1a; 用在普通DOM标签上&#xff0c;获取的是DOM节点。 用在组件标签上&#xff0c;获取的是组件实例对象 Vue2 中标签上的 ref 属性…

掌握AIGC的魔法:编写高质量提示词的艺术与科学

嘿&#xff0c;技术达人们&#xff0c;&#x1f680; 今天我们来聊聊AIGC界的超级明星——提示词&#xff08;Prompt&#xff09;。在AI生成内容的奇妙世界里&#xff0c;提示词就是那个点石成金的魔法棒。想要AI小伙伴听你的指挥&#xff0c;创造出令人惊叹的内容吗&#xff1…

9.2~9.3-模型量化学习内容

量化简介 量化是将模型浮点数变为定点数运行的过程。通过一个原始float数值range(scale、min、max)&#xff0c;将类似实属域的float数值映射到一个网格比较稀疏的int网络上&#xff0c;中间肯定会产生数值的偏移。 基本概念 &#xff1a;模型量化可以减少模型尺寸&#xff0…

驾驶模拟左拐右拐

目录 根据4个点确定投影变换关系&#xff1a; 驾驶模拟左拐右拐 平移 四个点选 通过3个点定义放射变换&#xff1a;结果不对 根据4个点确定投影变换关系&#xff1a; import cv2 import numpy as npdef apply_perspective_transform(image, src_points, dst_points):# 将选…

spring--小白面试版01

bean 1.Spring框架中的bean是单例的吗? Service Scope("singleton") public class UserServicelmpl implements UserService { } 在Scope中 singleton: bean在每个Spring IOC容器中只有一个实例 prototype:一个bean的定义可以有多个实例 2. Spring框架中的单例bea…

jdk11安装步骤(含安装包)

安装包 通过百度网盘分享的文件&#xff1a;jdk-11.0.15.1_windows-x64_bin.exe 链接&#xff1a;https://pan.baidu.com/s/1IYRnvtPvfgloS8rawtRDvg 提取码&#xff1a;sv1w 一、安装过程 双击安装程序 二、配置环境 右键“此电脑”&#xff0c;点击“属性”&#xff0c;点…

学生管理系统升级(登录注册 + 关联学生管理系统)

新增需求 这是在昨天的基础初代版本上面新增一个登录注册忘记密码的功能 需求分析 注册 登录 忘记密码 user类代码呈现 package StudentSystem;public class User {private String username;private String password;private String personID;private String phoneNumber;pu…

828华为云征文|华为云Flexus X实例docker部署srs6并调优,协议使用webrtc与rtmp

828华为云征文&#xff5c;华为云Flexus X实例docker部署srs6并调优&#xff0c;协议使用webrtc与rtmp 华为云最近正在举办828 B2B企业节&#xff0c;Flexus X实例的促销力度非常大&#xff0c;特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务…

KTH5701 系列低功耗、高精度 3D 霍尔传感器

KTH5701 是一款数字输出的 3D 霍尔芯片&#xff0c;内部 分别集成了 X 轴、 Y 轴和 Z 轴三个独立的霍尔传感器。 信号链采用高精度运放通过 16 bit ADC 将模拟信号 转换成数字输出。外部主机可以采用 SPI 或 I2C 两种 模式读出测量数据。此外&#xff0c;在芯片…

2024第三届大学生算法大赛 真题训练一 解题报告 | 珂学家

前言 题解 这是第三届大学生算法大赛(第二届为清华社杯)的赛前练习赛一. 这是上界比赛的体验报告: 2023第二届“清华社杯”大学生算法大赛 解题报告(流水账版) | 珂学家&#xff0c;个人还是非常推荐这个比赛。 难度分布&#xff1a;4 easy/4 mid-hard/2 hard 赛前练习赛一…

Node.js发票查验接口示例、识别查验接口参数返回

财务、审计等经常与发票打交道的人员常常会遇到虚假发票、错票、重复报销等一系列问题。对于会计审计、代理记账、电子商务等发票查验量多的企业来说&#xff0c;成千上万张发票如果仅依赖于人工来进行核验&#xff0c;速度慢效率低&#xff0c;准确率也没保障&#xff0c;因此…

Tomato靶机通关攻略

步骤一&#xff1a;进行端口扫描&#xff0c;找寻靶机地址 步骤二&#xff1a;访问靶机地址 步骤三&#xff1a;利用dirb进行扫描 得出&#xff1a;/antibot_image/进行访问 步骤四&#xff1a;进入antibots->info.php->右击进入页面源代码->发现存在文件包含漏洞 步…

如何让wave波形信号不显示全路径

Modesim仿真如何让wave信号不显示全路径 问题说明 在使用modesim仿真时&#xff0c;需要利用modesim的wave界面显示调试信号的波形&#xff0c;默认情况下wave栏的左边是显示抓捕信号的全路径的&#xff0c;如下图所示: 这种情况下&#xff0c;区分信号比较麻烦&#xff0c;如…

vulhub xxe靶机渗透测试

1.先用kali的nmap扫描端口 2. 找到靶机地址后用工具扫描目录 3.我们先进入robots.txt中 4.访问xxe文件 5.在登陆时抓包 这里可以看到在我们用户名的位置是有回显的&#xff0c;我们可以在这里做文章 6.因为在 linux 系统中/etc/passwd 文件包含有用户账号信息所以我们可以写一…

开源轻量级进程监控工具monit的使用以及monit进程监控工具常用的监控配置案例示例大全

一、开源轻量级进程监控工具monit的应用 今天在服务器杀进程时&#xff0c;发现有一个进程一直在重启&#xff0c;寻找服务器各种定时任务未发现有定时程序&#xff0c;也没有发现supervisord的进程管理服务&#xff0c;后来才发现服务器上启用了monit这个工具&#xff0c;moni…

上证50ETF期权交易策略有哪些?期权交易时要注意什么?

今天带你了解上证50ETF期权交易策略有哪些&#xff1f;期权交易时要注意什么&#xff1f;上证50ETF期权是一种以华夏50etf基金为标的物的金融衍生品&#xff0c;它允许投资者通过买卖期权合约来对冲风险或进行投机。 期权趋势型策略 趋势型的策略就是我们通常说的追涨杀跌&am…