bitcoind_request/command/
get_tx_out.rs

1/*
2gettxout "txid" n ( include_mempool )
3
4Returns details about an unspent transaction output.
5
6Arguments:
71. txid               (string, required) The transaction id
82. n                  (numeric, required) vout number
93. include_mempool    (boolean, optional, default=true) Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear.
10
11Result:
12{                             (json object)
13  "bestblock" : "hex",        (string) The hash of the block at the tip of the chain
14  "confirmations" : n,        (numeric) The number of confirmations
15  "value" : n,                (numeric) The transaction value in BTC
16  "scriptPubKey" : {          (json object)
17    "asm" : "hex",            (string)
18    "hex" : "hex",            (string)
19    "reqSigs" : n,            (numeric) Number of required signatures
20    "type" : "hex",           (string) The type, eg pubkeyhash
21    "addresses" : [           (json array) array of bitcoin addresses
22      "str",                  (string) bitcoin address
23      ...
24    ]
25  },
26  "coinbase" : true|false     (boolean) Coinbase or not
27}
28
29Examples:
30
31Get unspent transactions
32> bitcoin-cli listunspent
33
34View the details
35> bitcoin-cli gettxout "txid" 1
36
37As a JSON-RPC call
38> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "gettxout", "params": ["txid", 1]}' -H 'content-type: text/plain;' http://127.0.0.1:8332/
39 */
40
41use crate::{
42    client::Client,
43    command::{request::request, CallableCommand},
44};
45use serde::{Deserialize, Serialize};
46use serde_json::value::to_raw_value;
47
48const GET_TX_OUT_COMMAND: &str = "gettxout";
49
50#[derive(Serialize, Deserialize, Debug)]
51#[serde(rename_all = "camelCase")]
52pub struct ScriptPubKey {
53    pub asm: String,           // "hex"
54    pub hex: String,           // "hex"
55    pub req_sigs: Option<u64>, // Number of required signatures
56    #[serde(alias = "type")]
57    pub type_: String, // The type, eg pubkeyhash
58    // TODO: Why are there both of these. The docs say there is an "addresses" field
59    // (https://bitcoincore.org/en/doc/0.21.0/rpc/blockchain/gettxout/) but the transaction I'm
60    // testing only has an "address" field. Why? Will it return either/or?
61    pub addresses: Option<Vec<String>>, // array of bitcoin addresses
62    pub address: Option<String>,        // bitcoin addresses
63}
64
65#[derive(Serialize, Deserialize, Debug)]
66#[serde(rename_all = "camelCase")]
67pub struct GetTxOutCommandResponse {
68    bestblock: String,  // "hex" The hash of the block at the tip of the chain
69    confirmations: u64, // The number of confirmations
70    value: f64,         // The transaction value in BTC
71    script_pub_key: ScriptPubKey,
72    coinbase: bool, // Coinbase or not
73}
74
75pub struct GetTxOutCommand {
76    tx_id: String,                 // (string, required) The transaction id
77    n: u64,                        // (numeric, required) vout number
78    include_mempool: Option<bool>, // (boolean, optional, default=true) Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear.
79}
80impl GetTxOutCommand {
81    pub fn new(tx_id: String, n: u64) -> Self {
82        GetTxOutCommand {
83            tx_id,
84            n,
85            include_mempool: None,
86        }
87    }
88    // TODO: Currently errors out if you don't enable mempool inclusion but search for a mempool
89    // transaction
90    pub fn include_mempool(&mut self, include_mempool: bool) -> &Self {
91        self.include_mempool = Some(include_mempool);
92        self
93    }
94}
95impl CallableCommand for GetTxOutCommand {
96    type Response = GetTxOutCommandResponse;
97    fn call(&self, client: &Client) -> Result<Self::Response, jsonrpc::Error> {
98        let tx_id_arg = &self.tx_id;
99        let n_arg = &self.n;
100        let include_mempool = &self.include_mempool;
101
102        let tx_id_arg_raw_value = to_raw_value(&tx_id_arg).unwrap();
103        let n_arg_raw_value = to_raw_value(&n_arg).unwrap();
104        let mut params = vec![tx_id_arg_raw_value, n_arg_raw_value];
105        if let Some(include_mempool_arg) = include_mempool {
106            let include_mempool_arg_raw_value = to_raw_value(&include_mempool_arg).unwrap();
107            params.push(include_mempool_arg_raw_value)
108        }
109        let r = request(client, GET_TX_OUT_COMMAND, params);
110        let response: GetTxOutCommandResponse = r.result()?;
111        Ok(response)
112    }
113}