欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 波场(Tron)监听区块交易(TRX,USDT)

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

2024/10/25 2:19:50 来源:https://blog.csdn.net/qq_38935605/article/details/141892923  浏览:    关键词:波场(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

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com