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
    – Nawaz
    Dec 14 '20 at 0:17
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.

4
  • 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? Jul 20 '18 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 Aug 6 '18 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 Aug 7 '18 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. Aug 7 '18 at 20:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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