gcx/blockchain/genex-sdk-go/events.go

93 lines
1.9 KiB
Go

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
}