[C#] 追蹤 TRON 區塊鏈某合約的轉帳記錄

  • 12418
  • 0
  • 2025-11-18

在 TRON 區塊鏈上,如果我們想知道某個智能合約的交易紀錄,可以使用 TRON 提供的 API 來查詢,並解析其中的「轉帳地址」(from ,to , amount)。

為什麼要查詢 TRON 合約交易? 如果你有追塊的需要就會用到,主要也是因為最近遇到一些朋友問我詐騙的問題

只有透過分析走向才有辦法,所以最近都在弄這類的問題..

1. 這裡面處理 http 的問題 我都是使用  RestSharp 

2. 用 C# 取得 某合約的交易紀錄 ,這邊用的範例就是 USDT TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t

 public class ContractTransactionResponse
 {
     public List data { get; set; }
     public bool success { get; set; }
     public Meta meta { get; set; }

     public class Datum
     {
         public List ret { get; set; }
         public List signature { get; set; }
         public string txID { get; set; }
         public int net_usage { get; set; }
         public string raw_data_hex { get; set; }
         public int net_fee { get; set; }
         public int energy_usage { get; set; }
         public string block_timestamp { get; set; }
         public string blockNumber { get; set; }
         public int energy_fee { get; set; }
         public int energy_usage_total { get; set; }
         public RawData raw_data { get; set; }
         public List internal_transactions { get; set; }

         public class Ret
         {
             public string contractRet { get; set; }
         }

         public class RawData
         {
             public List contract { get; set; }
             public string ref_block_bytes { get; set; }
             public string ref_block_hash { get; set; }
             public object expiration { get; set; }
             public int fee_limit { get; set; }
             public object timestamp { get; set; }

             public class Contract
             {
                 public Parameter parameter { get; set; }
                 public string type { get; set; }
                 public class Parameter
                 {
                     public Value value { get; set; }
                     public string type_url { get; set; }

                     public class Value
                     {
                         public string data { get; set; }
                         public string owner_address { get; set; }
                         public string contract_address { get; set; }
                     }
                 }
             }

         }

     }

     public class Meta
     {
         public long at { get; set; }
         public string fingerprint { get; set; }
         public Links links { get; set; }
         public int page_size { get; set; }

         public class Links
         {
             public string next { get; set; }
         }
     }

 }

         // USDT ADDRESS
         GetContractTransactions("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t");

        /// 
        /// 取得 Contract Transactions 
        /// 
        /// Contract Address
        static void GetContractTransactions(string contractAddress)
        {


            var client = new RestClient("https://api.trongrid.io/v1/contracts/" + contractAddress + "/transactions");
            var request = new RestRequest("",Method.Get);
            request.AddHeader("accept", "application/json");

            var  response = client.Execute(request);

            var contractTransObj = JsonConvert.DeserializeObject(response.Content);

            foreach (var t in contractTransObj.data) {

                ////最後64位就是金額
                var amount =
                 BigInteger.Parse(t.raw_data.contract[0].parameter.value.data.Substring(t.raw_data.contract[0].parameter.value.data.Length - 64, 64), NumberStyles.AllowHexSpecifier);

                var to = ConvertHexToBase58Check("41" + (t.raw_data.contract[0].parameter.value.data.Substring(32, 40)));  // 取後 20 bytes
                var from = ConvertHexToBase58Check((t.raw_data.contract[0].parameter.value.owner_address));  // 取後 20 bytes


                Console.WriteLine("Block:"+t.blockNumber+", txid:"+t.txID+", from:"+ from + ", to:"+to +" ,amount:"+ amount);
            }

          //  Console.WriteLine(response.Content);

        }


     
  

3. 其中因為 to 的部分 不是直接可以拿到的 必須要透過解析 raw_data 

  var to = ConvertHexToBase58Check("41" + (t.raw_data.contract[0].parameter.value.data.Substring(32, 40)));  // 取後 20 bytes

這一點比較特別一點,其他資訊可以從  Response 拿到

這邊也附上轉換成為 TRC20 地址的轉換 function 



        //轉換成 TRC20 
        static string ConvertHexToBase58Check(string hexAddress)
        {
            byte[] addressBytes = HexToBytes(hexAddress);

            // 計算雙重 SHA-256 校驗碼
            using (SHA256 sha256 = SHA256.Create())
            {
                byte[] hash1 = sha256.ComputeHash(addressBytes);
                byte[] hash2 = sha256.ComputeHash(hash1);

                // 取前 4 位作為校驗碼
                byte[] checksum = hash2.Take(4).ToArray();

                // 拼接地址與校驗碼
                byte[] addressWithChecksum = addressBytes.Concat(checksum).ToArray();

                // 轉換為 Base58
                return EncodeBase58(addressWithChecksum);
            }
        }

        static byte[] HexToBytes(string hex)
        {
            return Enumerable.Range(0, hex.Length / 2)
                             .Select(x => Convert.ToByte(hex.Substring(x * 2, 2), 16))
                             .ToArray();
        }

        static string EncodeBase58(byte[] input)
        {
            var Base58Chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

            var intData = new BigInteger(input.Reverse().Concat(new byte[] { 0 }).ToArray());

            string result = "";
            while (intData > 0)
            {
                int remainder = (int)(intData % 58);
                intData /= 58;
                result = Base58Chars[remainder] + result;
            }

            // 保留前導 0
            foreach (byte b in input)
            {
                if (b == 0) result = '1' + result;
                else break;
            }

            return result;
        }

result:

隨機抽樣抓一筆來看看



一次最高 20 筆如果繼續往下,找時間我們在來繼續寫下去..

--

 本文原文首發於我的個人部落格:追蹤 TRON 區塊鏈某合約的轉帳記錄

---

The bug existed in all possible states.
Until I ran the code.