@smartledger/bsv 3.1.1 → 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.
- package/CHANGELOG.md +123 -1
- package/README.md +233 -277
- package/bsv.bundle.js +39 -0
- package/bsv.min.js +8 -8
- package/docs/ADVANCED_COVENANT_DEVELOPMENT.md +533 -0
- package/docs/COVENANT_DEVELOPMENT_RESOLVED.md +169 -0
- package/docs/CUSTOM_SCRIPT_DEVELOPMENT.md +320 -0
- package/docs/README.md +201 -0
- package/docs/block.md +46 -0
- package/docs/ecies.md +102 -0
- package/docs/index.md +104 -0
- package/docs/nchain.md +958 -0
- package/docs/networks.md +55 -0
- package/docs/preimage.md +126 -0
- package/docs/script.md +139 -0
- package/docs/transaction.md +174 -0
- package/docs/unspentoutput.md +32 -0
- package/examples/README.md +200 -0
- package/examples/basic/transaction-creation.js +534 -0
- package/examples/basic/transaction_signature_api_gap.js +178 -0
- package/examples/covenants/advanced_covenant_demo.js +219 -0
- package/examples/covenants/covenant_interface_demo.js +270 -0
- package/examples/covenants/covenant_manual_signature_resolved.js +212 -0
- package/examples/covenants/covenant_signature_template.js +117 -0
- package/examples/covenants2/covenant_bidirectional_example.js +262 -0
- package/examples/covenants2/covenant_utils_demo.js +120 -0
- package/examples/covenants2/preimage_covenant_utils.js +287 -0
- package/examples/covenants2/production_integration.js +256 -0
- package/examples/data/covenant_utxos.json +28 -0
- package/examples/data/utxos.json +26 -0
- package/examples/preimage/README.md +178 -0
- package/examples/preimage/extract_preimage_bidirectional.js +421 -0
- package/examples/preimage/generate_sample_preimage.js +208 -0
- package/examples/preimage/generate_sighash_examples.js +152 -0
- package/examples/preimage/parse_preimage.js +117 -0
- package/examples/preimage/test_preimage_extractor.js +53 -0
- package/examples/preimage/test_varint_extraction.js +95 -0
- package/examples/scripts/custom_script_helper_example.js +273 -0
- package/examples/scripts/custom_script_signature_test.js +344 -0
- package/examples/scripts/script_interpreter.js +193 -0
- package/examples/smart_contract/complete_workflow_demo.js +343 -0
- package/examples/smart_contract/covenant_builder_demo.js +176 -0
- package/examples/smart_contract/script_testing_integration.js +198 -0
- package/index.js +3 -0
- package/lib/covenant-interface.js +713 -0
- package/lib/opcode.js +14 -7
- package/lib/smart_contract/API_REFERENCE.md +862 -0
- package/lib/smart_contract/DOCUMENTATION_SUMMARY.md +201 -0
- package/lib/smart_contract/EXAMPLES.md +751 -0
- package/lib/smart_contract/QUICK_START.md +549 -0
- package/lib/smart_contract/README.md +395 -0
- package/lib/smart_contract/builder.js +452 -0
- package/lib/smart_contract/covenant.js +336 -0
- package/lib/smart_contract/covenant_builder.js +512 -0
- package/lib/smart_contract/index.js +350 -0
- package/lib/smart_contract/opcode_list.js +30 -0
- package/lib/smart_contract/opcode_map.js +1174 -0
- package/lib/smart_contract/opcodes.md +1173 -0
- package/lib/smart_contract/preimage.js +903 -0
- package/lib/smart_contract/script_interpreter.js +236 -0
- package/lib/smart_contract/script_tester.js +487 -0
- package/lib/smart_contract/script_utils.js +621 -0
- package/lib/smart_contract/sighash.js +310 -0
- package/lib/smart_contract/smartledger-opcode_review.md +70 -0
- package/lib/smart_contract/stack_examiner.js +129 -0
- package/lib/smart_contract/test_integration.js +269 -0
- package/lib/smart_contract/utxo_generator.js +367 -0
- package/package.json +43 -10
- package/utilities/blockchain-state.json +20478 -3
|
@@ -0,0 +1,862 @@
|
|
|
1
|
+
# SmartContract API Reference
|
|
2
|
+
|
|
3
|
+
**SmartLedger-BSV v3.2.0** - Complete JavaScript-to-Bitcoin Script Framework
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Quick Start](#quick-start)
|
|
8
|
+
2. [Core Classes](#core-classes)
|
|
9
|
+
3. [Interface Functions (52 Total)](#interface-functions)
|
|
10
|
+
4. [JavaScript-to-Script Framework](#javascript-to-script-framework)
|
|
11
|
+
5. [CovenantBuilder API (61 Methods)](#covenantbuilder-api)
|
|
12
|
+
6. [Opcode Mapping System](#opcode-mapping-system)
|
|
13
|
+
7. [Debug and Analysis Tools](#debug-and-analysis-tools)
|
|
14
|
+
8. [Real-World Examples](#real-world-examples)
|
|
15
|
+
9. [Error Handling](#error-handling)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
const SmartContract = require('bsv-elliptic-fix').SmartContract
|
|
23
|
+
|
|
24
|
+
// 🚀 Write covenant logic in JavaScript
|
|
25
|
+
const builder = SmartContract.createCovenantBuilder()
|
|
26
|
+
const covenant = builder
|
|
27
|
+
.extractField('value') // Extract value from preimage
|
|
28
|
+
.push('50c3000000000000') // Expected minimum value
|
|
29
|
+
.greaterThanOrEqual() // Ensure value >= minimum
|
|
30
|
+
.verify() // Assert condition
|
|
31
|
+
.build()
|
|
32
|
+
|
|
33
|
+
console.log('Generated ASM:', covenant.cleanedASM)
|
|
34
|
+
console.log('Generated Hex:', covenant.hex)
|
|
35
|
+
|
|
36
|
+
// 🧪 Simulate script execution
|
|
37
|
+
const result = SmartContract.simulateScript(['OP_1', 'OP_2', 'OP_ADD'])
|
|
38
|
+
console.log('Final stack:', result.finalStack) // ['03']
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Core Classes
|
|
44
|
+
|
|
45
|
+
### SmartContract.Covenant
|
|
46
|
+
**Production-ready covenant creation and management**
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
const privateKey = bsv.PrivateKey.fromRandom()
|
|
50
|
+
const covenant = SmartContract.createCovenant(privateKey, {
|
|
51
|
+
storageDir: './covenants'
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
// Create covenant from P2PKH UTXO
|
|
55
|
+
const result = covenant.createFromP2PKH({
|
|
56
|
+
txid: 'abc123...',
|
|
57
|
+
vout: 0,
|
|
58
|
+
satoshis: 100000,
|
|
59
|
+
script: 'p2pkh_script_hex'
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// Complete workflow
|
|
63
|
+
const flow = covenant.completeFlow(p2pkhUtxo, (tx, phase) => {
|
|
64
|
+
console.log(`${phase} transaction:`, tx.id)
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### SmartContract.Preimage
|
|
69
|
+
**BIP-143 preimage parsing with enhanced CompactSize varint support**
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
const preimage = SmartContract.extractPreimage(preimageHex, {
|
|
73
|
+
strategy: 'DYNAMIC' // AUTO-DETECT best extraction method
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
const fields = preimage.extract()
|
|
77
|
+
console.log('Script code:', fields.scriptCode.toString('hex'))
|
|
78
|
+
console.log('Amount:', fields.amount.toString('hex'))
|
|
79
|
+
|
|
80
|
+
// Handle the "zero hash mystery"
|
|
81
|
+
const sighashInfo = preimage.getSighashInfo()
|
|
82
|
+
if (sighashInfo.hasZeroHashes) {
|
|
83
|
+
console.log('Zero hash explanation:', SmartContract.explainZeroHashes())
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### SmartContract.SIGHASH
|
|
88
|
+
**SIGHASH flag analysis and zero hash behavior explanation**
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
const sighash = SmartContract.analyzeSIGHASH(0x41) // SIGHASH_ALL | FORKID
|
|
92
|
+
const analysis = sighash.analyze()
|
|
93
|
+
|
|
94
|
+
console.log('Flag name:', analysis.flagName)
|
|
95
|
+
console.log('Has ANYONECANPAY:', analysis.anyoneCanPay)
|
|
96
|
+
console.log('Zero hash behavior:', sighash.getZeroHashBehavior())
|
|
97
|
+
|
|
98
|
+
// Educational demonstrations
|
|
99
|
+
const allTypes = SmartContract.getAllSIGHASHTypes()
|
|
100
|
+
const demos = SmartContract.demonstrateAllSIGHASH()
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### SmartContract.CovenantBuilder
|
|
104
|
+
**High-level JavaScript-to-Bitcoin Script API**
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
const builder = SmartContract.createCovenantBuilder()
|
|
108
|
+
|
|
109
|
+
// Fluent API with 61 methods
|
|
110
|
+
const covenant = builder
|
|
111
|
+
.comment('Check minimum value requirement')
|
|
112
|
+
.extractField('value')
|
|
113
|
+
.push('1000000') // 1M satoshis
|
|
114
|
+
.greaterThanOrEqual()
|
|
115
|
+
.verify()
|
|
116
|
+
.build()
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Interface Functions
|
|
122
|
+
|
|
123
|
+
### Core Operations (5 functions)
|
|
124
|
+
|
|
125
|
+
#### `createCovenant(privateKey, options)`
|
|
126
|
+
Creates a new Covenant instance for covenant management.
|
|
127
|
+
|
|
128
|
+
```javascript
|
|
129
|
+
const covenant = SmartContract.createCovenant(privateKey, {
|
|
130
|
+
storageDir: './my-covenants',
|
|
131
|
+
network: 'mainnet'
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### `extractPreimage(preimageHex, options)`
|
|
136
|
+
Parses BIP-143 preimage with advanced field extraction.
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
const preimage = SmartContract.extractPreimage(preimageHex, {
|
|
140
|
+
strategy: 'DYNAMIC', // LEFT, RIGHT, or DYNAMIC
|
|
141
|
+
validateFields: true, // Validate extracted fields
|
|
142
|
+
detectSIGHASH: true // Analyze SIGHASH flags
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
const fields = preimage.extract()
|
|
146
|
+
console.log('Extracted fields:', Object.keys(fields))
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### `analyzeSIGHASH(sighashType)`
|
|
150
|
+
Analyzes SIGHASH flags and explains zero hash behavior.
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
const analysis = SmartContract.analyzeSIGHASH(0x41)
|
|
154
|
+
console.log('Flag details:', analysis.analyze())
|
|
155
|
+
console.log('Zero behavior:', analysis.getZeroHashBehavior())
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### `buildCovenant(privateKey, options)`
|
|
159
|
+
Creates advanced covenant builder with multi-field validation.
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
const builder = SmartContract.buildCovenant(privateKey, {
|
|
163
|
+
validateFields: ['hashPrevouts', 'amount'],
|
|
164
|
+
customRules: [/* custom validation functions */]
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### `completeCovenantFlow(privateKey, p2pkhUtxo, broadcastCallback)`
|
|
169
|
+
Executes complete covenant workflow from creation to spending.
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
const result = SmartContract.completeCovenantFlow(
|
|
173
|
+
privateKey,
|
|
174
|
+
p2pkhUtxo,
|
|
175
|
+
(transaction, phase) => {
|
|
176
|
+
console.log(`Broadcasting ${phase} transaction...`)
|
|
177
|
+
// Your broadcast logic here
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### JavaScript-to-Script Framework (7 functions)
|
|
183
|
+
|
|
184
|
+
#### `createCovenantBuilder()`
|
|
185
|
+
Creates a new CovenantBuilder instance for fluent script construction.
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
const builder = SmartContract.createCovenantBuilder()
|
|
189
|
+
|
|
190
|
+
// Chain operations fluently
|
|
191
|
+
const script = builder
|
|
192
|
+
.push('deadbeef')
|
|
193
|
+
.sha256()
|
|
194
|
+
.push('expected_hash')
|
|
195
|
+
.equal()
|
|
196
|
+
.verify()
|
|
197
|
+
.build()
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### `createValueLockCovenant(expectedValue)`
|
|
201
|
+
Creates a covenant that validates minimum value requirements.
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
const valueLock = SmartContract.createValueLockCovenant('50c3000000000000')
|
|
205
|
+
const script = valueLock.build()
|
|
206
|
+
|
|
207
|
+
console.log('Value lock ASM:', script.cleanedASM)
|
|
208
|
+
// Output: OP_SIZE 22 OP_SUB OP_SPLIT OP_DROP OP_8 OP_SPLIT OP_DROP 50c3000000000000 OP_GREATERTHANOREQUAL OP_VERIFY
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### `createHashLockCovenant(expectedHash)`
|
|
212
|
+
Creates a covenant that validates hash preimage requirements.
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
const hashLock = SmartContract.createHashLockCovenant('abcd1234')
|
|
216
|
+
const script = hashLock.build()
|
|
217
|
+
|
|
218
|
+
console.log('Hash lock operations:', script.operations.length)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### `createComplexValidationCovenant(rules)`
|
|
222
|
+
Creates a covenant with multiple validation rules.
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
const complex = SmartContract.createComplexValidationCovenant({
|
|
226
|
+
fields: {
|
|
227
|
+
value: { equals: '50c3000000000000' },
|
|
228
|
+
hashPrevouts: { notEquals: '0000000000000000000000000000000000000000000000000000000000000000' }
|
|
229
|
+
},
|
|
230
|
+
customLogic: builder => builder.push('custom_data').verify()
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### `getOpcodeMap()`
|
|
235
|
+
Returns the complete mapping of 121 Bitcoin Script opcodes.
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
const opcodes = SmartContract.getOpcodeMap()
|
|
239
|
+
|
|
240
|
+
console.log('Total opcodes:', Object.keys(opcodes).length) // 121
|
|
241
|
+
console.log('OP_ADD details:', opcodes.OP_ADD)
|
|
242
|
+
// { code: 0x93, action: function, description: 'Add two numbers', category: 'arithmetic' }
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
#### `simulateScript(operations, initialStack)`
|
|
246
|
+
Simulates Bitcoin Script execution with step-by-step debugging.
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
const simulation = SmartContract.simulateScript(['OP_1', 'OP_2', 'OP_ADD'], [])
|
|
250
|
+
|
|
251
|
+
console.log('Final stack:', simulation.finalStack) // ['03']
|
|
252
|
+
console.log('Execution steps:', simulation.history) // Detailed step history
|
|
253
|
+
console.log('Success:', simulation.success) // true
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
#### `createASMFromJS(operations)`
|
|
257
|
+
Converts JavaScript operation array to Bitcoin Script ASM.
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
const asm = SmartContract.createASMFromJS(['OP_DUP', 'OP_HASH160', 'deadbeef', 'OP_EQUALVERIFY'])
|
|
261
|
+
|
|
262
|
+
console.log('Generated ASM:', asm)
|
|
263
|
+
// Output: "OP_DUP OP_HASH160 deadbeef OP_EQUALVERIFY"
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Testing & Debugging (5 functions)
|
|
267
|
+
|
|
268
|
+
#### `testScript(unlockingScript, lockingScript, options)`
|
|
269
|
+
Tests script execution with unlocking and locking scripts.
|
|
270
|
+
|
|
271
|
+
```javascript
|
|
272
|
+
const result = SmartContract.testScript('OP_1', 'OP_VERIFY', {
|
|
273
|
+
enableDebug: true,
|
|
274
|
+
strict: true
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
console.log('Script valid:', result.valid)
|
|
278
|
+
console.log('Execution trace:', result.trace)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### `testCovenant(preimageHex, constraints, options)`
|
|
282
|
+
Tests covenant validation against preimage data.
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
const result = SmartContract.testCovenant(preimageHex, {
|
|
286
|
+
value: { min: 1000000 },
|
|
287
|
+
hashPrevouts: { notZero: true }
|
|
288
|
+
}, { enableLogging: true })
|
|
289
|
+
|
|
290
|
+
console.log('Covenant valid:', result.success)
|
|
291
|
+
console.log('Validation details:', result.validations)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
#### `testFieldExtraction(preimageHex, fieldName, options)`
|
|
295
|
+
Tests specific field extraction from preimage.
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
const result = SmartContract.testFieldExtraction(preimageHex, 'value', {
|
|
299
|
+
strategy: 'DYNAMIC',
|
|
300
|
+
validateResult: true
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
console.log('Extracted value:', result.extracted)
|
|
304
|
+
console.log('Extraction strategy used:', result.strategyUsed)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
#### `debugScript(config, options)`
|
|
308
|
+
Provides detailed script debugging and analysis.
|
|
309
|
+
|
|
310
|
+
```javascript
|
|
311
|
+
const debug = SmartContract.debugScript({
|
|
312
|
+
script: ['OP_1', 'OP_2', 'OP_ADD'],
|
|
313
|
+
breakpoints: [1, 2],
|
|
314
|
+
watchStack: true
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
console.log('Debug info:', debug.analysis)
|
|
318
|
+
console.log('Stack snapshots:', debug.stackSnapshots)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### `createTestEnvironment(options)`
|
|
322
|
+
Creates comprehensive testing environment with real UTXOs.
|
|
323
|
+
|
|
324
|
+
```javascript
|
|
325
|
+
const testEnv = SmartContract.createTestEnvironment({
|
|
326
|
+
generateUTXO: true,
|
|
327
|
+
createPreimage: true,
|
|
328
|
+
network: 'testnet'
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
console.log('Test UTXO:', testEnv.utxo)
|
|
332
|
+
console.log('Test preimage:', testEnv.preimage)
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Educational Resources (4 functions)
|
|
336
|
+
|
|
337
|
+
#### `explainZeroHashes()`
|
|
338
|
+
Explains the "zero hash mystery" in Bitcoin preimages.
|
|
339
|
+
|
|
340
|
+
```javascript
|
|
341
|
+
const explanation = SmartContract.explainZeroHashes()
|
|
342
|
+
|
|
343
|
+
console.log('Title:', explanation.title)
|
|
344
|
+
console.log('Problem:', explanation.problem)
|
|
345
|
+
console.log('Reality:', explanation.reality)
|
|
346
|
+
console.log('Solution:', explanation.solution)
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
#### `getAllSIGHASHTypes()`
|
|
350
|
+
Returns all SIGHASH flag types with descriptions.
|
|
351
|
+
|
|
352
|
+
```javascript
|
|
353
|
+
const types = SmartContract.getAllSIGHASHTypes()
|
|
354
|
+
|
|
355
|
+
types.forEach(type => {
|
|
356
|
+
console.log(`${type.name}: 0x${type.value.toString(16)} - ${type.description}`)
|
|
357
|
+
})
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### `demonstrateAllSIGHASH()`
|
|
361
|
+
Generates educational demonstrations for all SIGHASH types.
|
|
362
|
+
|
|
363
|
+
```javascript
|
|
364
|
+
const demos = SmartContract.demonstrateAllSIGHASH()
|
|
365
|
+
|
|
366
|
+
demos.forEach(demo => {
|
|
367
|
+
console.log(`${demo.typeName}:`)
|
|
368
|
+
console.log(' Behavior:', demo.demonstration.behavior)
|
|
369
|
+
console.log(' Zero hashes:', demo.demonstration.zeroHashes)
|
|
370
|
+
})
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
#### `getEducationalResources()`
|
|
374
|
+
Returns comprehensive educational materials.
|
|
375
|
+
|
|
376
|
+
```javascript
|
|
377
|
+
const resources = SmartContract.getEducationalResources()
|
|
378
|
+
|
|
379
|
+
console.log('Zero hash mystery:', resources.zeroHashMystery)
|
|
380
|
+
console.log('SIGHASH types:', resources.sighashTypes.length)
|
|
381
|
+
console.log('Example demos:', resources.exampleDemonstrations.length)
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Utility Functions (8 functions)
|
|
385
|
+
|
|
386
|
+
#### Constructor Classes (4 functions)
|
|
387
|
+
- `Covenant` - Covenant management class
|
|
388
|
+
- `Preimage` - Preimage parsing class
|
|
389
|
+
- `SIGHASH` - SIGHASH analysis class
|
|
390
|
+
- `Builder` - Advanced covenant builder class
|
|
391
|
+
|
|
392
|
+
#### Generators (4 functions)
|
|
393
|
+
- `UTXOGenerator` - Real UTXO generation class
|
|
394
|
+
- `ScriptTester` - Script testing utilities class
|
|
395
|
+
- `CovenantBuilder` - JavaScript-to-Script builder class
|
|
396
|
+
- `OpcodeMap` - Opcode mapping utilities class
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## JavaScript-to-Script Framework
|
|
401
|
+
|
|
402
|
+
The revolutionary framework allows you to write covenant logic in JavaScript and automatically generate Bitcoin Script.
|
|
403
|
+
|
|
404
|
+
### Basic Workflow
|
|
405
|
+
|
|
406
|
+
```javascript
|
|
407
|
+
// 1. Create builder
|
|
408
|
+
const builder = SmartContract.createCovenantBuilder()
|
|
409
|
+
|
|
410
|
+
// 2. Write logic in JavaScript
|
|
411
|
+
const covenant = builder
|
|
412
|
+
.comment('Validate transaction value')
|
|
413
|
+
.extractField('value') // Get value from preimage
|
|
414
|
+
.push('1000000') // 1M satoshis minimum
|
|
415
|
+
.greaterThanOrEqual() // value >= 1M
|
|
416
|
+
.verify() // Assert condition
|
|
417
|
+
.build()
|
|
418
|
+
|
|
419
|
+
// 3. Get Bitcoin Script output
|
|
420
|
+
console.log('ASM:', covenant.cleanedASM)
|
|
421
|
+
console.log('Hex:', covenant.hex)
|
|
422
|
+
console.log('Size:', covenant.operations.length, 'operations')
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Advanced Example: Multi-condition Covenant
|
|
426
|
+
|
|
427
|
+
```javascript
|
|
428
|
+
const builder = SmartContract.createCovenantBuilder()
|
|
429
|
+
|
|
430
|
+
const covenant = builder
|
|
431
|
+
.comment('Multi-condition covenant validation')
|
|
432
|
+
|
|
433
|
+
// Condition 1: Check minimum value
|
|
434
|
+
.extractField('value')
|
|
435
|
+
.push('1000000')
|
|
436
|
+
.greaterThanOrEqual()
|
|
437
|
+
.verify()
|
|
438
|
+
|
|
439
|
+
// Condition 2: Verify hash preimage
|
|
440
|
+
.push('deadbeef')
|
|
441
|
+
.sha256()
|
|
442
|
+
.push('expected_hash_of_deadbeef')
|
|
443
|
+
.equalVerify()
|
|
444
|
+
|
|
445
|
+
// Condition 3: Time lock validation
|
|
446
|
+
.extractField('nLockTime')
|
|
447
|
+
.push('1609459200') // Jan 1, 2021
|
|
448
|
+
.greaterThan()
|
|
449
|
+
.verify()
|
|
450
|
+
|
|
451
|
+
.build()
|
|
452
|
+
|
|
453
|
+
console.log('Complex covenant ASM:', covenant.cleanedASM)
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## CovenantBuilder API
|
|
459
|
+
|
|
460
|
+
The CovenantBuilder provides 61 methods for fluent covenant construction:
|
|
461
|
+
|
|
462
|
+
### Stack Operations (12 methods)
|
|
463
|
+
```javascript
|
|
464
|
+
builder
|
|
465
|
+
.push('data') // Push data onto stack
|
|
466
|
+
.dup() // Duplicate top item
|
|
467
|
+
.drop() // Remove top item
|
|
468
|
+
.swap() // Swap top two items
|
|
469
|
+
.over() // Copy second item to top
|
|
470
|
+
.rot() // Rotate top three items
|
|
471
|
+
.pick(depth) // Copy item at depth to top
|
|
472
|
+
.roll(depth) // Move item at depth to top
|
|
473
|
+
.depth() // Push stack depth
|
|
474
|
+
.size() // Push size of top item
|
|
475
|
+
.left(n) // Take left n bytes
|
|
476
|
+
.right(n) // Take right n bytes
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Arithmetic Operations (10 methods)
|
|
480
|
+
```javascript
|
|
481
|
+
builder
|
|
482
|
+
.add() // Add top two numbers
|
|
483
|
+
.sub() // Subtract: second - first
|
|
484
|
+
.mul() // Multiply top two numbers
|
|
485
|
+
.div() // Divide: second / first
|
|
486
|
+
.mod() // Modulo: second % first
|
|
487
|
+
.abs() // Absolute value
|
|
488
|
+
.negate() // Negate number
|
|
489
|
+
.min() // Minimum of two numbers
|
|
490
|
+
.max() // Maximum of two numbers
|
|
491
|
+
.within() // Check if x is within min/max
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Comparison Operations (8 methods)
|
|
495
|
+
```javascript
|
|
496
|
+
builder
|
|
497
|
+
.equal() // Check equality
|
|
498
|
+
.equalVerify() // Check equality and verify
|
|
499
|
+
.numEqual() // Numeric equality
|
|
500
|
+
.numNotEqual() // Numeric inequality
|
|
501
|
+
.lessThan() // Less than comparison
|
|
502
|
+
.lessThanOrEqual() // Less than or equal
|
|
503
|
+
.greaterThan() // Greater than comparison
|
|
504
|
+
.greaterThanOrEqual() // Greater than or equal
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### Logical Operations (6 methods)
|
|
508
|
+
```javascript
|
|
509
|
+
builder
|
|
510
|
+
.and() // Bitwise AND
|
|
511
|
+
.or() // Bitwise OR
|
|
512
|
+
.xor() // Bitwise XOR
|
|
513
|
+
.not() // Bitwise NOT
|
|
514
|
+
.boolAnd() // Boolean AND
|
|
515
|
+
.boolOr() // Boolean OR
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Cryptographic Operations (5 methods)
|
|
519
|
+
```javascript
|
|
520
|
+
builder
|
|
521
|
+
.hash160() // RIPEMD160(SHA256(x))
|
|
522
|
+
.hash256() // SHA256(SHA256(x))
|
|
523
|
+
.sha256() // SHA256(x)
|
|
524
|
+
.ripemd160() // RIPEMD160(x)
|
|
525
|
+
.invert() // Bitwise inversion
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Control Flow (4 methods)
|
|
529
|
+
```javascript
|
|
530
|
+
builder
|
|
531
|
+
.if() // Conditional execution
|
|
532
|
+
.else() // Else branch
|
|
533
|
+
.endif() // End conditional
|
|
534
|
+
.verify() // Assert top item is true
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### Data Manipulation (8 methods)
|
|
538
|
+
```javascript
|
|
539
|
+
builder
|
|
540
|
+
.split() // Split data at position
|
|
541
|
+
.cat() // Concatenate two items
|
|
542
|
+
.substr(start, length) // Extract substring
|
|
543
|
+
.size() // Get size of data
|
|
544
|
+
.left(n) // Take left n bytes
|
|
545
|
+
.right(n) // Take right n bytes
|
|
546
|
+
.extractField(name) // Extract preimage field
|
|
547
|
+
.validateField(name, expected) // Validate field value
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### Utility Methods (8 methods)
|
|
551
|
+
```javascript
|
|
552
|
+
builder
|
|
553
|
+
.comment(text) // Add documentation comment
|
|
554
|
+
.document(section) // Add documentation section
|
|
555
|
+
.simulate() // Simulate script execution
|
|
556
|
+
.build() // Build final script
|
|
557
|
+
.validateFields(fields) // Validate multiple fields
|
|
558
|
+
.validateRange(min, max) // Validate numeric range
|
|
559
|
+
.return() // Return from script
|
|
560
|
+
._analyzeStructure() // Internal: analyze script structure
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
## Opcode Mapping System
|
|
566
|
+
|
|
567
|
+
All 121 Bitcoin Script opcodes are mapped to JavaScript functions:
|
|
568
|
+
|
|
569
|
+
### Categories
|
|
570
|
+
|
|
571
|
+
1. **Constants (16 opcodes)**: `OP_FALSE`, `OP_TRUE`, `OP_1` through `OP_16`
|
|
572
|
+
2. **Push Data (4 opcodes)**: `OP_PUSHDATA1`, `OP_PUSHDATA2`, `OP_PUSHDATA4`
|
|
573
|
+
3. **Flow Control (6 opcodes)**: `OP_IF`, `OP_ELSE`, `OP_ENDIF`, `OP_VERIFY`, `OP_RETURN`
|
|
574
|
+
4. **Stack Operations (17 opcodes)**: `OP_DUP`, `OP_DROP`, `OP_SWAP`, etc.
|
|
575
|
+
5. **String Operations (8 opcodes)**: `OP_CAT`, `OP_SPLIT`, `OP_SIZE`, etc.
|
|
576
|
+
6. **Bitwise Logic (4 opcodes)**: `OP_AND`, `OP_OR`, `OP_XOR`, `OP_INVERT`
|
|
577
|
+
7. **Arithmetic (11 opcodes)**: `OP_ADD`, `OP_SUB`, `OP_MUL`, `OP_DIV`, etc.
|
|
578
|
+
8. **Comparison (8 opcodes)**: `OP_EQUAL`, `OP_LESSTHAN`, `OP_GREATERTHAN`, etc.
|
|
579
|
+
9. **Cryptographic (6 opcodes)**: `OP_SHA256`, `OP_HASH160`, `OP_CHECKSIG`, etc.
|
|
580
|
+
10. **Reserved (3 opcodes)**: `OP_RESERVED`, `OP_VER`, `OP_VERIF`
|
|
581
|
+
11. **Splice Operations (4 opcodes)**: `OP_LEFT`, `OP_RIGHT`, `OP_SUBSTR`
|
|
582
|
+
12. **Numeric (17 opcodes)**: `OP_1ADD`, `OP_1SUB`, `OP_NEGATE`, etc.
|
|
583
|
+
13. **Disabled (18 opcodes)**: Previously disabled opcodes now mapped
|
|
584
|
+
|
|
585
|
+
### Usage Example
|
|
586
|
+
|
|
587
|
+
```javascript
|
|
588
|
+
const opcodes = SmartContract.getOpcodeMap()
|
|
589
|
+
|
|
590
|
+
// Get specific opcode
|
|
591
|
+
console.log('OP_ADD:', opcodes.OP_ADD)
|
|
592
|
+
// { code: 0x93, action: function, description: 'Add two numbers', category: 'arithmetic' }
|
|
593
|
+
|
|
594
|
+
// Simulate specific opcode
|
|
595
|
+
const stack = ['02', '03'] // [2, 3]
|
|
596
|
+
const newStack = opcodes.OP_ADD.action(stack)
|
|
597
|
+
console.log('Result stack:', newStack) // ['05'] (2 + 3 = 5)
|
|
598
|
+
```
|
|
599
|
+
|
|
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
|
+
|
|
709
|
+
## Real-World Examples
|
|
710
|
+
|
|
711
|
+
### Example 1: Value-Preserving Covenant
|
|
712
|
+
|
|
713
|
+
```javascript
|
|
714
|
+
// Ensure transaction doesn't reduce value
|
|
715
|
+
const covenant = SmartContract.createCovenantBuilder()
|
|
716
|
+
.comment('Value preservation covenant')
|
|
717
|
+
.extractField('value') // Get current transaction value
|
|
718
|
+
.push('original_value_hex') // Expected original value
|
|
719
|
+
.greaterThanOrEqual() // Ensure value >= original
|
|
720
|
+
.verify() // Assert condition
|
|
721
|
+
.build()
|
|
722
|
+
|
|
723
|
+
console.log('Generated script size:', covenant.operations.length)
|
|
724
|
+
console.log('ASM:', covenant.cleanedASM)
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
### Example 2: Hash Lock with Time Delay
|
|
728
|
+
|
|
729
|
+
```javascript
|
|
730
|
+
const covenant = SmartContract.createCovenantBuilder()
|
|
731
|
+
.comment('Hash lock with time delay')
|
|
732
|
+
|
|
733
|
+
// Check if correct preimage is provided
|
|
734
|
+
.push('secret_data')
|
|
735
|
+
.sha256()
|
|
736
|
+
.push('expected_hash')
|
|
737
|
+
.equal()
|
|
738
|
+
|
|
739
|
+
// OR check if enough time has passed
|
|
740
|
+
.if()
|
|
741
|
+
.push(1) // Valid preimage path
|
|
742
|
+
.else()
|
|
743
|
+
.extractField('nLockTime')
|
|
744
|
+
.push('1640995200') // Jan 1, 2022
|
|
745
|
+
.greaterThan()
|
|
746
|
+
.endif()
|
|
747
|
+
|
|
748
|
+
.verify()
|
|
749
|
+
.build()
|
|
750
|
+
|
|
751
|
+
// Test the covenant
|
|
752
|
+
const simulation = SmartContract.simulateScript(covenant.operations)
|
|
753
|
+
console.log('Simulation result:', simulation.success)
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
### Example 3: Multi-Signature with Spending Conditions
|
|
757
|
+
|
|
758
|
+
```javascript
|
|
759
|
+
const covenant = SmartContract.createCovenantBuilder()
|
|
760
|
+
.comment('Multi-sig with spending conditions')
|
|
761
|
+
|
|
762
|
+
// Require 2-of-3 signatures (simplified)
|
|
763
|
+
.push('sig1')
|
|
764
|
+
.push('sig2')
|
|
765
|
+
.push('sig3')
|
|
766
|
+
.push(2) // Require 2 signatures
|
|
767
|
+
// ... multi-sig verification logic ...
|
|
768
|
+
|
|
769
|
+
// AND require minimum output value
|
|
770
|
+
.extractField('value')
|
|
771
|
+
.push('100000') // 100k satoshis minimum
|
|
772
|
+
.greaterThanOrEqual()
|
|
773
|
+
.verify()
|
|
774
|
+
|
|
775
|
+
.build()
|
|
776
|
+
|
|
777
|
+
console.log('Multi-sig covenant ASM:', covenant.cleanedASM)
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
---
|
|
781
|
+
|
|
782
|
+
## Error Handling
|
|
783
|
+
|
|
784
|
+
### Script Validation
|
|
785
|
+
|
|
786
|
+
```javascript
|
|
787
|
+
try {
|
|
788
|
+
const covenant = builder.build()
|
|
789
|
+
|
|
790
|
+
// Validate generated script
|
|
791
|
+
const validation = SmartContract.validateScript(covenant.operations)
|
|
792
|
+
if (!validation.valid) {
|
|
793
|
+
console.log('Script validation errors:', validation.errors)
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
} catch (error) {
|
|
797
|
+
console.log('Build error:', error.message)
|
|
798
|
+
}
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### Simulation Error Handling
|
|
802
|
+
|
|
803
|
+
```javascript
|
|
804
|
+
const simulation = SmartContract.simulateScript(['OP_1', 'OP_VERIFY'])
|
|
805
|
+
|
|
806
|
+
if (!simulation.success) {
|
|
807
|
+
console.log('Simulation failed:', simulation.error)
|
|
808
|
+
console.log('Failed at step:', simulation.failedStep)
|
|
809
|
+
console.log('Stack at failure:', simulation.stackAtFailure)
|
|
810
|
+
}
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
### Preimage Extraction Errors
|
|
814
|
+
|
|
815
|
+
```javascript
|
|
816
|
+
try {
|
|
817
|
+
const preimage = SmartContract.extractPreimage(preimageHex)
|
|
818
|
+
const fields = preimage.extract()
|
|
819
|
+
|
|
820
|
+
// Check for warnings
|
|
821
|
+
const validation = preimage.validate()
|
|
822
|
+
if (validation.warnings.length > 0) {
|
|
823
|
+
console.log('Extraction warnings:', validation.warnings)
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
} catch (error) {
|
|
827
|
+
console.log('Preimage extraction failed:', error.message)
|
|
828
|
+
}
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
---
|
|
832
|
+
|
|
833
|
+
## Performance Considerations
|
|
834
|
+
|
|
835
|
+
### Script Size Optimization
|
|
836
|
+
|
|
837
|
+
```javascript
|
|
838
|
+
// Use built-in optimization (if available)
|
|
839
|
+
const optimized = SmartContract.optimizeScript(covenant.operations)
|
|
840
|
+
console.log('Original size:', covenant.operations.length)
|
|
841
|
+
console.log('Optimized size:', optimized.length)
|
|
842
|
+
|
|
843
|
+
// Estimate script execution cost
|
|
844
|
+
const metrics = SmartContract.scriptMetrics(covenant.operations)
|
|
845
|
+
console.log('Estimated cost:', metrics.estimatedCost)
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
### Simulation Performance
|
|
849
|
+
|
|
850
|
+
```javascript
|
|
851
|
+
// For large scripts, use step limits
|
|
852
|
+
const simulation = SmartContract.simulateScript(operations, [], {
|
|
853
|
+
maxSteps: 10000,
|
|
854
|
+
enableLogging: false // Disable for performance
|
|
855
|
+
})
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
---
|
|
859
|
+
|
|
860
|
+
This API reference provides comprehensive coverage of all SmartContract functionality. The JavaScript-to-Bitcoin Script framework enables developers to write complex covenant logic in familiar JavaScript syntax while automatically generating optimized Bitcoin Script output.
|
|
861
|
+
|
|
862
|
+
For additional examples and tutorials, see the `/docs` directory in the repository.
|