Created
February 18, 2025 18:53
-
-
Save areshand/3aee6b11714bb50150b0f85288254235 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" | |
"fmt" | |
"log" | |
"math/big" | |
"github.com/ethereum/go-ethereum/core/types" | |
"github.com/ethereum/go-ethereum/ethclient" | |
) | |
// processBlock processes a single block and counts the occurrences of each event signature | |
func processBlock(client *ethclient.Client, blockNumber *big.Int) (map[string]int, error) { | |
eventCounts := make(map[string]int) | |
// Retrieve the block by number | |
block, err := client.BlockByNumber(context.Background(), blockNumber) | |
if err != nil { | |
if blockNumber.Sign() <= 0 { | |
return nil, fmt.Errorf("invalid block number %s: block numbers must be positive", blockNumber.String()) | |
} | |
return nil, fmt.Errorf("failed to retrieve block %s: %v", blockNumber.String(), err) | |
} | |
// Process each transaction in the block | |
for _, tx := range block.Transactions() { | |
var txReceipt *types.Receipt | |
retries := 3 | |
for retries > 0 { | |
txReceipt, err = client.TransactionReceipt(context.Background(), tx.Hash()) | |
if err == nil { | |
break | |
} | |
retries-- | |
log.Printf("retrying transaction receipt fetch for %s, retries left: %d", tx.Hash().Hex(), retries) | |
} | |
if err != nil { | |
log.Printf("failed to get transaction receipt for %s after retries: %v", tx.Hash().Hex(), err) | |
continue | |
} | |
// Process logs in the transaction receipt | |
for _, logEntry := range txReceipt.Logs { | |
if len(logEntry.Topics) > 0 && logEntry.Topics[0].Hex() != "" { | |
// The first topic is the event signature | |
signature := logEntry.Topics[0].Hex() | |
eventCounts[signature]++ | |
} | |
} | |
} | |
return eventCounts, nil | |
} | |
// processBlockRange processes a range of blocks and aggregates event counts | |
func processBlockRange(client *ethclient.Client, start, end *big.Int) (map[string]int, error) { | |
totalEventCounts := make(map[string]int) | |
// Iterate over the block range | |
for blockNumber := new(big.Int).Set(start); blockNumber.Cmp(end) <= 0; blockNumber.Add(blockNumber, big.NewInt(1)) { | |
eventCounts, err := processBlock(client, blockNumber) | |
if err != nil { | |
return nil, fmt.Errorf("failed to process block %s: %v", blockNumber.String(), err) | |
} | |
// Aggregate event counts | |
for signature, count := range eventCounts { | |
totalEventCounts[signature] += count | |
} | |
} | |
return totalEventCounts, nil | |
} | |
func main() { | |
client, err := ethclient.Dial("https://mainnet.storyrpc.io") | |
if err != nil { | |
log.Fatalf("Failed to connect to the Ethereum client: %v", err) | |
} | |
// Define the block range (latest 10 blocks) | |
latestBlock, err := client.BlockNumber(context.Background()) | |
if err != nil { | |
log.Fatalf("Failed to get latest block number: %v", err) | |
} | |
start := new(big.Int).SetUint64(latestBlock - 9) | |
end := new(big.Int).SetUint64(latestBlock) | |
totalEventCounts, err := processBlockRange(client, start, end) | |
if err != nil { | |
log.Fatalf("Failed to process block range: %v", err) | |
} | |
// Print the aggregated event counts | |
fmt.Println("Total event counts across the block range:") | |
for signature, count := range totalEventCounts { | |
fmt.Printf("%s: %d\n", signature, count) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment