Go-Ethereum Events – How to Listen for Events Starting at a Previous Block Number in Golang

eventsgo-ethereumgolang

I'm writing an Event listener for my smart contract using the go-ethereum library. I'm trying to figure out how to listen for all SubmitProof events and have successfully been able to use the builtin contract methods to start listening at the latest block. Here's my code for that:

package ethereum

import (
    "context"
    "fmt"
    "sync"

    "github.com/ethereum/go-ethereum/accounts/abi/bind"
    "github.com/ethereum/go-ethereum/common"

    "github.com/my-proj/contracts"
)

func main() {
    ctx := context.Background()

    contract, err := contracts.NewOracle(common.HexToAddress("0xafB0d8E313Fb2018098334F2B53435382BEaD561"), client)
    if err != nil {
        fmt.Println(err)
    }

    var wg sync.WaitGroup

    wg.Add(1)
    go listenForSubmitProof(ctx, &wg, contract)

    wg.Wait()
}

func listenForSubmitProof(ctx context.Context, wg *sync.WaitGroup, contract *contracts.Oracle) {
    defer wg.Done()

    events := make(chan *contracts.OracleSubmitProof)

    var start uint64 = 10472304
    opts := &bind.WatchOpts{
        Start:   &start,
        Context: ctx,
    }

    subscription, err := contract.WatchSubmitProof(opts, events, nil, nil)
    if err != nil {
        log.Fatal(err)
    }
    defer subscription.Unsubscribe()

    for {
        select {
        case <-ctx.Done():
            fmt.Println("done")
        case err := <-subscription.Err():
            fmt.Println(err)
        case event := <-events:
            blockNumber, err := client.BlockNumber(ctx)
            if err != nil {
                fmt.Println(err)
            }

            fmt.Printf("event happened at block %v", blockNumber)
            fmt.Printf("event: %v\n", event)
        }
    }
}

However, this only starts listening for events at the latest block onward. What I would expect is for the bind.WatchOpts to take the Start option and start scanning for events from that block forward.

    var start uint64 = 10472304
    opts := &bind.WatchOpts{
        Start:   &start,
        Context: ctx,
    }

I'm not entirely sure what the Start option is supposed to do, but I don't think I can use it to accomplish my goal.

Is there an easy way to start listening for events starting at block X? Or do I need to do an Event read first and then start listening at the latest block?

Best Answer

I think you should try using FilterOpts if you want to get historical data, if you want both historical and live events you should combine both.

Related Topic