Skip to content

Instantly share code, notes, and snippets.

@anthowen
Last active April 29, 2023 12:49
Show Gist options
  • Save anthowen/ff0ff3edf3a72136c394eb9507fe88ad to your computer and use it in GitHub Desktop.
Save anthowen/ff0ff3edf3a72136c394eb9507fe88ad to your computer and use it in GitHub Desktop.
Parse Azuki NFT transfer logs in Golang
package main
import (
"context"
"fmt"
"math/big"
"sync"
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
)
var wg sync.WaitGroup
func ParseBlockRange(client *ethclient.Client, startBlock int64, endBlock int64) {
defer wg.Done()
// Azuki Contract Address
collectionAddress := common.HexToAddress("0xED5AF388653567Af2F388E6224dC7C4b3241C544")
transferEventSignature := []byte("Transfer(address,address,uint256)")
// Create a query filter with block range, contract address and topics
query := ethereum.FilterQuery{
FromBlock: big.NewInt(startBlock),
ToBlock: big.NewInt(endBlock),
Addresses: []common.Address{collectionAddress},
Topics: [][]common.Hash{
{crypto.Keccak256Hash(transferEventSignature)},
},
}
// Get logs that matches the filter
transferLogs, err := client.FilterLogs(context.Background(), query)
if err != nil {
panic(err)
}
fmt.Printf("Within (%d, %d) blocks, there were %d transfers\n", startBlock, endBlock, len(transferLogs))
}
func main() {
// Create a client, connecting to the Ethereum mainnet RPC
client, err := ethclient.Dial("https://rpc.ankr.com/eth")
// If there is an error, exit early
if err != nil {
panic(err)
}
// Get the current block number
currentBlockNumber, err := client.BlockNumber(context.Background())
if err != nil {
panic(err)
}
fmt.Println("Search for Azuki transfer logs...")
// https://etherscan.io/block/17134512
// Apr-27-2023 02:20:35 AM +UTC
startBlockNumber := uint64(17134512)
for block := startBlockNumber; block <= currentBlockNumber; block += 3000 {
// Increase the wait group counter
wg.Add(1)
// Start a new goroutine to parse the certain range of blocks
go ParseBlockRange(client, int64(block), int64(block+3000))
time.Sleep(time.Second)
}
// Wait until wait group counter reaches 0, and exit the program
wg.Wait()
}
@anthowen
Copy link
Author

How to run

$ go mod init
$ go mod tiny

Example result

$ go run parse_azuki_logs.go
Search for Azuki transfer logs...
Within (17134512, 17137512) blocks, there were 52 transfers
Within (17137512, 17140512) blocks, there were 52 transfers
Within (17140512, 17143512) blocks, there were 210 transfers
Within (17143512, 17146512) blocks, there were 96 transfers
Within (17146512, 17149512) blocks, there were 46 transfers
Within (17149512, 17152512) blocks, there were 35 transfers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment