From 96fa4b7d9b2886738a162e80062e77029bb1c2f2 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Wed, 10 Feb 2021 14:26:57 +0100 Subject: [PATCH 1/2] Implement AsRef<[u8]> for Script --- src/blockdata/script.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/blockdata/script.rs b/src/blockdata/script.rs index bbb356e391..a72ac0004b 100644 --- a/src/blockdata/script.rs +++ b/src/blockdata/script.rs @@ -43,6 +43,12 @@ use util::key::PublicKey; /// A Bitcoin script pub struct Script(Box<[u8]>); +impl AsRef<[u8]> for Script { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + impl fmt::Debug for Script { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("Script(")?; From 851a3a15c0a124ff9e41e542b5445b4d59786b40 Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Wed, 10 Feb 2021 14:23:38 +0100 Subject: [PATCH 2/2] Make Script::fmt_asm a static method and add Script::str_asm This makes it convenient to print/construct the script assembly on byte slices withoout having to clone them to copy them to create a Script struct. --- src/blockdata/script.rs | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/blockdata/script.rs b/src/blockdata/script.rs index a72ac0004b..729707d18b 100644 --- a/src/blockdata/script.rs +++ b/src/blockdata/script.rs @@ -458,11 +458,11 @@ impl Script { Ok(bitcoinconsensus::verify (&self.0[..], amount, spending, index)?) } - /// Write the assembly decoding of the script to the formatter. - pub fn fmt_asm(&self, f: &mut dyn fmt::Write) -> fmt::Result { + /// Write the assembly decoding of the script bytes to the formatter. + pub fn bytes_to_asm_fmt(script: &[u8], f: &mut dyn fmt::Write) -> fmt::Result { let mut index = 0; - while index < self.0.len() { - let opcode = opcodes::All::from(self.0[index]); + while index < script.len() { + let opcode = opcodes::All::from(script[index]); index += 1; let data_len = if let opcodes::Class::PushBytes(n) = opcode.classify() { @@ -470,31 +470,31 @@ impl Script { } else { match opcode { opcodes::all::OP_PUSHDATA1 => { - if self.0.len() < index + 1 { + if script.len() < index + 1 { f.write_str("")?; break; } - match read_uint(&self.0[index..], 1) { + match read_uint(&script[index..], 1) { Ok(n) => { index += 1; n as usize } Err(_) => { f.write_str("")?; break; } } } opcodes::all::OP_PUSHDATA2 => { - if self.0.len() < index + 2 { + if script.len() < index + 2 { f.write_str("")?; break; } - match read_uint(&self.0[index..], 2) { + match read_uint(&script[index..], 2) { Ok(n) => { index += 2; n as usize } Err(_) => { f.write_str("")?; break; } } } opcodes::all::OP_PUSHDATA4 => { - if self.0.len() < index + 4 { + if script.len() < index + 4 { f.write_str("")?; break; } - match read_uint(&self.0[index..], 4) { + match read_uint(&script[index..], 4) { Ok(n) => { index += 4; n as usize } Err(_) => { f.write_str("")?; break; } } @@ -513,8 +513,8 @@ impl Script { // Write any pushdata if data_len > 0 { f.write_str(" ")?; - if index + data_len <= self.0.len() { - for ch in &self.0[index..index + data_len] { + if index + data_len <= script.len() { + for ch in &script[index..index + data_len] { write!(f, "{:02x}", ch)?; } index += data_len; @@ -527,12 +527,22 @@ impl Script { Ok(()) } - /// Get the assembly decoding of the script. - pub fn asm(&self) -> String { + /// Write the assembly decoding of the script to the formatter. + pub fn fmt_asm(&self, f: &mut dyn fmt::Write) -> fmt::Result { + Script::bytes_to_asm_fmt(self.as_ref(), f) + } + + /// Create an assembly decoding of the script in the given byte slice. + pub fn bytes_to_asm(script: &[u8]) -> String { let mut buf = String::new(); - self.fmt_asm(&mut buf).unwrap(); + Script::bytes_to_asm_fmt(script, &mut buf).unwrap(); buf } + + /// Get the assembly decoding of the script. + pub fn asm(&self) -> String { + Script::bytes_to_asm(self.as_ref()) + } } /// Creates a new script from an existing vector