Pass keys by value

We should pass `Copy` types by value not by reference. Pass the key
types by value.
This commit is contained in:
Tobin C. Harding 2024-01-25 18:05:07 +11:00
parent efdcadf2fd
commit 7929b51640
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
15 changed files with 50 additions and 50 deletions

View File

@ -44,7 +44,7 @@ fn main() -> ! {
// Derive address
let pubkey = pk.public_key(&secp).try_into().unwrap();
let address = Address::p2wpkh(&pubkey, Network::Bitcoin);
let address = Address::p2wpkh(pubkey, Network::Bitcoin);
hprintln!("Address: {}", address).unwrap();
assert_eq!(address.to_string(), "bc1qpx9t9pzzl4qsydmhyt6ctrxxjd4ep549np9993".to_string());

View File

@ -50,6 +50,6 @@ fn main() {
// manually creating indexes this time
let zero = ChildNumber::from_normal_idx(0).unwrap();
let public_key = xpub.derive_pub(&secp, &[zero, zero]).unwrap().public_key;
let address = Address::p2wpkh(&CompressedPublicKey(public_key), KnownHrp::Mainnet);
let address = Address::p2wpkh(CompressedPublicKey(public_key), KnownHrp::Mainnet);
println!("First receiving address: {}", address);
}

View File

@ -222,7 +222,7 @@ fn main() {
.enumerate()
.map(|(idx, input)| {
let (_, sig) = input.partial_sigs.iter().next().expect("we have one sig");
Witness::p2wpkh(sig, &pk_inputs[idx].0)
Witness::p2wpkh(sig, pk_inputs[idx].0)
})
.collect();
psbt.inputs.iter_mut().enumerate().for_each(|(idx, input)| {

View File

@ -259,7 +259,7 @@ impl WatchOnly {
let derived = self.account_0_xpub.derive_pub(secp, &path)?;
let pk = derived.to_pub();
let addr = Address::p2wpkh(&pk, NETWORK);
let addr = Address::p2wpkh(pk, NETWORK);
let path = path.into_derivation_path()?;
Ok((pk, addr, path))

View File

@ -76,7 +76,7 @@ fn main() {
// Update the witness stack.
let signature = bitcoin::ecdsa::Signature { signature, sighash_type };
let pk = sk.public_key(&secp);
*sighasher.witness_mut(input_index).unwrap() = Witness::p2wpkh(&signature, &pk);
*sighasher.witness_mut(input_index).unwrap() = Witness::p2wpkh(&signature, pk);
// Get the signed transaction.
let tx = sighasher.into_transaction();

View File

@ -298,7 +298,7 @@ fn generate_bip86_key_spend_tx(
let secret_key = master_xpriv.derive_priv(secp, &derivation_path).to_priv().inner;
sign_psbt_taproot(
&secret_key,
secret_key,
input.tap_internal_key.unwrap(),
None,
input,
@ -372,7 +372,7 @@ impl BenefactorWallet {
.push_int(locktime.to_consensus_u32() as i64)
.push_opcode(OP_CLTV)
.push_opcode(OP_DROP)
.push_x_only_key(&beneficiary_key)
.push_x_only_key(beneficiary_key)
.push_opcode(OP_CHECKSIG)
.into_script()
}
@ -532,7 +532,7 @@ impl BenefactorWallet {
let secret_key =
self.master_xpriv.derive_priv(&self.secp, &derivation_path).to_priv().inner;
sign_psbt_taproot(
&secret_key,
secret_key,
spend_info.internal_key(),
None,
input,
@ -664,7 +664,7 @@ impl BeneficiaryWallet {
sighash_type,
)?;
sign_psbt_taproot(
&secret_key,
secret_key,
*x_only_pubkey,
Some(*lh),
&mut psbt.inputs[0],
@ -724,7 +724,7 @@ impl BeneficiaryWallet {
// Calling this with `leaf_hash` = `None` will sign for key-spend
fn sign_psbt_taproot(
secret_key: &secp256k1::SecretKey,
secret_key: secp256k1::SecretKey,
pubkey: XOnlyPublicKey,
leaf_hash: Option<TapLeafHash>,
psbt_input: &mut psbt::Input,

View File

@ -421,7 +421,7 @@ impl Address {
/// Creates a witness pay to public key address from a public key.
///
/// This is the native segwit address type for an output redeemable with a single signature.
pub fn p2wpkh(pk: &CompressedPublicKey, hrp: impl Into<KnownHrp>) -> Self {
pub fn p2wpkh(pk: CompressedPublicKey, hrp: impl Into<KnownHrp>) -> Self {
let program = WitnessProgram::p2wpkh(pk);
Address::from_witness_program(program, hrp)
}
@ -429,7 +429,7 @@ impl Address {
/// Creates a pay to script address that embeds a witness pay to public key.
///
/// This is a segwit address type that looks familiar (as p2sh) to legacy clients.
pub fn p2shwpkh(pk: &CompressedPublicKey, network: impl Into<NetworkKind>) -> Address {
pub fn p2shwpkh(pk: CompressedPublicKey, network: impl Into<NetworkKind>) -> Address {
let builder = script::Builder::new().push_int(0).push_slice(pk.wpubkey_hash());
let script_hash = builder.as_script().script_hash();
Address::p2sh_from_hash(script_hash, network)
@ -628,7 +628,7 @@ impl Address {
/// This is determined by directly comparing the address payload with either the
/// hash of the given public key or the segwit redeem hash generated from the
/// 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 payload = self.payload_as_bytes();
let xonly_pubkey = XOnlyPublicKey::from(pubkey.inner);
@ -642,7 +642,7 @@ impl Address {
///
/// This will only work for Taproot addresses. The Public Key is
/// 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 {
xonly_pubkey.serialize() == *self.payload_as_bytes()
}
@ -966,7 +966,7 @@ mod tests {
let key = "033bc8c83c52df5712229a2f72206d90192366c36428cb0c12b6af98324d97bfbc"
.parse::<CompressedPublicKey>()
.unwrap();
let addr = Address::p2wpkh(&key, KnownHrp::Mainnet);
let addr = Address::p2wpkh(key, KnownHrp::Mainnet);
assert_eq!(&addr.to_string(), "bc1qvzvkjn4q3nszqxrv3nraga2r822xjty3ykvkuw");
assert_eq!(addr.address_type(), Some(AddressType::P2wpkh));
roundtrips(&addr, Bitcoin);
@ -991,7 +991,7 @@ mod tests {
let key = "026c468be64d22761c30cd2f12cbc7de255d592d7904b1bab07236897cc4c2e766"
.parse::<CompressedPublicKey>()
.unwrap();
let addr = Address::p2shwpkh(&key, NetworkKind::Main);
let addr = Address::p2shwpkh(key, NetworkKind::Main);
assert_eq!(&addr.to_string(), "3QBRmWNqqBGme9er7fMkGqtZtp4gjMFxhE");
assert_eq!(addr.address_type(), Some(AddressType::P2sh));
roundtrips(&addr, Bitcoin);
@ -1202,14 +1202,14 @@ mod tests {
let pubkey_string = "0347ff3dacd07a1f43805ec6808e801505a6e18245178609972a68afbc2777ff2b";
let pubkey = PublicKey::from_str(pubkey_string).expect("pubkey");
let result = address.is_related_to_pubkey(&pubkey);
let result = address.is_related_to_pubkey(pubkey);
assert!(result);
let unused_pubkey = PublicKey::from_str(
"02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c",
)
.expect("pubkey");
assert!(!address.is_related_to_pubkey(&unused_pubkey))
assert!(!address.is_related_to_pubkey(unused_pubkey))
}
#[test]
@ -1223,14 +1223,14 @@ mod tests {
let pubkey_string = "0347ff3dacd07a1f43805ec6808e801505a6e18245178609972a68afbc2777ff2b";
let pubkey = PublicKey::from_str(pubkey_string).expect("pubkey");
let result = address.is_related_to_pubkey(&pubkey);
let result = address.is_related_to_pubkey(pubkey);
assert!(result);
let unused_pubkey = PublicKey::from_str(
"02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c",
)
.expect("pubkey");
assert!(!address.is_related_to_pubkey(&unused_pubkey))
assert!(!address.is_related_to_pubkey(unused_pubkey))
}
#[test]
@ -1244,14 +1244,14 @@ mod tests {
let pubkey_string = "0347ff3dacd07a1f43805ec6808e801505a6e18245178609972a68afbc2777ff2b";
let pubkey = PublicKey::from_str(pubkey_string).expect("pubkey");
let result = address.is_related_to_pubkey(&pubkey);
let result = address.is_related_to_pubkey(pubkey);
assert!(result);
let unused_pubkey = PublicKey::from_str(
"02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c",
)
.expect("pubkey");
assert!(!address.is_related_to_pubkey(&unused_pubkey))
assert!(!address.is_related_to_pubkey(unused_pubkey))
}
#[test]
@ -1265,14 +1265,14 @@ mod tests {
let pubkey_string = "04e96e22004e3db93530de27ccddfdf1463975d2138ac018fc3e7ba1a2e5e0aad8e424d0b55e2436eb1d0dcd5cb2b8bcc6d53412c22f358de57803a6a655fbbd04";
let pubkey = PublicKey::from_str(pubkey_string).expect("pubkey");
let result = address.is_related_to_pubkey(&pubkey);
let result = address.is_related_to_pubkey(pubkey);
assert!(result);
let unused_pubkey = PublicKey::from_str(
"02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c",
)
.expect("pubkey");
assert!(!address.is_related_to_pubkey(&unused_pubkey))
assert!(!address.is_related_to_pubkey(unused_pubkey))
}
#[test]
@ -1291,14 +1291,14 @@ mod tests {
.expect("mainnet")
);
let result = address.is_related_to_pubkey(&pubkey);
let result = address.is_related_to_pubkey(pubkey);
assert!(result);
let unused_pubkey = PublicKey::from_str(
"02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c",
)
.expect("pubkey");
assert!(!address.is_related_to_pubkey(&unused_pubkey));
assert!(!address.is_related_to_pubkey(unused_pubkey));
}
#[test]
@ -1317,7 +1317,7 @@ mod tests {
.expect("mainnet")
);
let result = address.is_related_to_xonly_pubkey(&xonly_pubkey);
let result = address.is_related_to_xonly_pubkey(xonly_pubkey);
assert!(result);
}

View File

@ -64,7 +64,7 @@ impl Builder {
}
/// Adds instructions to push a public key onto the stack.
pub fn push_key(self, key: &PublicKey) -> Builder {
pub fn push_key(self, key: PublicKey) -> Builder {
if key.compressed {
self.push_slice(key.inner.serialize())
} else {
@ -73,7 +73,7 @@ impl Builder {
}
/// Adds instructions to push an XOnly public key onto the stack.
pub fn push_x_only_key(self, x_only_key: &XOnlyPublicKey) -> Builder {
pub fn push_x_only_key(self, x_only_key: XOnlyPublicKey) -> Builder {
self.push_slice(x_only_key.serialize())
}

View File

@ -76,7 +76,7 @@ impl ScriptBuf {
pub fn builder() -> Builder { Builder::new() }
/// Generates P2PK-type of scriptPubkey.
pub fn new_p2pk(pubkey: &PublicKey) -> Self {
pub fn new_p2pk(pubkey: PublicKey) -> Self {
Builder::new().push_key(pubkey).push_opcode(OP_CHECKSIG).into_script()
}

View File

@ -37,10 +37,10 @@ fn script() {
// keys
const KEYSTR1: &str = "21032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af";
let key = PublicKey::from_str(&KEYSTR1[2..]).unwrap();
script = script.push_key(&key); comp.extend_from_slice(&hex!(KEYSTR1)); assert_eq!(script.as_bytes(), &comp[..]);
script = script.push_key(key); comp.extend_from_slice(&hex!(KEYSTR1)); assert_eq!(script.as_bytes(), &comp[..]);
const KEYSTR2: &str = "41042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133";
let key = PublicKey::from_str(&KEYSTR2[2..]).unwrap();
script = script.push_key(&key); comp.extend_from_slice(&hex!(KEYSTR2)); assert_eq!(script.as_bytes(), &comp[..]);
script = script.push_key(key); comp.extend_from_slice(&hex!(KEYSTR2)); assert_eq!(script.as_bytes(), &comp[..]);
// opcodes
script = script.push_opcode(OP_CHECKSIG); comp.push(0xACu8); assert_eq!(script.as_bytes(), &comp[..]);
@ -51,7 +51,7 @@ fn script() {
fn p2pk_pubkey_bytes_valid_key_and_valid_script_returns_expected_key() {
let key_str = "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3";
let key = PublicKey::from_str(key_str).unwrap();
let p2pk = Script::builder().push_key(&key).push_opcode(OP_CHECKSIG).into_script();
let p2pk = Script::builder().push_key(key).push_opcode(OP_CHECKSIG).into_script();
let actual = p2pk.p2pk_pubkey_bytes().unwrap();
assert_eq!(actual.to_vec(), key.to_bytes());
}
@ -60,7 +60,7 @@ fn p2pk_pubkey_bytes_valid_key_and_valid_script_returns_expected_key() {
fn p2pk_pubkey_bytes_no_checksig_returns_none() {
let key_str = "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3";
let key = PublicKey::from_str(key_str).unwrap();
let no_checksig = Script::builder().push_key(&key).into_script();
let no_checksig = Script::builder().push_key(key).into_script();
assert_eq!(no_checksig.p2pk_pubkey_bytes(), None);
}
@ -81,7 +81,7 @@ fn p2pk_pubkey_bytes_no_key_returns_none() {
fn p2pk_pubkey_bytes_different_op_code_returns_none() {
let key_str = "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3";
let key = PublicKey::from_str(key_str).unwrap();
let different_op_code = Script::builder().push_key(&key).push_opcode(OP_NOP).into_script();
let different_op_code = Script::builder().push_key(key).push_opcode(OP_NOP).into_script();
assert!(different_op_code.p2pk_pubkey_bytes().is_none());
}
@ -106,7 +106,7 @@ fn p2pk_pubkey_bytes_invalid_key_returns_some() {
fn p2pk_pubkey_bytes_compressed_key_returns_expected_key() {
let compressed_key_str = "0311db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c";
let key = PublicKey::from_str(compressed_key_str).unwrap();
let p2pk = Script::builder().push_key(&key).push_opcode(OP_CHECKSIG).into_script();
let p2pk = Script::builder().push_key(key).push_opcode(OP_CHECKSIG).into_script();
let actual = p2pk.p2pk_pubkey_bytes().unwrap();
assert_eq!(actual.to_vec(), key.to_bytes());
}
@ -115,7 +115,7 @@ fn p2pk_pubkey_bytes_compressed_key_returns_expected_key() {
fn p2pk_public_key_valid_key_and_valid_script_returns_expected_key() {
let key_str = "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3";
let key = PublicKey::from_str(key_str).unwrap();
let p2pk = Script::builder().push_key(&key).push_opcode(OP_CHECKSIG).into_script();
let p2pk = Script::builder().push_key(key).push_opcode(OP_CHECKSIG).into_script();
let actual = p2pk.p2pk_public_key().unwrap();
assert_eq!(actual, key);
}
@ -124,7 +124,7 @@ fn p2pk_public_key_valid_key_and_valid_script_returns_expected_key() {
fn p2pk_public_key_no_checksig_returns_none() {
let key_str = "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3";
let key = PublicKey::from_str(key_str).unwrap();
let no_checksig = Script::builder().push_key(&key).into_script();
let no_checksig = Script::builder().push_key(key).into_script();
assert_eq!(no_checksig.p2pk_public_key(), None);
}
@ -144,7 +144,7 @@ fn p2pk_public_key_no_key_returns_none() {
fn p2pk_public_key_different_op_code_returns_none() {
let key_str = "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3";
let key = PublicKey::from_str(key_str).unwrap();
let different_op_code = Script::builder().push_key(&key).push_opcode(OP_NOP).into_script();
let different_op_code = Script::builder().push_key(key).push_opcode(OP_NOP).into_script();
assert!(different_op_code.p2pk_public_key().is_none());
}
@ -168,7 +168,7 @@ fn p2pk_public_key_invalid_key_returns_none() {
fn p2pk_public_key_compressed_key_returns_some() {
let compressed_key_str = "0311db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c";
let key = PublicKey::from_str(compressed_key_str).unwrap();
let p2pk = Script::builder().push_key(&key).push_opcode(OP_CHECKSIG).into_script();
let p2pk = Script::builder().push_key(key).push_opcode(OP_CHECKSIG).into_script();
let actual = p2pk.p2pk_public_key().unwrap();
assert_eq!(actual, key);
}
@ -180,7 +180,7 @@ fn script_x_only_key() {
// From: https://github.com/bitcoin-core/btcdeb/blob/e8c2750c4a4702768c52d15640ed03bf744d2601/doc/tapscript-example.md?plain=1#L43
const KEYSTR: &str = "209997a497d964fc1a62885b05a51166a65a90df00492c8d7cf61d6accf54803be";
let x_only_key = XOnlyPublicKey::from_str(&KEYSTR[2..]).unwrap();
let script = Builder::new().push_x_only_key(&x_only_key);
let script = Builder::new().push_x_only_key(x_only_key);
assert_eq!(script.into_bytes(), &hex!(KEYSTR) as &[u8]);
}
@ -202,7 +202,7 @@ fn script_generators() {
let pubkey =
PublicKey::from_str("0234e6a79c5359c613762d537e0e19d86c77c1666d8c9ab050f23acd198e97f93e")
.unwrap();
assert!(ScriptBuf::new_p2pk(&pubkey).is_p2pk());
assert!(ScriptBuf::new_p2pk(pubkey).is_p2pk());
let pubkey_hash = PubkeyHash::hash(&pubkey.inner.serialize());
assert!(ScriptBuf::new_p2pkh(&pubkey_hash).is_p2pkh());

View File

@ -72,7 +72,7 @@ impl WitnessProgram {
}
/// Creates a [`WitnessProgram`] from `pk` for a P2WPKH output.
pub fn p2wpkh(pk: &CompressedPublicKey) -> Self {
pub fn p2wpkh(pk: CompressedPublicKey) -> Self {
let hash = pk.wpubkey_hash();
WitnessProgram::new_p2wpkh(hash.to_byte_array())
}

View File

@ -243,7 +243,7 @@ impl Witness {
/// serialized public key. Also useful for spending a P2SH-P2WPKH output.
///
/// It is expected that `pubkey` is related to the secret key used to create `signature`.
pub fn p2wpkh(signature: &ecdsa::Signature, pubkey: &secp256k1::PublicKey) -> Witness {
pub fn p2wpkh(signature: &ecdsa::Signature, pubkey: secp256k1::PublicKey) -> Witness {
let mut witness = Witness::new();
witness.push_slice(&signature.serialize());
witness.push_slice(&pubkey.serialize());

View File

@ -194,7 +194,7 @@ impl PublicKey {
/// Computes the public key as supposed to be used with this secret.
pub fn from_private_key<C: secp256k1::Signing>(
secp: &Secp256k1<C>,
sk: &PrivateKey,
sk: PrivateKey,
) -> PublicKey {
sk.public_key(secp)
}
@ -327,7 +327,7 @@ impl CompressedPublicKey {
/// Computes the public key as supposed to be used with this secret.
pub fn from_private_key<C: secp256k1::Signing>(
secp: &Secp256k1<C>,
sk: &PrivateKey,
sk: PrivateKey,
) -> Result<Self, UncompressedPublicKeyError> {
sk.public_key(secp).try_into()
}
@ -1243,7 +1243,7 @@ mod tests {
let s = Secp256k1::new();
let sk = PrivateKey::from_str(KEY_WIF).unwrap();
let pk = PublicKey::from_private_key(&s, &sk);
let pk = PublicKey::from_private_key(&s, sk);
let pk_u = PublicKey { inner: pk.inner, compressed: false };
assert_tokens(&sk, &[Token::BorrowedStr(KEY_WIF)]);

View File

@ -2120,7 +2120,7 @@ mod tests {
let sk = SecretKey::new(&mut thread_rng());
let priv_key = PrivateKey::new(sk, NetworkKind::Test);
let pk = PublicKey::from_private_key(&secp, &priv_key);
let pk = PublicKey::from_private_key(&secp, priv_key);
(priv_key, pk, secp)
}

View File

@ -246,12 +246,12 @@ mod tests {
let p2pkh = Address::p2pkh(pubkey, NetworkKind::Main);
assert_eq!(signature2.is_signed_by_address(&secp, &p2pkh, msg_hash), Ok(true));
let p2wpkh = Address::p2wpkh(&pubkey, Network::Bitcoin);
let p2wpkh = Address::p2wpkh(pubkey, Network::Bitcoin);
assert_eq!(
signature2.is_signed_by_address(&secp, &p2wpkh, msg_hash),
Err(MessageSignatureError::UnsupportedAddressType(AddressType::P2wpkh))
);
let p2shwpkh = Address::p2shwpkh(&pubkey, NetworkKind::Main);
let p2shwpkh = Address::p2shwpkh(pubkey, NetworkKind::Main);
assert_eq!(
signature2.is_signed_by_address(&secp, &p2shwpkh, msg_hash),
Err(MessageSignatureError::UnsupportedAddressType(AddressType::P2sh))