Skip to content

Commit c2c567b

Browse files
committed
Implement new Encodable trait for Script<T>
Add functionality to enable consensus encoding scripts. Re-export the encoder from the `script` module.
1 parent 816cd96 commit c2c567b

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

primitives/src/script/borrowed.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use core::ops::{
77

88
#[cfg(feature = "arbitrary")]
99
use arbitrary::{Arbitrary, Unstructured};
10+
use encoding::{BytesEncoder, Encodable};
1011

1112
use super::ScriptBuf;
1213
use crate::prelude::{Box, ToOwned, Vec};
@@ -152,6 +153,22 @@ impl<T> Script<T> {
152153
pub fn to_hex(&self) -> alloc::string::String { alloc::format!("{:x}", self) }
153154
}
154155

156+
encoding::encoder_newtype! {
157+
/// The encoder for the [`Script<T>`] type.
158+
pub struct ScriptEncoder<'e>(BytesEncoder<'e>);
159+
}
160+
161+
impl<T> Encodable for Script<T> {
162+
type Encoder<'a>
163+
= ScriptEncoder<'a>
164+
where
165+
Self: 'a;
166+
167+
fn encoder(&self) -> Self::Encoder<'_> {
168+
ScriptEncoder(BytesEncoder::with_length_prefix(self.as_bytes()))
169+
}
170+
}
171+
155172
#[cfg(feature = "arbitrary")]
156173
impl<'a, T> Arbitrary<'a> for &'a Script<T> {
157174
#[inline]
@@ -248,4 +265,18 @@ mod tests {
248265
assert_eq!(script[1..=3].as_bytes(), &[2, 3, 4]);
249266
assert_eq!(script[..=2].as_bytes(), &[1, 2, 3]);
250267
}
268+
269+
#[test]
270+
#[cfg(feature = "alloc")]
271+
fn encode() {
272+
// Consensus encoding includes the length of the encoded data
273+
// (compact size encoded length prefix).
274+
let consensus_encoded: [u8; 6] = [0x05, 1, 2, 3, 4, 5];
275+
276+
// `from_bytes` does not expect the prefix.
277+
let script = Script::from_bytes(&consensus_encoded[1..]);
278+
279+
let got = encoding::encode_to_vec(script);
280+
assert_eq!(got, consensus_encoded);
281+
}
251282
}

primitives/src/script/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::prelude::{Borrow, BorrowMut, Box, Cow, ToOwned, Vec};
2626
#[rustfmt::skip] // Keep public re-exports separate.
2727
#[doc(inline)]
2828
pub use self::{
29-
borrowed::Script,
29+
borrowed::{Script, ScriptEncoder},
3030
owned::ScriptBuf,
3131
tag::{Tag, RedeemScriptTag, ScriptPubKeyTag, ScriptSigTag, TapScriptTag, WitnessScriptTag},
3232
};

0 commit comments

Comments
 (0)