Generé y usé enlaces Go para implementar algunos contratos y funcionó muy bien, pero veo que los eventos aún no están implementados. ¿Se discute este trabajo en alguna parte?
Me gustaría entender qué opciones hay para una aplicación del lado del servidor en Ir para ver eventos en contratos inteligentes implementados.
Sé que los eventos envuelven las operaciones de registro de EVM y residen como entradas dentro de los recibos de transacciones. Además, la visualización de eventos se realiza por instancia de contrato (no por clase).
Me gustaría evitar el análisis manual de eventos que podría hacer mediante el sondeo de cambios de registro JSON RPC o RPC pub/sub para registros .
¿Cuál es la forma sugerida actualmente en Go? Muestre con un ejemplo en código. ¡Gracias!
ACTUALIZAR
Abrió un problema para go-ethereum para agregar eventos para enlaces Go , así que haga +1. :)
Hasta abigen
que genere código para acceder a eventos a través de la interfaz del contrato, debe usar el método Client.SubscribeFilterLogs . Es bastante autoexplicativo. Debe proporcionar un canal que será alimentado por registros. Además, no te olvides de escuchar en Subscription.Err()
.
Consulte el artículo de consenso: Introducción técnica a eventos y registros en Ethereum para obtener información sobre el manejo de registros en Ethereum.
Ejemplo:
query := ethereum.FilterQuery{
FromBlock: nil,
ToBlock: nil,
// Topics [][]common.Hash
Addresses: []common.Address{myContractAddress}}
var logs = make(chan types.Log, 2)
s, err := client.SubscribeFilterLogs(context.TODO(), query, logs)
// check err
errChan := s.Err()
for {
select {
case err := <-errChan:
logger.Error("Logs subscription error", err)
break
case l := <-logs:
logger.Info("new log", log15.Spew(l))
}
}
aquí hay un ejemplo
package main
import (
"context"
"fmt"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/miguelmota/go-web3-example/greeter"
"log"
)
func main() {
client, err := ethclient.Dial("wss://rinkeby.infura.io/ws")
if err != nil {
log.Fatal(err)
}
greeterAddress := "a7b2eb1b9fff7c9625373a6a6d180e36b552fc4c"
priv := "abcdbcf6bdc3a8e57f311a2b4f513c25b20e3ad4606486d7a927d8074872cefg"
key, err := crypto.HexToECDSA(priv)
contractAddress := common.HexToAddress(greeterAddress)
greeterClient, err := greeter.NewGreeter(contractAddress, client)
if err != nil {
log.Fatal(err)
}
auth := bind.NewKeyedTransactor(key)
// not sure why I have to set this when using testrpc
// var nonce int64 = 0
// auth.Nonce = big.NewInt(nonce)
tx, err := greeterClient.Greet(auth, "hello")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Pending TX: 0x%x\n", tx.Hash())
query := ethereum.FilterQuery{
Addresses: []common.Address{contractAddress},
}
var ch = make(chan types.Log)
ctx := context.Background()
sub, err := client.SubscribeFilterLogs(ctx, query, ch)
if err != nil {
log.Println("Subscribe:", err)
return
}
for {
select {
case err := <-sub.Err():
log.Fatal(err)
case log := <-ch:
fmt.Println("Log:", log)
}
}
}
Ejemplo de contrato utilizado
pragma solidity ^0.4.9;
contract Greeter {
event _Greet(string name);
function greet(string name) public {
_Greet(name);
}
}
Roberto Zaremba