Skip to content

Commit

Permalink
descriptors: define script_code() for legacy outputs
Browse files Browse the repository at this point in the history
This fixes the incorrect assumption made in
283676e that the `scriptCode` was
defined in bip-0143.

In fact, it just became convoluted with bip-0143.

Reported-by: Andrew Poelstra <apoelstra@wpsoftware.net>
Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
  • Loading branch information
darosior committed Aug 28, 2020
1 parent a3370b7 commit 236bcf5
Showing 1 changed file with 11 additions and 12 deletions.
23 changes: 11 additions & 12 deletions src/descriptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,29 +393,28 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
}
}

/// Get the `scriptCode` as [defined by
/// bip-0143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification),
/// used to generate sighashes for spending Segwit outputs.
/// Get the `scriptCode` of a transaction output.
///
/// # Errors
/// - If the script descriptor type is non-segwit, as the script code is only defined for
/// segregated witness transaction outputs.
pub fn script_code(&self) -> Result<Script, Error> {
/// The `scriptCode` is the Script of the previous transaction output being serialized in the
/// sighash when evaluating a `CHECKSIG` & co. OP code.
pub fn script_code(&self) -> Script {
match *self {
// Spending non-segwit outputs requires "legacy" sighash and don't use bip143's `scriptCode`.
// For "legacy" outputs, it is defined as the txo's scriptPubKey.
Descriptor::Bare(..)
| Descriptor::Sh(..)
| Descriptor::Pk(..)
| Descriptor::Pkh(..)
| Descriptor::Sh(..) => Err(Error::BadDescriptor),
| Descriptor::Pkh(..) => self.script_pubkey(),
// For SegWit outputs, it is defined by bip-0143 (quoted below) and is different from
// the previous txo's scriptPubKey.
// The item 5:
// - For P2WPKH witness program, the scriptCode is `0x1976a914{20-byte-pubkey-hash}88ac`.
Descriptor::Wpkh(ref pk) | Descriptor::ShWpkh(ref pk) => {
let addr = bitcoin::Address::p2pkh(&pk.to_public_key(), bitcoin::Network::Bitcoin);
Ok(addr.script_pubkey())
addr.script_pubkey()
}
// - For P2WSH witness program, if the witnessScript does not contain any `OP_CODESEPARATOR`,
// the `scriptCode` is the `witnessScript` serialized as scripts inside CTxOut.
Descriptor::Wsh(ref d) | Descriptor::ShWsh(ref d) => Ok(d.encode()),
Descriptor::Wsh(ref d) | Descriptor::ShWsh(ref d) => d.encode(),
}
}
}
Expand Down

0 comments on commit 236bcf5

Please sign in to comment.