C# 实现 ethereum 的 web3 批量请求功能

加粗样式 web3js 是自带 BatchRequest 的封装的,

奈何C# 并没有所以自己封装了一个差不多的,

目前完成了部分接口,也算是提供了一个思路

    /// <summary>
    /// 演示
    /// </summary>
    public async void Demo()

BatchRequest.cs 代码例子

using Common;
using System.Text;
using static Web3LogsSubscribe3.Models.BatchRequestModels;
using static Web3LogsSubscribe3.Models.BatchRequestModels.JsonRpcReq;

namespace Web3LogsSubscribe
{


    public class BatchRequest : Web3Request
    {
        /// <summary>
        /// 网络对象
        /// </summary>
        HttpClient _httpClient;

        /// <summary>
        /// 请求数据
        /// </summary>
        private List<JsonRpcReq> reqData = new List<JsonRpcReq>();

        public BatchRequest(string url)
        {
            lock (Web3RequestEx.Url)
            {
                Web3RequestEx.Url = url;
            }

            _httpClient = new HttpClient()
            {
                BaseAddress = new Uri(url)
            };
        }

        /// <summary>
        /// 释放批量请求
        /// </summary>
        public void Clear()
        {
            reqData.Clear();
        }

        /// <summary>
        /// 添加批量转账请求
        /// </summary>
        /// <param name="jsonRpcReq"></param>
        /// <returns></returns>
        public JsonRpcReq[] Add(params JsonRpcReq[] jsonRpcReq)
        {
            lock (reqData)
            {
                foreach (var item in jsonRpcReq)
                {
                    item.id = reqData.Count() + 1;
                    reqData.Add(item);
                }
            }

            return jsonRpcReq;
        }

        /// <summary>
        /// 发送请求
        /// </summary>
        /// <returns></returns>
        public async Task<List<JsonRpcReq>> SendRequestAsync() => await reqData.SendRequestAsync(Web3RequestEx.Url);

        /// <summary>
        /// 演示
        /// </summary>
        public async void Demo()
        {

            var addr = "0xe3778dd4350592db6f6767ec73a9981076efab2d";
            var txhash = "0xe4e20d5503698d88a53b1436aad6c33c2720f57fe1145448f644114d9af3bc47";

            // 批量请求
            var batchRequest = new BatchRequest("https://rpc.ankr.com/bsc/");
            var hash = batchRequest.Add(
                BatchRequest.eth_getBalance(addr, (err, res) =>
                {

                    Console.WriteLine($"BatchRequest.eth_getBalance : {res}");

                })

                , BatchRequest.eth_getTransactionByHash(txhash, (err, res) =>
                {

                    Console.WriteLine($"BatchRequest.eth_getBalance : {res.ToJson()}");

                })
                );
            var res1 = await batchRequest.SendRequestAsync();

            // 单个请求
            var res2 = await Web3Request.eth_getBalance(addr, (err, res) =>
            {

                Console.WriteLine($"Web3Request.eth_getBalance : {res}");

            }).SendRequestAsync();

            var res3 = await Web3Request.eth_getTransactionByHash(txhash, (err, res) =>
            {

                Console.WriteLine($"Web3Request.eth_getTransactionByHash : {res.ToJson()}");

            }).SendRequestAsync();

        }

    }

    public static class Web3RequestEx
    {
        /// <summary>
        /// 单个请求时 必须先设置Url
        /// </summary>
        public static string Url = "";

        /// <summary>
        /// 发送请求
        /// </summary>
        /// <returns></returns>
        public static async Task<List<JsonRpcReq>> SendRequestAsync(this List<JsonRpcReq> reqData, string url = "")
        {
            if (string.IsNullOrEmpty(url)) url = Web3RequestEx.Url;
            else Web3RequestEx.Url = url;
            if (string.IsNullOrEmpty(url)) throw new Exception("需要提供url参数,或赋值 Web3RequestEx.Url");

            try
            {
                var _httpClient = new HttpClient();
                var content = new StringContent(reqData.ToJson(), Encoding.UTF8, "application/json");
                var response = await _httpClient.PostAsync(url, content);
                var responseJson = await response.Content.ReadAsStringAsync();
                var resObj = responseJson.ToObject<List<JsonRpcRes>>();

                // 处理结果
                for (int i = 0; i < resObj.Count; i++)
                {
                    try
                    {
                        reqData[i].result = resObj[i];
                        reqData[i].callback(resObj[i].error, reqData[i].result?.result);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"批量请求处理异常: {ex.Message}");
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return reqData;
        }

        /// <summary>
        /// 发送请求
        /// </summary>
        /// <returns></returns>
        public static async Task<List<JsonRpcReq>> SendRequestAsync(this JsonRpcReq reqData, string url = "")
            => await SendRequestAsync((new List<JsonRpcReq>() { reqData }), url != "" ? url : Web3RequestEx.Url);

        /// <summary>
        /// 添加批量请求
        /// </summary>
        public static JsonRpcReq GenJsonRpcReq(string method, Action<JsonRpcRes.Error?, object?> callback, params object[] paramList)
        {
            var list = new List<object>();

            // 过滤null参数
            foreach (var item in paramList) if (item != null) list.Add(item);

            return new JsonRpcReq()
            {
                jsonrpc = "2.0",
                id = 1,
                method = method,
                @params = list.ToArray(),
                callback = callback,
            };
        }
    }

    public class Web3Request
    {


        /// <summary>
        /// 订阅消息
        /// </summary>
        public static JsonRpcReq eth_subscribe(string type, object? ex = null, Action<JsonRpcRes.Error?, string?>? callback = null)
        {
            return Web3RequestEx.GenJsonRpcReq(System.Reflection.MethodBase.GetCurrentMethod()!.Name,
                (err, res) => callback?.Invoke(err, res?.ToString()),
                type, ex
                );
        }

        /// <summary>
        /// 订阅日志
        /// </summary>
        public static JsonRpcReq eth_subscribe_logs(string address, string topics, Action<JsonRpcRes.Error?, string?>? callback = null)
        {
            return eth_subscribe_logs(new string[] { address }, new string[] { topics }, callback);
        }

        public static JsonRpcReq eth_subscribe_logs(string[] address, string[] topics, Action<JsonRpcRes.Error?, string?>? callback = null)
        {
            return eth_subscribe("logs",
                (new LogsSubscribeReq
                {
                    address = address,
                    topics = topics
                }));
        }

        /// <summary>
        /// 查询主网余额
        /// </summary>
        public static JsonRpcReq eth_getBalance(string addr, Action<JsonRpcRes.Error?, string?>? callback = null)
        {
            return Web3RequestEx.GenJsonRpcReq(System.Reflection.MethodBase.GetCurrentMethod()!.Name,
                (err, res) => callback?.Invoke(err, res?.ToString()),
                addr, "latest"
                );
        }

        /// <summary>
        /// 查询哈希信息
        /// </summary>
        public static JsonRpcReq eth_getTransactionByHash(string txhash, Action<JsonRpcRes.Error?, JsonRpcRes.GetTransactionByHashRes?>? callback = null)
        {
            return Web3RequestEx.GenJsonRpcReq(System.Reflection.MethodBase.GetCurrentMethod()!.Name,
                (err, res) => callback?.Invoke(err, res?.ToString()!.ToObject<JsonRpcRes.GetTransactionByHashRes>()),
                txhash
                );
        }

        /// <summary>
        /// 查询哈希信息
        /// </summary>
        public static JsonRpcReq eth_getCode(string addr, Action<JsonRpcRes.Error?, JsonRpcRes.GetTransactionByHashRes?>? callback = null)
        {
            return Web3RequestEx.GenJsonRpcReq(System.Reflection.MethodBase.GetCurrentMethod()!.Name,
                (err, res) => callback?.Invoke(err, res?.ToString()!.ToObject<JsonRpcRes.GetTransactionByHashRes>()),
                addr,"latest"
                );
        }


    }
}

模型

using System.Text.Json.Serialization;

namespace Web3LogsSubscribe3.Models
{
    public class BatchRequestModels
    {
        /// <summary>
        /// Web3请求包体
        /// </summary>
        public class JsonRpcReq
        {
            public string jsonrpc { get; set; }
            public int id { get; set; }
            public string method { get; set; }
            public object[] @params { get; set; }

            [JsonIgnore]
            public Action<JsonRpcRes.Error?, object?> callback { get; set; }

            [JsonIgnore]
            public JsonRpcRes? result { get; set; }


            public class LogsSubscribeReq
            {
                public string[] address { get; set; }
                public object[] topics { get; set; }
            }

        }

        /// <summary>
        /// WEB3响应包体
        /// </summary>
        public class JsonRpcRes
        {
            public string jsonrpc { get; set; }
            public int id { get; set; }
            public object result { get; set; }
            public Error error { get; set; }

            public class Error
            {
                public int code { get; set; }
                public string message { get; set; }
            }

            public class GetTransactionByHashRes
            {
                public string BlockHash { get; set; }
                public string BlockNumber { get; set; }
                public string From { get; set; }
                public string Gas { get; set; }
                public string GasPrice { get; set; }
                public string Hash { get; set; }
                public string Input { get; set; }
                public string Nonce { get; set; }
                public string To { get; set; }
                public string TransactionIndex { get; set; }
                public string Value { get; set; }
                public string Type { get; set; }
                public string ChainId { get; set; }
                public string V { get; set; }
                public string R { get; set; }
                public string S { get; set; }
            }

        }



    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值