Merge rust-bitcoin/rust-bitcoin#1295: Remove usage of `opcodes::all`
c3e4399519
Remove usage of opcodes::all (Tobin C. Harding) Pull request description: We have all of the opcodes defined in a submodule called `all`, this allows wildcard imports without bringing in the other types in the `opcodes` module. Use wildcard import `use crate::blockdata::opcodes::all::*` instead of fully qualifying the path to opcodes. ### Original PR description (left here so the thread of discussion below makes sense) The `all` module adds no value, we can remove it without loss of meaning or clarity, doing so makes the code less verbose. EDIT: After review, now includes importing with wildcard and removing the `opcodes::` path from any type starting with `OP_`. Idea stolen from: https://github.com/rust-bitcoin/rust-bitcoin/pull/525 (patch 7) ACKs for top commit: Kixunil: ACKc3e4399519
apoelstra: ACKc3e4399519
Tree-SHA512: 300511d909a25e82c563b18da1b52bcf65653cd3efd8ff32dd5b9e839dacd57924953c1745dfb5e9301fa4f9fc0cd61a075f3a3fd94f6a5a9730bca5155dfd96
This commit is contained in:
commit
afcdfa4a59
|
@ -36,6 +36,7 @@ use crate::blockdata::constants::{
|
|||
};
|
||||
use crate::blockdata::script::Instruction;
|
||||
use crate::blockdata::{opcodes, script};
|
||||
use crate::blockdata::opcodes::all::*;
|
||||
use crate::error::ParseIntError;
|
||||
use crate::hash_types::{PubkeyHash, ScriptHash};
|
||||
use crate::hashes::{sha256, Hash, HashEngine};
|
||||
|
@ -324,9 +325,9 @@ impl TryFrom<opcodes::All> for WitnessVersion {
|
|||
match opcode.to_u8() {
|
||||
0 => Ok(WitnessVersion::V0),
|
||||
version
|
||||
if version >= opcodes::all::OP_PUSHNUM_1.to_u8()
|
||||
&& version <= opcodes::all::OP_PUSHNUM_16.to_u8() =>
|
||||
WitnessVersion::try_from(version - opcodes::all::OP_PUSHNUM_1.to_u8() + 1),
|
||||
if version >= OP_PUSHNUM_1.to_u8()
|
||||
&& version <= OP_PUSHNUM_16.to_u8() =>
|
||||
WitnessVersion::try_from(version - OP_PUSHNUM_1.to_u8() + 1),
|
||||
_ => Err(Error::MalformedWitnessVersion),
|
||||
}
|
||||
}
|
||||
|
@ -364,8 +365,8 @@ impl From<WitnessVersion> for opcodes::All {
|
|||
/// Converts [`WitnessVersion`] instance into corresponding Bitcoin scriptopcode (`OP_0`..`OP_16`).
|
||||
fn from(version: WitnessVersion) -> opcodes::All {
|
||||
match version {
|
||||
WitnessVersion::V0 => opcodes::all::OP_PUSHBYTES_0,
|
||||
no => opcodes::All::from(opcodes::all::OP_PUSHNUM_1.to_u8() + no.to_num() - 1),
|
||||
WitnessVersion::V0 => OP_PUSHBYTES_0,
|
||||
no => opcodes::All::from(OP_PUSHNUM_1.to_u8() + no.to_num() - 1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ use bitcoin_internals::impl_array_newtype;
|
|||
|
||||
use crate::hashes::hex::{self, HexIterator};
|
||||
use crate::hashes::{Hash, sha256d};
|
||||
use crate::blockdata::opcodes;
|
||||
use crate::blockdata::script;
|
||||
use crate::blockdata::opcodes::all::*;
|
||||
use crate::blockdata::locktime::absolute;
|
||||
use crate::blockdata::transaction::{OutPoint, Transaction, TxOut, TxIn, Sequence};
|
||||
use crate::blockdata::block::{Block, BlockHeader, BlockVersion};
|
||||
|
@ -92,7 +92,7 @@ fn bitcoin_genesis_tx() -> Transaction {
|
|||
.collect();
|
||||
let out_script = script::Builder::new()
|
||||
.push_slice(script_bytes.unwrap().as_slice())
|
||||
.push_opcode(opcodes::all::OP_CHECKSIG)
|
||||
.push_opcode(OP_CHECKSIG)
|
||||
.into_script();
|
||||
ret.output.push(TxOut {
|
||||
value: 50 * COIN_VALUE,
|
||||
|
|
|
@ -26,6 +26,11 @@ pub struct All {
|
|||
code: u8,
|
||||
}
|
||||
|
||||
// private import so we don't have to use `all::OP_FOO` in this file.
|
||||
use self::all::*;
|
||||
|
||||
/// The `all` module is provided so one can use a wildcard import `use bitcoin::opcodes::all::*` to
|
||||
/// get all the `OP_FOO` opcodes without getting other types defined in `opcodes` (e.g. `All`, `Class`).
|
||||
pub mod all {
|
||||
//! Constants associated with All type
|
||||
use super::All;
|
||||
|
@ -554,96 +559,96 @@ impl fmt::Display for All {
|
|||
f.write_str("OP_")?;
|
||||
match *self {
|
||||
All {code: x} if x <= 75 => write!(f, "PUSHBYTES_{}", self.code),
|
||||
all::OP_PUSHDATA1 => write!(f, "PUSHDATA1"),
|
||||
all::OP_PUSHDATA2 => write!(f, "PUSHDATA2"),
|
||||
all::OP_PUSHDATA4 => write!(f, "PUSHDATA4"),
|
||||
all::OP_PUSHNUM_NEG1 => write!(f, "PUSHNUM_NEG1"),
|
||||
all::OP_RESERVED => write!(f, "RESERVED"),
|
||||
All {code: x} if x >= all::OP_PUSHNUM_1.code && x <= all::OP_PUSHNUM_16.code => write!(f, "PUSHNUM_{}", x - all::OP_PUSHNUM_1.code + 1),
|
||||
all::OP_NOP => write!(f, "NOP"),
|
||||
all::OP_VER => write!(f, "VER"),
|
||||
all::OP_IF => write!(f, "IF"),
|
||||
all::OP_NOTIF => write!(f, "NOTIF"),
|
||||
all::OP_VERIF => write!(f, "VERIF"),
|
||||
all::OP_VERNOTIF => write!(f, "VERNOTIF"),
|
||||
all::OP_ELSE => write!(f, "ELSE"),
|
||||
all::OP_ENDIF => write!(f, "ENDIF"),
|
||||
all::OP_VERIFY => write!(f, "VERIFY"),
|
||||
all::OP_RETURN => write!(f, "RETURN"),
|
||||
all::OP_TOALTSTACK => write!(f, "TOALTSTACK"),
|
||||
all::OP_FROMALTSTACK => write!(f, "FROMALTSTACK"),
|
||||
all::OP_2DROP => write!(f, "2DROP"),
|
||||
all::OP_2DUP => write!(f, "2DUP"),
|
||||
all::OP_3DUP => write!(f, "3DUP"),
|
||||
all::OP_2OVER => write!(f, "2OVER"),
|
||||
all::OP_2ROT => write!(f, "2ROT"),
|
||||
all::OP_2SWAP => write!(f, "2SWAP"),
|
||||
all::OP_IFDUP => write!(f, "IFDUP"),
|
||||
all::OP_DEPTH => write!(f, "DEPTH"),
|
||||
all::OP_DROP => write!(f, "DROP"),
|
||||
all::OP_DUP => write!(f, "DUP"),
|
||||
all::OP_NIP => write!(f, "NIP"),
|
||||
all::OP_OVER => write!(f, "OVER"),
|
||||
all::OP_PICK => write!(f, "PICK"),
|
||||
all::OP_ROLL => write!(f, "ROLL"),
|
||||
all::OP_ROT => write!(f, "ROT"),
|
||||
all::OP_SWAP => write!(f, "SWAP"),
|
||||
all::OP_TUCK => write!(f, "TUCK"),
|
||||
all::OP_CAT => write!(f, "CAT"),
|
||||
all::OP_SUBSTR => write!(f, "SUBSTR"),
|
||||
all::OP_LEFT => write!(f, "LEFT"),
|
||||
all::OP_RIGHT => write!(f, "RIGHT"),
|
||||
all::OP_SIZE => write!(f, "SIZE"),
|
||||
all::OP_INVERT => write!(f, "INVERT"),
|
||||
all::OP_AND => write!(f, "AND"),
|
||||
all::OP_OR => write!(f, "OR"),
|
||||
all::OP_XOR => write!(f, "XOR"),
|
||||
all::OP_EQUAL => write!(f, "EQUAL"),
|
||||
all::OP_EQUALVERIFY => write!(f, "EQUALVERIFY"),
|
||||
all::OP_RESERVED1 => write!(f, "RESERVED1"),
|
||||
all::OP_RESERVED2 => write!(f, "RESERVED2"),
|
||||
all::OP_1ADD => write!(f, "1ADD"),
|
||||
all::OP_1SUB => write!(f, "1SUB"),
|
||||
all::OP_2MUL => write!(f, "2MUL"),
|
||||
all::OP_2DIV => write!(f, "2DIV"),
|
||||
all::OP_NEGATE => write!(f, "NEGATE"),
|
||||
all::OP_ABS => write!(f, "ABS"),
|
||||
all::OP_NOT => write!(f, "NOT"),
|
||||
all::OP_0NOTEQUAL => write!(f, "0NOTEQUAL"),
|
||||
all::OP_ADD => write!(f, "ADD"),
|
||||
all::OP_SUB => write!(f, "SUB"),
|
||||
all::OP_MUL => write!(f, "MUL"),
|
||||
all::OP_DIV => write!(f, "DIV"),
|
||||
all::OP_MOD => write!(f, "MOD"),
|
||||
all::OP_LSHIFT => write!(f, "LSHIFT"),
|
||||
all::OP_RSHIFT => write!(f, "RSHIFT"),
|
||||
all::OP_BOOLAND => write!(f, "BOOLAND"),
|
||||
all::OP_BOOLOR => write!(f, "BOOLOR"),
|
||||
all::OP_NUMEQUAL => write!(f, "NUMEQUAL"),
|
||||
all::OP_NUMEQUALVERIFY => write!(f, "NUMEQUALVERIFY"),
|
||||
all::OP_NUMNOTEQUAL => write!(f, "NUMNOTEQUAL"),
|
||||
all::OP_LESSTHAN => write!(f, "LESSTHAN"),
|
||||
all::OP_GREATERTHAN => write!(f, "GREATERTHAN"),
|
||||
all::OP_LESSTHANOREQUAL => write!(f, "LESSTHANOREQUAL"),
|
||||
all::OP_GREATERTHANOREQUAL => write!(f, "GREATERTHANOREQUAL"),
|
||||
all::OP_MIN => write!(f, "MIN"),
|
||||
all::OP_MAX => write!(f, "MAX"),
|
||||
all::OP_WITHIN => write!(f, "WITHIN"),
|
||||
all::OP_RIPEMD160 => write!(f, "RIPEMD160"),
|
||||
all::OP_SHA1 => write!(f, "SHA1"),
|
||||
all::OP_SHA256 => write!(f, "SHA256"),
|
||||
all::OP_HASH160 => write!(f, "HASH160"),
|
||||
all::OP_HASH256 => write!(f, "HASH256"),
|
||||
all::OP_CODESEPARATOR => write!(f, "CODESEPARATOR"),
|
||||
all::OP_CHECKSIG => write!(f, "CHECKSIG"),
|
||||
all::OP_CHECKSIGVERIFY => write!(f, "CHECKSIGVERIFY"),
|
||||
all::OP_CHECKMULTISIG => write!(f, "CHECKMULTISIG"),
|
||||
all::OP_CHECKMULTISIGVERIFY => write!(f, "CHECKMULTISIGVERIFY"),
|
||||
all::OP_CLTV => write!(f, "CLTV"),
|
||||
all::OP_CSV => write!(f, "CSV"),
|
||||
All {code: x} if (all::OP_NOP1.code..=all::OP_NOP10.code).contains(&x) => write!(f, "NOP{}", x - all::OP_NOP1.code + 1),
|
||||
all::OP_INVALIDOPCODE => write!(f, "INVALIDOPCODE"),
|
||||
all::OP_CHECKSIGADD => write!(f, "CHECKSIGADD"),
|
||||
OP_PUSHDATA1 => write!(f, "PUSHDATA1"),
|
||||
OP_PUSHDATA2 => write!(f, "PUSHDATA2"),
|
||||
OP_PUSHDATA4 => write!(f, "PUSHDATA4"),
|
||||
OP_PUSHNUM_NEG1 => write!(f, "PUSHNUM_NEG1"),
|
||||
OP_RESERVED => write!(f, "RESERVED"),
|
||||
All {code: x} if x >= OP_PUSHNUM_1.code && x <= OP_PUSHNUM_16.code => write!(f, "PUSHNUM_{}", x - OP_PUSHNUM_1.code + 1),
|
||||
OP_NOP => write!(f, "NOP"),
|
||||
OP_VER => write!(f, "VER"),
|
||||
OP_IF => write!(f, "IF"),
|
||||
OP_NOTIF => write!(f, "NOTIF"),
|
||||
OP_VERIF => write!(f, "VERIF"),
|
||||
OP_VERNOTIF => write!(f, "VERNOTIF"),
|
||||
OP_ELSE => write!(f, "ELSE"),
|
||||
OP_ENDIF => write!(f, "ENDIF"),
|
||||
OP_VERIFY => write!(f, "VERIFY"),
|
||||
OP_RETURN => write!(f, "RETURN"),
|
||||
OP_TOALTSTACK => write!(f, "TOALTSTACK"),
|
||||
OP_FROMALTSTACK => write!(f, "FROMALTSTACK"),
|
||||
OP_2DROP => write!(f, "2DROP"),
|
||||
OP_2DUP => write!(f, "2DUP"),
|
||||
OP_3DUP => write!(f, "3DUP"),
|
||||
OP_2OVER => write!(f, "2OVER"),
|
||||
OP_2ROT => write!(f, "2ROT"),
|
||||
OP_2SWAP => write!(f, "2SWAP"),
|
||||
OP_IFDUP => write!(f, "IFDUP"),
|
||||
OP_DEPTH => write!(f, "DEPTH"),
|
||||
OP_DROP => write!(f, "DROP"),
|
||||
OP_DUP => write!(f, "DUP"),
|
||||
OP_NIP => write!(f, "NIP"),
|
||||
OP_OVER => write!(f, "OVER"),
|
||||
OP_PICK => write!(f, "PICK"),
|
||||
OP_ROLL => write!(f, "ROLL"),
|
||||
OP_ROT => write!(f, "ROT"),
|
||||
OP_SWAP => write!(f, "SWAP"),
|
||||
OP_TUCK => write!(f, "TUCK"),
|
||||
OP_CAT => write!(f, "CAT"),
|
||||
OP_SUBSTR => write!(f, "SUBSTR"),
|
||||
OP_LEFT => write!(f, "LEFT"),
|
||||
OP_RIGHT => write!(f, "RIGHT"),
|
||||
OP_SIZE => write!(f, "SIZE"),
|
||||
OP_INVERT => write!(f, "INVERT"),
|
||||
OP_AND => write!(f, "AND"),
|
||||
OP_OR => write!(f, "OR"),
|
||||
OP_XOR => write!(f, "XOR"),
|
||||
OP_EQUAL => write!(f, "EQUAL"),
|
||||
OP_EQUALVERIFY => write!(f, "EQUALVERIFY"),
|
||||
OP_RESERVED1 => write!(f, "RESERVED1"),
|
||||
OP_RESERVED2 => write!(f, "RESERVED2"),
|
||||
OP_1ADD => write!(f, "1ADD"),
|
||||
OP_1SUB => write!(f, "1SUB"),
|
||||
OP_2MUL => write!(f, "2MUL"),
|
||||
OP_2DIV => write!(f, "2DIV"),
|
||||
OP_NEGATE => write!(f, "NEGATE"),
|
||||
OP_ABS => write!(f, "ABS"),
|
||||
OP_NOT => write!(f, "NOT"),
|
||||
OP_0NOTEQUAL => write!(f, "0NOTEQUAL"),
|
||||
OP_ADD => write!(f, "ADD"),
|
||||
OP_SUB => write!(f, "SUB"),
|
||||
OP_MUL => write!(f, "MUL"),
|
||||
OP_DIV => write!(f, "DIV"),
|
||||
OP_MOD => write!(f, "MOD"),
|
||||
OP_LSHIFT => write!(f, "LSHIFT"),
|
||||
OP_RSHIFT => write!(f, "RSHIFT"),
|
||||
OP_BOOLAND => write!(f, "BOOLAND"),
|
||||
OP_BOOLOR => write!(f, "BOOLOR"),
|
||||
OP_NUMEQUAL => write!(f, "NUMEQUAL"),
|
||||
OP_NUMEQUALVERIFY => write!(f, "NUMEQUALVERIFY"),
|
||||
OP_NUMNOTEQUAL => write!(f, "NUMNOTEQUAL"),
|
||||
OP_LESSTHAN => write!(f, "LESSTHAN"),
|
||||
OP_GREATERTHAN => write!(f, "GREATERTHAN"),
|
||||
OP_LESSTHANOREQUAL => write!(f, "LESSTHANOREQUAL"),
|
||||
OP_GREATERTHANOREQUAL => write!(f, "GREATERTHANOREQUAL"),
|
||||
OP_MIN => write!(f, "MIN"),
|
||||
OP_MAX => write!(f, "MAX"),
|
||||
OP_WITHIN => write!(f, "WITHIN"),
|
||||
OP_RIPEMD160 => write!(f, "RIPEMD160"),
|
||||
OP_SHA1 => write!(f, "SHA1"),
|
||||
OP_SHA256 => write!(f, "SHA256"),
|
||||
OP_HASH160 => write!(f, "HASH160"),
|
||||
OP_HASH256 => write!(f, "HASH256"),
|
||||
OP_CODESEPARATOR => write!(f, "CODESEPARATOR"),
|
||||
OP_CHECKSIG => write!(f, "CHECKSIG"),
|
||||
OP_CHECKSIGVERIFY => write!(f, "CHECKSIGVERIFY"),
|
||||
OP_CHECKMULTISIG => write!(f, "CHECKMULTISIG"),
|
||||
OP_CHECKMULTISIGVERIFY => write!(f, "CHECKMULTISIGVERIFY"),
|
||||
OP_CLTV => write!(f, "CLTV"),
|
||||
OP_CSV => write!(f, "CSV"),
|
||||
All {code: x} if (OP_NOP1.code..=OP_NOP10.code).contains(&x) => write!(f, "NOP{}", x - OP_NOP1.code + 1),
|
||||
OP_INVALIDOPCODE => write!(f, "INVALIDOPCODE"),
|
||||
OP_CHECKSIGADD => write!(f, "CHECKSIGADD"),
|
||||
All {code: x} => write!(f, "RETURN_{}", x),
|
||||
}
|
||||
}
|
||||
|
@ -651,7 +656,7 @@ impl fmt::Display for All {
|
|||
|
||||
/// Classification context for the opcode.
|
||||
///
|
||||
/// Some opcodes like [`all::OP_RESERVED`] abort the script in `ClassifyContext::Legacy` context,
|
||||
/// Some opcodes like [`OP_RESERVED`] abort the script in `ClassifyContext::Legacy` context,
|
||||
/// but will act as `OP_SUCCESSx` in `ClassifyContext::TapScript` (see BIP342 for full list).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum ClassifyContext {
|
||||
|
@ -665,7 +670,6 @@ impl All {
|
|||
/// Classifies an Opcode into a broad class.
|
||||
#[inline]
|
||||
pub fn classify(self, ctx: ClassifyContext) -> Class {
|
||||
use self::all::*;
|
||||
match (self, ctx) {
|
||||
// 3 opcodes illegal in all contexts
|
||||
(OP_VERIF, _) | (OP_VERNOTIF, _) | (OP_INVALIDOPCODE, _) => Class::IllegalOp,
|
||||
|
@ -752,13 +756,13 @@ impl serde::Serialize for All {
|
|||
}
|
||||
|
||||
/// Empty stack is also FALSE.
|
||||
pub static OP_FALSE: All = all::OP_PUSHBYTES_0;
|
||||
pub static OP_FALSE: All = OP_PUSHBYTES_0;
|
||||
/// Number 1 is also TRUE.
|
||||
pub static OP_TRUE: All = all::OP_PUSHNUM_1;
|
||||
pub static OP_TRUE: All = OP_PUSHNUM_1;
|
||||
/// Previously called OP_NOP2.
|
||||
pub static OP_NOP2: All = all::OP_CLTV;
|
||||
pub static OP_NOP2: All = OP_CLTV;
|
||||
/// Previously called OP_NOP3.
|
||||
pub static OP_NOP3: All = all::OP_CSV;
|
||||
pub static OP_NOP3: All = OP_CSV;
|
||||
|
||||
/// Broad categories of opcodes with similar behavior.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
|
@ -785,7 +789,7 @@ macro_rules! ordinary_opcode {
|
|||
#[doc(hidden)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Ordinary {
|
||||
$( $op = all::$op.code ),*
|
||||
$( $op = $op.code ),*
|
||||
}
|
||||
|
||||
impl fmt::Display for Ordinary {
|
||||
|
@ -799,7 +803,7 @@ macro_rules! ordinary_opcode {
|
|||
impl Ordinary {
|
||||
fn with(b: All) -> Self {
|
||||
match b {
|
||||
$( all::$op => { Ordinary::$op } ),*
|
||||
$( $op => { Ordinary::$op } ),*
|
||||
_ => unreachable!("construction of `Ordinary` type from non-ordinary opcode {}", b),
|
||||
}
|
||||
}
|
||||
|
@ -807,7 +811,7 @@ macro_rules! ordinary_opcode {
|
|||
/// Try to create from an All
|
||||
pub fn try_from_all(b: All) -> Option<Self> {
|
||||
match b {
|
||||
$( all::$op => { Some(Ordinary::$op) } ),*
|
||||
$( $op => { Some(Ordinary::$op) } ),*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -857,10 +861,10 @@ mod tests {
|
|||
|
||||
macro_rules! roundtrip {
|
||||
($unique:expr, $op:ident) => {
|
||||
assert_eq!(all::$op, All::from(all::$op.to_u8()));
|
||||
assert_eq!($op, All::from($op.to_u8()));
|
||||
|
||||
let s1 = format!("{}", all::$op);
|
||||
let s2 = format!("{:?}", all::$op);
|
||||
let s1 = format!("{}", $op);
|
||||
let s2 = format!("{:?}", $op);
|
||||
assert_eq!(s1, s2);
|
||||
assert_eq!(s1, stringify!($op));
|
||||
assert!($unique.insert(s1));
|
||||
|
@ -869,19 +873,19 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn classify_test() {
|
||||
let op174 = all::OP_CHECKMULTISIG;
|
||||
let op174 = OP_CHECKMULTISIG;
|
||||
assert_eq!(op174.classify(ClassifyContext::Legacy), Class::Ordinary(Ordinary::OP_CHECKMULTISIG));
|
||||
assert_eq!(op174.classify(ClassifyContext::TapScript), Class::ReturnOp);
|
||||
|
||||
let op175 = all::OP_CHECKMULTISIGVERIFY;
|
||||
let op175 = OP_CHECKMULTISIGVERIFY;
|
||||
assert_eq!(op175.classify(ClassifyContext::Legacy), Class::Ordinary(Ordinary::OP_CHECKMULTISIGVERIFY));
|
||||
assert_eq!(op175.classify(ClassifyContext::TapScript), Class::ReturnOp);
|
||||
|
||||
let op186 = all::OP_CHECKSIGADD;
|
||||
let op186 = OP_CHECKSIGADD;
|
||||
assert_eq!(op186.classify(ClassifyContext::Legacy), Class::ReturnOp);
|
||||
assert_eq!(op186.classify(ClassifyContext::TapScript), Class::Ordinary(Ordinary::OP_CHECKSIGADD));
|
||||
|
||||
let op187 = all::OP_RETURN_187;
|
||||
let op187 = OP_RETURN_187;
|
||||
assert_eq!(op187.classify(ClassifyContext::Legacy), Class::ReturnOp);
|
||||
assert_eq!(op187.classify(ClassifyContext::TapScript), Class::SuccessOp);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ use bitcoin_internals::write_err;
|
|||
|
||||
use crate::hash_types::{PubkeyHash, WPubkeyHash, ScriptHash, WScriptHash};
|
||||
use crate::blockdata::opcodes;
|
||||
use crate::blockdata::opcodes::all::*;
|
||||
use crate::consensus::{encode, Decodable, Encodable};
|
||||
use crate::hashes::{Hash, hex};
|
||||
use crate::policy::DUST_RELAY_TX_FEE;
|
||||
|
@ -363,27 +364,27 @@ impl Script {
|
|||
pub fn new_p2pk(pubkey: &PublicKey) -> Script {
|
||||
Builder::new()
|
||||
.push_key(pubkey)
|
||||
.push_opcode(opcodes::all::OP_CHECKSIG)
|
||||
.push_opcode(OP_CHECKSIG)
|
||||
.into_script()
|
||||
}
|
||||
|
||||
/// Generates P2PKH-type of scriptPubkey.
|
||||
pub fn new_p2pkh(pubkey_hash: &PubkeyHash) -> Script {
|
||||
Builder::new()
|
||||
.push_opcode(opcodes::all::OP_DUP)
|
||||
.push_opcode(opcodes::all::OP_HASH160)
|
||||
.push_opcode(OP_DUP)
|
||||
.push_opcode(OP_HASH160)
|
||||
.push_slice(&pubkey_hash[..])
|
||||
.push_opcode(opcodes::all::OP_EQUALVERIFY)
|
||||
.push_opcode(opcodes::all::OP_CHECKSIG)
|
||||
.push_opcode(OP_EQUALVERIFY)
|
||||
.push_opcode(OP_CHECKSIG)
|
||||
.into_script()
|
||||
}
|
||||
|
||||
/// Generates P2SH-type of scriptPubkey with a given hash of the redeem script.
|
||||
pub fn new_p2sh(script_hash: &ScriptHash) -> Script {
|
||||
Builder::new()
|
||||
.push_opcode(opcodes::all::OP_HASH160)
|
||||
.push_opcode(OP_HASH160)
|
||||
.push_slice(&script_hash[..])
|
||||
.push_opcode(opcodes::all::OP_EQUAL)
|
||||
.push_opcode(OP_EQUAL)
|
||||
.into_script()
|
||||
}
|
||||
|
||||
|
@ -420,7 +421,7 @@ impl Script {
|
|||
/// Generates OP_RETURN-type of scriptPubkey for the given data.
|
||||
pub fn new_op_return(data: &[u8]) -> Script {
|
||||
Builder::new()
|
||||
.push_opcode(opcodes::all::OP_RETURN)
|
||||
.push_opcode(OP_RETURN)
|
||||
.push_slice(data)
|
||||
.into_script()
|
||||
}
|
||||
|
@ -464,11 +465,11 @@ impl Script {
|
|||
return None
|
||||
}
|
||||
let script = Builder::new()
|
||||
.push_opcode(opcodes::all::OP_DUP)
|
||||
.push_opcode(opcodes::all::OP_HASH160)
|
||||
.push_opcode(OP_DUP)
|
||||
.push_opcode(OP_HASH160)
|
||||
.push_slice(&self[2..]) // The `self` script is 0x00, 0x14, <pubkey_hash>
|
||||
.push_opcode(opcodes::all::OP_EQUALVERIFY)
|
||||
.push_opcode(opcodes::all::OP_CHECKSIG)
|
||||
.push_opcode(OP_EQUALVERIFY)
|
||||
.push_opcode(OP_CHECKSIG)
|
||||
.into_script();
|
||||
|
||||
Some(script)
|
||||
|
@ -499,20 +500,20 @@ impl Script {
|
|||
#[inline]
|
||||
pub fn is_p2sh(&self) -> bool {
|
||||
self.0.len() == 23
|
||||
&& self.0[0] == opcodes::all::OP_HASH160.to_u8()
|
||||
&& self.0[1] == opcodes::all::OP_PUSHBYTES_20.to_u8()
|
||||
&& self.0[22] == opcodes::all::OP_EQUAL.to_u8()
|
||||
&& self.0[0] == OP_HASH160.to_u8()
|
||||
&& self.0[1] == OP_PUSHBYTES_20.to_u8()
|
||||
&& self.0[22] == OP_EQUAL.to_u8()
|
||||
}
|
||||
|
||||
/// Checks whether a script pubkey is a P2PKH output.
|
||||
#[inline]
|
||||
pub fn is_p2pkh(&self) -> bool {
|
||||
self.0.len() == 25
|
||||
&& self.0[0] == opcodes::all::OP_DUP.to_u8()
|
||||
&& self.0[1] == opcodes::all::OP_HASH160.to_u8()
|
||||
&& self.0[2] == opcodes::all::OP_PUSHBYTES_20.to_u8()
|
||||
&& self.0[23] == opcodes::all::OP_EQUALVERIFY.to_u8()
|
||||
&& self.0[24] == opcodes::all::OP_CHECKSIG.to_u8()
|
||||
&& self.0[0] == OP_DUP.to_u8()
|
||||
&& self.0[1] == OP_HASH160.to_u8()
|
||||
&& self.0[2] == OP_PUSHBYTES_20.to_u8()
|
||||
&& self.0[23] == OP_EQUALVERIFY.to_u8()
|
||||
&& self.0[24] == OP_CHECKSIG.to_u8()
|
||||
}
|
||||
|
||||
/// Checks whether a script pubkey is a P2PK output.
|
||||
|
@ -520,12 +521,12 @@ impl Script {
|
|||
pub fn is_p2pk(&self) -> bool {
|
||||
match self.len() {
|
||||
67 => {
|
||||
self.0[0] == opcodes::all::OP_PUSHBYTES_65.to_u8()
|
||||
&& self.0[66] == opcodes::all::OP_CHECKSIG.to_u8()
|
||||
self.0[0] == OP_PUSHBYTES_65.to_u8()
|
||||
&& self.0[66] == OP_CHECKSIG.to_u8()
|
||||
}
|
||||
35 => {
|
||||
self.0[0] == opcodes::all::OP_PUSHBYTES_33.to_u8()
|
||||
&& self.0[34] == opcodes::all::OP_CHECKSIG.to_u8()
|
||||
self.0[0] == OP_PUSHBYTES_33.to_u8()
|
||||
&& self.0[34] == OP_CHECKSIG.to_u8()
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
|
@ -545,8 +546,8 @@ impl Script {
|
|||
let ver_opcode = opcodes::All::from(self.0[0]); // Version 0 or PUSHNUM_1-PUSHNUM_16
|
||||
let push_opbyte = self.0[1]; // Second byte push opcode 2-40 bytes
|
||||
WitnessVersion::try_from(ver_opcode).is_ok()
|
||||
&& push_opbyte >= opcodes::all::OP_PUSHBYTES_2.to_u8()
|
||||
&& push_opbyte <= opcodes::all::OP_PUSHBYTES_40.to_u8()
|
||||
&& push_opbyte >= OP_PUSHBYTES_2.to_u8()
|
||||
&& push_opbyte <= OP_PUSHBYTES_40.to_u8()
|
||||
// Check that the rest of the script has the correct size
|
||||
&& script_len - 2 == push_opbyte as usize
|
||||
}
|
||||
|
@ -556,7 +557,7 @@ impl Script {
|
|||
pub fn is_v0_p2wsh(&self) -> bool {
|
||||
self.0.len() == 34
|
||||
&& self.witness_version() == Some(WitnessVersion::V0)
|
||||
&& self.0[1] == opcodes::all::OP_PUSHBYTES_32.to_u8()
|
||||
&& self.0[1] == OP_PUSHBYTES_32.to_u8()
|
||||
}
|
||||
|
||||
/// Checks whether a script pubkey is a P2WPKH output.
|
||||
|
@ -564,7 +565,7 @@ impl Script {
|
|||
pub fn is_v0_p2wpkh(&self) -> bool {
|
||||
self.0.len() == 22
|
||||
&& self.witness_version() == Some(WitnessVersion::V0)
|
||||
&& self.0[1] == opcodes::all::OP_PUSHBYTES_20.to_u8()
|
||||
&& self.0[1] == OP_PUSHBYTES_20.to_u8()
|
||||
}
|
||||
|
||||
/// Checks whether a script pubkey is a P2TR output.
|
||||
|
@ -572,13 +573,13 @@ impl Script {
|
|||
pub fn is_v1_p2tr(&self) -> bool {
|
||||
self.0.len() == 34
|
||||
&& self.witness_version() == Some(WitnessVersion::V1)
|
||||
&& self.0[1] == opcodes::all::OP_PUSHBYTES_32.to_u8()
|
||||
&& self.0[1] == OP_PUSHBYTES_32.to_u8()
|
||||
}
|
||||
|
||||
/// Check if this is an OP_RETURN output.
|
||||
pub fn is_op_return (&self) -> bool {
|
||||
match self.0.first() {
|
||||
Some(b) => *b == opcodes::all::OP_RETURN.to_u8(),
|
||||
Some(b) => *b == OP_RETURN.to_u8(),
|
||||
None => false
|
||||
}
|
||||
}
|
||||
|
@ -699,15 +700,15 @@ impl Script {
|
|||
n as usize
|
||||
} else {
|
||||
match opcode {
|
||||
opcodes::all::OP_PUSHDATA1 => {
|
||||
OP_PUSHDATA1 => {
|
||||
// side effects: may write and break from the loop
|
||||
read_push_data_len!(&mut iter, 1, f)
|
||||
}
|
||||
opcodes::all::OP_PUSHDATA2 => {
|
||||
OP_PUSHDATA2 => {
|
||||
// side effects: may write and break from the loop
|
||||
read_push_data_len!(&mut iter, 2, f)
|
||||
}
|
||||
opcodes::all::OP_PUSHDATA4 => {
|
||||
OP_PUSHDATA4 => {
|
||||
// side effects: may write and break from the loop
|
||||
read_push_data_len!(&mut iter, 4, f)
|
||||
}
|
||||
|
@ -721,7 +722,7 @@ impl Script {
|
|||
at_least_one = true;
|
||||
}
|
||||
// Write the opcode
|
||||
if opcode == opcodes::all::OP_PUSHBYTES_0 {
|
||||
if opcode == OP_PUSHBYTES_0 {
|
||||
f.write_str("OP_0")?;
|
||||
} else {
|
||||
write!(f, "{:?}", opcode)?;
|
||||
|
@ -999,23 +1000,23 @@ impl Builder {
|
|||
/// semantics.
|
||||
pub fn push_verify(mut self) -> Builder {
|
||||
match self.1 {
|
||||
Some(opcodes::all::OP_EQUAL) => {
|
||||
Some(OP_EQUAL) => {
|
||||
self.0.pop();
|
||||
self.push_opcode(opcodes::all::OP_EQUALVERIFY)
|
||||
self.push_opcode(OP_EQUALVERIFY)
|
||||
},
|
||||
Some(opcodes::all::OP_NUMEQUAL) => {
|
||||
Some(OP_NUMEQUAL) => {
|
||||
self.0.pop();
|
||||
self.push_opcode(opcodes::all::OP_NUMEQUALVERIFY)
|
||||
self.push_opcode(OP_NUMEQUALVERIFY)
|
||||
},
|
||||
Some(opcodes::all::OP_CHECKSIG) => {
|
||||
Some(OP_CHECKSIG) => {
|
||||
self.0.pop();
|
||||
self.push_opcode(opcodes::all::OP_CHECKSIGVERIFY)
|
||||
self.push_opcode(OP_CHECKSIGVERIFY)
|
||||
},
|
||||
Some(opcodes::all::OP_CHECKMULTISIG) => {
|
||||
Some(OP_CHECKMULTISIG) => {
|
||||
self.0.pop();
|
||||
self.push_opcode(opcodes::all::OP_CHECKMULTISIGVERIFY)
|
||||
self.push_opcode(OP_CHECKMULTISIGVERIFY)
|
||||
},
|
||||
_ => self.push_opcode(opcodes::all::OP_VERIFY),
|
||||
_ => self.push_opcode(OP_VERIFY),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1177,8 +1178,8 @@ mod test {
|
|||
script = script.push_key(&key); comp.extend(Vec::from_hex(keystr).unwrap().iter().cloned()); assert_eq!(&script[..], &comp[..]);
|
||||
|
||||
// opcodes
|
||||
script = script.push_opcode(opcodes::all::OP_CHECKSIG); comp.push(0xACu8); assert_eq!(&script[..], &comp[..]);
|
||||
script = script.push_opcode(opcodes::all::OP_CHECKSIG); comp.push(0xACu8); assert_eq!(&script[..], &comp[..]);
|
||||
script = script.push_opcode(OP_CHECKSIG); comp.push(0xACu8); assert_eq!(&script[..], &comp[..]);
|
||||
script = script.push_opcode(OP_CHECKSIG); comp.push(0xACu8); assert_eq!(&script[..], &comp[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1195,11 +1196,11 @@ mod test {
|
|||
#[test]
|
||||
fn script_builder() {
|
||||
// from txid 3bb5e6434c11fb93f64574af5d116736510717f2c595eb45b52c28e31622dfff which was in my mempool when I wrote the test
|
||||
let script = Builder::new().push_opcode(opcodes::all::OP_DUP)
|
||||
.push_opcode(opcodes::all::OP_HASH160)
|
||||
let script = Builder::new().push_opcode(OP_DUP)
|
||||
.push_opcode(OP_HASH160)
|
||||
.push_slice(&Vec::from_hex("16e1ae70ff0fa102905d4af297f6912bda6cce19").unwrap())
|
||||
.push_opcode(opcodes::all::OP_EQUALVERIFY)
|
||||
.push_opcode(opcodes::all::OP_CHECKSIG)
|
||||
.push_opcode(OP_EQUALVERIFY)
|
||||
.push_opcode(OP_CHECKSIG)
|
||||
.into_script();
|
||||
assert_eq!(script.to_hex(), "76a91416e1ae70ff0fa102905d4af297f6912bda6cce1988ac");
|
||||
}
|
||||
|
@ -1215,7 +1216,7 @@ mod test {
|
|||
let wpubkey_hash = WPubkeyHash::hash(&pubkey.inner.serialize());
|
||||
assert!(Script::new_v0_p2wpkh(&wpubkey_hash).is_v0_p2wpkh());
|
||||
|
||||
let script = Builder::new().push_opcode(opcodes::all::OP_NUMEQUAL)
|
||||
let script = Builder::new().push_opcode(OP_NUMEQUAL)
|
||||
.push_verify()
|
||||
.into_script();
|
||||
let script_hash = ScriptHash::hash(&script.serialize());
|
||||
|
@ -1258,7 +1259,7 @@ mod test {
|
|||
assert_eq!(nonverify2.to_hex(), "6969");
|
||||
|
||||
let equal = Builder::new()
|
||||
.push_opcode(opcodes::all::OP_EQUAL)
|
||||
.push_opcode(OP_EQUAL)
|
||||
.push_verify()
|
||||
.into_script();
|
||||
assert_eq!(equal.to_hex(), "88");
|
||||
|
@ -1268,7 +1269,7 @@ mod test {
|
|||
assert_eq!(equal2.to_hex(), "88");
|
||||
|
||||
let numequal = Builder::new()
|
||||
.push_opcode(opcodes::all::OP_NUMEQUAL)
|
||||
.push_opcode(OP_NUMEQUAL)
|
||||
.push_verify()
|
||||
.into_script();
|
||||
assert_eq!(numequal.to_hex(), "9d");
|
||||
|
@ -1278,7 +1279,7 @@ mod test {
|
|||
assert_eq!(numequal2.to_hex(), "9d");
|
||||
|
||||
let checksig = Builder::new()
|
||||
.push_opcode(opcodes::all::OP_CHECKSIG)
|
||||
.push_opcode(OP_CHECKSIG)
|
||||
.push_verify()
|
||||
.into_script();
|
||||
assert_eq!(checksig.to_hex(), "ad");
|
||||
|
@ -1288,7 +1289,7 @@ mod test {
|
|||
assert_eq!(checksig2.to_hex(), "ad");
|
||||
|
||||
let checkmultisig = Builder::new()
|
||||
.push_opcode(opcodes::all::OP_CHECKMULTISIG)
|
||||
.push_opcode(OP_CHECKMULTISIG)
|
||||
.push_verify()
|
||||
.into_script();
|
||||
assert_eq!(checkmultisig.to_hex(), "af");
|
||||
|
@ -1502,7 +1503,7 @@ mod test {
|
|||
let script_1 = Builder::new().push_slice(&[1, 2, 3, 4]).into_script();
|
||||
let script_2 = Builder::new().push_int(10).into_script();
|
||||
let script_3 = Builder::new().push_int(15).into_script();
|
||||
let script_4 = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script();
|
||||
let script_4 = Builder::new().push_opcode(OP_RETURN).into_script();
|
||||
|
||||
assert!(script_1 < script_2);
|
||||
assert!(script_2 < script_3);
|
||||
|
@ -1534,11 +1535,11 @@ mod test {
|
|||
assert_eq!(script_p2wpkh.dust_value(), crate::Amount::from_sat(294));
|
||||
|
||||
let script_p2pkh = Builder::new()
|
||||
.push_opcode(opcodes::all::OP_DUP)
|
||||
.push_opcode(opcodes::all::OP_HASH160)
|
||||
.push_opcode(OP_DUP)
|
||||
.push_opcode(OP_HASH160)
|
||||
.push_slice(&[42; 20])
|
||||
.push_opcode(opcodes::all::OP_EQUALVERIFY)
|
||||
.push_opcode(opcodes::all::OP_CHECKSIG)
|
||||
.push_opcode(OP_EQUALVERIFY)
|
||||
.push_opcode(OP_CHECKSIG)
|
||||
.into_script();
|
||||
assert!(script_p2pkh.is_p2pkh());
|
||||
assert_eq!(script_p2pkh.dust_value(), crate::Amount::from_sat(546));
|
||||
|
|
Loading…
Reference in New Issue