smartledger-bsv 3.3.5 ā 3.4.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.
- package/CHANGELOG.md +400 -0
- package/README.md +235 -80
- package/SECURITY.md +88 -0
- package/anchor-entry.js +1 -0
- package/bin/cli.js +354 -0
- package/bsv-anchor.min.js +12 -0
- package/bsv-covenant.min.js +8 -8
- package/bsv-didweb.min.js +12 -0
- package/bsv-gdaf.min.js +9 -9
- package/bsv-ltp.min.js +9 -9
- package/bsv-mnemonic.min.js +2 -2
- package/bsv-shamir.min.js +3 -3
- package/bsv-smartcontract.min.js +9 -9
- package/bsv-statuslist.min.js +18 -0
- package/bsv-vcjwt.min.js +12 -0
- package/bsv.bundle.js +9 -9
- package/bsv.d.ts +486 -9
- package/bsv.min.js +8 -8
- package/build/webpack.anchor.config.js +17 -0
- package/build/webpack.didweb.config.js +17 -0
- package/build/webpack.statuslist.config.js +17 -0
- package/build/webpack.vcjwt.config.js +17 -0
- package/didweb-entry.js +1 -0
- package/docs/COVENANT_DEVELOPMENT_RESOLVED.md +2 -2
- package/docs/MODULE_REFERENCE_COMPLETE.md +61 -58
- package/docs/advanced/LEGAL_TOKEN_PROTOCOL.md +3 -3
- package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
- package/docs/getting-started/INSTALLATION.md +30 -30
- package/docs/getting-started/QUICK_START.md +18 -18
- package/docs/migration/FROM_BSV_1_5_6.md +16 -10
- package/docs/technical/roadmap.md +3 -3
- package/gdaf-entry.js +1 -2
- package/index.js +68 -9
- package/lib/anchor/index.js +102 -0
- package/lib/browser-utxo-manager-es5.js +11 -4
- package/lib/browser-utxo-manager.js +15 -8
- package/lib/didweb/index.js +177 -0
- package/lib/ltp/claim.js +1 -0
- package/lib/ltp/obligation.js +1 -0
- package/lib/ltp/registry.js +2 -0
- package/lib/ltp/right.js +1 -0
- package/lib/smart_contract/covenant.js +10 -1
- package/lib/smartutxo.js +20 -12
- package/lib/statuslist/index.js +164 -0
- package/lib/transaction/transaction.js +8 -1
- package/lib/util/_.js +7 -1
- package/lib/vcjwt/index.js +189 -0
- package/ltp-entry.js +1 -2
- package/package.json +21 -15
- package/statuslist-entry.js +1 -0
- package/utilities/blockchain-state.js +32 -23
- package/vcjwt-entry.js +1 -0
- package/demos/README.md +0 -188
- package/demos/architecture_demo.js +0 -247
- package/demos/browser-test.html +0 -1208
- package/demos/bsv_wallet_demo.js +0 -242
- package/demos/complete_ltp_demo.js +0 -511
- package/demos/debug_tools_demo.js +0 -87
- package/demos/demo_features.js +0 -123
- package/demos/easy_interface_demo.js +0 -109
- package/demos/ecies_demo.js +0 -182
- package/demos/gdaf_core_test.js +0 -131
- package/demos/gdaf_demo.js +0 -237
- package/demos/ltp_demo.js +0 -361
- package/demos/ltp_primitives_demo.js +0 -403
- package/demos/message_demo.js +0 -209
- package/demos/preimage_separation_demo.js +0 -383
- package/demos/script_helper_demo.js +0 -289
- package/demos/security_demo.js +0 -287
- package/demos/shamir_demo.js +0 -121
- package/demos/simple_demo.js +0 -204
- package/demos/simple_p2pkh_demo.js +0 -169
- package/demos/simple_utxo_preimage_demo.js +0 -196
- package/demos/smart_contract_demo.html +0 -1347
- package/demos/smart_contract_demo.js +0 -910
- package/demos/utxo_generator_demo.js +0 -244
- package/demos/validation_pipeline_demo.js +0 -155
- package/demos/web3keys.html +0 -740
- package/examples/README.md +0 -200
- package/examples/basic/transaction-creation.js +0 -534
- package/examples/basic/transaction_signature_api_gap.js +0 -178
- package/examples/complete_workflow_demo.js +0 -783
- package/examples/covenants/advanced_covenant_demo.js +0 -219
- package/examples/covenants/covenant_interface_demo.js +0 -270
- package/examples/covenants/covenant_manual_signature_resolved.js +0 -212
- package/examples/covenants/covenant_signature_template.js +0 -117
- package/examples/covenants2/covenant_bidirectional_example.js +0 -262
- package/examples/covenants2/covenant_utils_demo.js +0 -120
- package/examples/covenants2/preimage_covenant_utils.js +0 -287
- package/examples/covenants2/production_integration.js +0 -256
- package/examples/data/covenant_utxos.json +0 -28
- package/examples/data/utxos.json +0 -26
- package/examples/definitive_working_demo.js +0 -261
- package/examples/final_working_contracts.js +0 -338
- package/examples/preimage/README.md +0 -178
- package/examples/preimage/extract_preimage_bidirectional.js +0 -421
- package/examples/preimage/generate_sample_preimage.js +0 -208
- package/examples/preimage/generate_sighash_examples.js +0 -152
- package/examples/preimage/parse_preimage.js +0 -117
- package/examples/preimage/test_preimage_extractor.js +0 -53
- package/examples/preimage/test_varint_extraction.js +0 -95
- package/examples/scripts/custom_script_helper_example.js +0 -273
- package/examples/scripts/custom_script_signature_test.js +0 -344
- package/examples/scripts/script_interpreter.js +0 -193
- package/examples/smart_contract/complete_workflow_demo.js +0 -343
- package/examples/smart_contract/covenant_builder_demo.js +0 -176
- package/examples/smart_contract/script_testing_integration.js +0 -198
- package/examples/smart_contract_templates.js +0 -718
- package/examples/working_smart_contracts.js +0 -348
- package/lib/smart_contract/test_integration.js +0 -269
- package/tests/browser-compatibility/README.md +0 -35
- package/tests/browser-compatibility/test-cdn-vs-local.html +0 -186
- package/tests/browser-compatibility/test-pbkdf2.html +0 -51
- package/tests/bundle-completeness-test.html +0 -131
- package/tests/bundle-demo.html +0 -476
- package/tests/smartcontract-test.html +0 -239
- package/tests/standalone-modules-test.html +0 -260
- package/tests/test.html +0 -612
- package/tests/test_builtin_verify.js +0 -117
- package/tests/test_debug_integration.js +0 -71
- package/tests/test_ecdsa_little.js +0 -70
- package/tests/test_shamir.js +0 -221
- package/tests/test_smartverify_der.js +0 -110
- package/tests/test_standalone_shamir.html +0 -83
- package/tests/unpkg-demo.html +0 -194
- package/utilities/blockchain-state.json +0 -118565
|
@@ -1,718 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Smart Contract Examples - Working Code Templates
|
|
3
|
-
* ===============================================
|
|
4
|
-
*
|
|
5
|
-
* Complete, runnable examples for smartledger-bsv smart contract development.
|
|
6
|
-
* Each example demonstrates different aspects of preimage validation contracts.
|
|
7
|
-
*
|
|
8
|
-
* Usage: node examples/smart_contract_templates.js
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const bsv = require('../index.js')
|
|
12
|
-
const path = require('path')
|
|
13
|
-
|
|
14
|
-
// Enable colored output if available
|
|
15
|
-
let chalk
|
|
16
|
-
try {
|
|
17
|
-
chalk = require('chalk')
|
|
18
|
-
} catch (e) {
|
|
19
|
-
// Fallback for environments without chalk
|
|
20
|
-
chalk = {
|
|
21
|
-
green: (text) => `ā
${text}`,
|
|
22
|
-
red: (text) => `ā ${text}`,
|
|
23
|
-
yellow: (text) => `ā ļø ${text}`,
|
|
24
|
-
blue: (text) => `ā¹ļø ${text}`,
|
|
25
|
-
magenta: (text) => `š® ${text}`,
|
|
26
|
-
cyan: (text) => `š ${text}`,
|
|
27
|
-
bold: (text) => `**${text}**`
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
console.log(chalk.bold.blue('\nš SmartLedger-BSV Smart Contract Templates\n'))
|
|
32
|
-
|
|
33
|
-
// ============================================================================
|
|
34
|
-
// 1. BASIC AMOUNT VALIDATION CONTRACT
|
|
35
|
-
// ============================================================================
|
|
36
|
-
|
|
37
|
-
class BasicAmountContract {
|
|
38
|
-
constructor(expectedAmount) {
|
|
39
|
-
this.expectedAmount = expectedAmount
|
|
40
|
-
this.privateKey = new bsv.PrivateKey()
|
|
41
|
-
this.script = this._buildScript()
|
|
42
|
-
this.address = this._createAddress()
|
|
43
|
-
|
|
44
|
-
console.log(chalk.green(`ā
BasicAmountContract created`))
|
|
45
|
-
console.log(chalk.blue(` Expected Amount: ${expectedAmount} satoshis`))
|
|
46
|
-
console.log(chalk.blue(` Contract Address: ${this.address.toString()}`))
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
_buildScript() {
|
|
50
|
-
const builder = new bsv.SmartContract.CovenantBuilder()
|
|
51
|
-
|
|
52
|
-
const builtScript = builder
|
|
53
|
-
.comment(`Validates payment of exactly ${this.expectedAmount} satoshis`)
|
|
54
|
-
.extractField('value')
|
|
55
|
-
.push(this.expectedAmount)
|
|
56
|
-
.numEqual()
|
|
57
|
-
.verify()
|
|
58
|
-
.build()
|
|
59
|
-
|
|
60
|
-
// Convert to BSV Script object
|
|
61
|
-
return new bsv.Script(builtScript.hex)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
_createAddress() {
|
|
65
|
-
return bsv.SmartContract.utils.createCovenantAddress(this.script)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
validatePayment(preimageHex) {
|
|
69
|
-
try {
|
|
70
|
-
console.log(chalk.yellow('š Testing payment validation...'))
|
|
71
|
-
|
|
72
|
-
const result = bsv.SmartContract.testScript(
|
|
73
|
-
preimageHex,
|
|
74
|
-
this.script.toHex(),
|
|
75
|
-
{ verbose: true }
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
if (result.valid) {
|
|
79
|
-
console.log(chalk.green('ā
Payment validation PASSED'))
|
|
80
|
-
} else {
|
|
81
|
-
console.log(chalk.red('ā Payment validation FAILED'))
|
|
82
|
-
console.log(chalk.red(` Error: ${result.error}`))
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return {
|
|
86
|
-
success: result.valid,
|
|
87
|
-
error: result.error
|
|
88
|
-
}
|
|
89
|
-
} catch (error) {
|
|
90
|
-
console.log(chalk.red('ā Validation error:', error.message))
|
|
91
|
-
return {
|
|
92
|
-
success: false,
|
|
93
|
-
error: error.message
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
getDeploymentInfo() {
|
|
99
|
-
return {
|
|
100
|
-
address: this.address,
|
|
101
|
-
script: {
|
|
102
|
-
asm: this.script.toASM(),
|
|
103
|
-
hex: this.script.toHex()
|
|
104
|
-
},
|
|
105
|
-
expectedAmount: this.expectedAmount
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// ============================================================================
|
|
111
|
-
// 2. MULTI-FIELD VALIDATION CONTRACT
|
|
112
|
-
// ============================================================================
|
|
113
|
-
|
|
114
|
-
class MultiFieldValidationContract {
|
|
115
|
-
constructor(params) {
|
|
116
|
-
this.params = {
|
|
117
|
-
minAmount: params.minAmount,
|
|
118
|
-
maxAmount: params.maxAmount || null,
|
|
119
|
-
requiredOutputsHash: params.requiredOutputsHash || null,
|
|
120
|
-
minLocktime: params.minLocktime || null,
|
|
121
|
-
...params
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
this.privateKey = new bsv.PrivateKey()
|
|
125
|
-
this.script = this._buildScript()
|
|
126
|
-
this.address = this._createAddress()
|
|
127
|
-
|
|
128
|
-
console.log(chalk.green(`ā
MultiFieldValidationContract created`))
|
|
129
|
-
console.log(chalk.blue(` Min Amount: ${this.params.minAmount} satoshis`))
|
|
130
|
-
if (this.params.maxAmount) {
|
|
131
|
-
console.log(chalk.blue(` Max Amount: ${this.params.maxAmount} satoshis`))
|
|
132
|
-
}
|
|
133
|
-
console.log(chalk.blue(` Contract Address: ${this.address.toString()}`))
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
_buildScript() {
|
|
137
|
-
const builder = new bsv.SmartContract.CovenantBuilder()
|
|
138
|
-
|
|
139
|
-
builder
|
|
140
|
-
.comment('Multi-field validation contract')
|
|
141
|
-
.comment(`Minimum amount: ${this.params.minAmount} satoshis`)
|
|
142
|
-
|
|
143
|
-
// Validate minimum amount
|
|
144
|
-
builder
|
|
145
|
-
.extractField('value')
|
|
146
|
-
.push(this.params.minAmount)
|
|
147
|
-
.greaterThanOrEqual()
|
|
148
|
-
.verify()
|
|
149
|
-
|
|
150
|
-
// Validate maximum amount (if specified)
|
|
151
|
-
if (this.params.maxAmount) {
|
|
152
|
-
builder
|
|
153
|
-
.comment(`Maximum amount: ${this.params.maxAmount} satoshis`)
|
|
154
|
-
.extractField('value')
|
|
155
|
-
.push(this.params.maxAmount)
|
|
156
|
-
.lessThanOrEqual()
|
|
157
|
-
.verify()
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Validate outputs (if specified)
|
|
161
|
-
if (this.params.requiredOutputsHash) {
|
|
162
|
-
builder
|
|
163
|
-
.comment('Validate required outputs')
|
|
164
|
-
.extractField('hashOutputs')
|
|
165
|
-
.push(this.params.requiredOutputsHash)
|
|
166
|
-
.equalVerify()
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Validate locktime (if specified)
|
|
170
|
-
if (this.params.minLocktime) {
|
|
171
|
-
builder
|
|
172
|
-
.comment(`Minimum locktime: ${this.params.minLocktime}`)
|
|
173
|
-
.extractField('nLocktime')
|
|
174
|
-
.push(this.params.minLocktime)
|
|
175
|
-
.greaterThanOrEqual()
|
|
176
|
-
.verify()
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const builtScript = builder.build()
|
|
180
|
-
return new bsv.Script(builtScript.hex)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
_createAddress() {
|
|
184
|
-
return bsv.SmartContract.utils.createCovenantAddress(this.script)
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
validateTransaction(preimageHex) {
|
|
188
|
-
try {
|
|
189
|
-
console.log(chalk.yellow('š Testing multi-field validation...'))
|
|
190
|
-
|
|
191
|
-
// Test each field validation
|
|
192
|
-
const results = {}
|
|
193
|
-
|
|
194
|
-
// Test complete script
|
|
195
|
-
const result = bsv.SmartContract.testScript(
|
|
196
|
-
preimageHex,
|
|
197
|
-
this.script.toHex(),
|
|
198
|
-
{ verbose: true }
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
if (result.valid) {
|
|
202
|
-
console.log(chalk.green('ā
All validations PASSED'))
|
|
203
|
-
} else {
|
|
204
|
-
console.log(chalk.red('ā Validation FAILED'))
|
|
205
|
-
console.log(chalk.red(` Error: ${result.error}`))
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return {
|
|
209
|
-
success: result.valid,
|
|
210
|
-
error: result.error,
|
|
211
|
-
details: results
|
|
212
|
-
}
|
|
213
|
-
} catch (error) {
|
|
214
|
-
console.log(chalk.red('ā Validation error:', error.message))
|
|
215
|
-
return {
|
|
216
|
-
success: false,
|
|
217
|
-
error: error.message
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// ============================================================================
|
|
224
|
-
// 3. ESCROW CONTRACT
|
|
225
|
-
// ============================================================================
|
|
226
|
-
|
|
227
|
-
class EscrowContract {
|
|
228
|
-
constructor(params) {
|
|
229
|
-
this.params = {
|
|
230
|
-
buyerPubKey: params.buyerPubKey,
|
|
231
|
-
sellerPubKey: params.sellerPubKey,
|
|
232
|
-
arbiterPubKey: params.arbiterPubKey,
|
|
233
|
-
escrowAmount: params.escrowAmount,
|
|
234
|
-
timeoutBlocks: params.timeoutBlocks,
|
|
235
|
-
...params
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
this.privateKey = new bsv.PrivateKey()
|
|
239
|
-
this.script = this._buildScript()
|
|
240
|
-
this.address = this._createAddress()
|
|
241
|
-
|
|
242
|
-
console.log(chalk.green(`ā
EscrowContract created`))
|
|
243
|
-
console.log(chalk.blue(` Escrow Amount: ${this.params.escrowAmount} satoshis`))
|
|
244
|
-
console.log(chalk.blue(` Timeout: ${this.params.timeoutBlocks} blocks`))
|
|
245
|
-
console.log(chalk.blue(` Contract Address: ${this.address.toString()}`))
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
_buildScript() {
|
|
249
|
-
const builder = new bsv.SmartContract.CovenantBuilder()
|
|
250
|
-
|
|
251
|
-
const builtScript = builder
|
|
252
|
-
.comment('Escrow contract with 2-of-3 release or timeout refund')
|
|
253
|
-
.comment(`Amount: ${this.params.escrowAmount} satoshis`)
|
|
254
|
-
.comment(`Timeout: ${this.params.timeoutBlocks} blocks`)
|
|
255
|
-
|
|
256
|
-
// Validate escrow amount
|
|
257
|
-
.extractField('value')
|
|
258
|
-
.push(this.params.escrowAmount)
|
|
259
|
-
.greaterThanOrEqual()
|
|
260
|
-
.verify()
|
|
261
|
-
|
|
262
|
-
// Additional escrow logic would go here
|
|
263
|
-
// This is a simplified version for demonstration
|
|
264
|
-
|
|
265
|
-
.build()
|
|
266
|
-
|
|
267
|
-
return new bsv.Script(builtScript.hex)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
_createAddress() {
|
|
271
|
-
return bsv.SmartContract.utils.createCovenantAddress(this.script)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
createReleaseTransaction(utxo, beneficiary, arbiterSignature) {
|
|
275
|
-
// Create transaction that releases funds to beneficiary
|
|
276
|
-
const tx = new bsv.Transaction()
|
|
277
|
-
.from({
|
|
278
|
-
txId: utxo.txid,
|
|
279
|
-
outputIndex: utxo.vout,
|
|
280
|
-
script: this.script.toHex(),
|
|
281
|
-
satoshis: utxo.satoshis
|
|
282
|
-
})
|
|
283
|
-
.to(beneficiary, this.params.escrowAmount - 1000) // minus fee
|
|
284
|
-
|
|
285
|
-
return tx
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
createRefundTransaction(utxo, refundAddress) {
|
|
289
|
-
// Create transaction that refunds to original sender after timeout
|
|
290
|
-
const tx = new bsv.Transaction()
|
|
291
|
-
.from({
|
|
292
|
-
txId: utxo.txid,
|
|
293
|
-
outputIndex: utxo.vout,
|
|
294
|
-
script: this.script.toHex(),
|
|
295
|
-
satoshis: utxo.satoshis
|
|
296
|
-
})
|
|
297
|
-
.to(refundAddress, this.params.escrowAmount - 1000) // minus fee
|
|
298
|
-
|
|
299
|
-
return tx
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// ============================================================================
|
|
304
|
-
// 4. SUBSCRIPTION CONTRACT
|
|
305
|
-
// ============================================================================
|
|
306
|
-
|
|
307
|
-
class SubscriptionContract {
|
|
308
|
-
constructor(params) {
|
|
309
|
-
this.params = {
|
|
310
|
-
serviceProvider: params.serviceProvider,
|
|
311
|
-
monthlyAmount: params.monthlyAmount,
|
|
312
|
-
maxPayments: params.maxPayments,
|
|
313
|
-
...params
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
this.privateKey = new bsv.PrivateKey()
|
|
317
|
-
this.script = this._buildScript()
|
|
318
|
-
this.address = this._createAddress()
|
|
319
|
-
|
|
320
|
-
console.log(chalk.green(`ā
SubscriptionContract created`))
|
|
321
|
-
console.log(chalk.blue(` Monthly Amount: ${this.params.monthlyAmount} satoshis`))
|
|
322
|
-
console.log(chalk.blue(` Max Payments: ${this.params.maxPayments}`))
|
|
323
|
-
console.log(chalk.blue(` Provider: ${this.params.serviceProvider}`))
|
|
324
|
-
console.log(chalk.blue(` Contract Address: ${this.address.toString()}`))
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
_buildScript() {
|
|
328
|
-
const builder = new bsv.SmartContract.CovenantBuilder()
|
|
329
|
-
|
|
330
|
-
const builtScript = builder
|
|
331
|
-
.comment('Subscription contract with fixed monthly payments')
|
|
332
|
-
.comment(`Monthly: ${this.params.monthlyAmount} satoshis`)
|
|
333
|
-
.comment(`Max payments: ${this.params.maxPayments}`)
|
|
334
|
-
|
|
335
|
-
// Validate payment amount
|
|
336
|
-
.extractField('value')
|
|
337
|
-
.push(this.params.monthlyAmount)
|
|
338
|
-
.numEqual()
|
|
339
|
-
.verify()
|
|
340
|
-
|
|
341
|
-
// Additional subscription logic would go here
|
|
342
|
-
// Payment counting, provider validation, etc.
|
|
343
|
-
|
|
344
|
-
.build()
|
|
345
|
-
|
|
346
|
-
return new bsv.Script(builtScript.hex)
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
_createAddress() {
|
|
350
|
-
return bsv.SmartContract.utils.createCovenantAddress(this.script)
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// ============================================================================
|
|
355
|
-
// 5. COMPLETE WORKFLOW DEMONSTRATION
|
|
356
|
-
// ============================================================================
|
|
357
|
-
|
|
358
|
-
class ContractWorkflowDemo {
|
|
359
|
-
constructor() {
|
|
360
|
-
console.log(chalk.bold.magenta('\nš Complete Contract Workflow Demonstration\n'))
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
async demonstrateFullWorkflow() {
|
|
364
|
-
console.log(chalk.cyan('Step 1: Create a basic payment validation contract'))
|
|
365
|
-
|
|
366
|
-
// Step 1: Create contract
|
|
367
|
-
const contract = new BasicAmountContract(100000) // 100,000 sats
|
|
368
|
-
|
|
369
|
-
console.log(chalk.cyan('\nStep 2: Deploy contract (simulate)'))
|
|
370
|
-
const deploymentInfo = contract.getDeploymentInfo()
|
|
371
|
-
console.log('Contract Script (ASM):', deploymentInfo.script.asm)
|
|
372
|
-
console.log('Contract Script (Hex):', deploymentInfo.script.hex)
|
|
373
|
-
|
|
374
|
-
console.log(chalk.cyan('\nStep 3: Generate test UTXO and preimage'))
|
|
375
|
-
|
|
376
|
-
// Create a test UTXO that funds the contract
|
|
377
|
-
const utxoGenerator = new bsv.SmartContract.UTXOGenerator({
|
|
378
|
-
network: 'testnet',
|
|
379
|
-
apiKey: 'test'
|
|
380
|
-
})
|
|
381
|
-
|
|
382
|
-
// Generate test preimage for validation
|
|
383
|
-
try {
|
|
384
|
-
const testPreimage = this._generateTestPreimage(contract, 100000)
|
|
385
|
-
|
|
386
|
-
console.log(chalk.cyan('\nStep 4: Validate contract execution'))
|
|
387
|
-
const validationResult = contract.validatePayment(testPreimage)
|
|
388
|
-
|
|
389
|
-
if (validationResult.success) {
|
|
390
|
-
console.log(chalk.green('ā
Contract workflow completed successfully!'))
|
|
391
|
-
} else {
|
|
392
|
-
console.log(chalk.red('ā Contract validation failed'))
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
} catch (error) {
|
|
396
|
-
console.log(chalk.yellow('ā ļø Test preimage generation skipped (requires real UTXO)'))
|
|
397
|
-
console.log(chalk.blue(' In production, you would:'))
|
|
398
|
-
console.log(chalk.blue(' 1. Fund the contract address'))
|
|
399
|
-
console.log(chalk.blue(' 2. Create spending transaction'))
|
|
400
|
-
console.log(chalk.blue(' 3. Generate preimage from spending transaction'))
|
|
401
|
-
console.log(chalk.blue(' 4. Validate against contract'))
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
_generateTestPreimage(contract, amount) {
|
|
406
|
-
// This would generate a real preimage in production
|
|
407
|
-
// For demo purposes, we'll return a placeholder
|
|
408
|
-
const dummyTx = new bsv.Transaction()
|
|
409
|
-
.from({
|
|
410
|
-
txId: 'a'.repeat(64),
|
|
411
|
-
outputIndex: 0,
|
|
412
|
-
script: contract.script.toHex(),
|
|
413
|
-
satoshis: 200000
|
|
414
|
-
})
|
|
415
|
-
.to(contract.address, amount)
|
|
416
|
-
|
|
417
|
-
// Generate preimage
|
|
418
|
-
return bsv.Transaction.sighash.sighashPreimage(
|
|
419
|
-
dummyTx,
|
|
420
|
-
bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID,
|
|
421
|
-
0,
|
|
422
|
-
contract.script,
|
|
423
|
-
new bsv.crypto.BN(200000)
|
|
424
|
-
).toString('hex')
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// ============================================================================
|
|
429
|
-
// 6. CONTRACT TESTING FRAMEWORK
|
|
430
|
-
// ============================================================================
|
|
431
|
-
|
|
432
|
-
class ContractTester {
|
|
433
|
-
constructor() {
|
|
434
|
-
this.testResults = []
|
|
435
|
-
console.log(chalk.bold.yellow('\nš§Ŗ Smart Contract Testing Framework\n'))
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
async testAllContracts() {
|
|
439
|
-
console.log(chalk.cyan('Running comprehensive contract tests...\n'))
|
|
440
|
-
|
|
441
|
-
// Test 1: Basic Amount Contract
|
|
442
|
-
await this._testBasicAmountContract()
|
|
443
|
-
|
|
444
|
-
// Test 2: Multi-Field Contract
|
|
445
|
-
await this._testMultiFieldContract()
|
|
446
|
-
|
|
447
|
-
// Test 3: Escrow Contract
|
|
448
|
-
await this._testEscrowContract()
|
|
449
|
-
|
|
450
|
-
// Test 4: Subscription Contract
|
|
451
|
-
await this._testSubscriptionContract()
|
|
452
|
-
|
|
453
|
-
// Print results
|
|
454
|
-
this._printTestResults()
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
async _testBasicAmountContract() {
|
|
458
|
-
console.log(chalk.blue('Test 1: Basic Amount Contract'))
|
|
459
|
-
|
|
460
|
-
try {
|
|
461
|
-
const contract = new BasicAmountContract(50000)
|
|
462
|
-
|
|
463
|
-
// Test with testFieldExtraction
|
|
464
|
-
const testPreimage = this._createMockPreimage({
|
|
465
|
-
value: 50000,
|
|
466
|
-
version: 2,
|
|
467
|
-
locktime: 0
|
|
468
|
-
})
|
|
469
|
-
|
|
470
|
-
// Test field extraction specifically
|
|
471
|
-
const fieldTest = bsv.SmartContract.testFieldExtraction(
|
|
472
|
-
testPreimage,
|
|
473
|
-
'value'
|
|
474
|
-
)
|
|
475
|
-
|
|
476
|
-
console.log(chalk.blue(' Field extraction ASM:'), fieldTest)
|
|
477
|
-
|
|
478
|
-
this.testResults.push({
|
|
479
|
-
name: 'Basic Amount Contract - Creation',
|
|
480
|
-
passed: true,
|
|
481
|
-
details: 'Contract created successfully'
|
|
482
|
-
})
|
|
483
|
-
|
|
484
|
-
} catch (error) {
|
|
485
|
-
console.log(chalk.red('ā Basic amount contract test failed:', error.message))
|
|
486
|
-
this.testResults.push({
|
|
487
|
-
name: 'Basic Amount Contract',
|
|
488
|
-
passed: false,
|
|
489
|
-
error: error.message
|
|
490
|
-
})
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
async _testMultiFieldContract() {
|
|
495
|
-
console.log(chalk.blue('Test 2: Multi-Field Contract'))
|
|
496
|
-
|
|
497
|
-
try {
|
|
498
|
-
const contract = new MultiFieldValidationContract({
|
|
499
|
-
minAmount: 100000,
|
|
500
|
-
maxAmount: 500000,
|
|
501
|
-
minLocktime: 600000
|
|
502
|
-
})
|
|
503
|
-
|
|
504
|
-
this.testResults.push({
|
|
505
|
-
name: 'Multi-Field Contract - Creation',
|
|
506
|
-
passed: true,
|
|
507
|
-
details: 'Multi-field contract created successfully'
|
|
508
|
-
})
|
|
509
|
-
|
|
510
|
-
} catch (error) {
|
|
511
|
-
console.log(chalk.red('ā Multi-field contract test failed:', error.message))
|
|
512
|
-
this.testResults.push({
|
|
513
|
-
name: 'Multi-Field Contract',
|
|
514
|
-
passed: false,
|
|
515
|
-
error: error.message
|
|
516
|
-
})
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
async _testEscrowContract() {
|
|
521
|
-
console.log(chalk.blue('Test 3: Escrow Contract'))
|
|
522
|
-
|
|
523
|
-
try {
|
|
524
|
-
const buyer = new bsv.PrivateKey()
|
|
525
|
-
const seller = new bsv.PrivateKey()
|
|
526
|
-
const arbiter = new bsv.PrivateKey()
|
|
527
|
-
|
|
528
|
-
const contract = new EscrowContract({
|
|
529
|
-
buyerPubKey: buyer.publicKey,
|
|
530
|
-
sellerPubKey: seller.publicKey,
|
|
531
|
-
arbiterPubKey: arbiter.publicKey,
|
|
532
|
-
escrowAmount: 1000000,
|
|
533
|
-
timeoutBlocks: 144
|
|
534
|
-
})
|
|
535
|
-
|
|
536
|
-
this.testResults.push({
|
|
537
|
-
name: 'Escrow Contract - Creation',
|
|
538
|
-
passed: true,
|
|
539
|
-
details: 'Escrow contract created successfully'
|
|
540
|
-
})
|
|
541
|
-
|
|
542
|
-
} catch (error) {
|
|
543
|
-
console.log(chalk.red('ā Escrow contract test failed:', error.message))
|
|
544
|
-
this.testResults.push({
|
|
545
|
-
name: 'Escrow Contract',
|
|
546
|
-
passed: false,
|
|
547
|
-
error: error.message
|
|
548
|
-
})
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
async _testSubscriptionContract() {
|
|
553
|
-
console.log(chalk.blue('Test 4: Subscription Contract'))
|
|
554
|
-
|
|
555
|
-
try {
|
|
556
|
-
const provider = new bsv.Address('1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2')
|
|
557
|
-
|
|
558
|
-
const contract = new SubscriptionContract({
|
|
559
|
-
serviceProvider: provider,
|
|
560
|
-
monthlyAmount: 10000000, // 0.1 BSV per month
|
|
561
|
-
maxPayments: 12
|
|
562
|
-
})
|
|
563
|
-
|
|
564
|
-
this.testResults.push({
|
|
565
|
-
name: 'Subscription Contract - Creation',
|
|
566
|
-
passed: true,
|
|
567
|
-
details: 'Subscription contract created successfully'
|
|
568
|
-
})
|
|
569
|
-
|
|
570
|
-
} catch (error) {
|
|
571
|
-
console.log(chalk.red('ā Subscription contract test failed:', error.message))
|
|
572
|
-
this.testResults.push({
|
|
573
|
-
name: 'Subscription Contract',
|
|
574
|
-
passed: false,
|
|
575
|
-
error: error.message
|
|
576
|
-
})
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
_createMockPreimage(params) {
|
|
581
|
-
// Create a simplified mock preimage for testing
|
|
582
|
-
// In production, use real transaction preimages
|
|
583
|
-
|
|
584
|
-
const version = Buffer.alloc(4)
|
|
585
|
-
version.writeUInt32LE(params.version || 2)
|
|
586
|
-
|
|
587
|
-
const hashPrevouts = Buffer.alloc(32, 0)
|
|
588
|
-
const hashSequence = Buffer.alloc(32, 0)
|
|
589
|
-
|
|
590
|
-
const outpoint = Buffer.alloc(36)
|
|
591
|
-
const scriptLen = Buffer.from([0]) // 0-length script
|
|
592
|
-
|
|
593
|
-
const value = Buffer.alloc(8)
|
|
594
|
-
value.writeUInt32LE(params.value || 0, 0)
|
|
595
|
-
|
|
596
|
-
const sequence = Buffer.alloc(4, 0xff)
|
|
597
|
-
const hashOutputs = Buffer.alloc(32, 0)
|
|
598
|
-
|
|
599
|
-
const locktime = Buffer.alloc(4)
|
|
600
|
-
locktime.writeUInt32LE(params.locktime || 0)
|
|
601
|
-
|
|
602
|
-
const sighash = Buffer.alloc(4)
|
|
603
|
-
sighash.writeUInt32LE(0x41) // SIGHASH_ALL | SIGHASH_FORKID
|
|
604
|
-
|
|
605
|
-
return Buffer.concat([
|
|
606
|
-
version,
|
|
607
|
-
hashPrevouts,
|
|
608
|
-
hashSequence,
|
|
609
|
-
outpoint,
|
|
610
|
-
scriptLen,
|
|
611
|
-
value,
|
|
612
|
-
sequence,
|
|
613
|
-
hashOutputs,
|
|
614
|
-
locktime,
|
|
615
|
-
sighash
|
|
616
|
-
]).toString('hex')
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
_printTestResults() {
|
|
620
|
-
console.log(chalk.bold.cyan('\nš Test Results Summary'))
|
|
621
|
-
console.log(chalk.cyan('========================\n'))
|
|
622
|
-
|
|
623
|
-
let passed = 0
|
|
624
|
-
let failed = 0
|
|
625
|
-
|
|
626
|
-
this.testResults.forEach(result => {
|
|
627
|
-
if (result.passed) {
|
|
628
|
-
console.log(chalk.green(`ā
${result.name}`))
|
|
629
|
-
if (result.details) console.log(chalk.blue(` ${result.details}`))
|
|
630
|
-
passed++
|
|
631
|
-
} else {
|
|
632
|
-
console.log(chalk.red(`ā ${result.name}`))
|
|
633
|
-
if (result.error) console.log(chalk.red(` Error: ${result.error}`))
|
|
634
|
-
failed++
|
|
635
|
-
}
|
|
636
|
-
})
|
|
637
|
-
|
|
638
|
-
console.log(chalk.cyan(`\nTotal: ${this.testResults.length} tests`))
|
|
639
|
-
console.log(chalk.green(`Passed: ${passed}`))
|
|
640
|
-
console.log(chalk.red(`Failed: ${failed}`))
|
|
641
|
-
|
|
642
|
-
if (failed === 0) {
|
|
643
|
-
console.log(chalk.bold.green('\nš All tests passed!'))
|
|
644
|
-
} else {
|
|
645
|
-
console.log(chalk.bold.yellow('\nā ļø Some tests failed. Review errors above.'))
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
// ============================================================================
|
|
651
|
-
// 7. MAIN EXECUTION
|
|
652
|
-
// ============================================================================
|
|
653
|
-
|
|
654
|
-
async function main() {
|
|
655
|
-
try {
|
|
656
|
-
console.log(chalk.bold.blue('Smart Contract Templates Demo'))
|
|
657
|
-
console.log(chalk.blue('============================\n'))
|
|
658
|
-
|
|
659
|
-
// Create example contracts
|
|
660
|
-
console.log(chalk.bold.cyan('1. Creating Example Contracts\n'))
|
|
661
|
-
|
|
662
|
-
const basicContract = new BasicAmountContract(100000)
|
|
663
|
-
console.log()
|
|
664
|
-
|
|
665
|
-
const multiContract = new MultiFieldValidationContract({
|
|
666
|
-
minAmount: 50000,
|
|
667
|
-
maxAmount: 200000,
|
|
668
|
-
minLocktime: 600000
|
|
669
|
-
})
|
|
670
|
-
console.log()
|
|
671
|
-
|
|
672
|
-
const escrowContract = new EscrowContract({
|
|
673
|
-
buyerPubKey: new bsv.PrivateKey().publicKey,
|
|
674
|
-
sellerPubKey: new bsv.PrivateKey().publicKey,
|
|
675
|
-
arbiterPubKey: new bsv.PrivateKey().publicKey,
|
|
676
|
-
escrowAmount: 1000000,
|
|
677
|
-
timeoutBlocks: 144
|
|
678
|
-
})
|
|
679
|
-
console.log()
|
|
680
|
-
|
|
681
|
-
// Run workflow demo
|
|
682
|
-
const workflowDemo = new ContractWorkflowDemo()
|
|
683
|
-
await workflowDemo.demonstrateFullWorkflow()
|
|
684
|
-
|
|
685
|
-
// Run tests
|
|
686
|
-
const tester = new ContractTester()
|
|
687
|
-
await tester.testAllContracts()
|
|
688
|
-
|
|
689
|
-
console.log(chalk.bold.green('\nšÆ Smart Contract Templates Demo Complete!\n'))
|
|
690
|
-
|
|
691
|
-
// Show usage instructions
|
|
692
|
-
console.log(chalk.bold.yellow('Next Steps:'))
|
|
693
|
-
console.log(chalk.yellow('1. Use these templates as starting points for your contracts'))
|
|
694
|
-
console.log(chalk.yellow('2. Modify the validation logic for your specific use cases'))
|
|
695
|
-
console.log(chalk.yellow('3. Test thoroughly before deploying to mainnet'))
|
|
696
|
-
console.log(chalk.yellow('4. Consider security implications and edge cases'))
|
|
697
|
-
console.log(chalk.yellow('5. See the full guide in docs/SMART_CONTRACT_DEVELOPMENT_GUIDE.md'))
|
|
698
|
-
|
|
699
|
-
} catch (error) {
|
|
700
|
-
console.error(chalk.bold.red('Demo Error:'), error.message)
|
|
701
|
-
console.error(chalk.red('Stack:'), error.stack)
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
// Export classes for use in other modules
|
|
706
|
-
module.exports = {
|
|
707
|
-
BasicAmountContract,
|
|
708
|
-
MultiFieldValidationContract,
|
|
709
|
-
EscrowContract,
|
|
710
|
-
SubscriptionContract,
|
|
711
|
-
ContractWorkflowDemo,
|
|
712
|
-
ContractTester
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
// Run demo if executed directly
|
|
716
|
-
if (require.main === module) {
|
|
717
|
-
main().catch(console.error)
|
|
718
|
-
}
|