波场(Tron)监控区块交易记录(http 版本,不依赖 sdk)

这篇具有很好参考价值的文章主要介绍了波场(Tron)监控区块交易记录(http 版本,不依赖 sdk)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

做项目的时候经常需要通过监控链的区块交易记录,然后根据交易记录与用户的地址进行核对,从而得知用户地址的充币和提币的情况。

var blockNumber = 0;  //用来记录当前检查的区块高度

while (true) {
    var stopWatch = new Stopwatch();
    stopWatch.Start();

    try {
        string responseString;
        if (blockNumber == 0) {
            const string url = "https://api.trongrid.io/wallet/getnowblock"; //获取最新区块交易明细
            responseString = HttpClientHelper.Get(url);
        } else {
            const string url = "https://api.trongrid.io/wallet/getblockbynum"; // 指定 blockNumber 获取区块交易明显
            var requestBody = new { num = blockNumber + 1 };
            responseString = HttpClientHelper.Post(url, JsonConvert.SerializeObject(requestBody), Encoding.UTF8);
        }

        var responseObject = JsonConvert.DeserializeObject<dynamic>(responseString);
        if (responseObject == null) throw new ThreadSleepException();
        if (responseObject.blockID == null) throw new ThreadSleepException();
        if (responseObject.block_header == null) throw new ThreadSleepException();

        blockNumber = (int)responseObject.block_header.raw_data.number;
        var blockHash = (string)responseObject.blockID;
        var millisecondTimestamp = (long)responseObject.block_header.raw_data.timestamp;
        Console.WriteLine($" 区块高度 {blockNumber}\t区块哈希 {blockHash}");

        if (responseObject.transactions == null || responseObject.transactions.Count == 0) continue;

        var addresses = new List<string>();
        foreach (var transaction in responseObject.transactions) {
            var ret = transaction.ret;
            if (ret == null) continue;
            if (ret.Count == 0) continue;
            if (ret[0].contractRet == null || ret[0].contractRet != "SUCCESS") continue;

            var rawData = transaction.raw_data;
            if (rawData == null) continue;

            var contracts = rawData.contract;
            if (contracts == null) continue;
            if (contracts.Count == 0) continue;

            var contract = contracts[0];
            if (contract == null) continue;

            var parameter = contract.parameter;
            if (parameter == null) continue;

            var value = parameter.value;
            if (value == null) continue;

            var type = (string)contract.type;
            switch (type) {
                case "TransferContract": {
                        if (value.to_address != null && value.asset_name == null) {
                            // TRX 转出地址
                            var fromAddress = Base58Encoder.EncodeFromHex((string)value.owner_address, 0x41);
                            // TRX 转入地址
                            var toAddress = Base58Encoder.EncodeFromHex((string)value.to_address, 0x41);
                            // 转账金额,long 类型
                            var amount = (long)value.amount;
                            // 转化成  decimal 类型方便业务逻辑处理
                            var transferAmount = amount / new decimal(1000000);

                            if (RedisProvider.Instance.KeyExists(fromAddress)) {
                                // TODO
                            }

                            if (RedisProvider.Instance.KeyExists(toAddress)) {
                                // TODO
                            }
                        }
                        break;
                    }
                case "TriggerSmartContract": {
                        // 这里监控的是 USDT 合约地址,如果需要监控其他 TRC20 代币,修改合约地址即可
                        if (value.contract_address != null && (string)value.contract_address == "41a614f803b6fd780986a42c78ec9c7f77e6ded13c") {
                            var data = (string)value.data;
                            switch (data[..8]) {
                                case "a9059cbb": {
                                        // USDT 转出地址
                                        var fromAddress = Base58Encoder.EncodeFromHex((string)value.owner_address, 0x41);
                                        // USDT 转入地址
                                        var toAddress = Base58Encoder.EncodeFromHex(((string)value.data).Substring(8, 64), 0x41);
                                        // 转账金额,long 类型
                                        var amount = Convert.ToInt64(((string)value.data).Substring(72, 64), 16);
                                        // 转化成  decimal 类型方便业务逻辑处理
                                        var transferAmount = amount / new decimal(1000000);

                                        if (RedisProvider.Instance.KeyExists(fromAddress)) {
                                            //TODO
                                        }

                                        if (RedisProvider.Instance.KeyExists(toAddress)) {
                                            //TODO
                                        }
                                        break;
                                    }
                            }
                        }
                        break;
                    }
                case "DelegateResourceContract": {
                        var receiverAddress = Base58Encoder.EncodeFromHex((string)value.receiver_address, 0x41);
                        // receiverAddress 是指监控到地址接受到了代理能量
                        // TODO
                        break;
                    }
                default: {
                        continue;
                    }
            }
        }
    } catch (ThreadSleepException) {
        if (stopWatch.ElapsedMilliseconds >= 1000) continue;
        Thread.Sleep((int)(1000 - stopWatch.ElapsedMilliseconds));
    } catch (Exception exception) {
        Console.WriteLine($" {exception}");
        LogManager.GetLogger(typeof(Program)).Error(exception);

        if (stopWatch.ElapsedMilliseconds >= 1000) continue;
        Thread.Sleep((int)(1000 - stopWatch.ElapsedMilliseconds));
    }

    if (stopWatch.ElapsedMilliseconds >= 2500) continue;
    Thread.Sleep((int)(2500 - stopWatch.ElapsedMilliseconds));
}
引用依赖
PM> Install-Package Newtonsoft.Json
PM> Install-Package StackExchange.Redis

这段代码运行的时候,首选是获取的最新的区块高度(接口 getnowblock),然后逐个累加(接口 getblockbynum)区块进行检查,核对交易,根据自己的业务逻辑在 TODO 里面进行处理。
我这里使用了 Redis 获取项目里面用户的地址与区块的交易记录进行比对。

其次代码里面使用了  stopWatch 进行区块时间的检查,因为波场是3秒出一个区块,但是由于服务器可能会出现网络故障,这个时候会漏掉区块,跟不上最新的高度,所以每次检查是 2.5秒,这样即使短时间断网,监控程序很快就能追上最新的高度,保证能获取到事实的交易数据。文章来源地址https://www.toymoban.com/news/detail-802723.html

HttpClientHelper
public static class HttpClientHelper {
    public static string Get(string url, int timeout = 12000) {
        var resp = Get((HttpWebRequest)WebRequest.Create(url), timeout);
        using var s = resp.GetResponseStream();
        using var sr = new StreamReader(s);

        return sr.ReadToEnd();
    }

    private static HttpWebResponse Get(HttpWebRequest req, int timeout = 12000) {
        req.Method = "GET";
        req.ContentType = "application/json";
        req.Timeout = timeout;
        req.Accept = "application/json";
        req.Headers.Set("TRON-PRO-API-KEY", "80a8b20f-a917-43a9-a2f1-809fe6eec0d6");
        return (HttpWebResponse)req.GetResponse();
    }


    public static string Post(string url, string requestBody, Encoding encoding, int timeout = 12000) {
        var resp = Post((HttpWebRequest)WebRequest.Create(url), requestBody, encoding, timeout);

        using var s = resp.GetResponseStream();
        using var sr = new StreamReader(s);
        return sr.ReadToEnd();
    }

    private static HttpWebResponse Post(HttpWebRequest req, string requestBody, Encoding encoding, int timeout = 12000) {
        var bs = encoding.GetBytes(requestBody);

        req.Method = "POST";
        req.ContentType = "application/json";
        req.ContentLength = bs.Length;
        req.Timeout = timeout;
        req.Accept = "application/json";
        req.Headers.Set("TRON-PRO-API-KEY", "80a8b20f-a917-43a9-a2f1-809fe6eec0d6");
        using (var s = req.GetRequestStream()) {
            s.Write(bs, 0, bs.Length);
        }

        return (HttpWebResponse)req.GetResponse();
    }
}
RedisProvider
public class RedisProvider {
    private readonly IDatabase _database = ConnectionMultiplexer.Connect("127.0.0.1:6379").GetDatabase();

    private RedisProvider() { }

    public static RedisProvider Instance { get; } = new RedisProvider();

    public bool KeyExists(string key) {
        return _database.KeyExists(key);
    }

    public bool StringSet(string key, string value) {
        return _database.StringSet(key, value);
    }

    public string StringGet(string key) {
        var value = _database.StringGet(key);
        return value.IsNull ? string.Empty : value.ToString();
    }
}
public class ThreadSleepException : Exception {

}

到了这里,关于波场(Tron)监控区块交易记录(http 版本,不依赖 sdk)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • .NET Core 离线生成 Tron 波场私钥和地址笔记

    波场(Tron)钱包设置多签 波场(Tron)网页版(本地)钱包开源 波场(Tron)项目常用工具分享 波场(Tron)离线签名、广播交易笔记 波场(Tron)离线生成私钥和地址笔记

    2023年04月13日
    浏览(40)
  • 携手ChainGPT 人工智能基础设施 波场TRON革新 Web3 版图

    近日,波场TRON与 Web3 人工智能基础设施服务商 ChainGPT 正式达成合作。通过本次合作,双方将进一步推动人工智能和区块链技术的融合,在实现优势互补的同时,真正惠及日常生活。 作为一站式的加密AI中心,ChainGPT 的人工智能工具需要进行大量计算,能耗高,而波场TRON采用的创新型代

    2024年02月05日
    浏览(41)
  • 波场链通过Tron JS SDK TronWeb发送带备注的TRC - 20 转账及使用简介

    波场链通过tronWeb发送带备注的TRC - 20 转账

    2024年02月11日
    浏览(55)
  • 聊一聊区块链-波场技术, 只聊技术

    最近因项目使用 tron 协议接入区块链, 故对其做了一番研究, 先把相关资料整理一遍, 供大家学习使用; 网上的这部分资料很少, 所以学习起来也是遇到了很多困难, 尤其是里面很多新的概念, 理解起来有一定的难度。比如说去中心化、地址、加密算法、算法因子、私钥含义、助

    2024年02月02日
    浏览(34)
  • 好用的区块链API SDK(TRON/ETH)

    2024年02月11日
    浏览(30)
  • 韩媒评UDC大会:区块链行业刮“环保之风”,TRON为最环保的企业

    9月23日,韩国备受关注的全球区块链会议“Upbit Developer Conference”(简称UDC)正式结束,大会以“想象你的区块链生活”为主题,汇聚了包括孙宇晨等在内的区块链领域的数十位领军人士,就“NFT”、“元宇宙”以及“Web 3.0”等区块链热点趋势进行了深入探讨。 当日,韩国知

    2024年01月23日
    浏览(39)
  • 对比传统交易模式与基于区块链的交易模式

    随着科技的不断进步,交易模式也在持续革新。传统交易模式与基于区块链的交易模式,作为两种截然不同的交易方式,各有其特点与影响。本文将对这两种交易模式进行详尽的对比,从多个维度揭示它们之间的差异。 传统交易模式通常依赖于中央机构或第三方来进行交易验

    2024年04月27日
    浏览(34)
  • 区块链常见交易问题-高级

    以太坊账户类型 交易部署合约 交易调用合约(ERC20 等) 合约运行报错 合约的gas不足 抛出event的交易 多合约互相调用 Token 与 NFT 数据区别 交易、消息与调用(Message Call)的区别 介绍区块链交易 区块链是一种记录保存系统,在将条目添加到数据链之前会有多个源来验证该条

    2024年02月06日
    浏览(34)
  • 简易区块链的搭建(3)——交易

    1. UTXO账户模型 产生背景: 为了解决第一类双花问题(一笔钱花两次) 原理介绍: 我们先来介绍传统的金融模式,你有10元存款,想转给我3元,银行会怎么操作? 很显然,他会将你的账户减3元,将我的账户加3元。 这种交易模式记录的是 交易结果 而UTXO账户模型记录的是

    2024年04月09日
    浏览(69)
  • 区块链系统:点对点交易原理

    比特币的交易是一种无需信任中介参与的P2P(Peer-to-peer)交易。 传统的电子交易,交易双方必须通过银行这样的信任机构作为中介,这样可以保证交易的安全性,因为银行记录了交易双方的账户资金,能保证在一笔交易中,要么保证成功,要么交易无效,不存在一方到账而另

    2024年02月15日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包