Merge rust-bitcoin/rust-bitcoin#2084: Add `Witness::p2wpkh` constructor
5901d35095
Add push_p2wpkh function on Witness (Tobin C. Harding)8cd409d561
Deprecate push_bitcoin_signature (Tobin C. Harding) Pull request description: In order to create the witness to spend p2wpkh output one must create a `Witness` that includes the signature and the pubkey, we should have a function for this. ## Notes The PR originally added a `push_p2wphk` method, this is now instead a constrcutor `Witness:p2wpkh` (after review discussion below). - Patch 1 changes `push_bitcoin_signature` to take an `ecdsa::Sigtnture` instead of an `ecdsa::SerializedSignature` - Patch 2 takes a `secp256k1::PublicKey` removing the need for an error path (discussed below). ACKs for top commit: sanket1729: ACK5901d35095
apoelstra: ACK5901d35095
Tree-SHA512: 646014d97daafbf0909106d8990debaf481ac6f3578f0ddf232d739c3e2d55ae1d0275abe5a4a1db1c5c192c8c5f0b5546fc65aac37b91a3729db881c5ad3dec
This commit is contained in:
commit
1c29dd97ce
|
@ -9,10 +9,9 @@ use core::convert::TryInto;
|
|||
use core::fmt;
|
||||
use core::ops::Index;
|
||||
|
||||
use secp256k1::ecdsa;
|
||||
|
||||
use crate::consensus::encode::{Error, MAX_VEC_SIZE};
|
||||
use crate::consensus::{Decodable, Encodable, WriteExt};
|
||||
use crate::crypto::ecdsa;
|
||||
use crate::io::{self, Read, Write};
|
||||
use crate::prelude::*;
|
||||
use crate::sighash::EcdsaSighashType;
|
||||
|
@ -237,6 +236,19 @@ impl Witness {
|
|||
/// Creates a new empty [`Witness`].
|
||||
pub fn new() -> Self { Witness::default() }
|
||||
|
||||
/// Creates a witness required to spend a P2WPKH output.
|
||||
///
|
||||
/// The witness will be made up of the DER encoded signature + sighash_type followed by the
|
||||
/// 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 {
|
||||
let mut witness = Witness::new();
|
||||
witness.push_slice(&signature.serialize());
|
||||
witness.push_slice(&pubkey.serialize());
|
||||
witness
|
||||
}
|
||||
|
||||
/// Creates a [`Witness`] object from a slice of bytes slices where each slice is a witness item.
|
||||
pub fn from_slice<T: AsRef<[u8]>>(slice: &[T]) -> Self {
|
||||
let witness_elements = slice.len();
|
||||
|
@ -321,9 +333,10 @@ impl Witness {
|
|||
|
||||
/// Pushes a DER-encoded ECDSA signature with a signature hash type as a new element on the
|
||||
/// witness, requires an allocation.
|
||||
#[deprecated(since = "0.30.0", note = "use push_ecdsa_signature instead")]
|
||||
pub fn push_bitcoin_signature(
|
||||
&mut self,
|
||||
signature: &ecdsa::SerializedSignature,
|
||||
signature: &secp256k1::ecdsa::SerializedSignature,
|
||||
hash_type: EcdsaSighashType,
|
||||
) {
|
||||
// Note that a maximal length ECDSA signature is 72 bytes, plus the sighash type makes 73
|
||||
|
@ -333,6 +346,13 @@ impl Witness {
|
|||
self.push(&sig[..signature.len() + 1]);
|
||||
}
|
||||
|
||||
/// Pushes, as a new element on the witness, an ECDSA signature.
|
||||
///
|
||||
/// Pushes the DER encoded signature + sighash_type, requires an allocation.
|
||||
pub fn push_ecdsa_signature(&mut self, signature: &ecdsa::Signature) {
|
||||
self.push_slice(&signature.serialize())
|
||||
}
|
||||
|
||||
fn element_at(&self, index: usize) -> Option<&[u8]> {
|
||||
let varint = VarInt::consensus_decode(&mut &self.content[index..]).ok()?;
|
||||
let start = index + varint.len();
|
||||
|
@ -525,8 +545,6 @@ impl From<Vec<&[u8]>> for Witness {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use secp256k1::ecdsa;
|
||||
|
||||
use super::*;
|
||||
use crate::consensus::{deserialize, serialize};
|
||||
use crate::internal_macros::hex;
|
||||
|
@ -624,9 +642,10 @@ mod test {
|
|||
// The very first signature in block 734,958
|
||||
let sig_bytes =
|
||||
hex!("304402207c800d698f4b0298c5aac830b822f011bb02df41eb114ade9a6702f364d5e39c0220366900d2a60cab903e77ef7dd415d46509b1f78ac78906e3296f495aa1b1b541");
|
||||
let sig = ecdsa::Signature::from_der(&sig_bytes).unwrap();
|
||||
let sig = secp256k1::ecdsa::Signature::from_der(&sig_bytes).unwrap();
|
||||
let mut witness = Witness::default();
|
||||
witness.push_bitcoin_signature(&sig.serialize_der(), EcdsaSighashType::All);
|
||||
let signature = ecdsa::Signature { sig, hash_ty: EcdsaSighashType::All };
|
||||
witness.push_ecdsa_signature(&signature);
|
||||
let expected_witness = vec![hex!(
|
||||
"304402207c800d698f4b0298c5aac830b822f011bb02df41eb114ade9a6702f364d5e39c0220366900d2a60cab903e77ef7dd415d46509b1f78ac78906e3296f495aa1b1b54101")
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue