# Class BSV::Script::Interpreter <a id="class-BSV-Script-Interpreter"></a>

**Inherits:** `Object`
**Includes:** `BSV::Script::Interpreter::Operations::Arithmetic`, `BSV::Script::Interpreter::Operations::Bitwise`, `BSV::Script::Interpreter::Operations::Crypto`, `BSV::Script::Interpreter::Operations::DataPush`, `BSV::Script::Interpreter::Operations::FlowControl`, `BSV::Script::Interpreter::Operations::Splice`, `BSV::Script::Interpreter::Operations::StackOps`

Bitcoin script interpreter implementing the post-Genesis BSV script engine.

Evaluates unlock + lock script pairs, supporting the full BSV opcode set
including restored opcodes (OP_MUL, OP_LSHIFT, OP_CAT, etc.) and post-Genesis
rules (OP_RETURN as early success, no script size limits).

**@example Evaluate scripts without transaction context**
```ruby
BSV::Script::Interpreter.evaluate(unlock_script, lock_script)
```

**@example Verify a transaction input**
```ruby
BSV::Script::Interpreter.verify(
  tx: transaction, input_index: 0,
  unlock_script: input.script, lock_script: prev_output.script,
  satoshis: prev_output.satoshis
)
```

## Constants
### `CHRONICLE_ONLY_OPCODES` <a id="constant-CHRONICLE_ONLY_OPCODES"></a> <a id="CHRONICLE_ONLY_OPCODES-constant"></a>
Opcodes that require Chronicle to execute. With explicit flags but without
UTXO_AFTER_CHRONICLE, executing any of these raises DISABLED_OPCODE. OP_VER /
OP_VERIF / OP_VERNOTIF are included because pre-Chronicle they're either
reserved (OP_VER) or behave as a conditional-only NOP in non-executing
branches — execution itself is disabled. Mirrors TS Spend.ts (lines ~694-709)
and Go IsDisabled.

### `CONDITIONAL_OPCODES` <a id="constant-CONDITIONAL_OPCODES"></a> <a id="CONDITIONAL_OPCODES-constant"></a>
Conditional opcodes must be processed even in non-executing branches to
maintain correct nesting depth. OP_VERIF and OP_VERNOTIF are included here
because they open conditional blocks (like OP_IF/OP_NOTIF) and must be
dispatched to track nesting depth even when the branch is not executing. This
matches the Go SDK's IsConditional() function.

### `KNOWN_FLAGS` <a id="constant-KNOWN_FLAGS"></a> <a id="KNOWN_FLAGS-constant"></a>
Recognised verification flag names. Catches typos (a misspelled `SIGPUSHONLLY`
would otherwise silently disable enforcement) and forces any new flag to be
declared here before use. The set is the union of flags appearing in the
canonical conformance corpus and the Bitcoin Core
<code>script_tests.json</code> fixture, plus the witness/taproot family that
downstream callers filter out before reaching the interpreter.

### `MAX_CONDITIONAL_DEPTH` <a id="constant-MAX_CONDITIONAL_DEPTH"></a> <a id="MAX_CONDITIONAL_DEPTH-constant"></a>
Maximum nesting depth for OP_IF / OP_NOTIF blocks. Prevents interpreter stack
overflow from deeply nested conditionals.

### `VER_CONDITIONAL_OPCODES` <a id="constant-VER_CONDITIONAL_OPCODES"></a> <a id="VER_CONDITIONAL_OPCODES-constant"></a>
The two version-conditional opcodes — extracted to module-level constants so
the interpreter hot path (every conditional dispatch / every executed chunk)
doesn't allocate a fresh Array per call.

## Attributes
### `astack` [R] <a id="attribute-i-astack"></a> <a id="astack-instance_method"></a>
Returns the value of attribute astack.

### `dstack` [R] <a id="attribute-i-dstack"></a> <a id="dstack-instance_method"></a>
Returns the value of attribute dstack.

## Public Class Methods
### `evaluate(unlock_script, lock_script, flags: = nil, tx_version: = nil)` <a id="method-c-evaluate"></a> <a id="evaluate-class_method"></a>
Evaluate unlock + lock scripts without transaction context.

Signature operations will always fail (no sighash available).
- **@param** `unlock_script` [Script] the unlocking script
- **@param** `lock_script` [Script] the locking script
- **@param** `flags` [Array<String>, Set<String>, nil] explicit verification flags
(e.g. +SIGPUSHONLY+, +CLEANSTACK+, +UTXO_AFTER_CHRONICLE+). +nil+
selects relaxed (post-Chronicle) mode where malleability checks are
off; an empty +[]+ array is explicit-but-empty (pre-Genesis,
pre-Chronicle strict mode). Each flag string must appear in
{KNOWN_FLAGS} — unknown names raise +ArgumentError+.
- **@param** `tx_version` [Integer, nil] transaction version made available to
+OP_VER+/+OP_VERIF+/+OP_VERNOTIF+ when no transaction is supplied
- **@raise** [ScriptError] if script execution fails
- **@raise** [ArgumentError] if +flags+ contains an unknown name or
+tx_version+ is not a valid uint32
- **@return** [Boolean] +true+ if execution succeeds

**@example Relaxed mode (post-Chronicle defaults, no malleability checks)**
```ruby
Interpreter.evaluate(unlock, lock)                  # flags defaults to nil
```

**@example Explicit flag set**
```ruby
Interpreter.evaluate(unlock, lock, flags: %w[UTXO_AFTER_GENESIS CLEANSTACK])
```

**@example Explicit-but-empty (pre-Genesis, pre-Chronicle, strict)**
```ruby
Interpreter.evaluate(unlock, lock, flags: [])       # NOT the same as nil
```

### `verify(tx:, input_index:, unlock_script:, lock_script:, satoshis:, flags: = nil)` <a id="method-c-verify"></a> <a id="verify-class_method"></a>
Verify a transaction input by evaluating its scripts.
- **@param** `tx` [Transaction::Tx] the transaction being verified
- **@param** `input_index` [Integer] the input index within the transaction
- **@param** `unlock_script` [Script] the input's unlocking script
- **@param** `lock_script` [Script] the previous output's locking script
- **@param** `satoshis` [Integer] the value of the previous output in satoshis
- **@param** `flags` [Array<String>, Set<String>, nil] explicit verification flags
(see {.evaluate}). Production callers (e.g. +Tx#verify_input+) do not
pass +flags+, so mainnet transaction validation always runs in
relaxed mode; the parameter exists for conformance-corpus and
regression-vector runners that need to drive specific flag combinations.
- **@raise** [ScriptError] if script execution fails
- **@raise** [ArgumentError] if +flags+ contains an unknown name
- **@return** [Boolean] +true+ if verification succeeds

## Public Instance Methods
### `execute()` <a id="method-i-execute"></a> <a id="execute-instance_method"></a>
Not documented.
