@smartledger/bsv 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,12 +6,13 @@
6
6
 
7
7
  1. [Quick Start](#quick-start)
8
8
  2. [Core Classes](#core-classes)
9
- 3. [Interface Functions (29 Total)](#interface-functions)
9
+ 3. [Interface Functions (52 Total)](#interface-functions)
10
10
  4. [JavaScript-to-Script Framework](#javascript-to-script-framework)
11
11
  5. [CovenantBuilder API (61 Methods)](#covenantbuilder-api)
12
12
  6. [Opcode Mapping System](#opcode-mapping-system)
13
- 7. [Real-World Examples](#real-world-examples)
14
- 8. [Error Handling](#error-handling)
13
+ 7. [Debug and Analysis Tools](#debug-and-analysis-tools)
14
+ 8. [Real-World Examples](#real-world-examples)
15
+ 9. [Error Handling](#error-handling)
15
16
 
16
17
  ---
17
18
 
@@ -598,6 +599,113 @@ console.log('Result stack:', newStack) // ['05'] (2 + 3 = 5)
598
599
 
599
600
  ---
600
601
 
602
+ ## Debug and Analysis Tools
603
+
604
+ ### Stack Examination
605
+
606
+ **Examine stack states during script execution**
607
+
608
+ ```javascript
609
+ // Examine stack evolution step-by-step
610
+ const lockingScript = "76a914" + "89abcdef".repeat(5) + "88ac" // P2PKH
611
+ const unlockingScript = "47" + "30440220".repeat(4) + "01" // Signature
612
+
613
+ const success = SmartContract.examineStack(lockingScript, unlockingScript)
614
+ // Outputs:
615
+ // šŸ” STACK EXAMINATION TOOL
616
+ // 🧩 Step 1: PUSH (signature)
617
+ // Stack: ['30440220...']
618
+ // 🧩 Step 2: OP_DUP
619
+ // Stack: ['30440220...', '30440220...']
620
+ // ... continues through all opcodes
621
+ ```
622
+
623
+ ### Script Debugging
624
+
625
+ **Interactive script debugging with step-by-step execution**
626
+
627
+ ```javascript
628
+ // Parse script from ASM or HEX
629
+ const unlocking = SmartContract.parseScript("OP_1 OP_2")
630
+ const locking = SmartContract.parseScript("OP_ADD OP_3 OP_EQUAL")
631
+
632
+ // Debug with full verification
633
+ SmartContract.debugScriptExecution(unlocking, locking, {
634
+ stepMode: false // Set to true for interactive step-by-step
635
+ })
636
+ // Outputs:
637
+ // šŸ” SCRIPT INTERPRETER DEBUGGER (FULL RUN)
638
+ // šŸ” Locking Script: OP_ADD OP_3 OP_EQUAL
639
+ // šŸ”“ Unlocking Script: OP_1 OP_2
640
+ // āœ… Result: TRUE (Success)
641
+ ```
642
+
643
+ ### Stack State Analysis
644
+
645
+ **Manual stack inspection and formatting**
646
+
647
+ ```javascript
648
+ const stack = [Buffer.from('01', 'hex'), Buffer.from('02', 'hex')]
649
+ const altstack = [Buffer.from('ff', 'hex')]
650
+
651
+ SmartContract.printStack(stack, altstack)
652
+ // Output:
653
+ // Stack: ['01', '02']
654
+ // AltStack: ['ff']
655
+ ```
656
+
657
+ ### Advanced Script Analysis
658
+
659
+ **Comprehensive script analysis and optimization**
660
+
661
+ ```javascript
662
+ // Analyze script complexity and find optimizations
663
+ const script = bsv.Script.fromASM("OP_DUP OP_DUP OP_DROP OP_HASH160")
664
+
665
+ const analysis = SmartContract.analyzeComplexity(script)
666
+ console.log('Complexity score:', analysis.score)
667
+ console.log('Optimization suggestions:', analysis.suggestions)
668
+
669
+ const optimized = SmartContract.optimizeScript(script)
670
+ console.log('Original ASM:', script.toASM())
671
+ console.log('Optimized ASM:', optimized.toASM())
672
+
673
+ // Explain script in human-readable format
674
+ const explanation = SmartContract.explainScript(script)
675
+ console.log('Script explanation:', explanation)
676
+ ```
677
+
678
+ ### Batch Testing
679
+
680
+ **Test multiple scripts efficiently**
681
+
682
+ ```javascript
683
+ const scripts = [
684
+ {
685
+ name: 'P2PKH Test',
686
+ unlocking: '47304402...',
687
+ locking: '76a914...88ac',
688
+ expectedResult: true
689
+ },
690
+ {
691
+ name: 'Multi-sig Test',
692
+ unlocking: '004730440...',
693
+ locking: '52210...53ae',
694
+ expectedResult: true
695
+ }
696
+ ]
697
+
698
+ const results = SmartContract.batchTestScripts(scripts, {
699
+ verbose: true,
700
+ stopOnFailure: false
701
+ })
702
+
703
+ console.log('Batch test results:', results)
704
+ // { passed: 2, failed: 0, results: [...] }
705
+ ```
706
+
707
+ ---
708
+
601
709
  ## Real-World Examples
602
710
 
603
711
  ### Example 1: Value-Preserving Covenant
@@ -15,6 +15,9 @@
15
15
  * - ScriptTester: Local script execution and debugging capabilities
16
16
  * - CovenantBuilder: JavaScript-to-Bitcoin Script covenant generator
17
17
  * - OpcodeMap: Comprehensive Bitcoin Script opcode mapping
18
+ * - ScriptUtils: Script analysis, conversion, and optimization utilities
19
+ * - StackExaminer: Stack state examination and step-by-step execution debugging
20
+ * - ScriptInterpreter: Interactive script debugging with full verification support
18
21
  */
19
22
 
20
23
  'use strict'
@@ -31,7 +34,9 @@ var SmartContract = {
31
34
  CovenantBuilder: require('./covenant_builder').CovenantBuilder,
32
35
  CovenantTemplates: require('./covenant_builder').CovenantTemplates,
33
36
  OpcodeMap: require('./opcode_map'),
34
- ScriptUtils: require('./script_utils')
37
+ ScriptUtils: require('./script_utils'),
38
+ StackExaminer: require('./stack_examiner'),
39
+ ScriptInterpreter: require('./script_interpreter')
35
40
  }
36
41
 
37
42
  // Convenience constructor methods
@@ -184,6 +189,36 @@ SmartContract.batchTestScripts = function(scripts, options) {
184
189
  return SmartContract.ScriptUtils.batchTestScripts(scripts, options)
185
190
  }
186
191
 
192
+ // Debug and analysis tools
193
+ SmartContract.examineStack = function(lockingHex, unlockingHex) {
194
+ return SmartContract.StackExaminer.runScript(lockingHex, unlockingHex)
195
+ }
196
+
197
+ SmartContract.debugScriptExecution = function(unlockingScript, lockingScript, options) {
198
+ options = options || {}
199
+ if (options.stepMode) {
200
+ return SmartContract.ScriptInterpreter.stepThroughScript(
201
+ SmartContract.ScriptInterpreter.parseScript(unlockingScript + ' ' + lockingScript),
202
+ new bsv.Transaction(),
203
+ true
204
+ )
205
+ } else {
206
+ return SmartContract.ScriptInterpreter.runFullEvaluation(
207
+ SmartContract.ScriptInterpreter.parseScript(unlockingScript),
208
+ SmartContract.ScriptInterpreter.parseScript(lockingScript),
209
+ new bsv.Transaction()
210
+ )
211
+ }
212
+ }
213
+
214
+ SmartContract.parseScript = function(scriptInput) {
215
+ return SmartContract.ScriptInterpreter.parseScript(scriptInput)
216
+ }
217
+
218
+ SmartContract.printStack = function(stack, altstack) {
219
+ return SmartContract.ScriptInterpreter.printStack(stack, altstack)
220
+ }
221
+
187
222
  // Quick covenant creation utility
188
223
  SmartContract.createQuickCovenant = function(type, params) {
189
224
  const builder = SmartContract.createCovenantBuilder()
@@ -305,6 +340,10 @@ SmartContract.features = {
305
340
  BATCH_TESTING: true,
306
341
  QUICK_COVENANTS: true,
307
342
  SCRIPT_EXPLANATIONS: true,
343
+ STACK_EXAMINATION: true,
344
+ SCRIPT_DEBUGGING: true,
345
+ STEP_BY_STEP_EXECUTION: true,
346
+ INTERACTIVE_DEBUGGING: true,
308
347
  PRODUCTION_READY: true
309
348
  }
310
349
 
@@ -0,0 +1,236 @@
1
+ /**
2
+ * script_interpreter_debugger.js
3
+ * ---------------------------------------------------------------
4
+ * Universal Bitcoin Script Interpreter Debugger for BSV
5
+ * Browser + Node.js compatible
6
+ * ---------------------------------------------------------------
7
+ * Usage:
8
+ * node script_interpreter_debugger.js [options]
9
+ *
10
+ * Options:
11
+ * --unlocking <hex|asm> Unlocking script (input scriptSig)
12
+ * --locking <hex|asm> Locking script (output scriptPubKey)
13
+ * --combined <hex|asm> Combined script (unlocking + locking)
14
+ * --step Step through opcode-by-opcode
15
+ * --truth Run full verification (TRUE/FALSE)
16
+ *
17
+ * Examples:
18
+ * node script_interpreter_debugger.js --locking "76a91489abcdefabbaabbaabbaabbaabbaabbaabbaabba88ac" --unlocking "4104abcd1234...ac" --truth
19
+ * node script_interpreter_debugger.js --combined "OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG" --step
20
+ */
21
+
22
+ // Browser-safe requires
23
+ let readline = null;
24
+ try {
25
+ // Only require readline in Node.js environment
26
+ if (typeof window === 'undefined' && typeof require !== 'undefined') {
27
+ readline = require("readline");
28
+ }
29
+ } catch (err) {
30
+ // Gracefully handle missing readline in browser
31
+ readline = null;
32
+ }
33
+
34
+ const bsv = (typeof window !== 'undefined' && window.bsv) ? window.bsv : require("../../index.js");
35
+
36
+ // Debug: Show Script Interpreter module structure (uncomment to inspect)
37
+ // const ScriptInterpreter = bsv.Script.Interpreter;
38
+ // console.log("Script Interpreter Module:", ScriptInterpreter);
39
+ /**
40
+ * Parse input as either ASM or HEX.
41
+ */
42
+ function parseScript(input) {
43
+ if (!input) return new bsv.Script();
44
+ const trimmed = input.trim();
45
+ const isHex = /^[0-9a-fA-F]+$/.test(trimmed.replace(/\s+/g, ""));
46
+ try {
47
+ return isHex
48
+ ? bsv.Script.fromHex(trimmed)
49
+ : bsv.Script.fromASM(trimmed);
50
+ } catch (err) {
51
+ console.error("āŒ Error parsing script:", err.message);
52
+ process.exit(1);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Display stack contents in readable format.
58
+ */
59
+ function printStack(stack, altstack = []) {
60
+ const fmt = (b) => (b.length ? b.toString("hex") : "(empty)");
61
+ const top = stack.map(fmt);
62
+ console.log("Stack:", top.length ? top : ["(empty)"]);
63
+ if (altstack.length) console.log("AltStack:", altstack.map(fmt));
64
+ }
65
+
66
+ /**
67
+ * Execute script step-by-step with optional interactivity.
68
+ */
69
+ async function stepThroughScript(combinedScript, tx, verbose = true) {
70
+ const interpreter = new bsv.Script.Interpreter();
71
+ interpreter.script = combinedScript;
72
+ interpreter.tx = tx;
73
+ interpreter.nIn = 0;
74
+ interpreter.flags = bsv.Script.Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID;
75
+
76
+ const chunks = combinedScript.chunks;
77
+
78
+ // Browser compatibility check for readline
79
+ let rl = null;
80
+ if (readline && typeof process !== 'undefined' && process.stdin) {
81
+ rl = readline.createInterface({
82
+ input: process.stdin,
83
+ output: process.stdout,
84
+ });
85
+ }
86
+
87
+ console.log("===========================================");
88
+ console.log("šŸ” SCRIPT INTERPRETER DEBUGGER (STEP MODE)");
89
+ console.log("===========================================\n");
90
+ console.log("Script:", combinedScript.toASM());
91
+ console.log("-------------------------------------------");
92
+
93
+ for (let i = 0; i < chunks.length; i++) {
94
+ const chunk = chunks[i];
95
+ const opname = bsv.Opcode.reverseMap[chunk.opcodenum] || "PUSH";
96
+
97
+ if (verbose && rl) {
98
+ await new Promise((resolve) =>
99
+ rl.question(`\n[${i + 1}/${chunks.length}] Step (${opname}) — press Enter to execute...`, resolve)
100
+ );
101
+ } else if (verbose) {
102
+ console.log(`\n[${i + 1}/${chunks.length}] Step (${opname})`);
103
+ }
104
+
105
+ try {
106
+ // Check if step method exists (compatibility check)
107
+ if (typeof interpreter.step === 'function') {
108
+ interpreter.step();
109
+ } else {
110
+ console.log("āš ļø Step-by-step execution not supported in this BSV version");
111
+ console.log("šŸ’” Consider using runFullEvaluation instead");
112
+ break;
113
+ }
114
+
115
+ console.log(`🧩 Executed: ${opname}`);
116
+ printStack(interpreter.stack, interpreter.altstack);
117
+ } catch (err) {
118
+ console.log(`āš ļø Error executing ${opname}: ${err.message}`);
119
+ break;
120
+ }
121
+ }
122
+
123
+ if (rl) rl.close();
124
+ console.log("\n===========================================");
125
+ console.log("āœ… Final Stack State:");
126
+ printStack(interpreter.stack || [], interpreter.altstack || []);
127
+ console.log("===========================================");
128
+ }
129
+
130
+ /**
131
+ * Run complete truth evaluation (non-interactive)
132
+ */
133
+ function runFullEvaluation(unlockingScript, lockingScript, tx) {
134
+ console.log("===========================================");
135
+ console.log("šŸ” SCRIPT INTERPRETER DEBUGGER (FULL RUN)");
136
+ console.log("===========================================\n");
137
+
138
+ const interpreter = new bsv.Script.Interpreter();
139
+
140
+ // For smartledger-bsv, need to provide satoshisBN parameter
141
+ const satoshisBN = new bsv.crypto.BN(100000); // 100,000 satoshis
142
+
143
+ const verified = interpreter.verify(
144
+ unlockingScript,
145
+ lockingScript,
146
+ tx,
147
+ 0,
148
+ bsv.Script.Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID,
149
+ satoshisBN
150
+ );
151
+
152
+ console.log("šŸ” Locking Script:", lockingScript.toASM());
153
+ console.log("šŸ”“ Unlocking Script:", unlockingScript.toASM());
154
+ console.log("-------------------------------------------");
155
+ console.log("āœ… Result:", verified ? "TRUE (Success)" : "āŒ FALSE (Failure)");
156
+ console.log("Final Stack:", interpreter.stack.map((b) => b.toString("hex")));
157
+ console.log("AltStack:", interpreter.altstack.map((b) => b.toString("hex")));
158
+ console.log("===========================================");
159
+ }
160
+
161
+ /**
162
+ * Main entrypoint
163
+ */
164
+ async function main() {
165
+ // Browser compatibility check
166
+ if (typeof process === 'undefined' || !process.argv) {
167
+ console.log("āš™ļø CLI mode not available in browser environment");
168
+ return;
169
+ }
170
+
171
+ const args = process.argv.slice(2);
172
+ const getArg = (name) => {
173
+ const idx = args.indexOf(name);
174
+ return idx !== -1 && args[idx + 1] ? args[idx + 1] : null;
175
+ };
176
+
177
+ const unlockingInput = getArg("--unlocking");
178
+ const lockingInput = getArg("--locking");
179
+ const combinedInput = getArg("--combined");
180
+ const stepMode = args.includes("--step");
181
+ const truthMode = args.includes("--truth");
182
+
183
+ // Build scripts
184
+ let unlockingScript, lockingScript, combinedScript;
185
+ if (combinedInput) {
186
+ combinedScript = parseScript(combinedInput);
187
+ } else {
188
+ unlockingScript = parseScript(unlockingInput);
189
+ lockingScript = parseScript(lockingInput);
190
+ const combinedBuf = Buffer.concat([
191
+ unlockingScript.toBuffer(),
192
+ lockingScript.toBuffer(),
193
+ ]);
194
+ combinedScript = bsv.Script.fromBuffer(combinedBuf);
195
+ }
196
+
197
+ // Dummy TX context for interpreter
198
+ const tx = new bsv.Transaction();
199
+
200
+ // Create proper input with UTXO information
201
+ const dummyInput = new bsv.Transaction.Input({
202
+ prevTxId: '0'.repeat(64),
203
+ outputIndex: 0,
204
+ script: bsv.Script.empty(),
205
+ satoshis: 100000,
206
+ output: new bsv.Transaction.Output({
207
+ satoshis: 100000,
208
+ script: bsv.Script.empty()
209
+ })
210
+ });
211
+
212
+ tx.addInput(dummyInput);
213
+ tx.addOutput(new bsv.Transaction.Output({ satoshis: 100000, script: bsv.Script.empty() }));
214
+
215
+ if (stepMode) {
216
+ await stepThroughScript(combinedScript, tx, true);
217
+ } else if (truthMode) {
218
+ runFullEvaluation(unlockingScript || bsv.Script.empty(), lockingScript || bsv.Script.empty(), tx);
219
+ } else {
220
+ console.log("āš™ļø No mode specified. Use --step or --truth");
221
+ }
222
+ }
223
+
224
+ // Export functions for module usage
225
+ module.exports = {
226
+ parseScript,
227
+ printStack,
228
+ stepThroughScript,
229
+ runFullEvaluation,
230
+ main
231
+ };
232
+
233
+ // CLI execution
234
+ if (typeof require !== 'undefined' && require.main === module) {
235
+ main();
236
+ }
@@ -176,7 +176,7 @@ function scriptMetrics(script) {
176
176
  }
177
177
 
178
178
  const asm = validation.asm
179
- const operations = asm.split(' ')
179
+ const operations = asm.split(' ').filter(op => op.length > 0) // Filter out empty strings
180
180
  const size = validation.size
181
181
 
182
182
  // Analyze operation types
@@ -199,9 +199,11 @@ function scriptMetrics(script) {
199
199
  })
200
200
 
201
201
  return {
202
- size: size,
202
+ length: size, // Changed from 'size' to 'length' for consistency
203
+ size: size, // Keep both for compatibility
203
204
  operations: operations.length,
204
- opcodes: opcodeCount,
205
+ opcodeCount: opcodeCount, // Changed from 'opcodes' for clarity
206
+ opcodes: opcodeCount, // Keep both for compatibility
205
207
  dataElements: dataCount,
206
208
  estimatedCost: executionCost,
207
209
  complexity: executionCost > 50 ? 'high' : executionCost > 10 ? 'medium' : 'low',
@@ -287,13 +289,23 @@ function optimizeScript(script) {
287
289
  const originalSize = estimateScriptSize(asm)
288
290
  const optimizedSize = estimateScriptSize(optimizedASM)
289
291
 
292
+ // Create script object from optimized ASM
293
+ let optimizedScript = null
294
+ try {
295
+ optimizedScript = bsv.Script.fromASM(optimizedASM)
296
+ } catch (err) {
297
+ // If we can't create a script object, that's okay
298
+ optimizedScript = null
299
+ }
300
+
290
301
  return {
291
302
  original: asm,
292
303
  optimized: optimizedASM,
293
304
  originalSize: originalSize,
294
305
  optimizedSize: optimizedSize,
295
306
  savings: originalSize - optimizedSize,
296
- improvement: originalSize > 0 ? ((originalSize - optimizedSize) / originalSize * 100).toFixed(1) + '%' : '0%'
307
+ improvement: originalSize > 0 ? ((originalSize - optimizedSize) / originalSize * 100).toFixed(1) + '%' : '0%',
308
+ script: optimizedScript // Add the script object
297
309
  }
298
310
  } catch (error) {
299
311
  return { error: error.message }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Stack Examination Tool (Browser + Node.js compatible)
3
+ * -----------------------------------------
4
+ * Run with:
5
+ * node stack_examiner.js <locking_script_hex> <unlocking_script_hex>
6
+ *
7
+ * Example:
8
+ * node stack_examiner.js "76a91489abcdefabbaabbaabbaabbaabbaabbaabbaabba88ac" "512103abcdef..."
9
+ *
10
+ * Browser usage:
11
+ * const examiner = require('./stack_examiner.js');
12
+ * examiner.runScript(lockingHex, unlockingHex);
13
+ */
14
+
15
+ // Browser-safe require
16
+ const bsv = (typeof window !== 'undefined' && window.bsv) ? window.bsv : require('../../index.js');
17
+ const util = require('util');
18
+
19
+ function bufferToHexArray(stack) {
20
+ return stack.map((buf) => buf.toString('hex'));
21
+ }
22
+
23
+ /**
24
+ * Executes a locking/unlocking script and prints intermediate stack states.
25
+ */
26
+ function runScript(lockingHex, unlockingHex) {
27
+ console.log("===========================================");
28
+ console.log("šŸ” STACK EXAMINATION TOOL");
29
+ console.log("===========================================\n");
30
+
31
+ console.log("šŸ” Locking Script:", lockingHex);
32
+ console.log("šŸ”“ Unlocking Script:", unlockingHex);
33
+ console.log("-------------------------------------------");
34
+
35
+ try {
36
+ const lockingScript = bsv.Script.fromHex(lockingHex);
37
+ const unlockingScript = bsv.Script.fromHex(unlockingHex);
38
+
39
+ const combined = bsv.Script.fromBuffer(
40
+ Buffer.concat([unlockingScript.toBuffer(), lockingScript.toBuffer()])
41
+ );
42
+
43
+ const interpreter = new bsv.Script.Interpreter();
44
+ const tx = new bsv.Transaction();
45
+
46
+ // Create proper transaction context
47
+ const dummyInput = new bsv.Transaction.Input({
48
+ prevTxId: '0'.repeat(64),
49
+ outputIndex: 0,
50
+ script: bsv.Script.empty()
51
+ });
52
+
53
+ tx.addInput(dummyInput);
54
+ tx.addOutput(new bsv.Transaction.Output({
55
+ satoshis: 100000,
56
+ script: lockingScript
57
+ }));
58
+
59
+ const scriptChunks = combined.chunks;
60
+ const sandbox = new bsv.Script.Interpreter();
61
+ sandbox.script = combined;
62
+ sandbox.tx = tx;
63
+ sandbox.nIn = 0;
64
+ sandbox.flags = bsv.Script.Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID;
65
+
66
+ // Step through each opcode
67
+ for (let i = 0; i < scriptChunks.length; i++) {
68
+ const chunk = scriptChunks[i];
69
+ try {
70
+ // Check if step method exists (compatibility check)
71
+ if (typeof sandbox.step === 'function') {
72
+ sandbox.step();
73
+ } else {
74
+ console.log("āš ļø Step-by-step execution not supported in this BSV version");
75
+ break;
76
+ }
77
+
78
+ console.log(`\n🧩 Step ${i + 1}: ${bsv.Opcode.reverseMap[chunk.opcodenum] || 'PUSH'}`);
79
+ console.log("Stack:", bufferToHexArray(sandbox.stack));
80
+ console.log("AltStack:", bufferToHexArray(sandbox.altstack));
81
+ } catch (err) {
82
+ console.log(`āš ļø Error executing opcode ${i + 1}:`, err.message);
83
+ break;
84
+ }
85
+ }
86
+
87
+ // Final verification with proper satoshis parameter
88
+ const satoshisBN = new bsv.crypto.BN(100000);
89
+ const verified = interpreter.verify(
90
+ unlockingScript,
91
+ lockingScript,
92
+ tx,
93
+ 0,
94
+ bsv.Script.Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID,
95
+ satoshisBN
96
+ );
97
+
98
+ console.log("\n===========================================");
99
+ console.log("āœ… Final Result:", verified ? "TRUE (Success)" : "āŒ FALSE (Failure)");
100
+ console.log("Final Stack:", bufferToHexArray(sandbox.stack || []));
101
+ console.log("AltStack:", bufferToHexArray(sandbox.altstack || []));
102
+ console.log("===========================================");
103
+
104
+ return verified;
105
+ } catch (err) {
106
+ console.error("āŒ Error in script execution:", err.message);
107
+ return false;
108
+ }
109
+ }
110
+
111
+ // ============================================
112
+ // CLI Entrypoint
113
+ // ============================================
114
+ if (typeof require !== 'undefined' && require.main === module) {
115
+ if (process.argv.length < 4) {
116
+ console.log("Usage: node stack_examiner.js <locking_script_hex> <unlocking_script_hex>");
117
+ process.exit(1);
118
+ }
119
+
120
+ const locking = process.argv[2];
121
+ const unlocking = process.argv[3];
122
+ runScript(locking, unlocking);
123
+ }
124
+
125
+ // Export for module usage
126
+ module.exports = {
127
+ runScript,
128
+ bufferToHexArray
129
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@smartledger/bsv",
3
- "version": "3.2.0",
4
- "description": "Advanced Bitcoin SV library with JavaScript-to-Bitcoin Script framework - Complete BSV API + BIP143 preimage parsing + 121 opcode mapping + covenant builder + nChain PUSHTX techniques + custom script development",
3
+ "version": "3.2.1",
4
+ "description": "Advanced Bitcoin SV library with JavaScript-to-Bitcoin Script framework - Complete BSV API + BIP143 preimage parsing + 121 opcode mapping + covenant builder + nChain PUSHTX techniques + custom script development + integrated debugging tools",
5
5
  "author": "SmartLedger Technology <hello@smartledger.technology> (https://smartledger.technology)",
6
6
  "homepage": "https://github.com/codenlighten/smartledger-bsv#readme",
7
7
  "bugs": {