Skip to content

Commit

Permalink
Add push_p2wpkh function on Witness
Browse files Browse the repository at this point in the history
In order to create the witness to spend p2wpkh output one must push the
signature and the pubkey, we should have a function for this.
  • Loading branch information
tcharding committed Sep 21, 2023
1 parent 3cad0f8 commit 60882e8
Showing 1 changed file with 34 additions and 0 deletions.
34 changes: 34 additions & 0 deletions bitcoin/src/blockdata/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,25 @@ impl Witness {
self.content[end_varint..end_varint + new_element.len()].copy_from_slice(new_element);
}

/// Pushes data onto the witness stack as required to spend a P2WPKH output.
///
/// Pushes the signature+sighash_type followed by the serialized public key. Also useful for
/// spending a P2SH-P2WPKH output.
///
/// Note that it is expected that `signature`, `hash_type`, and `pubkey` are related.
///
/// - `pubkey` is related to the private key that create `signature`.
/// - `hash_type` was used when creating the sighash signed to create `signature`.
pub fn push_p2wpkh(
&mut self,
signature: &ecdsa::Signature,
hash_type: EcdsaSighashType,
pubkey: &secp256k1::PublicKey,
) {
self.push_bitcoin_signature(signature, hash_type);
self.push_slice(&pubkey.serialize());
}

/// Pushes, as a new element on the witness, an ECDSA signature with the sighash type
/// concatenated, requires an allocation.
///
Expand Down Expand Up @@ -527,6 +546,21 @@ impl From<Vec<&[u8]>> for Witness {
fn from(vec: Vec<&[u8]>) -> Self { Witness::from_slice(&vec) }
}

/// Tried to use a legacy uncompressed pubkey in a segwit v0 transaction.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UncompressedPubkeyError;

impl fmt::Display for UncompressedPubkeyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "segwit v0 requires a compressed pubkey")
}
}

#[cfg(feature = "std")]
impl std::error::Error for UncompressedPubkeyError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
}

#[cfg(test)]
mod test {
use secp256k1::ecdsa;
Expand Down

0 comments on commit 60882e8

Please sign in to comment.