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}