bitcoin/blockdata/script/
owned.rs1#[cfg(feature = "encoding")]
4use core::convert::Infallible;
5#[cfg(feature = "encoding")]
6use core::fmt;
7#[cfg(doc)]
8use core::ops::Deref;
9
10#[cfg(feature = "arbitrary")]
11use actual_arbitrary::{self as arbitrary, Arbitrary, Unstructured};
12use hex::FromHex;
13use secp256k1::{Secp256k1, Verification};
14
15use crate::blockdata::opcodes::all::*;
16use crate::blockdata::opcodes::{self, Opcode};
17use crate::blockdata::script::witness_program::{WitnessProgram, P2A_PROGRAM};
18use crate::blockdata::script::witness_version::WitnessVersion;
19use crate::blockdata::script::{
20 opcode_to_verify, Builder, Instruction, PushBytes, Script, ScriptHash, WScriptHash,
21};
22#[cfg(feature = "encoding")]
23use crate::internal_macros::write_err;
24use crate::key::{
25 PubkeyHash, PublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey, WPubkeyHash,
26};
27use crate::prelude::*;
28use crate::taproot::TapNodeHash;
29
30#[derive(Default, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
40pub struct ScriptBuf(pub(in crate::blockdata::script) Vec<u8>);
41
42impl ScriptBuf {
43 #[inline]
45 pub const fn new() -> Self { ScriptBuf(Vec::new()) }
46
47 pub fn with_capacity(capacity: usize) -> Self { ScriptBuf(Vec::with_capacity(capacity)) }
49
50 pub fn reserve(&mut self, additional_len: usize) { self.0.reserve(additional_len); }
61
62 pub fn reserve_exact(&mut self, additional_len: usize) { self.0.reserve_exact(additional_len); }
76
77 pub fn as_script(&self) -> &Script { Script::from_bytes(&self.0) }
79
80 pub fn as_mut_script(&mut self) -> &mut Script { Script::from_bytes_mut(&mut self.0) }
82
83 pub fn builder() -> Builder { Builder::new() }
85
86 pub fn new_p2pk(pubkey: &PublicKey) -> Self {
88 Builder::new().push_key(pubkey).push_opcode(OP_CHECKSIG).into_script()
89 }
90
91 pub fn new_p2pkh(pubkey_hash: &PubkeyHash) -> Self {
93 Builder::new()
94 .push_opcode(OP_DUP)
95 .push_opcode(OP_HASH160)
96 .push_slice(pubkey_hash)
97 .push_opcode(OP_EQUALVERIFY)
98 .push_opcode(OP_CHECKSIG)
99 .into_script()
100 }
101
102 pub fn new_p2sh(script_hash: &ScriptHash) -> Self {
104 Builder::new()
105 .push_opcode(OP_HASH160)
106 .push_slice(script_hash)
107 .push_opcode(OP_EQUAL)
108 .into_script()
109 }
110
111 pub fn new_p2wpkh(pubkey_hash: &WPubkeyHash) -> Self {
113 ScriptBuf::new_witness_program_unchecked(WitnessVersion::V0, pubkey_hash)
115 }
116
117 pub fn new_p2wsh(script_hash: &WScriptHash) -> Self {
119 ScriptBuf::new_witness_program_unchecked(WitnessVersion::V0, script_hash)
121 }
122
123 pub fn new_p2tr<C: Verification>(
126 secp: &Secp256k1<C>,
127 internal_key: UntweakedPublicKey,
128 merkle_root: Option<TapNodeHash>,
129 ) -> Self {
130 let (output_key, _) = internal_key.tap_tweak(secp, merkle_root);
131 ScriptBuf::new_witness_program_unchecked(WitnessVersion::V1, output_key.serialize())
133 }
134
135 pub fn new_p2tr_tweaked(output_key: TweakedPublicKey) -> Self {
137 ScriptBuf::new_witness_program_unchecked(WitnessVersion::V1, output_key.serialize())
139 }
140
141 pub fn new_p2a() -> Self {
143 ScriptBuf::new_witness_program_unchecked(WitnessVersion::V1, P2A_PROGRAM)
144 }
145
146 pub fn new_witness_program(witness_program: &WitnessProgram) -> Self {
148 Builder::new()
149 .push_opcode(witness_program.version().into())
150 .push_slice(witness_program.program())
151 .into_script()
152 }
153
154 pub(crate) fn new_witness_program_unchecked<T: AsRef<PushBytes>>(
160 version: WitnessVersion,
161 program: T,
162 ) -> Self {
163 let program = program.as_ref();
164 debug_assert!(program.len() >= 2 && program.len() <= 40);
165 debug_assert!(version != WitnessVersion::V0 || program.len() == 20 || program.len() == 32);
167 Builder::new().push_opcode(version.into()).push_slice(program).into_script()
168 }
169
170 pub fn p2wpkh_script_code(wpkh: WPubkeyHash) -> ScriptBuf {
176 Builder::new()
177 .push_opcode(OP_DUP)
178 .push_opcode(OP_HASH160)
179 .push_slice(wpkh)
180 .push_opcode(OP_EQUALVERIFY)
181 .push_opcode(OP_CHECKSIG)
182 .into_script()
183 }
184
185 pub fn new_op_return<T: AsRef<PushBytes>>(data: T) -> Self {
187 Builder::new().push_opcode(OP_RETURN).push_slice(data).into_script()
188 }
189
190 pub fn from_hex(s: &str) -> Result<Self, hex::HexToBytesError> {
192 let v = Vec::from_hex(s)?;
193 Ok(ScriptBuf::from_bytes(v))
194 }
195
196 pub fn from_bytes(bytes: Vec<u8>) -> Self { ScriptBuf(bytes) }
200
201 pub fn into_bytes(self) -> Vec<u8> { self.0 }
205
206 pub fn push_opcode(&mut self, data: Opcode) { self.0.push(data.to_u8()); }
208
209 pub fn push_slice<T: AsRef<PushBytes>>(&mut self, data: T) {
211 let data = data.as_ref();
212 self.reserve(Self::reserved_len_for_slice(data.len()));
213 self.push_slice_no_opt(data);
214 }
215
216 fn push_slice_no_opt(&mut self, data: &PushBytes) {
218 match data.len() as u64 {
220 n if n < opcodes::Ordinary::OP_PUSHDATA1 as u64 => {
221 self.0.push(n as u8);
222 }
223 n if n < 0x100 => {
224 self.0.push(opcodes::Ordinary::OP_PUSHDATA1.to_u8());
225 self.0.push(n as u8);
226 }
227 n if n < 0x10000 => {
228 self.0.push(opcodes::Ordinary::OP_PUSHDATA2.to_u8());
229 self.0.push((n % 0x100) as u8);
230 self.0.push((n / 0x100) as u8);
231 }
232 n if n < 0x100000000 => {
233 self.0.push(opcodes::Ordinary::OP_PUSHDATA4.to_u8());
234 self.0.push((n % 0x100) as u8);
235 self.0.push(((n / 0x100) % 0x100) as u8);
236 self.0.push(((n / 0x10000) % 0x100) as u8);
237 self.0.push((n / 0x1000000) as u8);
238 }
239 _ => panic!("tried to put a 4bn+ sized object into a script!"),
240 }
241 self.0.extend_from_slice(data.as_bytes());
243 }
244
245 pub(in crate::blockdata::script) fn reserved_len_for_slice(len: usize) -> usize {
247 len + match len {
248 0..=0x4b => 1,
249 0x4c..=0xff => 2,
250 0x100..=0xffff => 3,
251 _ => 5,
253 }
254 }
255
256 pub fn push_instruction(&mut self, instruction: Instruction<'_>) {
263 match instruction {
264 Instruction::Op(opcode) => self.push_opcode(opcode),
265 Instruction::PushBytes(bytes) => self.push_slice(bytes),
266 }
267 }
268
269 pub fn push_instruction_no_opt(&mut self, instruction: Instruction<'_>) {
271 match instruction {
272 Instruction::Op(opcode) => self.push_opcode(opcode),
273 Instruction::PushBytes(bytes) => self.push_slice_no_opt(bytes),
274 }
275 }
276
277 pub fn scan_and_push_verify(&mut self) { self.push_verify(self.last_opcode()); }
292
293 pub(in crate::blockdata::script) fn push_verify(&mut self, last_opcode: Option<Opcode>) {
298 match opcode_to_verify(last_opcode) {
299 Some(opcode) => {
300 self.0.pop();
301 self.push_opcode(opcode);
302 }
303 None => self.push_opcode(OP_VERIFY),
304 }
305 }
306
307 #[must_use = "`self` will be dropped if the result is not used"]
314 #[inline]
315 pub fn into_boxed_script(self) -> Box<Script> {
316 let rw = Box::into_raw(self.0.into_boxed_slice()) as *mut Script;
318 unsafe { Box::from_raw(rw) }
319 }
320}
321
322impl<'a> core::iter::FromIterator<Instruction<'a>> for ScriptBuf {
323 fn from_iter<T>(iter: T) -> Self
324 where
325 T: IntoIterator<Item = Instruction<'a>>,
326 {
327 let mut script = ScriptBuf::new();
328 script.extend(iter);
329 script
330 }
331}
332
333impl<'a> Extend<Instruction<'a>> for ScriptBuf {
334 fn extend<T>(&mut self, iter: T)
335 where
336 T: IntoIterator<Item = Instruction<'a>>,
337 {
338 let iter = iter.into_iter();
339 if iter.size_hint().1.map(|max| max < 6).unwrap_or(false) {
342 let mut iter = iter.fuse();
343 let mut head = [None; 5];
346 let mut total_size = 0;
347 for (head, instr) in head.iter_mut().zip(&mut iter) {
348 total_size += instr.script_serialized_len();
349 *head = Some(instr);
350 }
351 assert!(
353 iter.next().is_none(),
354 "Buggy implementation of `Iterator` on {} returns invalid upper bound",
355 core::any::type_name::<T::IntoIter>()
356 );
357 self.reserve(total_size);
358 for instr in head.iter().cloned().flatten() {
359 self.push_instruction_no_opt(instr);
360 }
361 } else {
362 for instr in iter {
363 self.push_instruction(instr);
364 }
365 }
366 }
367}
368
369#[cfg(feature = "arbitrary")]
370impl<'a> Arbitrary<'a> for ScriptBuf {
371 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
372 let v = Vec::<u8>::arbitrary(u)?;
373 Ok(ScriptBuf(v))
374 }
375}
376
377#[cfg(feature = "encoding")]
378impl encoding::Decode for ScriptBuf {
379 type Decoder = ScriptBufDecoder;
380}
381
382#[cfg(feature = "encoding")]
384#[derive(Debug, Clone)]
385pub struct ScriptBufDecoder(encoding::ByteVecDecoder);
386
387#[cfg(feature = "encoding")]
388impl ScriptBufDecoder {
389 pub const fn new() -> Self { Self(encoding::ByteVecDecoder::new()) }
391}
392
393#[cfg(feature = "encoding")]
394impl Default for ScriptBufDecoder {
395 fn default() -> Self { Self::new() }
396}
397
398#[cfg(feature = "encoding")]
399impl encoding::Decoder for ScriptBufDecoder {
400 type Output = ScriptBuf;
401 type Error = ScriptBufDecoderError;
402
403 #[inline]
404 fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
405 self.0.push_bytes(bytes).map_err(ScriptBufDecoderError)
406 }
407
408 #[inline]
409 fn end(self) -> Result<Self::Output, Self::Error> {
410 Ok(ScriptBuf::from_bytes(self.0.end().map_err(ScriptBufDecoderError)?))
411 }
412
413 #[inline]
414 fn read_limit(&self) -> usize { self.0.read_limit() }
415}
416
417#[cfg(feature = "encoding")]
419#[derive(Debug, Clone, PartialEq, Eq)]
420pub struct ScriptBufDecoderError(pub(super) encoding::ByteVecDecoderError);
421
422#[cfg(feature = "encoding")]
423impl From<Infallible> for ScriptBufDecoderError {
424 fn from(never: Infallible) -> Self { match never {} }
425}
426
427#[cfg(feature = "encoding")]
428impl fmt::Display for ScriptBufDecoderError {
429 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write_err!(f, "decoder error"; self.0) }
430}
431
432#[cfg(all(feature = "encoding", feature = "std"))]
433impl std::error::Error for ScriptBufDecoderError {
434 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
435}