go-ethereum Eventabonnements funktionieren nicht?

Ich bin neu bei Go-Ethereum und sogar Golang im Allgemeinen, daher könnte meine Terminologie falsch sein. Ich vermute, die Ereignisbehandlung wird auch als "Abonnement" bezeichnet. Wie auch immer, mein eigentliches Problem ist, dass ich ein Ereignis auf einem Vertrag testen möchte, aber anscheinend keine Rückrufe bekomme.

Hier ist mein 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)

}

Hier mein Vertrag:

pragma solidity 0.4.25;

Vertrag TestCon {Ereignis HandleEvent (uint64-Code); Adresse öffentlicher Eigentümer;

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();
}

}

Was mache ich falsch? Oder liegt das an meinem Vertrag?

wss://ropsten.infura.io/wsist komplett? Ich hatte erwartet, dass es so istwss://ropsten.infura.io/ws/v3/427bec2fd1ca4870a8fbef8af8132e18

Antworten (1)

Hier ist ein voll funktionsfähiges Beispiel zum Abonnieren von Ereignisprotokollen eines Smart Contracts:

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
        }
    }
}

Weitere Beispiele finden Sie im Ethereum Development with Go- Leitfaden.

Ich habe meinen Code tatsächlich zum Laufen gebracht, anscheinend war die Transaktion in keinem Block enthalten, deshalb wurde das Ereignis nicht analysiert (kam beim Debuggen im Remix zu diesem Schluss). Danach hat es gut funktioniert, übrigens, in diesem Handbuch erwähnte er einen "Von"- und einen "Bis"-Block, was wohl bedeutet, dass wir angeben müssen, welche Blöcke wir auf Ereignisse hören müssen? Ich meine, ich kann den Block # leicht aus dem Code bekommen, aber ist es nicht ein bisschen unnötig? Und wie kann ich außerdem sicher sein, dass die im Leitfaden erwähnte Methode der beste Ansatz ist?
@ElioDecolli Fromund Tosind optional, wenn Sie nur Ereignisprotokolle aus einer Reihe von Blöcken benötigen. Sie sind beim Abonnieren nicht erforderlich, da Sie beim Abonnieren nur die neuesten Blöcke erhalten. Es ist die einzige Methode, die ich kenne, aber ich würde gerne von besseren Ansätzen hören, falls es welche gibt
Tatsächlich können wir durch Aufrufen von "FilterXXXX()" aus der Struktur des Vertrags in go auch auf jedes Ereignis aus einem bestimmten Vertrag zugreifen, es gibt zwei weitere Felder in bind.FilterOpts, von denen ich noch nicht weiß, wofür sie da sind. pastebin.com/F0fJtDLg
Auch "WatchXXXX()" ist ziemlich einfach zu verwenden und ermöglicht Ihnen den Zugriff auf Protokolle von einem neu bereitgestellten Vertrag. Ich denke, Sie sollten auch FIlter und Watch in die Anleitung aufnehmen.
Hallo Leute. in meinem Fall ist die vLog.Data immer leer. wie kann ich diesen Fehler beheben?