diff --git a/integration_test/tests/raw_transactions.rs b/integration_test/tests/raw_transactions.rs index ebe5d310..0c8005fc 100644 --- a/integration_test/tests/raw_transactions.rs +++ b/integration_test/tests/raw_transactions.rs @@ -214,6 +214,28 @@ fn raw_transactions__decode_script__modelled() { } } +#[test] +fn raw_transactions__decode_script_segwit__modelled() { + let node = Node::with_wallet(Wallet::Default, &["-txindex"]); + node.fund_wallet(); + // This is a witness_v0_keyhash P2WPKH (pay-to-witness-public-key-hash) script + let addr = node.client.get_new_address(None, None).expect("getnewaddress"); + let script = addr.script_pubkey(); + let hex = script.to_hex_string(); + + let json = node.client.decode_script(&hex).expect("decodescript"); + let model: Result = json.into_model(); + + let segwit = model.expect("DecodeScriptSegwit into model"); + + // Validate expected fields (based on known structure of P2WPKH) + assert!(segwit.asm.contains("OP_")); + assert_eq!(segwit.hex, script); + assert_eq!(segwit.type_, "witness_v0_keyhash"); + assert!(segwit.addresses.iter().any(|a| a == &addr)); + assert!(segwit.address.is_some()); +} + // Script builder code copied from rust-bitcoin script unit tests. fn arbitrary_p2pkh_script() -> ScriptBuf { let pubkey_hash = <[u8; 20]>::from_hex("16e1ae70ff0fa102905d4af297f6912bda6cce19").unwrap(); diff --git a/types/src/model/mod.rs b/types/src/model/mod.rs index 58fc3fc7..d2130b5b 100644 --- a/types/src/model/mod.rs +++ b/types/src/model/mod.rs @@ -41,10 +41,10 @@ pub use self::{ raw_transactions::{ AnalyzePsbt, AnalyzePsbtInput, AnalyzePsbtInputMissing, CombinePsbt, CombineRawTransaction, ConvertToPsbt, CreatePsbt, CreateRawTransaction, DecodePsbt, DecodeRawTransaction, - DecodeScript, DescriptorProcessPsbt, FinalizePsbt, FundRawTransaction, GetRawTransaction, - GetRawTransactionVerbose, JoinPsbts, MempoolAcceptance, SendRawTransaction, SignFail, - SignRawTransaction, SubmitPackage, SubmitPackageTxResult, SubmitPackageTxResultFees, - TestMempoolAccept, UtxoUpdatePsbt, + DecodeScript, DecodeScriptSegwit, DescriptorProcessPsbt, FinalizePsbt, FundRawTransaction, + GetRawTransaction, GetRawTransactionVerbose, JoinPsbts, MempoolAcceptance, + SendRawTransaction, SignFail, SignRawTransaction, SubmitPackage, SubmitPackageTxResult, + SubmitPackageTxResultFees, TestMempoolAccept, UtxoUpdatePsbt, }, util::{ CreateMultisig, DeriveAddresses, EstimateSmartFee, SignMessageWithPrivKey, ValidateAddress, diff --git a/types/src/model/raw_transactions.rs b/types/src/model/raw_transactions.rs index 4aa5007a..b6d12c6c 100644 --- a/types/src/model/raw_transactions.rs +++ b/types/src/model/raw_transactions.rs @@ -116,8 +116,31 @@ pub struct DecodeScript { pub addresses: Vec>, /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). pub p2sh: Option>, - /// Address of the P2SH script wrapping this witness redeem script - pub p2sh_segwit: Option, + /// Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped). + pub segwit: Option, + /// Address of the P2SH script wrapping this witness redeem script. + pub p2sh_segwit: Option>, +} +/// Models the `segwit` field returned by the `decodescript` RPC. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[serde(deny_unknown_fields)] +pub struct DecodeScriptSegwit { + /// Disassembly of the script. + pub asm: String, + /// The raw output script bytes, hex-encoded. + pub hex: ScriptBuf, + /// The output type (e.g. nonstandard, anchor, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_scripthash, witness_v0_keyhash, witness_v1_taproot, witness_unknown). + pub type_: String, + /// Bitcoin address (only if a well-defined address exists)v22 and later only. + pub address: Option>, + /// The required signatures. + pub required_signatures: Option, + /// List of bitcoin addresses. + pub addresses: Vec>, + /// Inferred descriptor for the script. v23 and later only. + pub descriptor: Option, + /// Address of the P2SH script wrapping this witness redeem script. + pub p2sh_segwit: Option>, } /// Models the result of JSON-RPC method `descriptorprocesspsbt`. diff --git a/types/src/v17/raw_transactions/error.rs b/types/src/v17/raw_transactions/error.rs index 5bb469a9..9fc55fcb 100644 --- a/types/src/v17/raw_transactions/error.rs +++ b/types/src/v17/raw_transactions/error.rs @@ -178,6 +178,8 @@ pub enum DecodeScriptError { Addresses(address::ParseError), /// Conversion of the transaction `p2sh` field failed. P2sh(address::ParseError), + /// Conversion of the transaction `segwit` field failed. + Segwit(DecodeScriptSegwitError), } impl fmt::Display for DecodeScriptError { @@ -188,6 +190,7 @@ impl fmt::Display for DecodeScriptError { E::Hex(ref e) => write_err!(f, "conversion of the `hex` field failed"; e), E::Addresses(ref e) => write_err!(f, "conversion of the `addresses` field failed"; e), E::P2sh(ref e) => write_err!(f, "conversion of the `p2sh` field failed"; e), + E::Segwit(ref e) => write_err!(f, "conversion of the `segwit` field failed"; e), } } } @@ -201,6 +204,34 @@ impl std::error::Error for DecodeScriptError { E::Hex(ref e) => Some(e), E::Addresses(ref e) => Some(e), E::P2sh(ref e) => Some(e), + E::Segwit(ref e) => Some(e), + } + } +} + +/// Error when converting a `DecodeScriptSegwit` type into the model type. +#[derive(Debug)] +pub enum DecodeScriptSegwitError { + /// Conversion of the transaction `addresses` field failed. + Addresses(address::ParseError), +} + +impl fmt::Display for DecodeScriptSegwitError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use DecodeScriptSegwitError as E; + match *self { + E::Addresses(ref e) => + write_err!(f, "conversion of the `addresses` field in `segwit` failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for DecodeScriptSegwitError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use DecodeScriptSegwitError as E; + match *self { + E::Addresses(ref e) => Some(e), } } } diff --git a/types/src/v17/raw_transactions/into.rs b/types/src/v17/raw_transactions/into.rs index 6e432798..d33b4e27 100644 --- a/types/src/v17/raw_transactions/into.rs +++ b/types/src/v17/raw_transactions/into.rs @@ -14,7 +14,8 @@ use super::{ FinalizePsbt, FinalizePsbtError, FundRawTransaction, FundRawTransactionError, GetRawTransaction, GetRawTransactionVerbose, GetRawTransactionVerboseError, MempoolAcceptance, PsbtInput, PsbtInputError, PsbtOutput, PsbtOutputError, SendRawTransaction, SignFail, - SignFailError, SignRawTransaction, SignRawTransactionError, TestMempoolAccept, + SignFailError, SignRawTransaction, SignRawTransactionError, TestMempoolAccept,DecodeScriptSegwit, + DecodeScriptSegwitError, }; use crate::model; use crate::psbt::RawTransactionError; @@ -310,6 +311,38 @@ impl DecodeScript { addresses, p2sh, p2sh_segwit: self.p2sh_segwit, + segwit: self.segwit.map(|s| s.into_model()).transpose().map_err(E::Segwit)?, + }) + } +} + +impl DecodeScriptSegwit { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use DecodeScriptSegwitError as E; + + // Convert `Option>` to `Vec>` + let addresses = match self.addresses { + Some(addrs) => addrs + .into_iter() + .map(|s| s.parse::>()) + .collect::>() + .map_err(E::Addresses)?, + None => vec![], + }; + + let required_signatures = self.required_signatures; + let p2sh_segwit = self.p2sh_segwit; + + Ok(model::DecodeScriptSegwit { + asm: self.asm, + hex: self.hex, + descriptor: None, + address:None, + type_: self.type_, + required_signatures, + addresses, + p2sh_segwit, }) } } diff --git a/types/src/v17/raw_transactions/mod.rs b/types/src/v17/raw_transactions/mod.rs index 43753458..af4de0ea 100644 --- a/types/src/v17/raw_transactions/mod.rs +++ b/types/src/v17/raw_transactions/mod.rs @@ -9,6 +9,8 @@ mod into; use std::collections::HashMap; +use bitcoin::address::{Address, NetworkUnchecked}; +use bitcoin::ScriptBuf; use serde::{Deserialize, Serialize}; use crate::ScriptSig; @@ -17,6 +19,7 @@ use crate::ScriptSig; pub use self::error::{ DecodePsbtError, DecodeScriptError, FundRawTransactionError, GetRawTransactionVerboseError, PsbtInputError, PsbtOutputError, SignFailError, SignRawTransactionError, FinalizePsbtError, + DecodeScriptSegwitError, }; // Re-export types that appear in the public API of this module. pub use crate::psbt::{ @@ -227,11 +230,11 @@ pub struct DecodeScript { pub addresses: Option>, /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). pub p2sh: Option, - /// Segwit data (see `DecodeScriptSegwit` for explanation). + /// Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped). pub segwit: Option, /// Address of the P2SH script wrapping this witness redeem script #[serde(rename = "p2sh-segwit")] - pub p2sh_segwit: Option, + pub p2sh_segwit: Option>, } /// Seemingly undocumented data returned in the `segwit` field of `DecodeScript`. @@ -239,11 +242,11 @@ pub struct DecodeScript { #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct DecodeScriptSegwit { - /// Script public key. + /// Disassembly of the script. pub asm: String, - /// Hex encoded public key. - pub hex: String, - /// The output type. + /// The raw output script bytes, hex-encoded. + pub hex: ScriptBuf, + /// The type of the output script (e.g. witness_v0_keyhash or witness_v0_scripthash). #[serde(rename = "type")] pub type_: String, /// The required signatures. @@ -251,9 +254,9 @@ pub struct DecodeScriptSegwit { pub required_signatures: Option, /// List of bitcoin addresses. pub addresses: Option>, - /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). + /// Address of the P2SH script wrapping this witness redeem script. #[serde(rename = "p2sh-segwit")] - pub p2sh_segtwit: Option, + pub p2sh_segwit: Option>, } /// Result of JSON-RPC method `finalizepsbt`. diff --git a/types/src/v22/mod.rs b/types/src/v22/mod.rs index 10efbccd..9059da4d 100644 --- a/types/src/v22/mod.rs +++ b/types/src/v22/mod.rs @@ -253,7 +253,9 @@ pub use self::{ blockchain::GetMempoolInfo, control::Logging, network::{Banned, GetPeerInfo, ListBanned}, - raw_transactions::{DecodeScript, DecodeScriptError}, + raw_transactions::{ + DecodeScript, DecodeScriptError, DecodeScriptSegwit, DecodeScriptSegwitError, + }, }; #[doc(inline)] pub use crate::{ diff --git a/types/src/v22/raw_transactions/error.rs b/types/src/v22/raw_transactions/error.rs index de5dee59..4c77e41a 100644 --- a/types/src/v22/raw_transactions/error.rs +++ b/types/src/v22/raw_transactions/error.rs @@ -17,6 +17,8 @@ pub enum DecodeScriptError { Addresses(address::ParseError), /// Conversion of the transaction `p2sh` field failed. P2sh(address::ParseError), + /// Conversion of the transaction `segwit` field failed. + Segwit(DecodeScriptSegwitError), } impl fmt::Display for DecodeScriptError { @@ -28,6 +30,7 @@ impl fmt::Display for DecodeScriptError { E::Address(ref e) => write_err!(f, "conversion of the `address` field failed"; e), E::Addresses(ref e) => write_err!(f, "conversion of the `addresses` field failed"; e), E::P2sh(ref e) => write_err!(f, "conversion of the `p2sh` field failed"; e), + E::Segwit(ref e) => write_err!(f, "conversion of the `segwit` field failed"; e), } } } @@ -42,6 +45,39 @@ impl std::error::Error for DecodeScriptError { E::Address(ref e) => Some(e), E::Addresses(ref e) => Some(e), E::P2sh(ref e) => Some(e), + E::Segwit(ref e) => Some(e), + } + } +} + +/// Error when converting a `DecodeScriptSegwit` type into the model type. +#[derive(Debug)] +pub enum DecodeScriptSegwitError { + /// Conversion of the transaction `address` field failed. + Address(address::ParseError), + /// Conversion of the transaction `addresses` field failed. + Addresses(address::ParseError), +} + +impl fmt::Display for DecodeScriptSegwitError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use DecodeScriptSegwitError as E; + match *self { + E::Address(ref e) => + write_err!(f, "conversion of the `address` field in `segwit` failed"; e), + E::Addresses(ref e) => + write_err!(f, "conversion of the `addresses` field in `segwit` failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for DecodeScriptSegwitError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use DecodeScriptSegwitError as E; + match *self { + E::Address(ref e) => Some(e), + E::Addresses(ref e) => Some(e), } } } diff --git a/types/src/v22/raw_transactions/into.rs b/types/src/v22/raw_transactions/into.rs index 317d8efe..060c2c46 100644 --- a/types/src/v22/raw_transactions/into.rs +++ b/types/src/v22/raw_transactions/into.rs @@ -2,7 +2,7 @@ use bitcoin::Address; -use super::{DecodeScript, DecodeScriptError}; +use super::{DecodeScript, DecodeScriptError, DecodeScriptSegwit, DecodeScriptSegwitError}; use crate::model; impl DecodeScript { @@ -32,7 +32,43 @@ impl DecodeScript { required_signatures: self.required_signatures, addresses, p2sh, + segwit: self.segwit.map(|s| s.into_model()).transpose().map_err(E::Segwit)?, p2sh_segwit: self.p2sh_segwit, }) } } + +impl DecodeScriptSegwit { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use DecodeScriptSegwitError as E; + + let address = match self.address { + Some(addr) => Some(addr.parse::>().map_err(E::Address)?), + None => None, + }; + // Convert `Option>` to `Vec>` + let addresses = match self.addresses { + Some(addrs) => addrs + .into_iter() + .map(|s| s.parse::>()) + .collect::>() + .map_err(E::Addresses)?, + None => vec![], + }; + + let required_signatures = self.required_signatures; + let p2sh_segwit = self.p2sh_segwit; + + Ok(model::DecodeScriptSegwit { + asm: self.asm, + hex: self.hex, + descriptor: None, + type_: self.type_, + address, + required_signatures, + addresses, + p2sh_segwit, + }) + } +} diff --git a/types/src/v22/raw_transactions/mod.rs b/types/src/v22/raw_transactions/mod.rs index 48c8146f..b9703323 100644 --- a/types/src/v22/raw_transactions/mod.rs +++ b/types/src/v22/raw_transactions/mod.rs @@ -7,9 +7,11 @@ mod error; mod into; +use bitcoin::address::{Address, NetworkUnchecked}; +use bitcoin::ScriptBuf; use serde::{Deserialize, Serialize}; -pub use self::error::DecodeScriptError; +pub use self::error::{DecodeScriptError, DecodeScriptSegwitError}; /// Result of JSON-RPC method `decodescript`. /// @@ -25,7 +27,7 @@ pub use self::error::DecodeScriptError; pub struct DecodeScript { /// Script public key. pub asm: String, - /// The output type. + /// The output type #[serde(rename = "type")] pub type_: String, /// Bitcoin address (only if a well-defined address exists). v22 and later only. @@ -37,22 +39,22 @@ pub struct DecodeScript { pub addresses: Option>, /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). pub p2sh: Option, - /// Segwit data (see `DecodeScriptSegwit` for explanation). + /// Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped). pub segwit: Option, /// Address of the P2SH script wrapping this witness redeem script #[serde(rename = "p2sh-segwit")] - pub p2sh_segwit: Option, + pub p2sh_segwit: Option>, } /// `segwit` item returned as part of `decodescript`. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct DecodeScriptSegwit { - /// Script public key. + /// Disassembly of the script. pub asm: String, - /// Hex encoded public key. - pub hex: String, - /// The output type. + /// The raw output script bytes, hex-encoded. + pub hex: ScriptBuf, + /// The output type (e.g. nonstandard, anchor, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_scripthash, witness_v0_keyhash, witness_v1_taproot, witness_unknown). #[serde(rename = "type")] pub type_: String, /// Bitcoin address (only if a well-defined address exists). v22 and later only. @@ -62,7 +64,7 @@ pub struct DecodeScriptSegwit { pub required_signatures: Option, /// List of bitcoin addresses. pub addresses: Option>, - /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). + /// Address of the P2SH script wrapping this witness redeem script. #[serde(rename = "p2sh-segwit")] - pub p2sh_segtwit: Option, + pub p2sh_segwit: Option>, } diff --git a/types/src/v23/mod.rs b/types/src/v23/mod.rs index 8544c252..10aa27d8 100644 --- a/types/src/v23/mod.rs +++ b/types/src/v23/mod.rs @@ -249,8 +249,8 @@ pub use self::{ control::Logging, network::GetPeerInfo, raw_transactions::{ - DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, GlobalXpub, Proprietary, - PsbtInput, PsbtOutput, + DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, DecodeScriptSegwit, + GlobalXpub, Proprietary, PsbtInput, PsbtOutput, }, util::CreateMultisig, wallet::{GetTransaction, GetTransactionError}, @@ -310,5 +310,5 @@ pub use crate::{ ImportDescriptors, ImportDescriptorsResult, PsbtBumpFee, PsbtBumpFeeError, Send, SendError, UnloadWallet, UpgradeWallet, }, - v22::{Banned, GetMempoolInfo, ListBanned, ScriptPubkey}, + v22::{Banned, GetMempoolInfo, ListBanned, ScriptPubkey,}, }; diff --git a/types/src/v23/raw_transactions/error.rs b/types/src/v23/raw_transactions/error.rs index ab9ad9ef..e843443e 100644 --- a/types/src/v23/raw_transactions/error.rs +++ b/types/src/v23/raw_transactions/error.rs @@ -6,6 +6,7 @@ use bitcoin::{address, bip32, hex, sighash}; use crate::error::write_err; use crate::v17::{Bip32DerivError, PartialSignatureError, RawTransactionError, WitnessUtxoError}; +use crate::v22::DecodeScriptSegwitError; /// Error when converting a `DecodePsbt` type into the model type. #[derive(Debug)] @@ -265,6 +266,8 @@ pub enum DecodeScriptError { Address(address::ParseError), /// Conversion of the transaction `addresses` field failed. Addresses(address::ParseError), + /// Conversion of the transaction `segwit` field failed. + Segwit(DecodeScriptSegwitError), /// Conversion of the transaction `p2sh` field failed. P2sh(address::ParseError), } @@ -277,6 +280,7 @@ impl fmt::Display for DecodeScriptError { E::Hex(ref e) => write_err!(f, "conversion of the `hex` field failed"; e), E::Address(ref e) => write_err!(f, "conversion of the `address` field failed"; e), E::Addresses(ref e) => write_err!(f, "conversion of the `addresses` field failed"; e), + E::Segwit(ref e) => write_err!(f, "conversion of the `segwit` field failed"; e), E::P2sh(ref e) => write_err!(f, "conversion of the `p2sh` field failed"; e), } } @@ -291,7 +295,8 @@ impl std::error::Error for DecodeScriptError { E::Hex(ref e) => Some(e), E::Address(ref e) => Some(e), E::Addresses(ref e) => Some(e), + E::Segwit(ref e) => Some(e), E::P2sh(ref e) => Some(e), } } -} +} \ No newline at end of file diff --git a/types/src/v23/raw_transactions/into.rs b/types/src/v23/raw_transactions/into.rs index 7697a3b3..2c0d9b54 100644 --- a/types/src/v23/raw_transactions/into.rs +++ b/types/src/v23/raw_transactions/into.rs @@ -9,8 +9,9 @@ use bitcoin::psbt::{self, raw, PsbtSighashType}; use bitcoin::{Address, Amount}; use super::{ - DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, GlobalXpub, GlobalXpubError, - Proprietary, PsbtInput, PsbtInputError, PsbtOutput, PsbtOutputError, + DecodePsbt, DecodePsbtError, DecodeScript, DecodeScriptError, DecodeScriptSegwit, + DecodeScriptSegwitError, GlobalXpub, GlobalXpubError, Proprietary, PsbtInput, PsbtInputError, + PsbtOutput, PsbtOutputError, }; use crate::model; @@ -334,7 +335,40 @@ impl DecodeScript { required_signatures: self.required_signatures, addresses, p2sh, + segwit: self.segwit.map(|s| s.into_model()).transpose().map_err(E::Segwit)?, p2sh_segwit: self.p2sh_segwit, }) } } +impl DecodeScriptSegwit { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use DecodeScriptSegwitError as E; + + let address = match self.address { + Some(addr) => Some(addr.parse::>().map_err(E::Address)?), + None => None, + }; + let addresses = match self.addresses { + Some(addrs) => addrs + .into_iter() + .map(|s| s.parse::>()) + .collect::>() + .map_err(E::Addresses)?, + None => vec![], + }; + let required_signatures = self.required_signatures; + let p2sh_segwit = self.p2sh_segwit; + + Ok(model::DecodeScriptSegwit { + asm: self.asm, + hex: self.hex, + descriptor: self.descriptor, + type_: self.type_, + address, + required_signatures, + addresses, + p2sh_segwit, + }) + } +} diff --git a/types/src/v23/raw_transactions/mod.rs b/types/src/v23/raw_transactions/mod.rs index 27054262..d592f99d 100644 --- a/types/src/v23/raw_transactions/mod.rs +++ b/types/src/v23/raw_transactions/mod.rs @@ -9,6 +9,8 @@ mod into; use std::collections::HashMap; +use bitcoin::address::{Address, NetworkUnchecked}; +use bitcoin::ScriptBuf; use serde::{Deserialize, Serialize}; use crate::ScriptSig; @@ -17,6 +19,7 @@ use crate::ScriptSig; pub use self::error::{DecodePsbtError, DecodeScriptError, GlobalXpubError, PsbtInputError, PsbtOutputError}; // Re-export types that appear in the public API of this module. pub use crate::psbt::{Bip32Deriv, PsbtScript, RawTransaction, WitnessUtxo}; +pub use crate::v22::DecodeScriptSegwitError; /// Result of JSON-RPC method `decodepsbt`. /// @@ -144,7 +147,7 @@ pub struct DecodeScript { /// Inferred descriptor for the script. v23 and later only. #[serde(rename = "desc")] pub descriptor: Option, - /// The output type. + /// The output type #[serde(rename = "type")] pub type_: String, /// Bitcoin address (only if a well-defined address exists). v22 and later only. @@ -156,22 +159,24 @@ pub struct DecodeScript { pub addresses: Option>, /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). pub p2sh: Option, - /// Segwit data (see `DecodeScriptSegwit` for explanation). + /// Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped). pub segwit: Option, /// Address of the P2SH script wrapping this witness redeem script #[serde(rename = "p2sh-segwit")] - pub p2sh_segwit: Option, + pub p2sh_segwit: Option>, } - /// `segwit` item returned as part of `decodescript`. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct DecodeScriptSegwit { - /// Script public key. + ///Disassembly of the script. pub asm: String, - /// Hex encoded public key. - pub hex: String, - /// The output type. + /// The raw output script bytes, hex-encoded. + pub hex: ScriptBuf, + /// Inferred descriptor for the script. v23 and later only. + #[serde(rename = "desc")] + pub descriptor: Option, + /// The output type (e.g. nonstandard, anchor, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_scripthash, witness_v0_keyhash, witness_v1_taproot, witness_unknown). #[serde(rename = "type")] pub type_: String, /// Bitcoin address (only if a well-defined address exists). v22 and later only. @@ -181,10 +186,7 @@ pub struct DecodeScriptSegwit { pub required_signatures: Option, /// List of bitcoin addresses. pub addresses: Option>, - /// Inferred descriptor for the script. v23 and later only. - #[serde(rename = "desc")] - pub descriptor: Option, - /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). + /// Address of the P2SH script wrapping this witness redeem script. #[serde(rename = "p2sh-segwit")] - pub p2sh_segtwit: Option, + pub p2sh_segwit: Option>, }