Last active
August 21, 2024 14:19
-
-
Save goodylili/7a2cb0bf20b5a9192f2d0d1ed3bcb330 to your computer and use it in GitHub Desktop.
listen to uniswap pair created events
This file contains 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" | |
"strings" | |
"time" | |
"github.com/ethereum/go-ethereum" | |
"github.com/ethereum/go-ethereum/accounts/abi" | |
"github.com/ethereum/go-ethereum/common" | |
"github.com/ethereum/go-ethereum/ethclient" | |
) | |
const UniswapV2FactoryABI = `[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"initCodeHash","type":"uint256"}],"name":"PairCreated","type":"event"}]` | |
const UniswapV2FactoryAddress = "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6" | |
func main() { | |
client, err := ethclient.Dial("https://mainnet.base.org") | |
if err != nil { | |
log.Fatalf("Failed to connect to the Ethereum client: %v", err) | |
} | |
parsedABI, err := abi.JSON(strings.NewReader(UniswapV2FactoryABI)) | |
if err != nil { | |
log.Fatalf("Failed to parse ABI: %v", err) | |
} | |
pairCreatedEvent := parsedABI.Events["PairCreated"] | |
filterQuery := ethereum.FilterQuery{ | |
Addresses: []common.Address{common.HexToAddress(UniswapV2FactoryAddress)}, | |
Topics: [][]common.Hash{ | |
{pairCreatedEvent.ID}, | |
}, | |
} | |
var lastBlock uint64 = 0 | |
for { | |
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | |
defer cancel() | |
latestBlock, err := client.BlockNumber(ctx) | |
if err != nil { | |
log.Printf("Failed to get latest block number: %v", err) | |
time.Sleep(5 * time.Second) | |
continue | |
} | |
if lastBlock == 0 { | |
lastBlock = latestBlock - 1 | |
} | |
filterQuery.FromBlock = new(big.Int).SetUint64(lastBlock + 1) | |
filterQuery.ToBlock = new(big.Int).SetUint64(latestBlock) | |
logs, err := client.FilterLogs(ctx, filterQuery) | |
if err != nil { | |
log.Printf("Failed to filter logs: %v", err) | |
time.Sleep(5 * time.Second) | |
continue | |
} | |
for _, vLog := range logs { | |
fmt.Printf("Raw Log Data: %s\n", vLog.Data) // Debug log data | |
fmt.Printf("Raw Log Topics: %v\n", vLog.Topics) // Debug log topics | |
event := struct { | |
Token0 common.Address | |
Token1 common.Address | |
Pair common.Address | |
InitCodeHash *big.Int | |
}{} | |
// Manually extract indexed topics | |
event.Token0 = common.HexToAddress(vLog.Topics[1].Hex()) | |
event.Token1 = common.HexToAddress(vLog.Topics[2].Hex()) | |
// Unpack non-indexed data | |
err := parsedABI.UnpackIntoInterface(&event, "PairCreated", vLog.Data) | |
if err != nil { | |
log.Printf("Failed to unpack log: %v", err) | |
continue | |
} | |
// Print out the unpacked data for verification | |
fmt.Printf("Unpacked Data:\n") | |
fmt.Printf("Token0: %s\n", event.Token0.Hex()) | |
fmt.Printf("Token1: %s\n", event.Token1.Hex()) | |
fmt.Printf("Pair Address: %s\n", event.Pair.Hex()) | |
fmt.Printf("InitCodeHash: %s\n\n", event.InitCodeHash.String()) | |
} | |
lastBlock = latestBlock | |
time.Sleep(15 * time.Second) | |
} | |
} |
This file contains 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" | |
"strings" | |
"time" | |
"github.com/ethereum/go-ethereum" | |
"github.com/ethereum/go-ethereum/accounts/abi" | |
"github.com/ethereum/go-ethereum/common" | |
"github.com/ethereum/go-ethereum/ethclient" | |
) | |
const UniswapV3FactoryABI = `[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":true,"internalType":"uint24","name":"fee","type":"uint24"},{"indexed":false,"internalType":"int24","name":"tickSpacing","type":"int24"},{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"PoolCreated","type":"event"}]` | |
const UniswapV3FactoryAddress = "" + | |
"" | |
func main() { | |
client, err := ethclient.Dial("https://mainnet.base.org") | |
if err != nil { | |
log.Fatalf("Failed to connect to the Base client: %v", err) | |
} | |
parsedABI, err := abi.JSON(strings.NewReader(UniswapV3FactoryABI)) | |
if err != nil { | |
log.Fatalf("Failed to parse ABI: %v", err) | |
} | |
filterQuery := ethereum.FilterQuery{ | |
Addresses: []common.Address{common.HexToAddress(UniswapV3FactoryAddress)}, | |
Topics: [][]common.Hash{ | |
{parsedABI.Events["PoolCreated"].ID}, | |
}, | |
} | |
var lastBlock uint64 = 0 | |
for { | |
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | |
defer cancel() | |
// Get the latest block number | |
latestBlock, err := client.BlockNumber(ctx) | |
if err != nil { | |
log.Printf("Failed to get latest block number: %v", err) | |
time.Sleep(5 * time.Second) | |
continue | |
} | |
if lastBlock == 0 { | |
lastBlock = latestBlock - 1 | |
} | |
filterQuery.FromBlock = new(big.Int).SetUint64(lastBlock + 1) | |
filterQuery.ToBlock = new(big.Int).SetUint64(latestBlock) | |
logs, err := client.FilterLogs(ctx, filterQuery) | |
if err != nil { | |
log.Printf("Failed to filter logs: %v", err) | |
time.Sleep(5 * time.Second) | |
continue | |
} | |
for _, vLog := range logs { | |
event := struct { | |
Token0 common.Address | |
Token1 common.Address | |
Fee *big.Int | |
TickSpacing *big.Int | |
Pool common.Address | |
}{} | |
err := parsedABI.UnpackIntoInterface(&event, "PoolCreated", vLog.Data) | |
if err != nil { | |
log.Printf("Failed to unpack log: %v", err) | |
continue | |
} | |
event.Token0 = common.HexToAddress(vLog.Topics[1].Hex()) | |
event.Token1 = common.HexToAddress(vLog.Topics[2].Hex()) | |
fmt.Printf("New pool created:\n") | |
fmt.Printf("Token0: %s\n", event.Token0.Hex()) | |
fmt.Printf("Token1: %s\n", event.Token1.Hex()) | |
fmt.Printf("Fee: %s\n", event.Fee.String()) | |
fmt.Printf("TickSpacing: %s\n", event.TickSpacing.String()) | |
fmt.Printf("Pool Address: %s\n\n", event.Pool.Hex()) | |
} | |
lastBlock = latestBlock | |
time.Sleep(15 * time.Second) | |
} | |
} |
theghostmac
commented
Aug 20, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment