在 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.

