Created
February 11, 2026 10:43
-
-
Save ydm/b9178e693c38ec11413cf07be7dc6f8c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "context" | |
| "encoding/csv" | |
| "encoding/json" | |
| "fmt" | |
| "log" | |
| "os" | |
| "sync" | |
| "time" | |
| "github.com/ethereum/go-ethereum/common" | |
| "github.com/ethereum/go-ethereum/core/types" | |
| "github.com/ethereum/go-ethereum/ethclient" | |
| ) | |
| const NODE = "https://mainnet.infura.io/v3/APIKEY" | |
| type TxResult struct { | |
| Hash string | |
| BlockHash string | |
| BlockNumber string | |
| From string | |
| To string | |
| Value string | |
| Input string | |
| Nonce uint64 | |
| Gas uint64 | |
| GasPrice string | |
| } | |
| func main() { | |
| client, err := ethclient.Dial(NODE) | |
| if err != nil { | |
| log.Fatalf("Failed to connect to Infura: %v", err) | |
| } | |
| defer client.Close() | |
| txHashes := ReadStringsFromJSON("txhashes.json") | |
| // txHashes := []string{} | |
| var wg sync.WaitGroup | |
| var mu sync.Mutex | |
| results := []TxResult{} | |
| missing := []string{} | |
| workerCount := 2 | |
| sem := make(chan struct{}, workerCount) | |
| for _, hashStr := range txHashes { | |
| fmt.Print(".") | |
| wg.Add(1) | |
| sem <- struct{}{} | |
| go func(h string) { | |
| defer wg.Done() | |
| defer func() { <-sem }() | |
| ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) | |
| defer cancel() | |
| txHash := common.HexToHash(h) | |
| tx, isPending, err := client.TransactionByHash(ctx, txHash) | |
| if err != nil { | |
| fmt.Println("\n[1]", err) | |
| mu.Lock() | |
| missing = append(missing, h) | |
| mu.Unlock() | |
| return | |
| } | |
| chainID, err := client.NetworkID(ctx) | |
| if err != nil { | |
| fmt.Println("\n[2]", err) | |
| mu.Lock() | |
| missing = append(missing, h) | |
| mu.Unlock() | |
| return | |
| } | |
| signer := types.LatestSignerForChainID(chainID) | |
| from, err := signer.Sender(tx) | |
| if err != nil { | |
| fmt.Println("\n[3]", err) | |
| mu.Lock() | |
| missing = append(missing, h) | |
| mu.Unlock() | |
| return | |
| } | |
| var blockHash string | |
| var blockNumber string | |
| if !isPending { | |
| receipt, err := client.TransactionReceipt(ctx, txHash) | |
| if err == nil { | |
| blockHash = receipt.BlockHash.Hex() | |
| blockNumber = receipt.BlockNumber.String() | |
| } | |
| } | |
| var to string | |
| if tx.To() != nil { | |
| to = tx.To().Hex() | |
| } | |
| result := TxResult{ | |
| Hash: tx.Hash().Hex(), | |
| BlockHash: blockHash, | |
| BlockNumber: blockNumber, | |
| From: from.Hex(), | |
| To: to, | |
| Value: tx.Value().String(), | |
| Input: fmt.Sprintf("0x%x", tx.Data()), | |
| Nonce: tx.Nonce(), | |
| Gas: tx.Gas(), | |
| GasPrice: tx.GasPrice().String(), | |
| } | |
| mu.Lock() | |
| results = append(results, result) | |
| mu.Unlock() | |
| }(hashStr) | |
| } | |
| wg.Wait() | |
| writeTransactionsCSV("transactions.csv", results) | |
| writeMissingCSV("missing_transactions.csv", missing) | |
| } | |
| func writeTransactionsCSV(filename string, txs []TxResult) { | |
| file, err := os.Create(filename) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| defer file.Close() | |
| writer := csv.NewWriter(file) | |
| defer writer.Flush() | |
| headers := []string{ | |
| "hash", "blockHash", "blockNumber", "from", "to", | |
| "value", "input", "nonce", "gas", "gasPrice", | |
| } | |
| writer.Write(headers) | |
| for _, tx := range txs { | |
| writer.Write([]string{ | |
| tx.Hash, | |
| tx.BlockHash, | |
| tx.BlockNumber, | |
| tx.From, | |
| tx.To, | |
| tx.Value, | |
| tx.Input, | |
| fmt.Sprintf("%d", tx.Nonce), | |
| fmt.Sprintf("%d", tx.Gas), | |
| tx.GasPrice, | |
| }) | |
| } | |
| } | |
| func writeMissingCSV(filename string, hashes []string) { | |
| file, err := os.Create(filename) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| defer file.Close() | |
| writer := csv.NewWriter(file) | |
| defer writer.Flush() | |
| writer.Write([]string{"tx_hash"}) | |
| for _, h := range hashes { | |
| writer.Write([]string{h}) | |
| } | |
| } | |
| func ReadStringsFromJSON(filename string) []string { | |
| var result []string | |
| file, err := os.Open(filename) | |
| if err != nil { | |
| return nil | |
| } | |
| defer file.Close() | |
| decoder := json.NewDecoder(file) | |
| _ = decoder.Decode(&result) // ignoring error per requirement | |
| return result | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment