Search code examples
curlrustbitcoinjson-rpc

Bitcoin cURL/JSON-RPC using Rust


I'm writing a code in RUST to query data from bitcoin-core using JSON-RPC. I'm using this curl-rust, but no output is being shown on running cargo run.

extern crate curl;

use std::io::Read;
use curl::easy::{Easy, List};

fn main() {
    let mut data = r#"{"jsonrpc":"1.0","id":"curltext","method":"getrawtransaction","params":["f8ae07a1292136def6d79d5aef15aacfa1aefa2db153037b878b06f00e2cd051", 2]}"#.as_bytes();

    let mut easy = Easy::new();
    easy.url("http://192.168.X.X:8332").unwrap();
    easy.post(true).unwrap();
    easy.post_field_size(data.len() as u64).unwrap();

    let mut list = List::new();
    list.append("Authorization: Basic some_user:some_password").unwrap();
    easy.http_headers(list).unwrap();

    let mut transfer = easy.transfer();
    transfer.read_function(|buf| {
        Ok(data.read(buf).unwrap_or(0))
    }).unwrap();
    transfer.perform().unwrap();
}

I would expect the code to give some output, why this isn't the case?


Solution

  • You're missing write_function call. An example:

    use std::io::Read;
    
    use curl::easy::Easy;
    
    fn main() {
        let mut body = r#"{"jsonrpc":"2.0","method":"guru.test","params":["Guru"],"id":123}"#.as_bytes();
    
        let mut easy = Easy::new();
        easy.url("https://gurujsonrpc.appspot.com/guru").unwrap();
        easy.post(true).unwrap();
        easy.post_field_size(body.len() as u64).unwrap();
    
        let mut data = Vec::new();
        {
            // Create transfer in separate scope ...
            let mut transfer = easy.transfer();
    
            // Request body
            transfer.read_function(|buf| {
                Ok(body.read(buf).unwrap_or(0))
            }).unwrap();
    
            // Response body
            transfer.write_function(|new_data| {
                data.extend_from_slice(new_data);
                Ok(new_data.len())
            }).unwrap();
    
            transfer.perform().unwrap();
            // .. to force drop it here, so we can use easy.response_code()
        }
    
        println!("{}", easy.response_code().unwrap());
        println!("Received {} bytes", data.len());
        if !data.is_empty() {
            println!("Bytes: {:?}", data);
            println!("As string: {}", String::from_utf8_lossy(&data));
        }
    }