smartledger-bsv 3.3.2 → 3.3.4

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.
Files changed (118) hide show
  1. package/CHANGELOG.md +220 -79
  2. package/README.md +283 -71
  3. package/bsv-covenant.min.js +26 -3
  4. package/bsv-gdaf.min.js +11 -9
  5. package/bsv-ltp.min.js +10 -8
  6. package/bsv-mnemonic.min.js +4 -4
  7. package/bsv-script-helper.min.js +2 -2
  8. package/bsv-security.min.js +3 -24
  9. package/bsv-shamir.min.js +2 -2
  10. package/bsv-smartcontract.min.js +10 -8
  11. package/bsv.bundle.js +9 -9
  12. package/bsv.min.js +10 -8
  13. package/build/webpack.bundle.config.js +2 -2
  14. package/build/webpack.config.js +2 -2
  15. package/build/webpack.covenant.config.js +2 -2
  16. package/build/webpack.gdaf.config.js +6 -43
  17. package/build/webpack.script-helper.config.js +2 -2
  18. package/build/webpack.security.config.js +2 -2
  19. package/build/webpack.smartcontract.config.js +2 -2
  20. package/bundle-entry.js +1 -341
  21. package/covenant-entry.js +1 -44
  22. package/demos/README.md +188 -0
  23. package/{architecture_demo.js → demos/architecture_demo.js} +2 -2
  24. package/demos/bsv_wallet_demo.js +242 -0
  25. package/{complete_ltp_demo.js → demos/complete_ltp_demo.js} +1 -1
  26. package/demos/debug_tools_demo.js +87 -0
  27. package/demos/demo_features.js +123 -0
  28. package/demos/easy_interface_demo.js +109 -0
  29. package/demos/ecies_demo.js +182 -0
  30. package/demos/gdaf_core_test.js +131 -0
  31. package/demos/gdaf_demo.js +237 -0
  32. package/demos/ltp_demo.js +361 -0
  33. package/demos/ltp_primitives_demo.js +403 -0
  34. package/demos/message_demo.js +209 -0
  35. package/demos/preimage_separation_demo.js +383 -0
  36. package/demos/script_helper_demo.js +289 -0
  37. package/demos/security_demo.js +287 -0
  38. package/{shamir_demo.js → demos/shamir_demo.js} +1 -1
  39. package/{simple_demo.js → demos/simple_demo.js} +1 -1
  40. package/demos/simple_p2pkh_demo.js +169 -0
  41. package/demos/simple_utxo_preimage_demo.js +196 -0
  42. package/demos/smart_contract_demo.html +1347 -0
  43. package/demos/smart_contract_demo.js +910 -0
  44. package/demos/utxo_generator_demo.js +244 -0
  45. package/demos/validation_pipeline_demo.js +155 -0
  46. package/demos/web3keys.html +740 -0
  47. package/docs/BUNDLE_UPDATE_SUMMARY.md +40 -0
  48. package/docs/DOCUMENTATION_REVIEW_REPORT.md +295 -0
  49. package/docs/FIX_CREATEHMAC_ISSUE.md +91 -0
  50. package/docs/MODULE_REFERENCE_COMPLETE.md +330 -0
  51. package/docs/README.md +107 -79
  52. package/docs/SMARTLEDGER_BSV_USAGE_ANSWERS.md +477 -0
  53. package/docs/SMARTLEDGER_BSV_USAGE_EXAMPLES.js +372 -0
  54. package/docs/SMARTLEDGER_BSV_USAGE_GUIDE.md +555 -0
  55. package/docs/SMART_CONTRACT_DEVELOPMENT_GUIDE.md +1459 -0
  56. package/docs/advanced/LEGAL_TOKEN_PROTOCOL.md +411 -0
  57. package/docs/advanced/SMART_CONTRACT_GUIDE.md +1255 -0
  58. package/docs/advanced/UTXO_MANAGER_GUIDE.md +851 -0
  59. package/docs/api/LTP.md +334 -0
  60. package/docs/getting-started/INSTALLATION.md +410 -0
  61. package/docs/getting-started/QUICK_START.md +180 -0
  62. package/docs/migration/FROM_BSV_1_5_6.md +260 -0
  63. package/docs/technical/GDAF_DEVELOPER_INTERFACE.md +187 -0
  64. package/docs/technical/GDAF_IMPLEMENTATION_COMPLETE.md +190 -0
  65. package/docs/technical/SHAMIR_INTEGRATION_SUMMARY.md +165 -0
  66. package/docs/technical/roadmap.md +1250 -0
  67. package/docs/technical/trust_law.md +142 -0
  68. package/examples/complete_workflow_demo.js +783 -0
  69. package/examples/definitive_working_demo.js +261 -0
  70. package/examples/final_working_contracts.js +338 -0
  71. package/examples/smart_contract_templates.js +718 -0
  72. package/examples/working_smart_contracts.js +348 -0
  73. package/gdaf-entry.js +2 -54
  74. package/index.js +32 -0
  75. package/lib/mnemonic/pbkdf2.browser.js +69 -0
  76. package/lib/mnemonic/pbkdf2.js +2 -68
  77. package/lib/mnemonic/pbkdf2.node.js +68 -0
  78. package/ltp-entry.js +2 -92
  79. package/package.json +21 -8
  80. package/script-helper-entry.js +1 -49
  81. package/security-entry.js +1 -70
  82. package/shamir-entry.js +1 -173
  83. package/smartcontract-entry.js +1 -133
  84. package/tests/browser-compatibility/README.md +35 -0
  85. package/tests/browser-compatibility/test-cdn-vs-local.html +186 -0
  86. package/tests/browser-compatibility/test-pbkdf2.html +51 -0
  87. package/tests/test_builtin_verify.js +117 -0
  88. package/tests/test_debug_integration.js +71 -0
  89. package/tests/test_ecdsa_little.js +70 -0
  90. package/tests/test_smartverify_der.js +110 -0
  91. package/utilities/blockchain-state.js +155 -155
  92. package/utilities/blockchain-state.json +103293 -5244
  93. package/utilities/miner-simulator.js +354 -358
  94. package/utilities/mock-utxo-generator.js +54 -54
  95. package/utilities/raw-tx-examples.js +120 -122
  96. package/utilities/success-demo.js +104 -105
  97. package/utilities/transaction-examples.js +188 -188
  98. package/utilities/utxo-manager.js +91 -91
  99. package/utilities/wallet-setup.js +79 -80
  100. package/utilities/working-signature-demo.js +108 -110
  101. package/SECURITY.md +0 -75
  102. package/build/bsv-covenant.min.js +0 -10
  103. package/build/bsv-script-helper.min.js +0 -10
  104. package/build/bsv-security.min.js +0 -31
  105. package/build/bsv-smartcontract.min.js +0 -39
  106. package/build/bsv.bundle.js +0 -39
  107. package/build/bsv.min.js +0 -39
  108. package/validation_test.js +0 -97
  109. /package/docs/{ADVANCED_COVENANT_DEVELOPMENT.md → advanced/ADVANCED_COVENANT_DEVELOPMENT.md} +0 -0
  110. /package/docs/{CUSTOM_SCRIPT_DEVELOPMENT.md → advanced/CUSTOM_SCRIPT_DEVELOPMENT.md} +0 -0
  111. /package/docs/{block.md → api/BLOCKS.md} +0 -0
  112. /package/docs/{ecies.md → api/ECIES.md} +0 -0
  113. /package/docs/{networks.md → api/NETWORKS.md} +0 -0
  114. /package/docs/{script.md → api/SCRIPTS.md} +0 -0
  115. /package/docs/{transaction.md → api/TRANSACTIONS.md} +0 -0
  116. /package/docs/{unspentoutput.md → api/UTXO.md} +0 -0
  117. /package/{test_shamir.js → tests/test_shamir.js} +0 -0
  118. /package/{test_standalone_shamir.html → tests/test_standalone_shamir.html} +0 -0
@@ -0,0 +1,383 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * UTXO Generator and Preimage Separation Demonstration
5
+ *
6
+ * This example shows how to:
7
+ * 1. Generate authentic UTXOs using the UTXOGenerator
8
+ * 2. Create transactions and extract BIP-143 preimages
9
+ * 3. Separate preimage into individual fields with detailed analysis
10
+ * 4. Display each component with hex values and interpretations
11
+ */
12
+
13
+ // Workaround for Node.js environment with minified BSV
14
+ global.window = global.window || {};
15
+ global.window.crypto = global.window.crypto || require('crypto').webcrypto || require('crypto');
16
+
17
+ const bsv = require('../bsv.min.js');
18
+ const SmartContract = bsv.SmartContract;
19
+
20
+ console.log('🔧 UTXO Generator and Preimage Separation Demo');
21
+ console.log('=' .repeat(60));
22
+
23
+ async function demonstrateUTXOAndPreimage() {
24
+ try {
25
+ // Step 1: Generate authentic UTXOs
26
+ console.log('\n📦 Step 1: Generating Authentic UTXOs');
27
+ console.log('-'.repeat(40));
28
+
29
+ // Create simple mock UTXOs for preimage demonstration
30
+ const demoPrivateKey = new bsv.PrivateKey();
31
+ const demoAddress = demoPrivateKey.toAddress();
32
+
33
+ const utxos = [
34
+ {
35
+ txid: '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
36
+ vout: 0,
37
+ scriptPubKey: bsv.Script.buildPublicKeyHashOut(demoAddress).toHex(),
38
+ satoshis: 150000
39
+ },
40
+ {
41
+ txid: 'abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890',
42
+ vout: 1,
43
+ scriptPubKey: bsv.Script.buildPublicKeyHashOut(demoAddress).toHex(),
44
+ satoshis: 150000
45
+ }
46
+ ];
47
+
48
+ console.log('✅ Mock UTXOs Created for Demo:');
49
+ console.log(` Count: ${utxos.length}`);
50
+ console.log(` Address: ${demoAddress.toString()}`);
51
+ console.log(` Private Key (WIF): ${demoPrivateKey.toWIF()}`);
52
+
53
+ utxos.forEach((utxo, index) => {
54
+ console.log(`\n UTXO ${index + 1}:`);
55
+ console.log(` TXID: ${utxo.txid}`);
56
+ console.log(` VOUT: ${utxo.vout}`);
57
+ console.log(` Satoshis: ${utxo.satoshis.toLocaleString()}`);
58
+ console.log(` Script: ${utxo.script}`);
59
+ });
60
+
61
+ // Step 2: Create a transaction using the UTXOs
62
+ console.log('\n\n🔨 Step 2: Creating Transaction from UTXOs');
63
+ console.log('-'.repeat(40));
64
+
65
+ const privateKey = demoPrivateKey;
66
+ const address = demoAddress;
67
+
68
+ // Create transaction spending first UTXO
69
+ const tx = new bsv.Transaction()
70
+ .from({
71
+ txId: utxos[0].txid,
72
+ outputIndex: utxos[0].vout,
73
+ scriptPubKey: utxos[0].scriptPubKey,
74
+ satoshis: utxos[0].satoshis
75
+ })
76
+ .to(address, 140000) // Send to same address with fee
77
+ .change(address) // Change back to same address
78
+ .sign(privateKey);
79
+
80
+ console.log('✅ Transaction Created:');
81
+ console.log(` Transaction ID: ${tx.id}`);
82
+ console.log(` Inputs: ${tx.inputs.length}`);
83
+ console.log(` Outputs: ${tx.outputs.length}`);
84
+ console.log(` Fee: ${tx.getFee()} satoshis`);
85
+
86
+ // Display transaction details
87
+ tx.inputs.forEach((input, index) => {
88
+ console.log(`\n Input ${index + 1}:`);
89
+ console.log(` Previous TXID: ${input.prevTxId.toString('hex')}`);
90
+ console.log(` Output Index: ${input.outputIndex}`);
91
+ console.log(` Script: ${input.script ? input.script.toString() : 'None'}`);
92
+ });
93
+
94
+ tx.outputs.forEach((output, index) => {
95
+ console.log(`\n Output ${index + 1}:`);
96
+ console.log(` Satoshis: ${output.satoshis.toLocaleString()}`);
97
+ console.log(` Script: ${output.script.toString()}`);
98
+ console.log(` Address: ${output.script.toAddress().toString()}`);
99
+ });
100
+
101
+ // Step 3: Generate BIP-143 Preimage
102
+ console.log('\n\n🔍 Step 3: Generating BIP-143 Preimage');
103
+ console.log('-'.repeat(40));
104
+
105
+ const inputIndex = 0;
106
+ const sighashType = bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID;
107
+ const subscript = bsv.Script.buildPublicKeyHashOut(address);
108
+ const satoshis = new bsv.crypto.BN(utxos[0].satoshis);
109
+
110
+ const preimageBuffer = bsv.Transaction.sighash.sighashPreimage(
111
+ tx,
112
+ sighashType,
113
+ inputIndex,
114
+ subscript,
115
+ satoshis
116
+ );
117
+
118
+ console.log('✅ Preimage Generated:');
119
+ console.log(` Length: ${preimageBuffer.length} bytes`);
120
+ console.log(` Hex: ${preimageBuffer.toString('hex')}`);
121
+ console.log(` SIGHASH Type: 0x${sighashType.toString(16)}`);
122
+
123
+ // Step 4: Separate Preimage into Individual Fields
124
+ console.log('\n\n🔬 Step 4: Preimage Field Separation Analysis');
125
+ console.log('='.repeat(60));
126
+
127
+ // Create preimage analyzer
128
+ const preimage = new SmartContract.Preimage(preimageBuffer.toString('hex'));
129
+
130
+ // Extract all fields using different strategies
131
+ console.log('\n📋 Field Extraction Strategy Comparison:');
132
+ console.log('-'.repeat(50));
133
+
134
+ try {
135
+ const leftExtraction = preimage.extract('LEFT');
136
+ console.log('✅ LEFT extraction successful:', Object.keys(leftExtraction).length, 'fields');
137
+ } catch (error) {
138
+ console.log('❌ LEFT extraction failed:', error.message);
139
+ }
140
+
141
+ try {
142
+ const rightExtraction = preimage.extract('RIGHT');
143
+ console.log('✅ RIGHT extraction successful:', Object.keys(rightExtraction).length, 'fields');
144
+ } catch (error) {
145
+ console.log('❌ RIGHT extraction failed:', error.message);
146
+ }
147
+
148
+ try {
149
+ const dynamicExtraction = preimage.extract('DYNAMIC');
150
+ console.log('✅ DYNAMIC extraction successful:', Object.keys(dynamicExtraction).length, 'fields');
151
+ } catch (error) {
152
+ console.log('❌ DYNAMIC extraction failed:', error.message);
153
+ }
154
+
155
+ // Manual field-by-field extraction with detailed analysis
156
+ console.log('\n\n🔍 Detailed Field-by-Field Analysis:');
157
+ console.log('='.repeat(60));
158
+
159
+ const fields = [
160
+ 'version',
161
+ 'hashPrevouts',
162
+ 'hashSequence',
163
+ 'outpoint',
164
+ 'scriptCode',
165
+ 'amount',
166
+ 'sequence',
167
+ 'hashOutputs',
168
+ 'locktime',
169
+ 'sighash'
170
+ ];
171
+
172
+ let offset = 0;
173
+ const fieldDetails = {};
174
+
175
+ fields.forEach((fieldName, index) => {
176
+ console.log(`\n${index + 1}. ${fieldName.toUpperCase()}:`);
177
+ console.log('-'.repeat(20));
178
+
179
+ try {
180
+ const fieldBuffer = preimage.getField(fieldName);
181
+ fieldDetails[fieldName] = {
182
+ buffer: fieldBuffer,
183
+ hex: fieldBuffer.toString('hex'),
184
+ length: fieldBuffer.length,
185
+ offset: offset
186
+ };
187
+
188
+ console.log(` Hex Value: ${fieldBuffer.toString('hex')}`);
189
+ console.log(` Length: ${fieldBuffer.length} bytes`);
190
+ console.log(` Offset: ${offset}-${offset + fieldBuffer.length - 1}`);
191
+
192
+ // Interpret field values where possible
193
+ switch (fieldName) {
194
+ case 'version':
195
+ const version = fieldBuffer.readUInt32LE(0);
196
+ console.log(` Interpreted: Version ${version}`);
197
+ break;
198
+
199
+ case 'amount':
200
+ const amount = fieldBuffer.readBigUInt64LE(0);
201
+ console.log(` Interpreted: ${amount.toString()} satoshis (${(Number(amount) / 100000000).toFixed(8)} BSV)`);
202
+ break;
203
+
204
+ case 'sequence':
205
+ const sequence = fieldBuffer.readUInt32LE(0);
206
+ console.log(` Interpreted: Sequence ${sequence} (0x${sequence.toString(16)})`);
207
+ break;
208
+
209
+ case 'locktime':
210
+ const locktime = fieldBuffer.readUInt32LE(0);
211
+ if (locktime < 500000000) {
212
+ console.log(` Interpreted: Block height ${locktime}`);
213
+ } else {
214
+ console.log(` Interpreted: Unix timestamp ${locktime} (${new Date(locktime * 1000).toISOString()})`);
215
+ }
216
+ break;
217
+
218
+ case 'sighash':
219
+ const sighashValue = fieldBuffer.readUInt32LE(0);
220
+ console.log(` Interpreted: SIGHASH 0x${sighashValue.toString(16)}`);
221
+
222
+ // Decode SIGHASH flags
223
+ const flags = [];
224
+ if (sighashValue & 0x01) flags.push('SIGHASH_ALL');
225
+ if (sighashValue & 0x02) flags.push('SIGHASH_NONE');
226
+ if (sighashValue & 0x03) flags.push('SIGHASH_SINGLE');
227
+ if (sighashValue & 0x80) flags.push('SIGHASH_ANYONECANPAY');
228
+ if (sighashValue & 0x40) flags.push('SIGHASH_FORKID');
229
+
230
+ console.log(` Flags: ${flags.join(' | ')}`);
231
+ break;
232
+
233
+ case 'outpoint':
234
+ const txid = fieldBuffer.slice(0, 32).reverse().toString('hex');
235
+ const vout = fieldBuffer.slice(32, 36).readUInt32LE(0);
236
+ console.log(` Interpreted: ${txid}:${vout}`);
237
+ break;
238
+
239
+ case 'scriptCode':
240
+ try {
241
+ const script = new bsv.Script(fieldBuffer);
242
+ console.log(` Interpreted: ${script.toString()}`);
243
+ } catch (error) {
244
+ console.log(` Interpreted: Raw script data (${fieldBuffer.length} bytes)`);
245
+ }
246
+ break;
247
+
248
+ default:
249
+ if (fieldBuffer.length === 32) {
250
+ console.log(` Interpreted: 32-byte hash (likely SHA256)`);
251
+ } else {
252
+ console.log(` Interpreted: Raw binary data`);
253
+ }
254
+ }
255
+
256
+ offset += fieldBuffer.length;
257
+
258
+ } catch (error) {
259
+ console.log(` ❌ Error extracting field: ${error.message}`);
260
+ fieldDetails[fieldName] = { error: error.message };
261
+ }
262
+ });
263
+
264
+ // Step 5: Preimage Validation and Analysis
265
+ console.log('\n\n🔍 Step 5: Preimage Validation and Analysis');
266
+ console.log('='.repeat(60));
267
+
268
+ // Get SIGHASH analysis
269
+ try {
270
+ const sighashInfo = preimage.getSighashInfo();
271
+ console.log('\n📊 SIGHASH Analysis:');
272
+ console.log(` Has zero hashes: ${sighashInfo.hasZeroHashes ? '⚠️ YES' : '✅ NO'}`);
273
+ console.log(` SIGHASH type detected: ${sighashInfo.type || 'Unknown'}`);
274
+ console.log(` Is standard: ${sighashInfo.isStandard ? '✅ YES' : '❌ NO'}`);
275
+
276
+ if (sighashInfo.warnings && sighashInfo.warnings.length > 0) {
277
+ console.log('\n⚠️ Warnings:');
278
+ sighashInfo.warnings.forEach(warning => {
279
+ console.log(` - ${warning}`);
280
+ });
281
+ }
282
+ } catch (error) {
283
+ console.log('❌ SIGHASH analysis failed:', error.message);
284
+ }
285
+
286
+ // Verify preimage reconstruction
287
+ console.log('\n🔧 Preimage Reconstruction Verification:');
288
+ console.log('-'.repeat(40));
289
+
290
+ let reconstructed = Buffer.alloc(0);
291
+ let reconstructionErrors = 0;
292
+
293
+ fields.forEach(fieldName => {
294
+ if (fieldDetails[fieldName] && fieldDetails[fieldName].buffer) {
295
+ reconstructed = Buffer.concat([reconstructed, fieldDetails[fieldName].buffer]);
296
+ } else {
297
+ reconstructionErrors++;
298
+ console.log(` ❌ Missing field: ${fieldName}`);
299
+ }
300
+ });
301
+
302
+ const originalHex = preimageBuffer.toString('hex');
303
+ const reconstructedHex = reconstructed.toString('hex');
304
+ const matches = originalHex === reconstructedHex;
305
+
306
+ console.log(` Original length: ${preimageBuffer.length} bytes`);
307
+ console.log(` Reconstructed length: ${reconstructed.length} bytes`);
308
+ console.log(` Reconstruction errors: ${reconstructionErrors}`);
309
+ console.log(` Fields match: ${matches ? '✅ YES' : '❌ NO'}`);
310
+
311
+ if (!matches && reconstructionErrors === 0) {
312
+ console.log('\n🔍 Hex Comparison (first 200 chars):');
313
+ console.log(` Original: ${originalHex.substring(0, 200)}${originalHex.length > 200 ? '...' : ''}`);
314
+ console.log(` Reconstructed: ${reconstructedHex.substring(0, 200)}${reconstructedHex.length > 200 ? '...' : ''}`);
315
+ }
316
+
317
+ // Step 6: Summary and Statistics
318
+ console.log('\n\n📈 Step 6: Summary and Statistics');
319
+ console.log('='.repeat(60));
320
+
321
+ const totalFields = fields.length;
322
+ const successfulFields = Object.keys(fieldDetails).filter(k => fieldDetails[k].buffer).length;
323
+ const totalBytes = Object.values(fieldDetails)
324
+ .filter(f => f.buffer)
325
+ .reduce((sum, f) => sum + f.buffer.length, 0);
326
+
327
+ console.log('\n📊 Extraction Statistics:');
328
+ console.log(` Total fields: ${totalFields}`);
329
+ console.log(` Successfully extracted: ${successfulFields}`);
330
+ console.log(` Success rate: ${((successfulFields / totalFields) * 100).toFixed(1)}%`);
331
+ console.log(` Total bytes processed: ${totalBytes}`);
332
+ console.log(` Average field size: ${(totalBytes / successfulFields).toFixed(1)} bytes`);
333
+
334
+ console.log('\n📋 Field Size Distribution:');
335
+ Object.entries(fieldDetails)
336
+ .filter(([name, data]) => data.buffer)
337
+ .sort((a, b) => b[1].buffer.length - a[1].buffer.length)
338
+ .forEach(([name, data]) => {
339
+ const percentage = ((data.buffer.length / totalBytes) * 100).toFixed(1);
340
+ console.log(` ${name.padEnd(15)}: ${data.buffer.length.toString().padStart(2)} bytes (${percentage.padStart(4)}%)`);
341
+ });
342
+
343
+ // Final validation
344
+ console.log('\n✅ Demonstration Complete!');
345
+ console.log(` UTXOs generated: ${utxos.length}`);
346
+ console.log(` Transaction created: ${tx.id}`);
347
+ console.log(` Preimage extracted: ${preimageBuffer.length} bytes`);
348
+ console.log(` Fields separated: ${successfulFields}/${totalFields}`);
349
+ console.log(` Reconstruction: ${matches ? 'Success' : 'Partial'}`);
350
+
351
+ return {
352
+ utxos,
353
+ transaction: tx,
354
+ preimage: preimageBuffer,
355
+ fields: fieldDetails,
356
+ statistics: {
357
+ totalFields,
358
+ successfulFields,
359
+ totalBytes,
360
+ reconstructionMatches: matches
361
+ }
362
+ };
363
+
364
+ } catch (error) {
365
+ console.error('\n❌ Demonstration failed:', error.message);
366
+ console.error('Stack trace:', error.stack);
367
+ throw error;
368
+ }
369
+ }
370
+
371
+ // Run the demonstration
372
+ if (require.main === module) {
373
+ demonstrateUTXOAndPreimage()
374
+ .then(result => {
375
+ console.log('\n🎉 All operations completed successfully!');
376
+ })
377
+ .catch(error => {
378
+ console.error('\n💥 Demonstration failed:', error.message);
379
+ process.exit(1);
380
+ });
381
+ }
382
+
383
+ module.exports = { demonstrateUTXOAndPreimage };
@@ -0,0 +1,289 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Script Helper Utilities Demo
5
+ * ============================
6
+ *
7
+ * Demonstrates the SmartLedger-BSV Script Helper utilities for
8
+ * Bitcoin Script development and analysis.
9
+ *
10
+ * Features demonstrated:
11
+ * - Script building and construction
12
+ * - ASM parsing and generation
13
+ * - Script analysis and optimization
14
+ * - Opcode utilities and mapping
15
+ * - Script debugging tools
16
+ */
17
+
18
+ const bsv = require('../index.js');
19
+
20
+ console.log('🛠️ SmartLedger-BSV Script Helper Demo');
21
+ console.log('======================================\n');
22
+
23
+ async function demonstrateScriptHelper() {
24
+ try {
25
+ // Check if custom script helper is available
26
+ let ScriptHelper;
27
+ try {
28
+ ScriptHelper = require('../lib/custom-script-helper.js');
29
+ console.log('✅ Custom Script Helper loaded');
30
+ } catch (e) {
31
+ console.log('ℹ️ Using built-in BSV Script utilities');
32
+ ScriptHelper = null;
33
+ }
34
+
35
+ // Test 1: Basic Script Construction
36
+ console.log('🏗️ Test 1: Basic Script Construction');
37
+ console.log('------------------------------------');
38
+
39
+ // P2PKH script
40
+ const privateKey = bsv.PrivateKey.fromRandom();
41
+ const address = privateKey.toAddress();
42
+ const p2pkhScript = bsv.Script.buildPublicKeyHashOut(address);
43
+
44
+ console.log('🔐 Generated Address:', address.toString());
45
+ console.log('📜 P2PKH Script ASM:', p2pkhScript.toString());
46
+ console.log('🔢 P2PKH Script Hex:', p2pkhScript.toHex());
47
+ console.log('📏 Script Size:', p2pkhScript.toBuffer().length, 'bytes');
48
+ console.log('');
49
+
50
+ // P2SH script
51
+ const redeemScript = bsv.Script.buildMultisigOut([privateKey.publicKey], 1);
52
+ const p2shScript = bsv.Script.buildScriptHashOut(redeemScript);
53
+
54
+ console.log('🔄 Redeem Script ASM:', redeemScript.toString());
55
+ console.log('📦 P2SH Script ASM:', p2shScript.toString());
56
+ console.log('🔢 P2SH Script Hex:', p2shScript.toHex());
57
+ console.log('');
58
+
59
+ // Test 2: Script Analysis
60
+ console.log('🔍 Test 2: Script Analysis');
61
+ console.log('-------------------------');
62
+
63
+ const scripts = [
64
+ { name: 'P2PKH', script: p2pkhScript },
65
+ { name: 'P2SH', script: p2shScript },
66
+ { name: 'Multisig', script: redeemScript }
67
+ ];
68
+
69
+ scripts.forEach(({ name, script }) => {
70
+ console.log(`📊 ${name} Analysis:`);
71
+ console.log(` 📏 Size: ${script.toBuffer().length} bytes`);
72
+ console.log(` 🧩 Chunks: ${script.chunks.length}`);
73
+ console.log(` 📋 Push-only: ${script.isPushOnly()}`);
74
+ console.log(` 🔗 Has multisig: ${script.toString().includes('CHECKMULTISIG')}`);
75
+ console.log(` ⏰ Has timelock: ${script.toString().includes('CHECKLOCKTIMEVERIFY')}`);
76
+ console.log('');
77
+ });
78
+
79
+ // Test 3: Custom Script Building
80
+ console.log('⚙️ Test 3: Custom Script Building');
81
+ console.log('---------------------------------');
82
+
83
+ // Build a custom script with various operations
84
+ const customScript = new bsv.Script()
85
+ .add(bsv.Opcode.OP_DUP)
86
+ .add(bsv.Opcode.OP_HASH160)
87
+ .add(address.hashBuffer)
88
+ .add(bsv.Opcode.OP_EQUALVERIFY)
89
+ .add(bsv.Opcode.OP_CHECKSIG);
90
+
91
+ console.log('🛠️ Custom Script ASM:', customScript.toString());
92
+ console.log('🔢 Custom Script Hex:', customScript.toHex());
93
+
94
+ // Verify it matches P2PKH
95
+ const isEquivalent = customScript.toString() === p2pkhScript.toString();
96
+ console.log('🎯 Equivalent to P2PKH:', isEquivalent ? '✅' : '❌');
97
+ console.log('');
98
+
99
+ // Test 4: Script Parsing and Conversion
100
+ console.log('🔄 Test 4: Script Parsing and Conversion');
101
+ console.log('---------------------------------------');
102
+
103
+ const testASM = 'OP_DUP OP_HASH160 OP_PUSHDATA1 0x14 0x' + address.hashBuffer.toString('hex') + ' OP_EQUALVERIFY OP_CHECKSIG';
104
+ console.log('📝 Input ASM:', testASM);
105
+
106
+ try {
107
+ const parsedScript = bsv.Script.fromASM(testASM);
108
+ console.log('✅ Successfully parsed ASM');
109
+ console.log('📜 Parsed Script:', parsedScript.toString());
110
+ console.log('🔢 Script Hex:', parsedScript.toHex());
111
+
112
+ // Convert back to ASM
113
+ const backToASM = parsedScript.toString();
114
+ console.log('🔄 Back to ASM:', backToASM);
115
+ console.log('🎯 Round-trip success:', testASM.includes('OP_DUP') && backToASM.includes('OP_DUP') ? '✅' : '❌');
116
+
117
+ } catch (error) {
118
+ console.log('❌ ASM parsing error:', error.message);
119
+ }
120
+ console.log('');
121
+
122
+ // Test 5: Opcode Analysis
123
+ console.log('🔤 Test 5: Opcode Analysis');
124
+ console.log('-------------------------');
125
+
126
+ const opcodes = [
127
+ bsv.Opcode.OP_0,
128
+ bsv.Opcode.OP_1,
129
+ bsv.Opcode.OP_DUP,
130
+ bsv.Opcode.OP_HASH160,
131
+ bsv.Opcode.OP_EQUAL,
132
+ bsv.Opcode.OP_CHECKSIG,
133
+ bsv.Opcode.OP_CHECKMULTISIG,
134
+ bsv.Opcode.OP_CHECKLOCKTIMEVERIFY
135
+ ];
136
+
137
+ console.log('📋 Common Opcodes:');
138
+ opcodes.forEach(opcode => {
139
+ const name = bsv.Opcode.reverseMap[opcode] || `OP_${opcode}`;
140
+ console.log(` ${opcode.toString().padStart(3)} = ${name}`);
141
+ });
142
+ console.log('');
143
+
144
+ // Test 6: Script Complexity Analysis
145
+ console.log('📊 Test 6: Script Complexity Analysis');
146
+ console.log('------------------------------------');
147
+
148
+ const complexScripts = [
149
+ {
150
+ name: 'Simple P2PKH',
151
+ script: p2pkhScript,
152
+ expectedOps: 5
153
+ },
154
+ {
155
+ name: 'Multisig 1-of-1',
156
+ script: redeemScript,
157
+ expectedOps: 4
158
+ },
159
+ {
160
+ name: 'Time Lock',
161
+ script: new bsv.Script()
162
+ .add(144) // ~24 hours in blocks
163
+ .add(bsv.Opcode.OP_CHECKLOCKTIMEVERIFY)
164
+ .add(bsv.Opcode.OP_DROP)
165
+ .add(bsv.Opcode.OP_DUP)
166
+ .add(bsv.Opcode.OP_HASH160)
167
+ .add(address.hashBuffer)
168
+ .add(bsv.Opcode.OP_EQUALVERIFY)
169
+ .add(bsv.Opcode.OP_CHECKSIG),
170
+ expectedOps: 8
171
+ }
172
+ ];
173
+
174
+ complexScripts.forEach(({ name, script, expectedOps }) => {
175
+ const chunks = script.chunks.length;
176
+ const size = script.toBuffer().length;
177
+ const complexity = chunks > 10 ? 'High' : chunks > 5 ? 'Medium' : 'Low';
178
+
179
+ console.log(`🔍 ${name}:`);
180
+ console.log(` 📊 Chunks: ${chunks} (expected ~${expectedOps})`);
181
+ console.log(` 📏 Size: ${size} bytes`);
182
+ console.log(` ⚡ Complexity: ${complexity}`);
183
+ console.log(` 💰 Est. fee (1 sat/byte): ${size} satoshis`);
184
+ console.log('');
185
+ });
186
+
187
+ // Test 7: Script Validation
188
+ console.log('✅ Test 7: Script Validation');
189
+ console.log('---------------------------');
190
+
191
+ const validationTests = [
192
+ {
193
+ name: 'Valid P2PKH',
194
+ script: p2pkhScript,
195
+ shouldPass: true
196
+ },
197
+ {
198
+ name: 'Valid Multisig',
199
+ script: redeemScript,
200
+ shouldPass: true
201
+ },
202
+ {
203
+ name: 'Empty Script',
204
+ script: new bsv.Script(),
205
+ shouldPass: true
206
+ },
207
+ {
208
+ name: 'Invalid Opcode Script',
209
+ script: (() => {
210
+ try {
211
+ return new bsv.Script().add(255); // Invalid opcode
212
+ } catch (e) {
213
+ return null;
214
+ }
215
+ })(),
216
+ shouldPass: false
217
+ }
218
+ ];
219
+
220
+ validationTests.forEach(({ name, script, shouldPass }) => {
221
+ if (!script) {
222
+ console.log(`⚠️ ${name}: Could not create (expected for invalid tests)`);
223
+ return;
224
+ }
225
+
226
+ try {
227
+ const isValid = script.toBuffer().length >= 0; // Basic validation
228
+ console.log(`${isValid === shouldPass ? '✅' : '❌'} ${name}: ${isValid ? 'Valid' : 'Invalid'}`);
229
+ } catch (error) {
230
+ const failed = !shouldPass;
231
+ console.log(`${failed ? '✅' : '❌'} ${name}: Failed validation (${error.message.substring(0, 30)}...)`);
232
+ }
233
+ });
234
+ console.log('');
235
+
236
+ // Test 8: Performance Metrics
237
+ console.log('🚀 Test 8: Performance Metrics');
238
+ console.log('-----------------------------');
239
+
240
+ const iterations = 1000;
241
+
242
+ // Script creation performance
243
+ const createStart = Date.now();
244
+ for (let i = 0; i < iterations; i++) {
245
+ const tempKey = bsv.PrivateKey.fromRandom();
246
+ const tempAddr = tempKey.toAddress();
247
+ bsv.Script.buildPublicKeyHashOut(tempAddr);
248
+ }
249
+ const createEnd = Date.now();
250
+ const createTime = createEnd - createStart;
251
+
252
+ // Script parsing performance
253
+ const parseStart = Date.now();
254
+ const testScript = p2pkhScript.toString();
255
+ for (let i = 0; i < iterations; i++) {
256
+ bsv.Script.fromASM(testScript);
257
+ }
258
+ const parseEnd = Date.now();
259
+ const parseTime = parseEnd - parseStart;
260
+
261
+ console.log(`⏱️ Script Creation: ${createTime}ms for ${iterations} scripts`);
262
+ console.log(`📊 Creation Rate: ${(iterations * 1000 / createTime).toFixed(0)} scripts/second`);
263
+ console.log(`⏱️ Script Parsing: ${parseTime}ms for ${iterations} parses`);
264
+ console.log(`📊 Parsing Rate: ${(iterations * 1000 / parseTime).toFixed(0)} parses/second`);
265
+
266
+ } catch (error) {
267
+ console.error('❌ Demo error:', error.message);
268
+ console.error('📋 Stack:', error.stack);
269
+ }
270
+ }
271
+
272
+ // Run the demo
273
+ demonstrateScriptHelper().then(() => {
274
+ console.log('\n🎉 Script Helper Demo completed!');
275
+ console.log('');
276
+ console.log('💡 Use Cases:');
277
+ console.log(' • Custom script development and testing');
278
+ console.log(' • Script analysis and optimization');
279
+ console.log(' • Educational Bitcoin Script learning');
280
+ console.log(' • Smart contract script generation');
281
+ console.log(' • Transaction script debugging');
282
+ console.log(' • Fee estimation for complex scripts');
283
+ console.log('');
284
+ console.log('🔧 Integration Tips:');
285
+ console.log(' • Use with SmartContract framework for covenants');
286
+ console.log(' • Combine with UTXOGenerator for complete testing');
287
+ console.log(' • Store optimized scripts for production use');
288
+ console.log(' • Validate scripts before blockchain deployment');
289
+ });