5

Given the code below, geth returns:

{"jsonrpc":"2.0","id":"1","error":{"code":-32602,"message":
"json: cannot unmarshal object into Go value of type []interface {}"}}

The code connects to geth, but I am obviously sending the wrong data for params. Geth wants [] and not an object. If I change the code to send a string that looks like [], geth still complains.

Question: how do I send a [] to geth?

#[macro_use] extern crate hyper;
extern crate rustc_serialize;
extern crate url;

use std::io::Read;
use hyper::{Client};
use hyper::header::{Headers, ContentType};
use rustc_serialize::{Encodable, json};
use rustc_serialize::json::Object;

fn post_json<T>(url: &str, payload: &T) -> hyper::Result<String>
    where T: Encodable {
    let client = Client::new();
    let body = json::encode(payload).unwrap();
    let mut response = try!(client.post(url).header(ContentType::json()).body(&body[..]).send());
    let mut buf = String::new();
    try!(response.read_to_string(&mut buf));
    Ok(buf)
}
#[derive(RustcDecodable, RustcEncodable)]
struct Param {
    num: String,
    detail: bool,
}
#[derive(RustcDecodable, RustcEncodable)]
struct RpcRequest {
    jsonrpc: String,
    method: String,
    params: Param,
    id: String,
}
fn main() {
    let request = RpcRequest {
        jsonrpc: "2.0".to_owned(),
        method: "eth_getBlockByNumber".to_owned(),
        params: Param { num: "1".to_owned(), detail: true },
        id: "1".to_owned(),
    };
    println!("{}", post_json("http://localhost:8545", &request).unwrap());
}
4
+50

The params field in JSON-RPC needs to be an array, while you are passing a single serialized Param struct. To create a dynamic array containing different JSON-primitive values you can use a Vec<Json> (where Json is a rustc_serialize::json::Json enum):

use rustc_serialize::json::Json;

// ...

#[derive(RustcDecodable, RustcEncodable)]
struct RpcRequest {
    jsonrpc: String,
    method: String,
    params: Vec<Json>,
    id: String,
}

And then:

let request = RpcRequest {
    jsonrpc: "2.0".into(),
    method: "eth_getBlockByNumber".into(),
    params: vec![Json::String("1".into()), Json::Boolean(true)],
    id: "1".into(),
};
0

You can also use rust-web3 library. It allows you to content to either geth or parity clients through http and ipc. Using the rpc is as simple as

extern crate web3;

use web3::futures::Future;

fn main() {
  let web3 = web3::Web3::new(web3::transports::Http::new("http://localhost:8545").unwrap());
  let accounts = web3.eth().accounts().wait().unwrap();

  println!("Accounts: {:?}", accounts);
}
2

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.