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

2025-02-19

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

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

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


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

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

public class ContractTransactionResponse { public List<Datum> data { get; set; } public bool success { get; set; } public Meta meta { get; set; } public class Datum { public List<Ret> ret { get; set; } public List<string> 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<object> internal_transactions { get; set; } public class Ret { public string contractRet { get; set; } } public class RawData { public List<Contract> 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"); /// <summary> /// 取得 Contract Transactions /// </summary> /// <param name="contractAddress">Contract Address</param> 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<ContractTransactionResponse>(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 筆如果繼續往下,找時間我們在來繼續寫下去..


當麻許的碎念筆記 2014 | Donma Hsu Design.