Merge rust-bitcoin/rust-bitcoin#1979: Make `Payload` and `AddressEncoding` private
7f75447c1d
Make Payload private and inline functionality (Tobin C. Harding)b12bf07232
Make the AddressEncoding type private (Tobin C. Harding) Pull request description: The `AddressEncoding` and `Payload` types are implementation details and should never have been public. Make them private. Fix: #1908 ACKs for top commit: Kixunil: ACK7f75447c1d
apoelstra: ACK7f75447c1d
Tree-SHA512: 37083bc759f32e5187126c4f8d39c9c9cb39bd80a92b2479128da39f4db7672fe0be24a58756a387fe944c63efb4ffacc58c1dac071f3314e882ed0f0e9f5a23
This commit is contained in:
commit
9f602a613b
|
@ -97,8 +97,7 @@ impl FromStr for AddressType {
|
||||||
|
|
||||||
/// The method used to produce an address.
|
/// The method used to produce an address.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[non_exhaustive]
|
enum Payload {
|
||||||
pub enum Payload {
|
|
||||||
/// P2PKH address.
|
/// P2PKH address.
|
||||||
PubkeyHash(PubkeyHash),
|
PubkeyHash(PubkeyHash),
|
||||||
/// P2SH address.
|
/// P2SH address.
|
||||||
|
@ -107,139 +106,17 @@ pub enum Payload {
|
||||||
WitnessProgram(WitnessProgram),
|
WitnessProgram(WitnessProgram),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Payload {
|
|
||||||
/// Constructs a [Payload] from an output script (`scriptPubkey`).
|
|
||||||
pub fn from_script(script: &Script) -> Result<Payload, Error> {
|
|
||||||
Ok(if script.is_p2pkh() {
|
|
||||||
let bytes = script.as_bytes()[3..23].try_into().expect("statically 20B long");
|
|
||||||
Payload::PubkeyHash(PubkeyHash::from_byte_array(bytes))
|
|
||||||
} else if script.is_p2sh() {
|
|
||||||
let bytes = script.as_bytes()[2..22].try_into().expect("statically 20B long");
|
|
||||||
Payload::ScriptHash(ScriptHash::from_byte_array(bytes))
|
|
||||||
} else if script.is_witness_program() {
|
|
||||||
let opcode = script.first_opcode().expect("witness_version guarantees len() > 4");
|
|
||||||
|
|
||||||
let witness_program = script.as_bytes()[2..].to_vec();
|
|
||||||
|
|
||||||
let witness_program =
|
|
||||||
WitnessProgram::new(WitnessVersion::try_from(opcode)?, witness_program)?;
|
|
||||||
Payload::WitnessProgram(witness_program)
|
|
||||||
} else {
|
|
||||||
return Err(Error::UnrecognizedScript);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generates a script pubkey spending to this [Payload].
|
|
||||||
pub fn script_pubkey(&self) -> ScriptBuf {
|
|
||||||
match *self {
|
|
||||||
Payload::PubkeyHash(ref hash) => ScriptBuf::new_p2pkh(hash),
|
|
||||||
Payload::ScriptHash(ref hash) => ScriptBuf::new_p2sh(hash),
|
|
||||||
Payload::WitnessProgram(ref prog) => ScriptBuf::new_witness_program(prog),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the address creates a particular script
|
|
||||||
/// This function doesn't make any allocations.
|
|
||||||
pub fn matches_script_pubkey(&self, script: &Script) -> bool {
|
|
||||||
match *self {
|
|
||||||
Payload::PubkeyHash(ref hash) if script.is_p2pkh() =>
|
|
||||||
&script.as_bytes()[3..23] == <PubkeyHash as AsRef<[u8; 20]>>::as_ref(hash),
|
|
||||||
Payload::ScriptHash(ref hash) if script.is_p2sh() =>
|
|
||||||
&script.as_bytes()[2..22] == <ScriptHash as AsRef<[u8; 20]>>::as_ref(hash),
|
|
||||||
Payload::WitnessProgram(ref prog) if script.is_witness_program() =>
|
|
||||||
&script.as_bytes()[2..] == prog.program().as_bytes(),
|
|
||||||
Payload::PubkeyHash(_) | Payload::ScriptHash(_) | Payload::WitnessProgram(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a pay to (compressed) public key hash payload from a public key
|
|
||||||
#[inline]
|
|
||||||
pub fn p2pkh(pk: &PublicKey) -> Payload { Payload::PubkeyHash(pk.pubkey_hash()) }
|
|
||||||
|
|
||||||
/// Creates a pay to script hash P2SH payload from a script
|
|
||||||
#[inline]
|
|
||||||
pub fn p2sh(script: &Script) -> Result<Payload, Error> {
|
|
||||||
if script.len() > MAX_SCRIPT_ELEMENT_SIZE {
|
|
||||||
return Err(Error::ExcessiveScriptSize);
|
|
||||||
}
|
|
||||||
Ok(Payload::ScriptHash(script.script_hash()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a witness pay to public key payload from a public key
|
|
||||||
pub fn p2wpkh(pk: &PublicKey) -> Result<Payload, Error> {
|
|
||||||
let prog = WitnessProgram::new(
|
|
||||||
WitnessVersion::V0,
|
|
||||||
pk.wpubkey_hash().ok_or(Error::UncompressedPubkey)?,
|
|
||||||
)?;
|
|
||||||
Ok(Payload::WitnessProgram(prog))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a pay to script payload that embeds a witness pay to public key
|
|
||||||
pub fn p2shwpkh(pk: &PublicKey) -> Result<Payload, Error> {
|
|
||||||
let builder = script::Builder::new()
|
|
||||||
.push_int(0)
|
|
||||||
.push_slice(pk.wpubkey_hash().ok_or(Error::UncompressedPubkey)?);
|
|
||||||
|
|
||||||
Ok(Payload::ScriptHash(builder.into_script().script_hash()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a witness pay to script hash payload.
|
|
||||||
pub fn p2wsh(script: &Script) -> Payload {
|
|
||||||
let prog = WitnessProgram::new(WitnessVersion::V0, script.wscript_hash())
|
|
||||||
.expect("wscript_hash has len 32 compatible with segwitv0");
|
|
||||||
Payload::WitnessProgram(prog)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a pay to script payload that embeds a witness pay to script hash address
|
|
||||||
pub fn p2shwsh(script: &Script) -> Payload {
|
|
||||||
let ws = script::Builder::new().push_int(0).push_slice(script.wscript_hash()).into_script();
|
|
||||||
|
|
||||||
Payload::ScriptHash(ws.script_hash())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a pay to taproot payload from untweaked key
|
|
||||||
pub fn p2tr<C: Verification>(
|
|
||||||
secp: &Secp256k1<C>,
|
|
||||||
internal_key: UntweakedPublicKey,
|
|
||||||
merkle_root: Option<TapNodeHash>,
|
|
||||||
) -> Payload {
|
|
||||||
let (output_key, _parity) = internal_key.tap_tweak(secp, merkle_root);
|
|
||||||
let prog = WitnessProgram::new(WitnessVersion::V1, output_key.to_inner().serialize())
|
|
||||||
.expect("taproot output key has len 32 <= 40");
|
|
||||||
Payload::WitnessProgram(prog)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a pay to taproot payload from a pre-tweaked output key.
|
|
||||||
///
|
|
||||||
/// This method is not recommended for use and [Payload::p2tr()] should be used where possible.
|
|
||||||
pub fn p2tr_tweaked(output_key: TweakedPublicKey) -> Payload {
|
|
||||||
let prog = WitnessProgram::new(WitnessVersion::V1, output_key.to_inner().serialize())
|
|
||||||
.expect("taproot output key has len 32 <= 40");
|
|
||||||
Payload::WitnessProgram(prog)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a byte slice of the inner program of the payload. If the payload
|
|
||||||
/// is a script hash or pubkey hash, a reference to the hash is returned.
|
|
||||||
fn inner_prog_as_bytes(&self) -> &[u8] {
|
|
||||||
match self {
|
|
||||||
Payload::ScriptHash(hash) => hash.as_ref(),
|
|
||||||
Payload::PubkeyHash(hash) => hash.as_ref(),
|
|
||||||
Payload::WitnessProgram(prog) => prog.program().as_bytes(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A utility struct to encode an address payload with the given parameters.
|
/// A utility struct to encode an address payload with the given parameters.
|
||||||
/// This is a low-level utility struct. Consider using `Address` instead.
|
/// This is a low-level utility struct. Consider using `Address` instead.
|
||||||
pub struct AddressEncoding<'a> {
|
struct AddressEncoding<'a> {
|
||||||
/// The address payload to encode.
|
/// The address payload to encode.
|
||||||
pub payload: &'a Payload,
|
payload: &'a Payload,
|
||||||
/// base58 version byte for p2pkh payloads (e.g. 0x00 for "1..." addresses).
|
/// base58 version byte for p2pkh payloads (e.g. 0x00 for "1..." addresses).
|
||||||
pub p2pkh_prefix: u8,
|
p2pkh_prefix: u8,
|
||||||
/// base58 version byte for p2sh payloads (e.g. 0x05 for "3..." addresses).
|
/// base58 version byte for p2sh payloads (e.g. 0x05 for "3..." addresses).
|
||||||
pub p2sh_prefix: u8,
|
p2sh_prefix: u8,
|
||||||
/// The bech32 human-readable part.
|
/// The bech32 human-readable part.
|
||||||
pub hrp: Hrp,
|
hrp: Hrp,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Formats bech32 as upper case if alternate formatting is chosen (`{:#}`).
|
/// Formats bech32 as upper case if alternate formatting is chosen (`{:#}`).
|
||||||
|
@ -437,7 +314,7 @@ impl<N: NetworkValidation> serde::Serialize for Address<N> {
|
||||||
/// `Address<NetworkUnchecked>`.
|
/// `Address<NetworkUnchecked>`.
|
||||||
impl<V: NetworkValidation> Address<V> {
|
impl<V: NetworkValidation> Address<V> {
|
||||||
/// Returns a reference to the payload of this address.
|
/// Returns a reference to the payload of this address.
|
||||||
pub fn payload(&self) -> &Payload { &self.0.payload }
|
fn payload(&self) -> &Payload { &self.0.payload }
|
||||||
|
|
||||||
/// Returns a reference to the network of this address.
|
/// Returns a reference to the network of this address.
|
||||||
pub fn network(&self) -> &Network { &self.0.network }
|
pub fn network(&self) -> &Network { &self.0.network }
|
||||||
|
@ -449,7 +326,7 @@ impl<V: NetworkValidation> Address<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts and returns the network and payload components of the `Address`.
|
/// Extracts and returns the network and payload components of the `Address`.
|
||||||
pub fn into_parts(self) -> (Network, Payload) {
|
fn into_parts(self) -> (Network, Payload) {
|
||||||
let AddressInner { payload, network } = self.0;
|
let AddressInner { payload, network } = self.0;
|
||||||
(network, payload)
|
(network, payload)
|
||||||
}
|
}
|
||||||
|
@ -507,8 +384,7 @@ impl<V: NetworkValidation> Address<V> {
|
||||||
|
|
||||||
/// Create new address from given components, infering the network validation
|
/// Create new address from given components, infering the network validation
|
||||||
/// marker type of the address.
|
/// marker type of the address.
|
||||||
#[inline]
|
fn new(network: Network, payload: Payload) -> Self {
|
||||||
pub fn new(network: Network, payload: Payload) -> Self {
|
|
||||||
Self(AddressInner { network, payload }, PhantomData)
|
Self(AddressInner { network, payload }, PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,7 +396,8 @@ impl Address {
|
||||||
/// This is the preferred non-witness type address.
|
/// This is the preferred non-witness type address.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn p2pkh(pk: &PublicKey, network: Network) -> Address {
|
pub fn p2pkh(pk: &PublicKey, network: Network) -> Address {
|
||||||
Address::new(network, Payload::p2pkh(pk))
|
let payload = Payload::PubkeyHash(pk.pubkey_hash());
|
||||||
|
Address(AddressInner { network, payload }, PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pay to script hash P2SH address from a script.
|
/// Creates a pay to script hash P2SH address from a script.
|
||||||
|
@ -529,7 +406,11 @@ impl Address {
|
||||||
/// these days.
|
/// these days.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn p2sh(script: &Script, network: Network) -> Result<Address, Error> {
|
pub fn p2sh(script: &Script, network: Network) -> Result<Address, Error> {
|
||||||
Ok(Address::new(network, Payload::p2sh(script)?))
|
if script.len() > MAX_SCRIPT_ELEMENT_SIZE {
|
||||||
|
return Err(Error::ExcessiveScriptSize);
|
||||||
|
}
|
||||||
|
let payload = Payload::ScriptHash(script.script_hash());
|
||||||
|
Ok(Address(AddressInner { network, payload }, PhantomData))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a witness pay to public key address from a public key.
|
/// Creates a witness pay to public key address from a public key.
|
||||||
|
@ -539,7 +420,12 @@ impl Address {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Will only return an error if an uncompressed public key is provided.
|
/// Will only return an error if an uncompressed public key is provided.
|
||||||
pub fn p2wpkh(pk: &PublicKey, network: Network) -> Result<Address, Error> {
|
pub fn p2wpkh(pk: &PublicKey, network: Network) -> Result<Address, Error> {
|
||||||
Ok(Address::new(network, Payload::p2wpkh(pk)?))
|
let prog = WitnessProgram::new(
|
||||||
|
WitnessVersion::V0,
|
||||||
|
pk.wpubkey_hash().ok_or(Error::UncompressedPubkey)?,
|
||||||
|
)?;
|
||||||
|
let payload = Payload::WitnessProgram(prog);
|
||||||
|
Ok(Address(AddressInner { network, payload }, PhantomData))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pay to script address that embeds a witness pay to public key.
|
/// Creates a pay to script address that embeds a witness pay to public key.
|
||||||
|
@ -549,19 +435,29 @@ impl Address {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Will only return an Error if an uncompressed public key is provided.
|
/// Will only return an Error if an uncompressed public key is provided.
|
||||||
pub fn p2shwpkh(pk: &PublicKey, network: Network) -> Result<Address, Error> {
|
pub fn p2shwpkh(pk: &PublicKey, network: Network) -> Result<Address, Error> {
|
||||||
Ok(Address::new(network, Payload::p2shwpkh(pk)?))
|
let builder = script::Builder::new()
|
||||||
|
.push_int(0)
|
||||||
|
.push_slice(pk.wpubkey_hash().ok_or(Error::UncompressedPubkey)?);
|
||||||
|
|
||||||
|
let payload = Payload::ScriptHash(builder.into_script().script_hash());
|
||||||
|
Ok(Address(AddressInner { network, payload }, PhantomData))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a witness pay to script hash address.
|
/// Creates a witness pay to script hash address.
|
||||||
pub fn p2wsh(script: &Script, network: Network) -> Address {
|
pub fn p2wsh(script: &Script, network: Network) -> Address {
|
||||||
Address::new(network, Payload::p2wsh(script))
|
let prog = WitnessProgram::new(WitnessVersion::V0, script.wscript_hash())
|
||||||
|
.expect("wscript_hash has len 32 compatible with segwitv0");
|
||||||
|
let payload = Payload::WitnessProgram(prog);
|
||||||
|
Address(AddressInner { network, payload }, PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pay to script address that embeds a witness pay to script hash address.
|
/// Creates a pay to script address that embeds a witness pay to script hash address.
|
||||||
///
|
///
|
||||||
/// This is a segwit address type that looks familiar (as p2sh) to legacy clients.
|
/// This is a segwit address type that looks familiar (as p2sh) to legacy clients.
|
||||||
pub fn p2shwsh(script: &Script, network: Network) -> Address {
|
pub fn p2shwsh(script: &Script, network: Network) -> Address {
|
||||||
Address::new(network, Payload::p2shwsh(script))
|
let ws = script::Builder::new().push_int(0).push_slice(script.wscript_hash()).into_script();
|
||||||
|
let payload = Payload::ScriptHash(ws.script_hash());
|
||||||
|
Address(AddressInner { network, payload }, PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pay to taproot address from an untweaked key.
|
/// Creates a pay to taproot address from an untweaked key.
|
||||||
|
@ -571,14 +467,30 @@ impl Address {
|
||||||
merkle_root: Option<TapNodeHash>,
|
merkle_root: Option<TapNodeHash>,
|
||||||
network: Network,
|
network: Network,
|
||||||
) -> Address {
|
) -> Address {
|
||||||
Address::new(network, Payload::p2tr(secp, internal_key, merkle_root))
|
let (output_key, _parity) = internal_key.tap_tweak(secp, merkle_root);
|
||||||
|
let prog = WitnessProgram::new(WitnessVersion::V1, output_key.to_inner().serialize())
|
||||||
|
.expect("taproot output key has len 32 <= 40");
|
||||||
|
let payload = Payload::WitnessProgram(prog);
|
||||||
|
Address(AddressInner { network, payload }, PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pay to taproot address from a pre-tweaked output key.
|
/// Creates a pay to taproot address from a pre-tweaked output key.
|
||||||
///
|
///
|
||||||
/// This method is not recommended for use, [`Address::p2tr()`] should be used where possible.
|
/// This method is not recommended for use, [`Address::p2tr()`] should be used where possible.
|
||||||
pub fn p2tr_tweaked(output_key: TweakedPublicKey, network: Network) -> Address {
|
pub fn p2tr_tweaked(output_key: TweakedPublicKey, network: Network) -> Address {
|
||||||
Address::new(network, Payload::p2tr_tweaked(output_key))
|
let prog = WitnessProgram::new(WitnessVersion::V1, output_key.to_inner().serialize())
|
||||||
|
.expect("taproot output key has len 32 <= 40");
|
||||||
|
let payload = Payload::WitnessProgram(prog);
|
||||||
|
Address(AddressInner { network, payload }, PhantomData)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates an address from an arbitrary witness program.
|
||||||
|
///
|
||||||
|
/// This only exists to support future witness versions. If you are doing normal mainnet things
|
||||||
|
/// then you likely do not need this constructor.
|
||||||
|
pub fn from_witness_program(program: WitnessProgram, network: Network) -> Address {
|
||||||
|
let inner = AddressInner { payload: Payload::WitnessProgram(program), network };
|
||||||
|
Address(inner, PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the address type of the address.
|
/// Gets the address type of the address.
|
||||||
|
@ -605,11 +517,34 @@ impl Address {
|
||||||
|
|
||||||
/// Constructs an [`Address`] from an output script (`scriptPubkey`).
|
/// Constructs an [`Address`] from an output script (`scriptPubkey`).
|
||||||
pub fn from_script(script: &Script, network: Network) -> Result<Address, Error> {
|
pub fn from_script(script: &Script, network: Network) -> Result<Address, Error> {
|
||||||
Ok(Address::new(network, Payload::from_script(script)?))
|
let payload = if script.is_p2pkh() {
|
||||||
|
let bytes = script.as_bytes()[3..23].try_into().expect("statically 20B long");
|
||||||
|
Payload::PubkeyHash(PubkeyHash::from_byte_array(bytes))
|
||||||
|
} else if script.is_p2sh() {
|
||||||
|
let bytes = script.as_bytes()[2..22].try_into().expect("statically 20B long");
|
||||||
|
Payload::ScriptHash(ScriptHash::from_byte_array(bytes))
|
||||||
|
} else if script.is_witness_program() {
|
||||||
|
let opcode = script.first_opcode().expect("witness_version guarantees len() > 4");
|
||||||
|
|
||||||
|
let witness_program = script.as_bytes()[2..].to_vec();
|
||||||
|
|
||||||
|
let witness_program =
|
||||||
|
WitnessProgram::new(WitnessVersion::try_from(opcode)?, witness_program)?;
|
||||||
|
Payload::WitnessProgram(witness_program)
|
||||||
|
} else {
|
||||||
|
return Err(Error::UnrecognizedScript);
|
||||||
|
};
|
||||||
|
Ok(Address(AddressInner { network, payload }, PhantomData))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a script pubkey spending to this address.
|
/// Generates a script pubkey spending to this address.
|
||||||
pub fn script_pubkey(&self) -> ScriptBuf { self.payload().script_pubkey() }
|
pub fn script_pubkey(&self) -> ScriptBuf {
|
||||||
|
match self.payload() {
|
||||||
|
Payload::PubkeyHash(ref hash) => ScriptBuf::new_p2pkh(hash),
|
||||||
|
Payload::ScriptHash(ref hash) => ScriptBuf::new_p2sh(hash),
|
||||||
|
Payload::WitnessProgram(ref prog) => ScriptBuf::new_witness_program(prog),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a URI string *bitcoin:address* optimized to be encoded in QR codes.
|
/// Creates a URI string *bitcoin:address* optimized to be encoded in QR codes.
|
||||||
///
|
///
|
||||||
|
@ -647,7 +582,7 @@ impl Address {
|
||||||
/// given key. For taproot addresses, the supplied key is assumed to be tweaked
|
/// given key. For taproot addresses, the supplied key is assumed to be tweaked
|
||||||
pub fn is_related_to_pubkey(&self, pubkey: &PublicKey) -> bool {
|
pub fn is_related_to_pubkey(&self, pubkey: &PublicKey) -> bool {
|
||||||
let pubkey_hash = pubkey.pubkey_hash();
|
let pubkey_hash = pubkey.pubkey_hash();
|
||||||
let payload = self.payload().inner_prog_as_bytes();
|
let payload = self.inner_prog_as_bytes();
|
||||||
let xonly_pubkey = XOnlyPublicKey::from(pubkey.inner);
|
let xonly_pubkey = XOnlyPublicKey::from(pubkey.inner);
|
||||||
|
|
||||||
(*pubkey_hash.as_byte_array() == *payload)
|
(*pubkey_hash.as_byte_array() == *payload)
|
||||||
|
@ -660,14 +595,32 @@ impl Address {
|
||||||
/// This will only work for Taproot addresses. The Public Key is
|
/// This will only work for Taproot addresses. The Public Key is
|
||||||
/// assumed to have already been tweaked.
|
/// assumed to have already been tweaked.
|
||||||
pub fn is_related_to_xonly_pubkey(&self, xonly_pubkey: &XOnlyPublicKey) -> bool {
|
pub fn is_related_to_xonly_pubkey(&self, xonly_pubkey: &XOnlyPublicKey) -> bool {
|
||||||
let payload = self.payload().inner_prog_as_bytes();
|
let payload = self.inner_prog_as_bytes();
|
||||||
payload == xonly_pubkey.serialize()
|
payload == xonly_pubkey.serialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the address creates a particular script
|
/// Returns true if the address creates a particular script
|
||||||
/// This function doesn't make any allocations.
|
/// This function doesn't make any allocations.
|
||||||
pub fn matches_script_pubkey(&self, script_pubkey: &Script) -> bool {
|
pub fn matches_script_pubkey(&self, script_pubkey: &Script) -> bool {
|
||||||
self.payload().matches_script_pubkey(script_pubkey)
|
match &self.payload() {
|
||||||
|
Payload::PubkeyHash(ref hash) if script_pubkey.is_p2pkh() =>
|
||||||
|
&script_pubkey.as_bytes()[3..23] == <PubkeyHash as AsRef<[u8; 20]>>::as_ref(hash),
|
||||||
|
Payload::ScriptHash(ref hash) if script_pubkey.is_p2sh() =>
|
||||||
|
&script_pubkey.as_bytes()[2..22] == <ScriptHash as AsRef<[u8; 20]>>::as_ref(hash),
|
||||||
|
Payload::WitnessProgram(ref prog) if script_pubkey.is_witness_program() =>
|
||||||
|
&script_pubkey.as_bytes()[2..] == prog.program().as_bytes(),
|
||||||
|
Payload::PubkeyHash(_) | Payload::ScriptHash(_) | Payload::WitnessProgram(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a byte slice of the inner program of the payload. If the payload
|
||||||
|
/// is a script hash or pubkey hash, a reference to the hash is returned.
|
||||||
|
fn inner_prog_as_bytes(&self) -> &[u8] {
|
||||||
|
match &self.payload() {
|
||||||
|
Payload::ScriptHash(hash) => hash.as_ref(),
|
||||||
|
Payload::PubkeyHash(hash) => hash.as_ref(),
|
||||||
|
Payload::WitnessProgram(prog) => prog.program().as_bytes(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue