package genex import ( "context" "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/core/types" ) // SubscribeEvents 监听链上事件 func (c *Client) SubscribeEvents(ctx context.Context, filter EventFilter) (<-chan ChainEvent, error) { ch := make(chan ChainEvent, 100) query := ethereum.FilterQuery{} if filter.ContractAddress != nil { query.Addresses = append(query.Addresses, *filter.ContractAddress) } if filter.FromBlock != nil { query.FromBlock = filter.FromBlock } if filter.ToBlock != nil { query.ToBlock = filter.ToBlock } logCh := make(chan types.Log, 100) sub, err := c.ethClient.SubscribeFilterLogs(ctx, query, logCh) if err != nil { return nil, err } go func() { defer close(ch) for { select { case log := <-logCh: ch <- ChainEvent{ Type: "log", BlockHeight: int64(log.BlockNumber), TxHash: log.TxHash.Hex(), Data: map[string]interface{}{ "address": log.Address.Hex(), "topics": log.Topics, "data": log.Data, }, } case err := <-sub.Err(): if err != nil { return } case <-ctx.Done(): sub.Unsubscribe() return } } }() return ch, nil } // SubscribeNewBlocks 监听新区块 func (c *Client) SubscribeNewBlocks(ctx context.Context) (<-chan *BlockInfo, error) { ch := make(chan *BlockInfo, 10) headers := make(chan *types.Header, 10) sub, err := c.ethClient.SubscribeNewHead(ctx, headers) if err != nil { return nil, err } go func() { defer close(ch) for { select { case header := <-headers: ch <- &BlockInfo{ Height: header.Number.Int64(), Hash: header.Hash().Hex(), Timestamp: time.Unix(int64(header.Time), 0), Proposer: header.Coinbase.Hex(), } case <-sub.Err(): return case <-ctx.Done(): sub.Unsubscribe() return } } }() return ch, nil }