¿Cómo comunicarse con el servidor JSON RPC mediante programación usando Go?

¿Hay alguna forma de interactuar con el servidor JSON RPC directamente en Go?

Intenté lo siguiente:

  1. Iniciar el servidor RPC con "geth --rpc"

  2. Ejecutando el siguiente código:

    package main
    
    import (
        "fmt"
    
        "github.com/ethereum/go-ethereum/rpc"
        "github.com/ethereum/go-ethereum/rpc/comms"
    )
    
    func main() {
    
        client, err := comms.ClientFromEndpoint("rpc:127.0.0.1", 0)
        if err != nil {
            panic(err)
        }
    
        xeth := rpc.NewXeth(client)
    
        type p interface {
        }
    
        response := make(map[string]interface{}, 0)
        var params []interface{}
        response, err = xeth.Call("eth_gasPrice", params)
    
        if err != nil {
            panic(err)
        }
    
        fmt.Println(response)
    }
    

La conexión parece funcionar, pero me sale el siguiente error:

panic: interface conversion: interface {} is string, not map[string]interface {}

goroutine 1 [running]:
panic(0x48c3d00, 0xc820098380)
    /usr/local/go/src/runtime/panic.go:481 +0x3e6
github.com/ethereum/go-ethereum/rpc.(*Xeth).Call(0xc8201bdc80, 0x49ee5f0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/tim/Documents/go_workspace/src/github.com/ethereum/go-ethereum/rpc/xeth.go:72 +0x4dc
main.main()
    /Users/tim/Documents/go_workspace/src/eth_test/main.go:23 +0x12e
exit status 2

Si cambio el método "Llamar" aquí: https://github.com/ethereum/go-ethereum/blob/master/rpc/xeth.go , puedo cambiar la afirmación de tipo al tipo correcto y obtengo el resultado correcto espalda.

Aparte de eso, los comentarios en el archivo vinculado (xeth.go) dicen que es una interfaz para un nodo remoto; sin embargo, quiero una interfaz para un nodo local.

Pensé que debe ser posible iniciar primero el servidor RPC (que de lo contrario se inicia con "geth --rpc" en la consola) de forma puramente programática, ya que el comando de la consola llamará a los métodos Go después de todo y, en segundo lugar, debería ser posible enviar RPC. solicitudes mediante GO.

¿Qué estoy haciendo mal aquí?

Probé el código y creo que hay un error en xeth.go , pero no he encontrado una solución y, como en @makevoidla respuesta, simplemente usaría otra biblioteca de cliente JSON-RPC mientras esperaba que xeth.go fuera fijado. Esperando a que karalabe@githubaka @Péter Szilágyiresponda.
¡Muchas gracias! Consideré que podría ser un error. ¿No es el problema que el tipo de respuesta no siempre es map[string]interface {}? No sé si puedes hacer ese tipo de afirmación.

Respuestas (2)

Puede echar un vistazo a un enfoque simplista que tomamos para etherapis: https://github.com/etherapis/etherapis/blob/master/etherapis/geth/api.go

Sin embargo, hay un cliente RPC en proceso que ya debería admitir suscripciones también. Sin embargo, no estoy seguro de cuándo Félix abrirá su PR con él.

No tengo la solución para su código porque no he investigado el uso de las funciones internas de go-ethereum para hacer llamadas RPC, pero he creado una biblioteca de cliente rpc muy pequeña que puede encontrar en mi github que usa gorequest y simplejson ( No soy un experto en ir;))

También está el archivo "principal" donde comencé a envolver las llamadas yendo a una API mejor definida, puede verificar cómo se implementa el método más simple aquí, básicamente solo llamo a la mini-lib con el método y los argumentos correctos, en este caso ninguno, emita el valor y devuélvalo.

Además, esto le dará el código y funcionará de inmediato si su geth tiene habilitado --rpc y está en el puerto predeterminado:

go get github.com/makevoid/web3_go

cd en el directorio y luego ejecute:

go run web3_go.go

Espero que esto ayude, dime si tienes problemas para ejecutarlo.

¡¡Muchas gracias!! Creo que al final hubiera terminado escribiendo algo como esto, parece que alguien ya lo ha hecho :D