Merge rust-bitcoin/rust-bitcoin#1663: Create Address::matches_script_pubkey method
d71c31c235
Create Address::matches_script_pubkey method (hashmap) Pull request description: to check if an address creates a particular script without allocating. fixes rust-bitcoin/rust-bitcoin#1604 ACKs for top commit: Kixunil: ACKd71c31c235
apoelstra: ACKd71c31c235
Tree-SHA512: cb60a53ae2be7c47dcd27415c883a73c81d57cbbf0bc92eaf76243d79d9c8e2c2efe91bef65a7e67ed26fec376f11325709ff27025d054813b1907ea2bf4961c
This commit is contained in:
commit
fbb3b82b93
|
@ -469,6 +469,23 @@ impl Payload {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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
|
/// Creates a pay to (compressed) public key hash payload from a public key
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn p2pkh(pk: &PublicKey) -> Payload { Payload::PubkeyHash(pk.pubkey_hash()) }
|
pub fn p2pkh(pk: &PublicKey) -> Payload { Payload::PubkeyHash(pk.pubkey_hash()) }
|
||||||
|
@ -955,6 +972,12 @@ impl Address {
|
||||||
let payload = self.payload.inner_prog_as_bytes();
|
let payload = self.payload.inner_prog_as_bytes();
|
||||||
payload == xonly_pubkey.serialize()
|
payload == xonly_pubkey.serialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the address creates a particular script
|
||||||
|
/// This function doesn't make any allocations.
|
||||||
|
pub fn matches_script_pubkey(&self, script_pubkey: &Script) -> bool {
|
||||||
|
self.payload.matches_script_pubkey(script_pubkey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Methods that can be called only on `Address<NetworkUnchecked>`.
|
/// Methods that can be called only on `Address<NetworkUnchecked>`.
|
||||||
|
@ -1723,4 +1746,31 @@ mod tests {
|
||||||
let want = Err(Error::UnknownAddressType("invalid".to_string()));
|
let want = Err(Error::UnknownAddressType("invalid".to_string()));
|
||||||
assert_eq!(got, want);
|
assert_eq!(got, want);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_matches_script_pubkey() {
|
||||||
|
let addresses = [
|
||||||
|
"1QJVDzdqb1VpbDK7uDeyVXy9mR27CJiyhY",
|
||||||
|
"1J4LVanjHMu3JkXbVrahNuQCTGCRRgfWWx",
|
||||||
|
"33iFwdLuRpW1uK1RTRqsoi8rR4NpDzk66k",
|
||||||
|
"3QBRmWNqqBGme9er7fMkGqtZtp4gjMFxhE",
|
||||||
|
"bc1zw508d6qejxtdg4y5r3zarvaryvaxxpcs",
|
||||||
|
"bc1qvzvkjn4q3nszqxrv3nraga2r822xjty3ykvkuw",
|
||||||
|
"bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
|
||||||
|
"bc1pgllnmtxs0g058qz7c6qgaqq4qknwrqj9z7rqn9e2dzhmcfmhlu4sfadf5e",
|
||||||
|
];
|
||||||
|
for addr in &addresses {
|
||||||
|
let addr = Address::from_str(addr)
|
||||||
|
.unwrap()
|
||||||
|
.require_network(Network::Bitcoin)
|
||||||
|
.unwrap();
|
||||||
|
for another in &addresses {
|
||||||
|
let another = Address::from_str(another)
|
||||||
|
.unwrap()
|
||||||
|
.require_network(Network::Bitcoin)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(addr.matches_script_pubkey(&another.script_pubkey()), addr == another);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue