1#![allow(clippy::result_large_err)]
6use super::evaluation_error::{
34 ExecutionContext, ScriptEvaluationError, ScriptResource, ScriptResourceLimit,
35};
36use super::op::*;
37use super::script_num::ScriptNum;
38use super::{LockingScript, Script, ScriptChunk, UnlockingScript};
39use crate::primitives::bsv::sighash::{
40 compute_sighash_for_signing, SighashParams, TxInput, TxOutput, SIGHASH_FORKID,
41};
42use crate::primitives::bsv::tx_signature::TransactionSignature;
43use crate::primitives::ec::PublicKey;
44use crate::primitives::{hash160, ripemd160, sha1, sha256, sha256d, to_hex, BigNumber};
45
46const MAX_SCRIPT_ELEMENT_SIZE: usize = 1024 * 1024 * 1024;
52
53const DEFAULT_MEMORY_LIMIT: usize = 32_000_000;
55
56const MAX_MULTISIG_KEY_COUNT: i64 = i32::MAX as i64;
58
59const REQUIRE_MINIMAL_PUSH: bool = true;
61
62const REQUIRE_PUSH_ONLY_UNLOCKING: bool = true;
64
65const REQUIRE_LOW_S_SIGNATURES: bool = true;
67
68const REQUIRE_CLEAN_STACK: bool = true;
70
71lazy_static::lazy_static! {
76 static ref SCRIPTNUM_NEG_1: Vec<u8> = ScriptNum::to_bytes(&BigNumber::from_i64(-1));
78
79 static ref SCRIPTNUMS_0_TO_16: Vec<Vec<u8>> = (0..=16)
81 .map(|i| ScriptNum::to_bytes(&BigNumber::from_i64(i)))
82 .collect();
83}
84
85pub struct SpendParams {
91 pub source_txid: [u8; 32],
93 pub source_output_index: u32,
95 pub source_satoshis: u64,
97 pub locking_script: LockingScript,
99 pub transaction_version: i32,
101 pub other_inputs: Vec<TxInput>,
103 pub outputs: Vec<TxOutput>,
105 pub input_index: usize,
107 pub unlocking_script: UnlockingScript,
109 pub input_sequence: u32,
111 pub lock_time: u32,
113 pub memory_limit: Option<usize>,
115}
116
117pub struct Spend {
124 source_txid: [u8; 32],
126 source_output_index: u32,
127 source_satoshis: u64,
128 locking_script: LockingScript,
129 transaction_version: i32,
130 other_inputs: Vec<TxInput>,
131 outputs: Vec<TxOutput>,
132 input_index: usize,
133 unlocking_script: UnlockingScript,
134 input_sequence: u32,
135 lock_time: u32,
136
137 context: ExecutionContext,
139 program_counter: usize,
140 last_code_separator: Option<usize>,
141 stack: Vec<Vec<u8>>,
142 alt_stack: Vec<Vec<u8>>,
143 if_stack: Vec<bool>,
144 memory_limit: usize,
145 stack_mem: usize,
146 alt_stack_mem: usize,
147 require_push_only: bool,
148 require_minimal: bool,
149 require_low_s: bool,
150 require_clean_stack: bool,
151
152 unlocking_chunks: Vec<crate::script::chunk::ScriptChunk>,
157 locking_chunks: Vec<crate::script::chunk::ScriptChunk>,
158}
159
160impl Spend {
161 pub fn new(params: SpendParams) -> Self {
163 let mut spend = Self {
164 source_txid: params.source_txid,
165 source_output_index: params.source_output_index,
166 source_satoshis: params.source_satoshis,
167 locking_script: params.locking_script,
168 transaction_version: params.transaction_version,
169 other_inputs: params.other_inputs,
170 outputs: params.outputs,
171 input_index: params.input_index,
172 unlocking_script: params.unlocking_script,
173 input_sequence: params.input_sequence,
174 lock_time: params.lock_time,
175 context: ExecutionContext::UnlockingScript,
176 program_counter: 0,
177 unlocking_chunks: Vec::new(),
178 locking_chunks: Vec::new(),
179 last_code_separator: None,
180 stack: Vec::new(),
181 alt_stack: Vec::new(),
182 if_stack: Vec::new(),
183 memory_limit: params.memory_limit.unwrap_or(DEFAULT_MEMORY_LIMIT),
184 stack_mem: 0,
185 alt_stack_mem: 0,
186 require_push_only: REQUIRE_PUSH_ONLY_UNLOCKING,
187 require_minimal: REQUIRE_MINIMAL_PUSH && params.transaction_version <= 1,
191 require_low_s: REQUIRE_LOW_S_SIGNATURES && params.transaction_version <= 1,
192 require_clean_stack: REQUIRE_CLEAN_STACK && params.transaction_version <= 1,
193 };
194 spend.unlocking_chunks = spend.unlocking_script.chunks();
195 spend.locking_chunks = spend.locking_script.chunks();
196 spend.reset();
197 spend
198 }
199
200 pub fn set_require_minimal(&mut self, require: bool) {
205 self.require_minimal = require;
206 }
207
208 pub fn set_require_push_only(&mut self, require: bool) {
215 self.require_push_only = require;
216 }
217
218 pub fn reset(&mut self) {
220 self.context = ExecutionContext::UnlockingScript;
221 self.program_counter = 0;
222 self.last_code_separator = None;
223 self.stack.clear();
224 self.alt_stack.clear();
225 self.if_stack.clear();
226 self.stack_mem = 0;
227 self.alt_stack_mem = 0;
228 }
229
230 pub fn validate(&mut self) -> Result<bool, ScriptEvaluationError> {
236 if self.require_push_only && !self.unlocking_script.is_push_only() {
238 return Err(self.error(
239 "Unlocking scripts can only contain push operations, and no other opcodes.",
240 ));
241 }
242
243 while self.step()? {
245 if self.context == ExecutionContext::LockingScript
247 && self.program_counter >= self.locking_chunks.len()
248 {
249 break;
250 }
251 }
252
253 if !self.if_stack.is_empty() {
255 return Err(self.error(
256 "Every OP_IF, OP_NOTIF, or OP_ELSE must be terminated with OP_ENDIF prior to the end of the script.",
257 ));
258 }
259
260 if self.require_clean_stack && self.stack.len() != 1 {
262 return Err(self.error(&format!(
263 "The clean stack rule requires exactly one item to be on the stack after script execution, found {}.",
264 self.stack.len()
265 )));
266 }
267
268 if self.stack.is_empty() {
270 return Err(self.error(
271 "The top stack element must be truthy after script evaluation (stack is empty).",
272 ));
273 }
274
275 if !ScriptNum::cast_to_bool(&self.stack[self.stack.len() - 1]) {
276 return Err(self.error("The top stack element must be truthy after script evaluation."));
277 }
278
279 Ok(true)
280 }
281
282 pub fn step(&mut self) -> Result<bool, ScriptEvaluationError> {
288 if self.stack_mem > self.memory_limit {
292 return Err(self.resource_error(ScriptResource::Stack, self.stack_mem));
293 }
294 if self.alt_stack_mem > self.memory_limit {
295 return Err(self.resource_error(ScriptResource::AltStack, self.alt_stack_mem));
296 }
297
298 if self.context == ExecutionContext::UnlockingScript
302 && self.program_counter >= self.unlocking_chunks.len()
303 {
304 if !self.if_stack.is_empty() {
305 return Err(self.error(
306 "Every OP_IF, OP_NOTIF, or OP_ELSE must be terminated with OP_ENDIF prior to the end of the unlocking script.",
307 ));
308 }
309 self.alt_stack.clear();
310 self.alt_stack_mem = 0;
311 self.last_code_separator = None;
312 self.context = ExecutionContext::LockingScript;
313 self.program_counter = 0;
314 }
315
316 let current_len = match self.context {
319 ExecutionContext::UnlockingScript => self.unlocking_chunks.len(),
320 ExecutionContext::LockingScript => self.locking_chunks.len(),
321 };
322
323 if self.program_counter >= current_len {
324 return Ok(false);
325 }
326
327 let op_owned = match self.context {
328 ExecutionContext::UnlockingScript => {
329 self.unlocking_chunks[self.program_counter].clone()
330 }
331 ExecutionContext::LockingScript => self.locking_chunks[self.program_counter].clone(),
332 };
333 let operation = &op_owned;
334 let current_opcode = operation.op;
335
336 if let Some(ref data) = operation.data {
338 if data.len() > MAX_SCRIPT_ELEMENT_SIZE {
339 return Err(self.error(&format!(
340 "Data push > {} bytes (pc={})",
341 MAX_SCRIPT_ELEMENT_SIZE, self.program_counter
342 )));
343 }
344 }
345
346 let is_executing = !self.if_stack.contains(&false);
348
349 if is_executing && is_opcode_disabled(current_opcode) {
351 return Err(self.error(&format!(
352 "This opcode is currently disabled. (Opcode: {}, PC: {})",
353 opcode_to_name(current_opcode).unwrap_or("UNKNOWN"),
354 self.program_counter
355 )));
356 }
357
358 if is_executing && current_opcode <= OP_PUSHDATA4 {
360 if self.require_minimal && !is_chunk_minimal_push(operation) {
362 return Err(self.error(&format!(
363 "This data is not minimally-encoded. (PC: {})",
364 self.program_counter
365 )));
366 }
367 let data = operation.data.clone().unwrap_or_default();
368 self.push_stack(data)?;
369 } else if is_executing || (OP_IF..=OP_ENDIF).contains(¤t_opcode) {
370 self.execute_opcode(current_opcode, operation)?;
372 }
373
374 self.program_counter += 1;
375 Ok(true)
376 }
377
378 fn execute_opcode(
383 &mut self,
384 opcode: u8,
385 chunk: &ScriptChunk,
386 ) -> Result<(), ScriptEvaluationError> {
387 let is_executing = !self.if_stack.contains(&false);
388
389 match opcode {
390 OP_1NEGATE => {
394 self.push_stack_copy(&SCRIPTNUM_NEG_1)?;
395 }
396 OP_0 => {
397 self.push_stack_copy(&SCRIPTNUMS_0_TO_16[0])?;
398 }
399 OP_1..=OP_16 => {
400 let n = (opcode - OP_1 + 1) as usize;
401 self.push_stack_copy(&SCRIPTNUMS_0_TO_16[n])?;
402 }
403
404 OP_NOP | OP_NOP1 | OP_NOP2 | OP_NOP3 | OP_NOP4 | OP_NOP5 | OP_NOP6 | OP_NOP7
408 | OP_NOP8 | OP_NOP9 | OP_NOP10 => {}
409 0xba..=0xff => {}
411
412 OP_IF | OP_NOTIF => {
416 let mut f_value = false;
417 if is_executing {
418 if self.stack.is_empty() {
419 return Err(self.error(
420 "OP_IF and OP_NOTIF require at least one item on the stack when they are used!",
421 ));
422 }
423 let buf = self.pop_stack()?;
424 f_value = ScriptNum::cast_to_bool(&buf);
425 if opcode == OP_NOTIF {
426 f_value = !f_value;
427 }
428 }
429 self.if_stack.push(f_value);
430 }
431 OP_ELSE => {
432 if self.if_stack.is_empty() {
433 return Err(self.error("OP_ELSE requires a preceeding OP_IF."));
434 }
435 let last = self.if_stack.len() - 1;
436 self.if_stack[last] = !self.if_stack[last];
437 }
438 OP_ENDIF => {
439 if self.if_stack.is_empty() {
440 return Err(self.error("OP_ENDIF requires a preceeding OP_IF."));
441 }
442 self.if_stack.pop();
443 }
444 OP_VERIFY => {
445 if self.stack.is_empty() {
446 return Err(
447 self.error("OP_VERIFY requires at least one item to be on the stack.")
448 );
449 }
450 let f_value = ScriptNum::cast_to_bool(self.stack_top()?);
451 if !f_value {
452 return Err(self.error("OP_VERIFY requires the top stack value to be truthy."));
453 }
454 self.pop_stack()?;
455 }
456 OP_RETURN => {
457 let end = match self.context {
459 ExecutionContext::UnlockingScript => self.unlocking_chunks.len(),
460 ExecutionContext::LockingScript => self.locking_chunks.len(),
461 };
462 self.program_counter = end;
463 self.if_stack.clear();
464 if self.program_counter > 0 {
466 self.program_counter -= 1;
467 }
468 }
469
470 OP_TOALTSTACK => {
474 if self.stack.is_empty() {
475 return Err(
476 self.error("OP_TOALTSTACK requires at least one item to be on the stack.")
477 );
478 }
479 let item = self.pop_stack()?;
480 self.push_alt_stack(item)?;
481 }
482 OP_FROMALTSTACK => {
483 if self.alt_stack.is_empty() {
484 return Err(self.error(
485 "OP_FROMALTSTACK requires at least one item to be on the alt stack.",
486 ));
487 }
488 let item = self.pop_alt_stack()?;
489 self.push_stack(item)?;
490 }
491 OP_2DROP => {
492 if self.stack.len() < 2 {
493 return Err(
494 self.error("OP_2DROP requires at least two items to be on the stack.")
495 );
496 }
497 self.pop_stack()?;
498 self.pop_stack()?;
499 }
500 OP_2DUP => {
501 if self.stack.len() < 2 {
502 return Err(
503 self.error("OP_2DUP requires at least two items to be on the stack.")
504 );
505 }
506 let buf1 = self.stack_top_n(2)?.to_vec();
507 let buf2 = self.stack_top()?.to_vec();
508 self.push_stack(buf1)?;
509 self.push_stack(buf2)?;
510 }
511 OP_3DUP => {
512 if self.stack.len() < 3 {
513 return Err(
514 self.error("OP_3DUP requires at least three items to be on the stack.")
515 );
516 }
517 let buf1 = self.stack_top_n(3)?.to_vec();
518 let buf2 = self.stack_top_n(2)?.to_vec();
519 let buf3 = self.stack_top()?.to_vec();
520 self.push_stack(buf1)?;
521 self.push_stack(buf2)?;
522 self.push_stack(buf3)?;
523 }
524 OP_2OVER => {
525 if self.stack.len() < 4 {
526 return Err(
527 self.error("OP_2OVER requires at least four items to be on the stack.")
528 );
529 }
530 let buf1 = self.stack_top_n(4)?.to_vec();
531 let buf2 = self.stack_top_n(3)?.to_vec();
532 self.push_stack(buf1)?;
533 self.push_stack(buf2)?;
534 }
535 OP_2ROT => {
536 if self.stack.len() < 6 {
537 return Err(
538 self.error("OP_2ROT requires at least six items to be on the stack.")
539 );
540 }
541 let x6 = self.pop_stack()?;
542 let x5 = self.pop_stack()?;
543 let x4 = self.pop_stack()?;
544 let x3 = self.pop_stack()?;
545 let x2 = self.pop_stack()?;
546 let x1 = self.pop_stack()?;
547 self.push_stack(x3)?;
548 self.push_stack(x4)?;
549 self.push_stack(x5)?;
550 self.push_stack(x6)?;
551 self.push_stack(x1)?;
552 self.push_stack(x2)?;
553 }
554 OP_2SWAP => {
555 if self.stack.len() < 4 {
556 return Err(
557 self.error("OP_2SWAP requires at least four items to be on the stack.")
558 );
559 }
560 let x4 = self.pop_stack()?;
561 let x3 = self.pop_stack()?;
562 let x2 = self.pop_stack()?;
563 let x1 = self.pop_stack()?;
564 self.push_stack(x3)?;
565 self.push_stack(x4)?;
566 self.push_stack(x1)?;
567 self.push_stack(x2)?;
568 }
569 OP_IFDUP => {
570 if self.stack.is_empty() {
571 return Err(
572 self.error("OP_IFDUP requires at least one item to be on the stack.")
573 );
574 }
575 let top = self.stack_top()?.to_vec();
576 if ScriptNum::cast_to_bool(&top) {
577 self.push_stack(top)?;
578 }
579 }
580 OP_DEPTH => {
581 let depth = BigNumber::from_u64(self.stack.len() as u64);
582 self.push_stack(ScriptNum::to_bytes(&depth))?;
583 }
584 OP_DROP => {
585 if self.stack.is_empty() {
586 return Err(
587 self.error("OP_DROP requires at least one item to be on the stack.")
588 );
589 }
590 self.pop_stack()?;
591 }
592 OP_DUP => {
593 if self.stack.is_empty() {
594 return Err(self.error("OP_DUP requires at least one item to be on the stack."));
595 }
596 let top = self.stack_top()?.to_vec();
597 self.push_stack(top)?;
598 }
599 OP_NIP => {
600 if self.stack.len() < 2 {
601 return Err(
602 self.error("OP_NIP requires at least two items to be on the stack.")
603 );
604 }
605 let top = self.pop_stack()?;
606 self.pop_stack()?;
607 self.push_stack(top)?;
608 }
609 OP_OVER => {
610 if self.stack.len() < 2 {
611 return Err(
612 self.error("OP_OVER requires at least two items to be on the stack.")
613 );
614 }
615 let second = self.stack_top_n(2)?.to_vec();
616 self.push_stack(second)?;
617 }
618 OP_PICK | OP_ROLL => {
619 if self.stack.len() < 2 {
620 return Err(self.error(&format!(
621 "{} requires at least two items to be on the stack.",
622 opcode_to_name(opcode).unwrap_or("OP_PICK/ROLL")
623 )));
624 }
625 let n_bytes = self.pop_stack()?;
626 let bn = ScriptNum::from_bytes(&n_bytes, self.require_minimal)
627 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
628
629 let n = bn.to_i64().unwrap_or(i64::MAX);
630 if n < 0 || n >= self.stack.len() as i64 {
631 return Err(self.error(&format!(
632 "{} requires the top stack element to be 0 or a positive number less than the current size of the stack.",
633 opcode_to_name(opcode).unwrap_or("OP_PICK/ROLL")
634 )));
635 }
636
637 let n_idx = n as usize;
638 let item = self.stack[self.stack.len() - 1 - n_idx].clone();
639
640 if opcode == OP_ROLL {
641 let remove_idx = self.stack.len() - 1 - n_idx;
642 let removed = self.stack.remove(remove_idx);
643 self.stack_mem -= removed.len();
644 self.push_stack(item)?;
645 } else {
646 self.push_stack(item)?;
648 }
649 }
650 OP_ROT => {
651 if self.stack.len() < 3 {
652 return Err(
653 self.error("OP_ROT requires at least three items to be on the stack.")
654 );
655 }
656 let x3 = self.pop_stack()?;
657 let x2 = self.pop_stack()?;
658 let x1 = self.pop_stack()?;
659 self.push_stack(x2)?;
660 self.push_stack(x3)?;
661 self.push_stack(x1)?;
662 }
663 OP_SWAP => {
664 if self.stack.len() < 2 {
665 return Err(
666 self.error("OP_SWAP requires at least two items to be on the stack.")
667 );
668 }
669 let x2 = self.pop_stack()?;
670 let x1 = self.pop_stack()?;
671 self.push_stack(x2)?;
672 self.push_stack(x1)?;
673 }
674 OP_TUCK => {
675 if self.stack.len() < 2 {
676 return Err(
677 self.error("OP_TUCK requires at least two items to be on the stack.")
678 );
679 }
680 let top = self.stack_top()?.to_vec();
681 self.ensure_stack_mem(top.len())?;
682 let insert_idx = self.stack.len() - 2;
683 self.stack.insert(insert_idx, top.clone());
684 self.stack_mem += top.len();
685 }
686 OP_SIZE => {
687 if self.stack.is_empty() {
688 return Err(
689 self.error("OP_SIZE requires at least one item to be on the stack.")
690 );
691 }
692 let size = self.stack_top()?.len();
693 let bn = BigNumber::from_u64(size as u64);
694 self.push_stack(ScriptNum::to_bytes(&bn))?;
695 }
696
697 OP_CAT => {
701 if self.stack.len() < 2 {
702 return Err(
703 self.error("OP_CAT requires at least two items to be on the stack.")
704 );
705 }
706 let buf2 = self.pop_stack()?;
707 let buf1 = self.pop_stack()?;
708 let mut result = buf1;
709 result.extend(buf2);
710 if result.len() > MAX_SCRIPT_ELEMENT_SIZE {
711 return Err(self.error(&format!(
712 "It's not currently possible to push data larger than {} bytes.",
713 MAX_SCRIPT_ELEMENT_SIZE
714 )));
715 }
716 self.push_stack(result)?;
717 }
718 OP_SPLIT => {
719 if self.stack.len() < 2 {
720 return Err(
721 self.error("OP_SPLIT requires at least two items to be on the stack.")
722 );
723 }
724 let pos_bytes = self.pop_stack()?;
725 let data = self.pop_stack()?;
726
727 let pos_bn = ScriptNum::from_bytes(&pos_bytes, self.require_minimal)
728 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
729 let pos = pos_bn.to_i64().unwrap_or(-1);
730
731 if pos < 0 || pos > data.len() as i64 {
732 return Err(self.error(
733 "OP_SPLIT requires the first stack item to be a non-negative number less than or equal to the size of the second-from-top stack item.",
734 ));
735 }
736
737 let split_idx = pos as usize;
738 let left = data[..split_idx].to_vec();
739 let right = data[split_idx..].to_vec();
740 self.push_stack(left)?;
741 self.push_stack(right)?;
742 }
743 OP_NUM2BIN => {
744 if self.stack.len() < 2 {
745 return Err(
746 self.error("OP_NUM2BIN requires at least two items to be on the stack.")
747 );
748 }
749 let size_bytes = self.pop_stack()?;
750 let size_bn = ScriptNum::from_bytes(&size_bytes, self.require_minimal)
751 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
752 let size = size_bn.to_i64().unwrap_or(-1);
753
754 if size < 0 || size > MAX_SCRIPT_ELEMENT_SIZE as i64 {
755 return Err(self.error(&format!(
756 "It's not currently possible to push data larger than {} bytes or negative size.",
757 MAX_SCRIPT_ELEMENT_SIZE
758 )));
759 }
760 let size = size as usize;
761 if size > self.memory_limit {
768 return Err(self.resource_error(ScriptResource::ElementSize, size));
769 }
770
771 let rawnum = self.pop_stack()?;
772 let minimal = ScriptNum::minimally_encode(&rawnum);
773
774 if minimal.len() > size {
775 return Err(self.error(
776 "OP_NUM2BIN requires that the size expressed in the top stack item is large enough to hold the value expressed in the second-from-top stack item.",
777 ));
778 }
779
780 if minimal.len() == size {
781 self.push_stack(minimal)?;
782 } else {
783 let mut result = vec![0u8; size];
785 let mut signbit = 0u8;
786
787 if !minimal.is_empty() {
788 signbit = minimal[minimal.len() - 1] & 0x80;
789 let mut minimal_copy = minimal.clone();
790 if let Some(last) = minimal_copy.last_mut() {
791 *last &= 0x7f;
792 }
793 result[..minimal_copy.len()].copy_from_slice(&minimal_copy);
794 }
795
796 if signbit != 0 {
797 result[size - 1] |= 0x80;
798 }
799 self.push_stack(result)?;
800 }
801 }
802 OP_BIN2NUM => {
803 if self.stack.is_empty() {
804 return Err(
805 self.error("OP_BIN2NUM requires at least one item to be on the stack.")
806 );
807 }
808 let buf = self.pop_stack()?;
809 let result = ScriptNum::minimally_encode(&buf);
810 if !ScriptNum::is_minimally_encoded(&result) {
811 return Err(
812 self.error("OP_BIN2NUM requires that the resulting number is valid.")
813 );
814 }
815 self.push_stack(result)?;
816 }
817
818 OP_INVERT => {
822 if self.stack.is_empty() {
823 return Err(
824 self.error("OP_INVERT requires at least one item to be on the stack.")
825 );
826 }
827 let buf = self.pop_stack()?;
828 let result: Vec<u8> = buf.iter().map(|&b| !b).collect();
829 self.push_stack(result)?;
830 }
831 OP_AND | OP_OR | OP_XOR => {
832 if self.stack.len() < 2 {
833 return Err(self.error(&format!(
834 "{} requires at least two items on the stack.",
835 opcode_to_name(opcode).unwrap_or("OP")
836 )));
837 }
838 let buf2 = self.pop_stack()?;
839 let buf1 = self.pop_stack()?;
840 if buf1.len() != buf2.len() {
841 return Err(self.error(&format!(
842 "{} requires the top two stack items to be the same size.",
843 opcode_to_name(opcode).unwrap_or("OP")
844 )));
845 }
846 let result: Vec<u8> = buf1
847 .iter()
848 .zip(buf2.iter())
849 .map(|(&a, &b)| match opcode {
850 OP_AND => a & b,
851 OP_OR => a | b,
852 _ => a ^ b, })
854 .collect();
855 self.push_stack(result)?;
856 }
857 OP_EQUAL | OP_EQUALVERIFY => {
858 if self.stack.len() < 2 {
859 return Err(self.error(&format!(
860 "{} requires at least two items to be on the stack.",
861 opcode_to_name(opcode).unwrap_or("OP_EQUAL")
862 )));
863 }
864 let buf2 = self.pop_stack()?;
865 let buf1 = self.pop_stack()?;
866 let equal = buf1 == buf2;
867 self.push_stack(if equal { vec![1] } else { vec![] })?;
868
869 if opcode == OP_EQUALVERIFY {
870 if !equal {
871 return Err(self.error(
872 "OP_EQUALVERIFY requires the top two stack items to be equal.",
873 ));
874 }
875 self.pop_stack()?;
876 }
877 }
878 OP_LSHIFT | OP_RSHIFT => {
879 if self.stack.len() < 2 {
880 return Err(self.error(&format!(
881 "{} requires at least two items to be on the stack.",
882 opcode_to_name(opcode).unwrap_or("OP")
883 )));
884 }
885 let n_bytes = self.pop_stack()?;
886 let buf = self.pop_stack()?;
887
888 let n_bn = ScriptNum::from_bytes(&n_bytes, self.require_minimal)
889 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
890 let n = n_bn.to_i64().unwrap_or(-1);
891
892 if n < 0 {
893 return Err(self.error(&format!(
894 "{} requires the top item on the stack not to be negative.",
895 opcode_to_name(opcode).unwrap_or("OP")
896 )));
897 }
898
899 if buf.is_empty() {
900 self.push_stack(vec![])?;
901 } else {
902 let len = buf.len();
911 let result: Vec<u8> = if (n as u128) >= (len as u128) * 8 {
912 vec![0u8; len]
913 } else {
914 let byte_shift = (n as usize) / 8;
915 let bit_shift = (n as usize) % 8;
916 let mut out = vec![0u8; len];
917 #[allow(clippy::needless_range_loop)]
918 for i in 0..len {
919 if opcode == OP_LSHIFT {
920 let src = i + byte_shift;
921 let hi = if src < len { buf[src] } else { 0 };
922 let lo = if bit_shift > 0 && src + 1 < len {
923 buf[src + 1]
924 } else {
925 0
926 };
927 out[i] = if bit_shift == 0 {
928 hi
929 } else {
930 (hi << bit_shift) | (lo >> (8 - bit_shift))
931 };
932 } else {
933 if i >= byte_shift {
935 let src = i - byte_shift;
936 let hi = buf[src];
937 let carry = if bit_shift > 0 && src >= 1 {
938 buf[src - 1]
939 } else {
940 0
941 };
942 out[i] = if bit_shift == 0 {
943 hi
944 } else {
945 (hi >> bit_shift) | (carry << (8 - bit_shift))
946 };
947 }
948 }
949 }
950 out
951 };
952 self.push_stack(result)?;
953 }
954 }
955
956 OP_1ADD | OP_1SUB | OP_NEGATE | OP_ABS | OP_NOT | OP_0NOTEQUAL => {
960 if self.stack.is_empty() {
961 return Err(self.error(&format!(
962 "{} requires at least one item to be on the stack.",
963 opcode_to_name(opcode).unwrap_or("OP")
964 )));
965 }
966 let buf = self.pop_stack()?;
967 let mut bn = ScriptNum::from_bytes(&buf, self.require_minimal)
968 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
969
970 bn = match opcode {
971 OP_1ADD => bn.add(&BigNumber::one()),
972 OP_1SUB => bn.sub(&BigNumber::one()),
973 OP_NEGATE => bn.neg(),
974 OP_ABS => bn.abs(),
975 OP_NOT => {
976 if bn.is_zero() {
977 BigNumber::one()
978 } else {
979 BigNumber::zero()
980 }
981 }
982 OP_0NOTEQUAL => {
983 if bn.is_zero() {
984 BigNumber::zero()
985 } else {
986 BigNumber::one()
987 }
988 }
989 _ => bn,
990 };
991 self.push_stack(ScriptNum::to_bytes(&bn))?;
992 }
993 OP_ADD
994 | OP_SUB
995 | OP_MUL
996 | OP_DIV
997 | OP_MOD
998 | OP_BOOLAND
999 | OP_BOOLOR
1000 | OP_NUMEQUAL
1001 | OP_NUMEQUALVERIFY
1002 | OP_NUMNOTEQUAL
1003 | OP_LESSTHAN
1004 | OP_GREATERTHAN
1005 | OP_LESSTHANOREQUAL
1006 | OP_GREATERTHANOREQUAL
1007 | OP_MIN
1008 | OP_MAX => {
1009 if self.stack.len() < 2 {
1010 return Err(self.error(&format!(
1011 "{} requires at least two items to be on the stack.",
1012 opcode_to_name(opcode).unwrap_or("OP")
1013 )));
1014 }
1015 let buf2 = self.pop_stack()?;
1016 let buf1 = self.pop_stack()?;
1017 let bn1 = ScriptNum::from_bytes(&buf1, self.require_minimal)
1018 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
1019 let bn2 = ScriptNum::from_bytes(&buf2, self.require_minimal)
1020 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
1021
1022 let result = match opcode {
1023 OP_ADD => bn1.add(&bn2),
1024 OP_SUB => bn1.sub(&bn2),
1025 OP_MUL => bn1.mul(&bn2),
1026 OP_DIV => {
1027 if bn2.is_zero() {
1028 return Err(self.error("OP_DIV cannot divide by zero!"));
1029 }
1030 bn1.div(&bn2)
1031 }
1032 OP_MOD => {
1033 if bn2.is_zero() {
1034 return Err(self.error("OP_MOD cannot divide by zero!"));
1035 }
1036 bn1.mod_floor(&bn2)
1037 }
1038 OP_BOOLAND => {
1039 if !bn1.is_zero() && !bn2.is_zero() {
1040 BigNumber::one()
1041 } else {
1042 BigNumber::zero()
1043 }
1044 }
1045 OP_BOOLOR => {
1046 if !bn1.is_zero() || !bn2.is_zero() {
1047 BigNumber::one()
1048 } else {
1049 BigNumber::zero()
1050 }
1051 }
1052 OP_NUMEQUAL | OP_NUMEQUALVERIFY => {
1053 if bn1 == bn2 {
1054 BigNumber::one()
1055 } else {
1056 BigNumber::zero()
1057 }
1058 }
1059 OP_NUMNOTEQUAL => {
1060 if bn1 != bn2 {
1061 BigNumber::one()
1062 } else {
1063 BigNumber::zero()
1064 }
1065 }
1066 OP_LESSTHAN => {
1067 if bn1 < bn2 {
1068 BigNumber::one()
1069 } else {
1070 BigNumber::zero()
1071 }
1072 }
1073 OP_GREATERTHAN => {
1074 if bn1 > bn2 {
1075 BigNumber::one()
1076 } else {
1077 BigNumber::zero()
1078 }
1079 }
1080 OP_LESSTHANOREQUAL => {
1081 if bn1 <= bn2 {
1082 BigNumber::one()
1083 } else {
1084 BigNumber::zero()
1085 }
1086 }
1087 OP_GREATERTHANOREQUAL => {
1088 if bn1 >= bn2 {
1089 BigNumber::one()
1090 } else {
1091 BigNumber::zero()
1092 }
1093 }
1094 OP_MIN => {
1095 if bn1 < bn2 {
1096 bn1
1097 } else {
1098 bn2
1099 }
1100 }
1101 OP_MAX => {
1102 if bn1 > bn2 {
1103 bn1
1104 } else {
1105 bn2
1106 }
1107 }
1108 _ => BigNumber::zero(),
1109 };
1110
1111 self.push_stack(ScriptNum::to_bytes(&result))?;
1112
1113 if opcode == OP_NUMEQUALVERIFY {
1114 if !ScriptNum::cast_to_bool(self.stack_top()?) {
1115 return Err(self
1116 .error("OP_NUMEQUALVERIFY requires the top stack item to be truthy."));
1117 }
1118 self.pop_stack()?;
1119 }
1120 }
1121 OP_WITHIN => {
1122 if self.stack.len() < 3 {
1123 return Err(
1124 self.error("OP_WITHIN requires at least three items to be on the stack.")
1125 );
1126 }
1127 let max_bytes = self.pop_stack()?;
1128 let min_bytes = self.pop_stack()?;
1129 let x_bytes = self.pop_stack()?;
1130 let max_bn = ScriptNum::from_bytes(&max_bytes, self.require_minimal)
1131 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
1132 let min_bn = ScriptNum::from_bytes(&min_bytes, self.require_minimal)
1133 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
1134 let x_bn = ScriptNum::from_bytes(&x_bytes, self.require_minimal)
1135 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
1136
1137 let in_range = x_bn >= min_bn && x_bn < max_bn;
1138 self.push_stack(if in_range { vec![1] } else { vec![] })?;
1139 }
1140
1141 OP_RIPEMD160 => {
1145 if self.stack.is_empty() {
1146 return Err(
1147 self.error("OP_RIPEMD160 requires at least one item to be on the stack.")
1148 );
1149 }
1150 let buf = self.pop_stack()?;
1151 let hash = ripemd160(&buf);
1152 self.push_stack(hash.to_vec())?;
1153 }
1154 OP_SHA1 => {
1155 if self.stack.is_empty() {
1156 return Err(
1157 self.error("OP_SHA1 requires at least one item to be on the stack.")
1158 );
1159 }
1160 let buf = self.pop_stack()?;
1161 let hash = sha1(&buf);
1162 self.push_stack(hash.to_vec())?;
1163 }
1164 OP_SHA256 => {
1165 if self.stack.is_empty() {
1166 return Err(
1167 self.error("OP_SHA256 requires at least one item to be on the stack.")
1168 );
1169 }
1170 let buf = self.pop_stack()?;
1171 let hash = sha256(&buf);
1172 self.push_stack(hash.to_vec())?;
1173 }
1174 OP_HASH160 => {
1175 if self.stack.is_empty() {
1176 return Err(
1177 self.error("OP_HASH160 requires at least one item to be on the stack.")
1178 );
1179 }
1180 let buf = self.pop_stack()?;
1181 let hash = hash160(&buf);
1182 self.push_stack(hash.to_vec())?;
1183 }
1184 OP_HASH256 => {
1185 if self.stack.is_empty() {
1186 return Err(
1187 self.error("OP_HASH256 requires at least one item to be on the stack.")
1188 );
1189 }
1190 let buf = self.pop_stack()?;
1191 let hash = sha256d(&buf);
1192 self.push_stack(hash.to_vec())?;
1193 }
1194 OP_CODESEPARATOR => {
1195 self.last_code_separator = Some(self.program_counter);
1196 }
1197 OP_CHECKSIG | OP_CHECKSIGVERIFY => {
1198 if self.stack.len() < 2 {
1199 return Err(self.error(&format!(
1200 "{} requires at least two items to be on the stack.",
1201 opcode_to_name(opcode).unwrap_or("OP_CHECKSIG")
1202 )));
1203 }
1204 let pubkey_bytes = self.pop_stack()?;
1205 let sig_bytes = self.pop_stack()?;
1206
1207 self.check_signature_encoding(&sig_bytes)?;
1209 self.check_public_key_encoding(&pubkey_bytes)?;
1210
1211 let subscript = self.build_subscript(&sig_bytes)?;
1213
1214 let success = if sig_bytes.is_empty() {
1216 false
1217 } else {
1218 self.verify_signature(&sig_bytes, &pubkey_bytes, &subscript)?
1219 };
1220
1221 self.push_stack(if success { vec![1] } else { vec![] })?;
1222
1223 if opcode == OP_CHECKSIGVERIFY {
1224 if !success {
1225 return Err(self.error(
1226 "OP_CHECKSIGVERIFY requires that a valid signature is provided.",
1227 ));
1228 }
1229 self.pop_stack()?;
1230 }
1231 }
1232 OP_CHECKMULTISIG | OP_CHECKMULTISIGVERIFY => {
1233 self.op_checkmultisig(opcode)?;
1234 }
1235
1236 0x01..=0x4b => {
1240 let data = chunk.data.clone().unwrap_or_default();
1242 self.push_stack(data)?;
1243 }
1244 OP_PUSHDATA1 | OP_PUSHDATA2 | OP_PUSHDATA4 => {
1245 let data = chunk.data.clone().unwrap_or_default();
1246 self.push_stack(data)?;
1247 }
1248
1249 _ => {
1253 return Err(self.error(&format!(
1254 "Invalid opcode {} (pc={}).",
1255 opcode, self.program_counter
1256 )));
1257 }
1258 }
1259
1260 Ok(())
1261 }
1262
1263 fn op_checkmultisig(&mut self, opcode: u8) -> Result<(), ScriptEvaluationError> {
1268 if self.stack.is_empty() {
1270 return Err(self.error(&format!(
1271 "{} requires at least 1 item for nKeys.",
1272 opcode_to_name(opcode).unwrap_or("OP_CHECKMULTISIG")
1273 )));
1274 }
1275
1276 let n_keys_bytes = self.pop_stack()?;
1277 let n_keys_bn = ScriptNum::from_bytes(&n_keys_bytes, self.require_minimal)
1278 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
1279 let n_keys = n_keys_bn.to_i64().unwrap_or(-1);
1280
1281 if !(0..=MAX_MULTISIG_KEY_COUNT).contains(&n_keys) {
1282 return Err(self.error(&format!(
1283 "{} requires a key count between 0 and {}.",
1284 opcode_to_name(opcode).unwrap_or("OP_CHECKMULTISIG"),
1285 MAX_MULTISIG_KEY_COUNT
1286 )));
1287 }
1288 let n_keys = n_keys as usize;
1289
1290 if self.stack.len() < n_keys {
1292 return Err(self.error(&format!(
1293 "{} stack too small for keys. Need {}, have {}.",
1294 opcode_to_name(opcode).unwrap_or("OP_CHECKMULTISIG"),
1295 n_keys,
1296 self.stack.len()
1297 )));
1298 }
1299
1300 let mut pubkeys = Vec::with_capacity(n_keys);
1301 for _ in 0..n_keys {
1302 pubkeys.push(self.pop_stack()?);
1303 }
1304
1305 if self.stack.is_empty() {
1307 return Err(self.error(&format!(
1308 "{} requires item for nSigs.",
1309 opcode_to_name(opcode).unwrap_or("OP_CHECKMULTISIG")
1310 )));
1311 }
1312
1313 let n_sigs_bytes = self.pop_stack()?;
1314 let n_sigs_bn = ScriptNum::from_bytes(&n_sigs_bytes, self.require_minimal)
1315 .map_err(|e| self.error(&format!("Invalid script number: {}", e)))?;
1316 let n_sigs = n_sigs_bn.to_i64().unwrap_or(-1);
1317
1318 if n_sigs < 0 || n_sigs as usize > n_keys {
1319 return Err(self.error(&format!(
1320 "{} requires the number of signatures to be no greater than the number of keys.",
1321 opcode_to_name(opcode).unwrap_or("OP_CHECKMULTISIG")
1322 )));
1323 }
1324 let n_sigs = n_sigs as usize;
1325
1326 if self.stack.len() < n_sigs {
1328 return Err(self.error(&format!(
1329 "{} stack too small for sigs. Need {}, have {}.",
1330 opcode_to_name(opcode).unwrap_or("OP_CHECKMULTISIG"),
1331 n_sigs,
1332 self.stack.len()
1333 )));
1334 }
1335
1336 let mut sigs = Vec::with_capacity(n_sigs);
1337 for _ in 0..n_sigs {
1338 sigs.push(self.pop_stack()?);
1339 }
1340
1341 let base_script = match self.context {
1343 ExecutionContext::UnlockingScript => self.unlocking_script.as_script().clone(),
1344 ExecutionContext::LockingScript => self.locking_script.as_script().clone(),
1345 };
1346 let start_idx = self.last_code_separator.map(|i| i + 1).unwrap_or(0);
1347 let chunks = base_script.chunks();
1348 let mut subscript_chunks: Vec<ScriptChunk> = chunks.into_iter().skip(start_idx).collect();
1349 if self.context == ExecutionContext::UnlockingScript {
1352 subscript_chunks.extend(self.locking_script.as_script().chunks());
1353 }
1354 let mut subscript = Script::from_chunks(subscript_chunks);
1355
1356 for sig in &sigs {
1357 let sig_script = Script::new();
1358 let mut sig_script = sig_script;
1359 sig_script.write_bin(sig);
1360 subscript.find_and_delete(&sig_script);
1361 }
1362
1363 let mut success = true;
1365 let mut sig_idx = 0;
1366 let mut key_idx = 0;
1367
1368 while success && sig_idx < n_sigs {
1369 if key_idx >= n_keys {
1370 success = false;
1371 break;
1372 }
1373
1374 let sig_bytes = &sigs[sig_idx];
1375 let pubkey_bytes = &pubkeys[key_idx];
1376
1377 if self.check_signature_encoding(sig_bytes).is_err()
1379 || self.check_public_key_encoding(pubkey_bytes).is_err()
1380 {
1381 return Err(self.error(&format!(
1382 "{} requires correct encoding for the public key and signature.",
1383 opcode_to_name(opcode).unwrap_or("OP_CHECKMULTISIG")
1384 )));
1385 }
1386
1387 let sig_valid = if sig_bytes.is_empty() {
1388 false
1389 } else {
1390 self.verify_signature(sig_bytes, pubkey_bytes, &subscript)
1391 .unwrap_or(false)
1392 };
1393
1394 if sig_valid {
1395 sig_idx += 1;
1396 }
1397 key_idx += 1;
1398
1399 if n_sigs - sig_idx > n_keys - key_idx {
1400 success = false;
1401 }
1402 }
1403
1404 if self.stack.is_empty() {
1406 return Err(self.error(&format!(
1407 "{} requires an extra item (dummy) to be on the stack.",
1408 opcode_to_name(opcode).unwrap_or("OP_CHECKMULTISIG")
1409 )));
1410 }
1411 let dummy = self.pop_stack()?;
1412 if !dummy.is_empty() {
1413 return Err(self.error(&format!(
1414 "{} requires the extra stack item (dummy) to be empty.",
1415 opcode_to_name(opcode).unwrap_or("OP_CHECKMULTISIG")
1416 )));
1417 }
1418
1419 self.push_stack(if success { vec![1] } else { vec![] })?;
1420
1421 if opcode == OP_CHECKMULTISIGVERIFY {
1422 if !success {
1423 return Err(self.error(
1424 "OP_CHECKMULTISIGVERIFY requires that a sufficient number of valid signatures are provided.",
1425 ));
1426 }
1427 self.pop_stack()?;
1428 }
1429
1430 Ok(())
1431 }
1432
1433 fn check_signature_encoding(&self, sig: &[u8]) -> Result<(), ScriptEvaluationError> {
1438 if sig.is_empty() {
1439 return Ok(());
1440 }
1441
1442 if !is_valid_signature_encoding(sig) {
1444 return Err(self.error("The signature format is invalid."));
1445 }
1446
1447 let tx_sig = TransactionSignature::from_checksig_format(sig)
1449 .map_err(|_| self.error("The signature format is invalid."))?;
1450
1451 if self.require_low_s && !tx_sig.has_low_s() {
1452 return Err(self.error("The signature must have a low S value."));
1453 }
1454
1455 if (tx_sig.scope() & SIGHASH_FORKID) == 0 {
1456 return Err(self.error("The signature must use SIGHASH_FORKID."));
1457 }
1458
1459 Ok(())
1460 }
1461
1462 fn check_public_key_encoding(&self, pubkey: &[u8]) -> Result<(), ScriptEvaluationError> {
1463 if pubkey.is_empty() {
1464 return Err(self.error("Public key is empty."));
1465 }
1466
1467 if pubkey.len() < 33 {
1468 return Err(self.error("The public key is too short, it must be at least 33 bytes."));
1469 }
1470
1471 if pubkey[0] == 0x04 {
1472 if pubkey.len() != 65 {
1473 return Err(self.error("The non-compressed public key must be 65 bytes."));
1474 }
1475 } else if pubkey[0] == 0x02 || pubkey[0] == 0x03 {
1476 if pubkey.len() != 33 {
1477 return Err(self.error("The compressed public key must be 33 bytes."));
1478 }
1479 } else {
1480 return Err(self.error("The public key is in an unknown format."));
1481 }
1482
1483 PublicKey::from_bytes(pubkey)
1485 .map_err(|_| self.error("The public key is in an unknown format."))?;
1486
1487 Ok(())
1488 }
1489
1490 fn build_subscript(&self, sig_bytes: &[u8]) -> Result<Script, ScriptEvaluationError> {
1491 let base_script = match self.context {
1492 ExecutionContext::UnlockingScript => self.unlocking_script.as_script().clone(),
1493 ExecutionContext::LockingScript => self.locking_script.as_script().clone(),
1494 };
1495
1496 let start_idx = self.last_code_separator.map(|i| i + 1).unwrap_or(0);
1497 let chunks = base_script.chunks();
1498 let mut subscript_chunks: Vec<ScriptChunk> = chunks.into_iter().skip(start_idx).collect();
1499 if self.context == ExecutionContext::UnlockingScript {
1505 subscript_chunks.extend(self.locking_script.as_script().chunks());
1506 }
1507 let mut subscript = Script::from_chunks(subscript_chunks);
1508
1509 let mut sig_script = Script::new();
1511 sig_script.write_bin(sig_bytes);
1512 subscript.find_and_delete(&sig_script);
1513
1514 Ok(subscript)
1515 }
1516
1517 fn verify_signature(
1518 &self,
1519 sig_bytes: &[u8],
1520 pubkey_bytes: &[u8],
1521 subscript: &Script,
1522 ) -> Result<bool, ScriptEvaluationError> {
1523 let tx_sig = match TransactionSignature::from_checksig_format(sig_bytes) {
1525 Ok(s) => s,
1526 Err(_) => return Ok(false),
1527 };
1528
1529 let pubkey = match PublicKey::from_bytes(pubkey_bytes) {
1530 Ok(p) => p,
1531 Err(_) => return Ok(false),
1532 };
1533
1534 let inputs = self.build_inputs_array();
1536
1537 let sighash = compute_sighash_for_signing(&SighashParams {
1539 version: self.transaction_version,
1540 inputs: &inputs,
1541 outputs: &self.outputs,
1542 locktime: self.lock_time,
1543 input_index: self.input_index,
1544 subscript: &subscript.to_binary(),
1545 satoshis: self.source_satoshis,
1546 scope: tx_sig.scope(),
1547 });
1548
1549 Ok(pubkey.verify(&sighash, tx_sig.signature()))
1551 }
1552
1553 fn build_inputs_array(&self) -> Vec<TxInput> {
1554 let mut inputs = Vec::with_capacity(self.other_inputs.len() + 1);
1555
1556 for (i, other) in self.other_inputs.iter().enumerate() {
1558 if i == self.input_index {
1559 inputs.push(TxInput {
1561 txid: self.source_txid,
1562 output_index: self.source_output_index,
1563 script: self.unlocking_script.to_binary(),
1564 sequence: self.input_sequence,
1565 });
1566 }
1567 inputs.push(other.clone());
1568 }
1569
1570 if self.input_index >= self.other_inputs.len() {
1572 inputs.push(TxInput {
1573 txid: self.source_txid,
1574 output_index: self.source_output_index,
1575 script: self.unlocking_script.to_binary(),
1576 sequence: self.input_sequence,
1577 });
1578 }
1579
1580 inputs
1581 }
1582
1583 fn push_stack(&mut self, item: Vec<u8>) -> Result<(), ScriptEvaluationError> {
1588 self.ensure_stack_mem(item.len())?;
1589 self.stack_mem += item.len();
1590 self.stack.push(item);
1591 Ok(())
1592 }
1593
1594 fn push_stack_copy(&mut self, item: &[u8]) -> Result<(), ScriptEvaluationError> {
1595 self.push_stack(item.to_vec())
1596 }
1597
1598 fn pop_stack(&mut self) -> Result<Vec<u8>, ScriptEvaluationError> {
1599 if self.stack.is_empty() {
1600 return Err(self.error("Attempted to pop from an empty stack."));
1601 }
1602 let item = self.stack.pop().unwrap();
1603 self.stack_mem -= item.len();
1604 Ok(item)
1605 }
1606
1607 fn stack_top(&self) -> Result<&Vec<u8>, ScriptEvaluationError> {
1608 if self.stack.is_empty() {
1609 return Err(self.error("Stack is empty."));
1610 }
1611 Ok(&self.stack[self.stack.len() - 1])
1612 }
1613
1614 fn stack_top_n(&self, n: usize) -> Result<&Vec<u8>, ScriptEvaluationError> {
1615 if self.stack.len() < n {
1616 return Err(self.error(&format!(
1617 "Stack underflow accessing element at index {}. Stack length is {}.",
1618 n,
1619 self.stack.len()
1620 )));
1621 }
1622 Ok(&self.stack[self.stack.len() - n])
1623 }
1624
1625 fn push_alt_stack(&mut self, item: Vec<u8>) -> Result<(), ScriptEvaluationError> {
1626 self.ensure_alt_stack_mem(item.len())?;
1627 self.alt_stack_mem += item.len();
1628 self.alt_stack.push(item);
1629 Ok(())
1630 }
1631
1632 fn pop_alt_stack(&mut self) -> Result<Vec<u8>, ScriptEvaluationError> {
1633 if self.alt_stack.is_empty() {
1634 return Err(self.error("Attempted to pop from an empty alt stack."));
1635 }
1636 let item = self.alt_stack.pop().unwrap();
1637 self.alt_stack_mem -= item.len();
1638 Ok(item)
1639 }
1640
1641 fn ensure_stack_mem(&self, additional: usize) -> Result<(), ScriptEvaluationError> {
1642 if self.stack_mem + additional > self.memory_limit {
1643 return Err(self.resource_error(ScriptResource::Stack, self.stack_mem + additional));
1644 }
1645 Ok(())
1646 }
1647
1648 fn ensure_alt_stack_mem(&self, additional: usize) -> Result<(), ScriptEvaluationError> {
1649 if self.alt_stack_mem + additional > self.memory_limit {
1650 return Err(
1651 self.resource_error(ScriptResource::AltStack, self.alt_stack_mem + additional)
1652 );
1653 }
1654 Ok(())
1655 }
1656
1657 fn resource_error(&self, resource: ScriptResource, attempted: usize) -> ScriptEvaluationError {
1661 let label = match resource {
1662 ScriptResource::Stack => "Stack memory usage",
1663 ScriptResource::AltStack => "Alt stack memory usage",
1664 ScriptResource::ElementSize => "Script element allocation",
1665 };
1666 self.error(&format!("{label} has exceeded {} bytes", self.memory_limit))
1667 .with_resource_limit(ScriptResourceLimit {
1668 resource,
1669 limit: self.memory_limit,
1670 attempted,
1671 })
1672 }
1673
1674 fn error(&self, message: &str) -> ScriptEvaluationError {
1679 ScriptEvaluationError::new(
1680 message,
1681 to_hex(&self.source_txid),
1682 self.source_output_index,
1683 self.context,
1684 self.program_counter,
1685 self.stack.clone(),
1686 self.alt_stack.clone(),
1687 self.if_stack.clone(),
1688 self.stack_mem,
1689 self.alt_stack_mem,
1690 )
1691 }
1692}
1693
1694fn is_opcode_disabled(op: u8) -> bool {
1700 matches!(op, OP_2MUL | OP_2DIV | OP_VER | OP_VERIF | OP_VERNOTIF)
1701}
1702
1703fn is_chunk_minimal_push(chunk: &ScriptChunk) -> bool {
1705 let data = match &chunk.data {
1706 Some(d) => d,
1707 None => return true,
1708 };
1709 let op = chunk.op;
1710
1711 if data.is_empty() {
1712 return op == OP_0;
1713 }
1714
1715 if data.len() == 1 && data[0] >= 1 && data[0] <= 16 {
1716 return op == OP_1 + (data[0] - 1);
1717 }
1718
1719 if data.len() == 1 && data[0] == 0x81 {
1720 return op == OP_1NEGATE;
1721 }
1722
1723 if data.len() <= 75 {
1724 return op as usize == data.len();
1725 }
1726
1727 if data.len() <= 255 {
1728 return op == OP_PUSHDATA1;
1729 }
1730
1731 if data.len() <= 65535 {
1732 return op == OP_PUSHDATA2;
1733 }
1734
1735 true
1736}
1737
1738fn is_valid_signature_encoding(sig: &[u8]) -> bool {
1740 if sig.len() < 9 || sig.len() > 73 {
1741 return false;
1742 }
1743
1744 if sig[0] != 0x30 {
1746 return false;
1747 }
1748
1749 if sig[1] as usize != sig.len() - 3 {
1751 return false;
1752 }
1753
1754 if sig[2] != 0x02 {
1756 return false;
1757 }
1758
1759 let r_len = sig[3] as usize;
1760 if r_len == 0 || 5 + r_len >= sig.len() {
1761 return false;
1762 }
1763
1764 let s_offset = 4 + r_len;
1766 if sig[s_offset] != 0x02 {
1767 return false;
1768 }
1769
1770 let s_len = sig[s_offset + 1] as usize;
1771 if s_len == 0 {
1772 return false;
1773 }
1774
1775 if r_len + s_len + 7 != sig.len() {
1777 return false;
1778 }
1779
1780 if (sig[4] & 0x80) != 0 {
1782 return false;
1783 }
1784
1785 if r_len > 1 && sig[4] == 0x00 && (sig[5] & 0x80) == 0 {
1787 return false;
1788 }
1789
1790 let s_value_offset = s_offset + 2;
1792 if (sig[s_value_offset] & 0x80) != 0 {
1793 return false;
1794 }
1795
1796 if s_len > 1 && sig[s_value_offset] == 0x00 && (sig[s_value_offset + 1] & 0x80) == 0 {
1798 return false;
1799 }
1800
1801 true
1802}
1803
1804#[cfg(test)]
1805mod tests {
1806 use super::*;
1807
1808 #[test]
1809 fn test_is_opcode_disabled() {
1810 assert!(is_opcode_disabled(OP_2MUL));
1811 assert!(is_opcode_disabled(OP_2DIV));
1812 assert!(is_opcode_disabled(OP_VER));
1813 assert!(is_opcode_disabled(OP_VERIF));
1814 assert!(is_opcode_disabled(OP_VERNOTIF));
1815
1816 assert!(!is_opcode_disabled(OP_DUP));
1817 assert!(!is_opcode_disabled(OP_MUL));
1818 assert!(!is_opcode_disabled(OP_CAT));
1819 }
1820
1821 #[test]
1822 fn test_is_chunk_minimal_push() {
1823 let chunk = ScriptChunk::new(OP_0, Some(vec![]));
1825 assert!(is_chunk_minimal_push(&chunk));
1826
1827 let chunk = ScriptChunk::new(3, Some(vec![1, 2, 3]));
1829 assert!(is_chunk_minimal_push(&chunk));
1830
1831 let chunk = ScriptChunk::new(OP_1, Some(vec![1]));
1833 assert!(is_chunk_minimal_push(&chunk));
1834
1835 let chunk = ScriptChunk::new(1, Some(vec![1]));
1837 assert!(!is_chunk_minimal_push(&chunk));
1838 }
1839
1840 #[test]
1841 fn test_simple_stack_script() {
1842 let locking = LockingScript::from_asm("OP_ADD OP_3 OP_EQUAL").unwrap();
1845 let unlocking = UnlockingScript::from_asm("OP_1 OP_2").unwrap();
1846
1847 let mut spend = Spend::new(SpendParams {
1848 source_txid: [0u8; 32],
1849 source_output_index: 0,
1850 source_satoshis: 0,
1851 locking_script: locking,
1852 transaction_version: 1,
1853 other_inputs: vec![],
1854 outputs: vec![],
1855 input_index: 0,
1856 unlocking_script: unlocking,
1857 input_sequence: 0xffffffff,
1858 lock_time: 0,
1859 memory_limit: None,
1860 });
1861
1862 let result = spend.validate();
1863 assert!(result.is_ok(), "Expected valid spend, got {:?}", result);
1864 }
1865
1866 #[test]
1867 fn test_if_else_endif() {
1868 let locking = LockingScript::from_asm("OP_IF OP_2 OP_ELSE OP_3 OP_ENDIF").unwrap();
1871 let unlocking = UnlockingScript::from_asm("OP_1").unwrap();
1872
1873 let mut spend = Spend::new(SpendParams {
1874 source_txid: [0u8; 32],
1875 source_output_index: 0,
1876 source_satoshis: 0,
1877 locking_script: locking,
1878 transaction_version: 1,
1879 other_inputs: vec![],
1880 outputs: vec![],
1881 input_index: 0,
1882 unlocking_script: unlocking,
1883 input_sequence: 0xffffffff,
1884 lock_time: 0,
1885 memory_limit: None,
1886 });
1887
1888 let result = spend.validate();
1889 assert!(result.is_ok(), "Expected valid spend, got {:?}", result);
1890 }
1891
1892 #[test]
1893 fn test_hash_operations() {
1894 let locking = LockingScript::from_asm("OP_SHA256 OP_SIZE OP_NIP 20 OP_EQUAL").unwrap();
1898 let unlocking = UnlockingScript::from_asm("00").unwrap();
1899
1900 let mut spend = Spend::new(SpendParams {
1901 source_txid: [0u8; 32],
1902 source_output_index: 0,
1903 source_satoshis: 0,
1904 locking_script: locking,
1905 transaction_version: 1,
1906 other_inputs: vec![],
1907 outputs: vec![],
1908 input_index: 0,
1909 unlocking_script: unlocking,
1910 input_sequence: 0xffffffff,
1911 lock_time: 0,
1912 memory_limit: None,
1913 });
1914
1915 let result = spend.validate();
1916 assert!(result.is_ok(), "Expected valid spend, got {:?}", result);
1917 }
1918
1919 #[test]
1920 fn test_failing_script() {
1921 let locking = LockingScript::from_asm("OP_0").unwrap();
1923 let unlocking = UnlockingScript::new();
1924
1925 let mut spend = Spend::new(SpendParams {
1926 source_txid: [0u8; 32],
1927 source_output_index: 0,
1928 source_satoshis: 0,
1929 locking_script: locking,
1930 transaction_version: 1,
1931 other_inputs: vec![],
1932 outputs: vec![],
1933 input_index: 0,
1934 unlocking_script: unlocking,
1935 input_sequence: 0xffffffff,
1936 lock_time: 0,
1937 memory_limit: None,
1938 });
1939
1940 let result = spend.validate();
1941 assert!(result.is_err(), "Expected failed validation");
1942 }
1943}