@smartledger/bsv 3.4.3 → 3.4.5

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 (89) hide show
  1. package/CHANGELOG.md +367 -0
  2. package/README.md +72 -72
  3. package/SECURITY.md +88 -0
  4. package/bin/cli.js +13 -8
  5. package/bsv-covenant.min.js +4 -4
  6. package/bsv-gdaf.min.js +5 -5
  7. package/bsv-ltp.min.js +7 -7
  8. package/bsv-smartcontract.min.js +5 -5
  9. package/bsv.bundle.js +5 -5
  10. package/bsv.d.ts +486 -9
  11. package/bsv.min.js +5 -5
  12. package/docs/COVENANT_DEVELOPMENT_RESOLVED.md +2 -2
  13. package/docs/MODULE_REFERENCE_COMPLETE.md +60 -57
  14. package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
  15. package/docs/getting-started/INSTALLATION.md +30 -30
  16. package/docs/getting-started/QUICK_START.md +14 -14
  17. package/docs/migration/FROM_BSV_1_5_6.md +5 -5
  18. package/gdaf-entry.js +1 -2
  19. package/index.js +20 -7
  20. package/lib/script/script.js +19 -0
  21. package/lib/smart_contract/covenant.js +10 -1
  22. package/lib/smartutxo.js +20 -12
  23. package/lib/transaction/input/publickeyhash.js +6 -1
  24. package/lib/transaction/transaction.js +12 -1
  25. package/ltp-entry.js +1 -2
  26. package/package.json +3 -3
  27. package/utilities/blockchain-state.js +32 -23
  28. package/demos/README.md +0 -188
  29. package/demos/architecture_demo.js +0 -247
  30. package/demos/browser-test.html +0 -1208
  31. package/demos/bsv_wallet_demo.js +0 -242
  32. package/demos/complete_ltp_demo.js +0 -511
  33. package/demos/debug_tools_demo.js +0 -87
  34. package/demos/demo_features.js +0 -123
  35. package/demos/easy_interface_demo.js +0 -109
  36. package/demos/ecies_demo.js +0 -182
  37. package/demos/gdaf_demo.js +0 -237
  38. package/demos/ltp_demo.js +0 -361
  39. package/demos/ltp_primitives_demo.js +0 -403
  40. package/demos/message_demo.js +0 -209
  41. package/demos/preimage_separation_demo.js +0 -383
  42. package/demos/script_helper_demo.js +0 -289
  43. package/demos/security_demo.js +0 -287
  44. package/demos/shamir_demo.js +0 -121
  45. package/demos/simple_demo.js +0 -204
  46. package/demos/simple_p2pkh_demo.js +0 -169
  47. package/demos/simple_utxo_preimage_demo.js +0 -196
  48. package/demos/smart_contract_demo.html +0 -1347
  49. package/demos/smart_contract_demo.js +0 -910
  50. package/demos/utxo_generator_demo.js +0 -244
  51. package/demos/validation_pipeline_demo.js +0 -155
  52. package/demos/web3keys.html +0 -740
  53. package/examples/README.md +0 -200
  54. package/examples/basic/transaction-creation.js +0 -534
  55. package/examples/basic/transaction_signature_api_gap.js +0 -178
  56. package/examples/complete_workflow_demo.js +0 -783
  57. package/examples/covenants/advanced_covenant_demo.js +0 -219
  58. package/examples/covenants/covenant_interface_demo.js +0 -270
  59. package/examples/covenants/covenant_manual_signature_resolved.js +0 -212
  60. package/examples/covenants/covenant_signature_template.js +0 -117
  61. package/examples/covenants2/covenant_bidirectional_example.js +0 -262
  62. package/examples/covenants2/covenant_utils_demo.js +0 -120
  63. package/examples/covenants2/preimage_covenant_utils.js +0 -287
  64. package/examples/covenants2/production_integration.js +0 -256
  65. package/examples/data/covenant_utxos.json +0 -28
  66. package/examples/data/utxos.json +0 -26
  67. package/examples/definitive_working_demo.js +0 -261
  68. package/examples/final_working_contracts.js +0 -338
  69. package/examples/legacy/README.md +0 -11
  70. package/examples/legacy/smart_contract_test_integration.js +0 -269
  71. package/examples/legacy/test_builtin_verify.js +0 -117
  72. package/examples/legacy/test_debug_integration.js +0 -71
  73. package/examples/legacy/test_ecdsa_little.js +0 -70
  74. package/examples/legacy/test_shamir.js +0 -221
  75. package/examples/legacy/test_smartverify_der.js +0 -110
  76. package/examples/preimage/README.md +0 -178
  77. package/examples/preimage/extract_preimage_bidirectional.js +0 -421
  78. package/examples/preimage/generate_sample_preimage.js +0 -208
  79. package/examples/preimage/generate_sighash_examples.js +0 -152
  80. package/examples/preimage/parse_preimage.js +0 -117
  81. package/examples/preimage/test_preimage_extractor.js +0 -53
  82. package/examples/preimage/test_varint_extraction.js +0 -95
  83. package/examples/scripts/custom_script_helper_example.js +0 -273
  84. package/examples/scripts/script_interpreter.js +0 -193
  85. package/examples/smart_contract/complete_workflow_demo.js +0 -343
  86. package/examples/smart_contract/covenant_builder_demo.js +0 -176
  87. package/examples/smart_contract/script_testing_integration.js +0 -198
  88. package/examples/smart_contract_templates.js +0 -718
  89. package/examples/working_smart_contracts.js +0 -348
@@ -1,221 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * BSV Shamir Secret Sharing Test
5
- * Comprehensive test of the Shamir Secret Sharing implementation
6
- */
7
-
8
- 'use strict'
9
-
10
- console.log('=== BSV Shamir Secret Sharing Test ===\n')
11
-
12
- // Load the BSV library with Shamir support
13
- var bsv
14
- try {
15
- bsv = require('./index.js')
16
- console.log('✓ Loaded BSV library with Shamir support')
17
- } catch (e) {
18
- console.error('✗ Failed to load BSV library:', e.message)
19
- process.exit(1)
20
- }
21
-
22
- // Test 1: Basic functionality test
23
- console.log('\n--- Test 1: Basic Secret Sharing ---')
24
- try {
25
- var secret = 'Hello, Bitcoin SV!'
26
- var threshold = 3
27
- var shares = 5
28
-
29
- console.log('Original secret:', secret)
30
- console.log('Threshold:', threshold, '/ Total shares:', shares)
31
-
32
- // Split the secret
33
- var splitShares = bsv.Shamir.split(secret, threshold, shares)
34
- console.log('✓ Successfully split secret into', splitShares.length, 'shares')
35
-
36
- // Reconstruct with minimum shares
37
- var reconstructed = bsv.Shamir.combine(splitShares.slice(0, threshold))
38
- var reconstructedSecret = reconstructed.toString('utf8')
39
-
40
- console.log('Reconstructed:', reconstructedSecret)
41
-
42
- if (reconstructedSecret === secret) {
43
- console.log('✓ Test 1 PASSED: Secret correctly reconstructed')
44
- } else {
45
- console.log('✗ Test 1 FAILED: Secret reconstruction failed')
46
- }
47
- } catch (e) {
48
- console.log('✗ Test 1 ERROR:', e.message)
49
- }
50
-
51
- // Test 2: Larger secret test
52
- console.log('\n--- Test 2: Large Secret Test ---')
53
- try {
54
- var largeSecret = 'This is a much longer secret that will test the chunking functionality of the Shamir Secret Sharing implementation. It should handle secrets of arbitrary length by breaking them into manageable chunks and processing each chunk separately.'
55
- var threshold2 = 4
56
- var shares2 = 7
57
-
58
- console.log('Large secret length:', largeSecret.length, 'characters')
59
-
60
- var splitShares2 = bsv.Shamir.split(largeSecret, threshold2, shares2)
61
- console.log('✓ Successfully split large secret')
62
-
63
- var reconstructed2 = bsv.Shamir.combine(splitShares2.slice(0, threshold2))
64
- var reconstructedSecret2 = reconstructed2.toString('utf8')
65
-
66
- if (reconstructedSecret2 === largeSecret) {
67
- console.log('✓ Test 2 PASSED: Large secret correctly reconstructed')
68
- } else {
69
- console.log('✗ Test 2 FAILED: Large secret reconstruction failed')
70
- console.log('Expected length:', largeSecret.length)
71
- console.log('Actual length:', reconstructedSecret2.length)
72
- console.log('First 50 chars expected:', largeSecret.substring(0, 50))
73
- console.log('First 50 chars actual :', reconstructedSecret2.substring(0, 50))
74
- console.log('Match:', largeSecret === reconstructedSecret2)
75
- }
76
- } catch (e) {
77
- console.log('✗ Test 2 ERROR:', e.message)
78
- }
79
-
80
- // Test 3: Different share combinations
81
- console.log('\n--- Test 3: Share Combination Test ---')
82
- try {
83
- var secret3 = 'Testing different combinations'
84
- var splitShares3 = bsv.Shamir.split(secret3, 3, 6)
85
-
86
- // Test different combinations of 3 shares
87
- var combinations = [
88
- [0, 1, 2], // First three
89
- [1, 3, 5], // Every other
90
- [2, 4, 5] // Last three + one
91
- ]
92
-
93
- var allPassed = true
94
- for (var i = 0; i < combinations.length; i++) {
95
- var combo = combinations[i]
96
- var testShares = combo.map(function(idx) { return splitShares3[idx] })
97
- var reconstructed3 = bsv.Shamir.combine(testShares)
98
- var result = reconstructed3.toString('utf8')
99
-
100
- if (result === secret3) {
101
- console.log('✓ Combination', combo, 'successful')
102
- } else {
103
- console.log('✗ Combination', combo, 'failed')
104
- allPassed = false
105
- }
106
- }
107
-
108
- if (allPassed) {
109
- console.log('✓ Test 3 PASSED: All share combinations work')
110
- } else {
111
- console.log('✗ Test 3 FAILED: Some combinations failed')
112
- }
113
- } catch (e) {
114
- console.log('✗ Test 3 ERROR:', e.message)
115
- }
116
-
117
- // Test 4: Share verification
118
- console.log('\n--- Test 4: Share Verification Test ---')
119
- try {
120
- var secret4 = 'Verification test'
121
- var splitShares4 = bsv.Shamir.split(secret4, 2, 4)
122
-
123
- var validCount = 0
124
- for (var j = 0; j < splitShares4.length; j++) {
125
- if (bsv.Shamir.verifyShare(splitShares4[j])) {
126
- validCount++
127
- }
128
- }
129
-
130
- if (validCount === splitShares4.length) {
131
- console.log('✓ Test 4 PASSED: All shares verified as valid')
132
- } else {
133
- console.log('✗ Test 4 FAILED: Only', validCount, 'of', splitShares4.length, 'shares valid')
134
- }
135
-
136
- // Test invalid share
137
- var invalidShare = { invalid: 'data' }
138
- if (!bsv.Shamir.verifyShare(invalidShare)) {
139
- console.log('✓ Invalid share correctly rejected')
140
- } else {
141
- console.log('✗ Invalid share incorrectly accepted')
142
- }
143
- } catch (e) {
144
- console.log('✗ Test 4 ERROR:', e.message)
145
- }
146
-
147
- // Test 5: Error handling
148
- console.log('\n--- Test 5: Error Handling Test ---')
149
- try {
150
- var errorTests = [
151
- function() { bsv.Shamir.split('', 2, 3) }, // Empty secret
152
- function() { bsv.Shamir.split('secret', 1, 3) }, // Threshold too low
153
- function() { bsv.Shamir.split('secret', 3, 2) }, // More threshold than shares
154
- function() { bsv.Shamir.combine([]) }, // Empty shares array
155
- function() { bsv.Shamir.combine([{id: 1, threshold: 2, shares: 3, length: 1, bytes: []}]) } // Insufficient shares
156
- ]
157
-
158
- var errorsPassed = 0
159
- for (var k = 0; k < errorTests.length; k++) {
160
- try {
161
- errorTests[k]()
162
- console.log('✗ Error test', k + 1, 'should have thrown an error')
163
- } catch (e) {
164
- console.log('✓ Error test', k + 1, 'correctly threw:', e.message)
165
- errorsPassed++
166
- }
167
- }
168
-
169
- if (errorsPassed === errorTests.length) {
170
- console.log('✓ Test 5 PASSED: All error conditions handled correctly')
171
- } else {
172
- console.log('✗ Test 5 FAILED: Some error conditions not handled')
173
- }
174
- } catch (e) {
175
- console.log('✗ Test 5 ERROR:', e.message)
176
- }
177
-
178
- // Test 6: Binary data test
179
- console.log('\n--- Test 6: Binary Data Test ---')
180
- try {
181
- var binaryData = Buffer.from([0x00, 0x01, 0x02, 0xFF, 0xFE, 0xFD, 0x80, 0x7F])
182
- var splitBinary = bsv.Shamir.split(binaryData, 2, 3)
183
- var reconstructedBinary = bsv.Shamir.combine(splitBinary.slice(0, 2))
184
-
185
- if (Buffer.compare(binaryData, reconstructedBinary) === 0) {
186
- console.log('✓ Test 6 PASSED: Binary data correctly handled')
187
- } else {
188
- console.log('✗ Test 6 FAILED: Binary data reconstruction failed')
189
- console.log('Original:', Array.from(binaryData))
190
- console.log('Reconstructed:', Array.from(reconstructedBinary))
191
- }
192
- } catch (e) {
193
- console.log('✗ Test 6 ERROR:', e.message)
194
- }
195
-
196
- // Test 7: Generate test vectors
197
- console.log('\n--- Test 7: Test Vectors Generation ---')
198
- try {
199
- var testVectors = bsv.Shamir.generateTestVectors()
200
-
201
- console.log('Test vectors generated:')
202
- console.log('- Secret:', testVectors.secret)
203
- console.log('- Threshold:', testVectors.threshold)
204
- console.log('- Total shares:', testVectors.totalShares)
205
- console.log('- Shares generated:', testVectors.shares.length)
206
- console.log('- Reconstruction successful:', testVectors.valid)
207
-
208
- if (testVectors.valid) {
209
- console.log('✓ Test 7 PASSED: Test vectors generated and validated')
210
- } else {
211
- console.log('✗ Test 7 FAILED: Test vectors validation failed')
212
- }
213
- } catch (e) {
214
- console.log('✗ Test 7 ERROR:', e.message)
215
- }
216
-
217
- console.log('\n=== Shamir Secret Sharing Tests Complete ===')
218
- console.log('💡 Integration successful! Shamir Secret Sharing is now available in:')
219
- console.log(' • Main library: bsv.Shamir or bsv.crypto.Shamir')
220
- console.log(' • Standalone: bsv-shamir.min.js (after build)')
221
- console.log(' • CDN ready: Use npm run build-shamir to generate minified version')
@@ -1,110 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Test SmartVerify DER Buffer Handling
5
- *
6
- * Tests SmartVerify with different input types to isolate the DER parsing issue
7
- */
8
-
9
- const bsv = require('./index.js');
10
-
11
- console.log('🔍 Test SmartVerify DER Buffer Handling');
12
- console.log('=======================================\n');
13
-
14
- // Simple signature test like minimal reproduction
15
- const privateKey = new bsv.PrivateKey('L1aW4aubDFB7yfras2S1mN3bqg9nwySY8nkoLmJebSLD5BWv3ENZ');
16
- const publicKey = privateKey.publicKey;
17
- const message = Buffer.from('hello world', 'utf8');
18
- const hash = bsv.crypto.Hash.sha256(message);
19
-
20
- console.log('Creating signature...');
21
- const signature = bsv.crypto.ECDSA.sign(hash, privateKey);
22
- const derSig = signature.toDER();
23
-
24
- console.log(`Original signature r: ${signature.r.toString('hex')}`);
25
- console.log(`Original signature s: ${signature.s.toString('hex')}`);
26
- console.log(`DER buffer: ${derSig.toString('hex')}`);
27
- console.log(`DER length: ${derSig.length}`);
28
-
29
- console.log('\n🧪 SmartVerify Test Matrix:');
30
- console.log('===========================');
31
-
32
- // Test 1: Signature object
33
- const smartVerifyObj = bsv.SmartVerify.smartVerify(hash, signature, publicKey);
34
- console.log(`SmartVerify(hash, sigObject, pubkey): ${smartVerifyObj ? '✅ VALID' : '❌ INVALID'}`);
35
-
36
- // Test 2: DER buffer
37
- const smartVerifyBuffer = bsv.SmartVerify.smartVerify(hash, derSig, publicKey);
38
- console.log(`SmartVerify(hash, derBuffer, pubkey): ${smartVerifyBuffer ? '✅ VALID' : '❌ INVALID'}`);
39
-
40
- // Test 3: Manually parsed DER
41
- try {
42
- const parsedFromDER = bsv.crypto.Signature.fromDER(derSig);
43
- console.log(`Parsed from DER r: ${parsedFromDER.r.toString('hex')}`);
44
- console.log(`Parsed from DER s: ${parsedFromDER.s.toString('hex')}`);
45
-
46
- const smartVerifyParsed = bsv.SmartVerify.smartVerify(hash, parsedFromDER, publicKey);
47
- console.log(`SmartVerify(hash, parsedSig, pubkey): ${smartVerifyParsed ? '✅ VALID' : '❌ INVALID'}`);
48
-
49
- console.log('\n🔍 Compare r,s values:');
50
- console.log('======================');
51
- console.log(`Original r: ${signature.r.toString('hex')}`);
52
- console.log(`Parsed r : ${parsedFromDER.r.toString('hex')}`);
53
- console.log(`r matches : ${signature.r.eq(parsedFromDER.r) ? '✅ YES' : '❌ NO'}`);
54
-
55
- console.log(`Original s: ${signature.s.toString('hex')}`);
56
- console.log(`Parsed s : ${parsedFromDER.s.toString('hex')}`);
57
- console.log(`s matches : ${signature.s.eq(parsedFromDER.s) ? '✅ YES' : '❌ NO'}`);
58
-
59
- } catch (error) {
60
- console.log(`❌ DER parsing failed: ${error.message}`);
61
- }
62
-
63
- console.log('\n🔧 Debug SmartVerify DER Parsing:');
64
- console.log('==================================');
65
-
66
- // Let's manually step through what SmartVerify does with DER buffers
67
- try {
68
- console.log('Step 1: Input validation...');
69
- console.log(` Hash is Buffer: ${Buffer.isBuffer(hash)}`);
70
- console.log(` Hash length: ${hash.length}`);
71
- console.log(` DER is Buffer: ${Buffer.isBuffer(derSig)}`);
72
-
73
- console.log('Step 2: DER parsing in SmartVerify...');
74
-
75
- // This replicates what SmartVerify does internally
76
- const Signature = bsv.crypto.Signature;
77
- const testParsed = Signature.fromDER(derSig);
78
- console.log(` Parsed successfully: ✅`);
79
- console.log(` Parsed r: ${testParsed.r.toString('hex')}`);
80
- console.log(` Parsed s: ${testParsed.s.toString('hex')}`);
81
-
82
- const BN = bsv.crypto.BN;
83
- const r = BN.isBN(testParsed.r) ? testParsed.r : new BN(testParsed.r);
84
- const s = BN.isBN(testParsed.s) ? testParsed.s : new BN(testParsed.s);
85
- console.log(` r as BN: ${r.toString('hex')}`);
86
- console.log(` s as BN: ${s.toString('hex')}`);
87
-
88
- // Check canonicalization
89
- const Point = bsv.crypto.Point;
90
- const n = Point.getN();
91
- const nh = n.shrn(1);
92
- console.log(` s > n/2: ${s.gt(nh)}`);
93
-
94
- const canonicalS = s.gt(nh) ? n.sub(s) : s;
95
- console.log(` canonical s: ${canonicalS.toString('hex')}`);
96
-
97
- // Test final ECDSA call
98
- const canonicalSig = new Signature({
99
- r: r,
100
- s: canonicalS
101
- });
102
-
103
- const ECDSA = bsv.crypto.ECDSA;
104
- const finalResult = ECDSA.verify(hash, canonicalSig, publicKey, 'little');
105
- console.log(` Final ECDSA result: ${finalResult ? '✅ VALID' : '❌ INVALID'}`);
106
-
107
- } catch (error) {
108
- console.log(`❌ Debug failed: ${error.message}`);
109
- console.log(`Stack: ${error.stack}`);
110
- }
@@ -1,178 +0,0 @@
1
- # BIP-143 Preimage Tools
2
-
3
- This directory contains tools and examples for working with Bitcoin BIP-143 transaction preimages.
4
-
5
- ## Files
6
-
7
- ### `extract_preimage_bidirectional.js`
8
- **Advanced bidirectional preimage field extractor with optimal ASM generation**
9
-
10
- Intelligently extracts any BIP-143 preimage field using the most efficient strategy:
11
- - **LEFT extraction** for early fields (nVersion, hashPrevouts, etc.)
12
- - **RIGHT extraction** for late fields (value, nLocktime, sighashType, etc.)
13
- - **DYNAMIC extraction** for variable-length scriptCode
14
-
15
- #### Features
16
- - ✅ Complete BIP-143 specification compliance
17
- - ✅ Optimal operation count for each field
18
- - ✅ Generates production-ready Bitcoin Script ASM
19
- - ✅ Handles variable scriptCode dynamically
20
- - ✅ Robust error handling and validation
21
- - ✅ Field interpretation (satoshis, version numbers, etc.)
22
-
23
- #### Usage
24
- ```bash
25
- # Extract any preimage field
26
- node extract_preimage_bidirectional.js <preimage_hex> <field_name>
27
-
28
- # Examples
29
- node extract_preimage_bidirectional.js 01000000ab12cd... scriptCode
30
- node extract_preimage_bidirectional.js 01000000ab12cd... value
31
- node extract_preimage_bidirectional.js 01000000ab12cd... sighashType
32
- ```
33
-
34
- #### Available Fields
35
-
36
- **LEFT Fields (fixed offsets from start):**
37
- - `nVersion` (4 bytes) - Transaction version
38
- - `hashPrevouts` (32 bytes) - Hash of all input outpoints
39
- - `hashSequence` (32 bytes) - Hash of all input sequences
40
- - `outpoint_txid` (32 bytes) - Current input's previous transaction ID
41
- - `outpoint_vout` (4 bytes) - Current input's previous output index
42
- - `scriptLen` (1 byte) - Length of the scriptCode
43
-
44
- **DYNAMIC Field (uses internal length):**
45
- - `scriptCode` (variable) - The script being executed
46
-
47
- **RIGHT Fields (fixed offsets from end):**
48
- - `value` (8 bytes) - Input amount in satoshis
49
- - `nSequence` (4 bytes) - Current input's sequence number
50
- - `hashOutputs` (32 bytes) - Hash of all outputs
51
- - `nLocktime` (4 bytes) - Transaction lock time
52
- - `sighashType` (4 bytes) - Signature hash type
53
-
54
- #### Integration with Covenant Framework
55
-
56
- The generated ASM can be used directly in covenant locking scripts:
57
-
58
- ```javascript
59
- const { CovenantInterface } = require('../../lib/covenant-interface');
60
-
61
- // Use bidirectional extraction in covenant
62
- const covenant = new CovenantInterface();
63
- const script = covenant.createAdvancedCovenant({
64
- type: 'custom',
65
- rules: {
66
- // Insert generated ASM for preimage field extraction
67
- extractValue: `
68
- # Generated by extract_preimage_bidirectional.js
69
- OP_SIZE
70
- 52 OP_SUB
71
- OP_SPLIT
72
- OP_DROP
73
- 8 OP_SPLIT
74
- OP_DROP
75
- `
76
- }
77
- });
78
- ```
79
-
80
- #### BIP-143 Structure Reference
81
-
82
- ```
83
- Total: LEFT(105) + scriptCode(variable) + RIGHT(52) bytes
84
-
85
- LEFT ZONE (105 bytes): DYNAMIC: RIGHT ZONE (52 bytes):
86
- ├─ nVersion (4) ├─ scriptCode ├─ value (8)
87
- ├─ hashPrevouts (32) └─ (scriptLen bytes) ├─ nSequence (4)
88
- ├─ hashSequence (32) ├─ hashOutputs (32)
89
- ├─ outpoint_txid (32) ├─ nLocktime (4)
90
- ├─ outpoint_vout (4) └─ sighashType (4)
91
- └─ scriptLen (1)
92
- ```
93
-
94
- ## See Also
95
- - `../../docs/preimage.md` - BIP-143 technical specification
96
- - `../../docs/ADVANCED_COVENANT_DEVELOPMENT.md` - Covenant implementation guide
97
- - `../covenants/` - Complete covenant examples using preimage extraction
98
- - `../../lib/covenant-interface.js` - CovenantPreimage class implementation
99
-
100
- ### `generate_sighash_examples.js`
101
- **SIGHASH flag preimage generator demonstrating "zero hash" behavior**
102
-
103
- Explains why multi-input transactions appear to have "extra zeros" - they're not bugs but required by BIP-143 SIGHASH rules:
104
-
105
- #### Features
106
- - ✅ Complete SIGHASH flag support (ALL, NONE, SINGLE, ANYONECANPAY)
107
- - ✅ Demonstrates zero hash field behavior
108
- - ✅ Educational tool for multi-input transaction analysis
109
- - ✅ Integration with bidirectional extractor
110
-
111
- #### Usage
112
- ```bash
113
- # Generate SIGHASH examples
114
- node generate_sighash_examples.js [sighash_type]
115
-
116
- # Examples showing zero hash behavior
117
- node generate_sighash_examples.js ALL_ANYONECANPAY_FORKID # Zero hashPrevouts + hashSequence
118
- node generate_sighash_examples.js NONE_FORKID # Zero hashOutputs
119
- node generate_sighash_examples.js NONE_ANYONECANPAY_FORKID # Zero all hash fields
120
- ```
121
-
122
- #### SIGHASH Flag Behavior
123
- | SIGHASH Type | hashPrevouts | hashSequence | hashOutputs | Use Case |
124
- |--------------|-------------|-------------|-------------|-----------|
125
- | ALL_FORKID | Normal | Normal | Normal | Standard signing |
126
- | NONE_FORKID | Normal | Normal | **Zero** | Blank check |
127
- | SINGLE_FORKID | Normal | Normal | **Zero** | One-to-one |
128
- | ALL_ANYONECANPAY_FORKID | **Zero** | **Zero** | Normal | Crowdfunding |
129
- | NONE_ANYONECANPAY_FORKID | **Zero** | **Zero** | **Zero** | Maximum flexibility |
130
-
131
- ### `test_varint_extraction.js`
132
- **Comprehensive CompactSize varint test suite**
133
-
134
- Validates proper parsing of 1-3 byte CompactSize varints in real-world scenarios:
135
- - 1-byte encoding: 0-252 bytes (most common)
136
- - 3-byte encoding: 253-65535 bytes (large scripts)
137
- - 5-byte encoding: 65536+ bytes (huge scripts)
138
-
139
- ## 🧠 **Understanding the "Extra Zero" Mystery**
140
-
141
- ### The Problem
142
- Developers often see patterns like this in BSV preimages and think it's a bug:
143
- ```
144
- ...1976a914000000000000...
145
- ```
146
-
147
- ### The Reality
148
- These zeros are **intentional** and required by Bitcoin's BIP-143 specification:
149
-
150
- 1. **CompactSize Varint Encoding**
151
- - Scripts ≥253 bytes use 3-byte encoding: `0xFD + 2-byte length`
152
- - This adds "extra bytes" that look like zeros to developers expecting 1-byte
153
-
154
- 2. **SIGHASH Flag Behavior**
155
- - `ANYONECANPAY`: Zeros out `hashPrevouts` and `hashSequence` (64 zero bytes)
156
- - `NONE`: Zeros out `hashOutputs` (32 zero bytes)
157
- - `SINGLE`: Zeros out `hashOutputs` for unmatched outputs
158
-
159
- 3. **Multi-Input Concatenation Issues**
160
- - Wrong byte boundary slicing between inputs
161
- - Reusing preimage buffers without proper re-serialization
162
-
163
- ### The Solution
164
- Our bidirectional extractor handles all these cases:
165
- - ✅ **Auto-detects** CompactSize varint size (1-3 bytes)
166
- - ✅ **Warns about** zero hashes with SIGHASH flag context
167
- - ✅ **Validates** preimage structure against BIP-143
168
- - ✅ **Generates** optimal ASM regardless of complexity
169
-
170
- ## Performance Notes
171
-
172
- The enhanced bidirectional strategy minimizes script operations:
173
- - **LEFT fields**: Direct offset splitting (2-3 operations)
174
- - **RIGHT fields**: Size-based splitting (3-4 operations)
175
- - **scriptCode**: Dynamic extraction using CompactSize varint (3-4 operations)
176
- - **Zero hash detection**: Automatic with contextual warnings
177
-
178
- This is significantly more efficient than linear parsing and handles all BIP-143 edge cases that break traditional parsers.