0

I'm new to go-ethereum and even Golang in general so my terminology might be wrong, I'm guessing event handling is also referred to as "subscription"? Anyways, my actual issue is that I want to test out an event on a contract, but I can't seem to get any callbacks.

Here's my code:

func main() {
client, err := ethclient.Dial("wss://ropsten.infura.io/ws")


if err != nil{
    log.Fatal(err)
}


fmt.Println("We have a connection!")

privateKey, err := crypto.HexToECDSA("blablabla")
if(err != nil){
    log.Fatal(err)
}

publicKey := privateKey.Public()


publicECDSA := publicKey.(*ecdsa.PublicKey)

fromAddress := crypto.PubkeyToAddress(*publicECDSA)

nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
gasPrice, err := client.SuggestGasPrice(context.Background())

auth := bind.NewKeyedTransactor(privateKey)
auth.Nonce = big.NewInt(int64(nonce))
auth.GasLimit = uint64(300000)
auth.GasPrice = gasPrice
auth.Value = big.NewInt(int64(0))

testAddr := common.HexToAddress("blablablabla")
testEvent, err := TestEvent.NewTestEvent(testAddr, client)
if(err != nil){
    log.Fatal(err)
}

resChan := make(chan *TestEvent.TestEventHandleEvent)

if(err != nil){
    log.Fatal(err)
}

start := uint64(0)
testEvent.WatchHandleEvent(&bind.WatchOpts{
    Context: context.Background(),
    Start: &start}, resChan)

if(err != nil){
    log.Fatal(err)
}

timer := time.NewTimer(5 * time.Second)
go func(){
    <- timer.C
    _, err := testEvent.Gotcha(auth)
    if(err != nil){
        log.Fatal(err)
    }
}()

code := <-resChan
fmt.Println(code)

close(resChan)

}

Here's my contract:

pragma solidity 0.4.25;

contract TestCon { event HandleEvent(uint64 code); address public owner;

constructor() public{
    owner = msg.sender;
}

function Gotcha() public payable {
    if(msg.sender == owner)
    {
        emit HandleEvent(10);  // I've deployed the contract from the same address. So this should match.
        return;
    }
    revert();
}

}

what am I doing wrong? Or is that a problem with my contract?

1
  • wss://ropsten.infura.io/ws is complete? I was expecting it to be like wss://ropsten.infura.io/ws/v3/427bec2fd1ca4870a8fbef8af8132e18 Commented Dec 14, 2020 at 0:17

1 Answer 1

0

Here's a full working example of how to subscribe to event logs of a smart contract:

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ethereum/go-ethereum"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/ethclient"
)

func main() {
    client, err := ethclient.Dial("wss://rinkeby.infura.io/ws")
    if err != nil {
        log.Fatal(err)
    }

    contractAddress := common.HexToAddress(" 0x147B8eb97fD247D06C4006D269c90C1908Fb5D54")
    query := ethereum.FilterQuery{
        Addresses: []common.Address{contractAddress},
    }

    logs := make(chan types.Log)
    sub, err := client.SubscribeFilterLogs(context.Background(), query, logs)
    if err != nil {
        log.Fatal(err)
    }

    for {
        select {
        case err := <-sub.Err():
            log.Fatal(err)
        case vLog := <-logs:
            fmt.Println(vLog) // pointer to event log
        }
    }
}

For more example check out the Ethereum Development with Go guide book.

6
  • I've actually got my code working, seems that the transaction wasn't included in any block, that is why the event wasn't parsed (came to this conclusion while debugging in remix). It worked fine after that, btw, in that guide book he mentioned a "From" and a "To" block, which I guess means that we have to specify which blocks we have to listen for events? I mean I can easily get the block # from code but isn't it a little bit unneeded? And furthermore how can I be sure that the method mentioned in the guide is the best approach? Commented Jul 20, 2018 at 21:31
  • @ElioDecolli From and To are optional if you only need event logs from within a range of blocks. They are not necessary when subscribing because you'll only get the latest blocks when subscribing. It's the only method I know of but would love to hear about better approaches if there are
    – Miguel
    Commented Aug 6, 2018 at 18:24
  • Actually by calling "FilterXXXX()" from the contract's struct in go we can also access each event from a specified contract, there are two more fields in the bind.FilterOpts which I don't know what are there for yet. pastebin.com/F0fJtDLg Commented Aug 7, 2018 at 20:41
  • Also "WatchXXXX()" is pretty easy to use and lets you access logs from a newly deployed contract, I think you should add FIlter and Watch too on the guide. Commented Aug 7, 2018 at 20:47
  • hi guys. in my case the vLog.Data always empty. how can I solve this error? Commented Jul 28, 2022 at 10:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.