From 83abd5b89ae0138a777fe634b54e39325632447d Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Tue, 14 Jan 2025 10:03:51 +0100 Subject: [PATCH] maintain provably unspendable semantincs --- src/rest.rs | 4 ++-- src/util/mod.rs | 1 + src/util/script.rs | 15 +++++++++++++++ src/util/transaction.rs | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/rest.rs b/src/rest.rs index ca94afa68..91afcbf3a 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -305,7 +305,7 @@ impl TxOutValue { "fee" } else if script.is_empty() { "empty" - } else if script.is_op_return() { + } else if crate::util::provably_unspendable(&script) { "op_return" } else if script.is_p2pk() { "p2pk" @@ -319,7 +319,7 @@ impl TxOutValue { "v0_p2wsh" } else if script.is_p2tr() { "v1_p2tr" - } else if script.is_op_return() { + } else if crate::util::provably_unspendable(&script) { "provably_unspendable" } else { "unknown" diff --git a/src/util/mod.rs b/src/util/mod.rs index 0a9701b8e..18b0c5c92 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -10,6 +10,7 @@ pub use self::block::{ BlockHeaderMeta, BlockId, BlockMeta, BlockStatus, HeaderEntry, HeaderList, DEFAULT_BLOCKHASH, }; pub use self::fees::get_tx_fee; +pub(crate) use self::script::provably_unspendable; pub use self::script::{get_innerscripts, ScriptToAddr, ScriptToAsm}; pub use self::transaction::{ extract_tx_prevouts, get_prev_outpoints, has_prevout, is_coinbase, is_spendable, diff --git a/src/util/script.rs b/src/util/script.rs index 9f44c4ea6..d04c5f87d 100644 --- a/src/util/script.rs +++ b/src/util/script.rs @@ -79,3 +79,18 @@ pub fn get_innerscripts(txin: &TxIn, prevout: &TxOut) -> InnerScripts { witness_script, } } + +/// Compatible with Script::is_provably_unspendable on rust-bitcoin v0.31 and before because it checks also IllegalOp class +pub(crate) fn provably_unspendable(script: &Script) -> bool { + use bitcoin::blockdata::opcodes::Class::{IllegalOp, ReturnOp}; + + match script.as_bytes().first() { + Some(b) => { + let first = bitcoin::Opcode::from(*b); + let class = first.classify(bitcoin::blockdata::opcodes::ClassifyContext::Legacy); + + class == ReturnOp || class == IllegalOp + } + None => false, + } +} diff --git a/src/util/transaction.rs b/src/util/transaction.rs index af3d87c98..6775ca754 100644 --- a/src/util/transaction.rs +++ b/src/util/transaction.rs @@ -70,7 +70,7 @@ pub fn has_prevout(txin: &TxIn) -> bool { pub fn is_spendable(txout: &TxOut) -> bool { #[cfg(not(feature = "liquid"))] - return !txout.script_pubkey.is_op_return(); + return !crate::util::provably_unspendable(&txout.script_pubkey); #[cfg(feature = "liquid")] return !txout.is_fee() && !txout.script_pubkey.is_provably_unspendable(); }