@smartledger/bsv 7.8.1 → 7.10.0
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 +117 -6
- package/README.md +38 -38
- package/bsv-covenant.min.js +1 -1
- package/bsv-ecies.min.js +1 -1
- package/bsv-gdaf.min.js +54 -54
- package/bsv-ltp.min.js +58 -85
- package/bsv-message.min.js +2 -2
- package/bsv-mnemonic.min.js +12 -14
- package/bsv-script-helper.min.js +1 -1
- package/bsv-shamir.min.js +14 -16
- package/bsv-smartcontract.min.js +23 -25
- package/bsv.bundle.js +54 -54
- package/bsv.min.js +54 -54
- package/build/esbuild.js +84 -4
- package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
- package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
- package/docs/getting-started/INSTALLATION.md +23 -23
- package/docs/getting-started/QUICK_START.md +7 -7
- package/docs/migration/FROM_BSV_1_5_6.md +5 -5
- package/index.js +9 -1
- package/lib/covenant/helpers.js +146 -0
- package/lib/covenant/index.js +21 -0
- package/lib/covenant/pushtx.js +243 -0
- package/lib/covenant-interface.js +408 -397
- package/lib/custom-script-helper.js +44 -38
- package/lib/ecies/bitcore-ecies.js +3 -4
- package/lib/ecies/electrum-ecies.js +4 -6
- package/lib/ecies/errors.js +1 -1
- package/lib/gdaf/attestation-signer.js +7 -7
- package/lib/gdaf/attestation-verifier.js +5 -6
- package/lib/gdaf/did-resolver.js +10 -9
- package/lib/gdaf/smartledger-anchor.js +13 -12
- package/lib/gdaf/zk-prover.js +8 -8
- package/lib/ltp/anchor.js +2 -3
- package/lib/ltp/claim.js +2 -3
- package/lib/ltp/index.js +2 -3
- package/lib/ltp/obligation.js +9 -9
- package/lib/ltp/proof.js +7 -7
- package/lib/ltp/registry.js +4 -5
- package/lib/ltp/right.js +11 -11
- package/lib/message/index.js +5 -4
- package/lib/message/message.js +11 -11
- package/lib/mnemonic/errors.js +1 -1
- package/lib/mnemonic/index.js +5 -4
- package/lib/mnemonic/mnemonic.js +22 -10
- package/lib/ordinals/bsv20.js +4 -4
- package/lib/ordinals/inscription.js +8 -12
- package/lib/ordinals/ordlock.js +26 -21
- package/lib/script/interpreter.js +96 -31
- package/lib/smart_contract/authorizers.js +8 -6
- package/lib/smart_contract/builder.js +32 -26
- package/lib/smart_contract/covenant.js +32 -25
- package/lib/smart_contract/covenant_helpers.js +8 -128
- package/lib/smart_contract/debugger.js +9 -6
- package/lib/smart_contract/dsl.js +5 -6
- package/lib/smart_contract/index.js +11 -8
- package/lib/smart_contract/locks.js +3 -4
- package/lib/smart_contract/opcode_list.js +2 -3
- package/lib/smart_contract/pels.js +4 -5
- package/lib/smart_contract/preimage.js +11 -7
- package/lib/smart_contract/pushtx.js +8 -263
- package/lib/smart_contract/script_interpreter.js +112 -105
- package/lib/smart_contract/script_tester.js +24 -18
- package/lib/smart_contract/script_utils.js +15 -14
- package/lib/smart_contract/sighash.js +23 -15
- package/lib/smart_contract/stack_examiner.js +70 -63
- package/lib/smart_contract/token.js +6 -6
- package/lib/smart_contract/utxo_generator.js +21 -15
- package/lib/smartutxo.js +27 -21
- package/lib/spv/headerchain.js +3 -3
- package/lib/spv/merkleproof.js +3 -3
- package/package.json +4 -2
- package/test/script/chronicle.js +53 -10
- package/test/script/interpreter.js +9 -6
- package/test/script/string_ops.js +26 -10
- package/version.js +1 -1
|
@@ -13,7 +13,13 @@
|
|
|
13
13
|
|
|
14
14
|
'use strict'
|
|
15
15
|
|
|
16
|
-
var
|
|
16
|
+
var sighash = require('../transaction/sighash')
|
|
17
|
+
var Interpreter = require('../script/interpreter')
|
|
18
|
+
var Signature = require('../crypto/signature')
|
|
19
|
+
var Hash = require('../crypto/hash')
|
|
20
|
+
var BN = require('../crypto/bn')
|
|
21
|
+
var Transaction = require('../transaction')
|
|
22
|
+
var Script = require('../script')
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
25
|
* @deprecated NON-ENFORCING. `buildLockingScript` / `createCovenant` emit
|
|
@@ -45,7 +51,7 @@ function Builder(privateKey, options) {
|
|
|
45
51
|
this.validationRules = []
|
|
46
52
|
|
|
47
53
|
this.sighashType = this.options.sighashType ||
|
|
48
|
-
(
|
|
54
|
+
(Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID)
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
// The scripts this class builds are non-enforcing (see the class @deprecated note).
|
|
@@ -125,7 +131,7 @@ Builder.prototype.useTemplate = function(template, params) {
|
|
|
125
131
|
*/
|
|
126
132
|
Builder.prototype.buildLockingScript = function(preimageData) {
|
|
127
133
|
this._assertEnforcingAllowed()
|
|
128
|
-
var script = new
|
|
134
|
+
var script = new Script()
|
|
129
135
|
|
|
130
136
|
if (this.scriptTemplate) {
|
|
131
137
|
return this._buildFromTemplate(preimageData)
|
|
@@ -143,17 +149,17 @@ Builder.prototype.buildLockingScript = function(preimageData) {
|
|
|
143
149
|
* @returns {Script} Constructed unlocking script
|
|
144
150
|
*/
|
|
145
151
|
Builder.prototype.buildUnlockingScript = function(spendingTx, inputIndex, covenantData) {
|
|
146
|
-
var script = new
|
|
152
|
+
var script = new Script()
|
|
147
153
|
|
|
148
154
|
// Add signature
|
|
149
|
-
var covenantScript =
|
|
150
|
-
var signature =
|
|
155
|
+
var covenantScript = Script.fromHex(covenantData.script)
|
|
156
|
+
var signature = sighash.sign(
|
|
151
157
|
spendingTx,
|
|
152
158
|
this.privateKey,
|
|
153
159
|
this.sighashType,
|
|
154
160
|
inputIndex,
|
|
155
161
|
covenantScript,
|
|
156
|
-
new
|
|
162
|
+
new BN(covenantData.satoshis)
|
|
157
163
|
)
|
|
158
164
|
|
|
159
165
|
var fullSignature = Buffer.concat([
|
|
@@ -189,7 +195,7 @@ Builder.prototype.createCovenant = function(utxo, buildOptions) {
|
|
|
189
195
|
buildOptions = buildOptions || {}
|
|
190
196
|
|
|
191
197
|
// Create covenant creation transaction
|
|
192
|
-
var creationTx = new
|
|
198
|
+
var creationTx = new Transaction()
|
|
193
199
|
.from({
|
|
194
200
|
txId: utxo.txid,
|
|
195
201
|
outputIndex: utxo.vout,
|
|
@@ -199,13 +205,13 @@ Builder.prototype.createCovenant = function(utxo, buildOptions) {
|
|
|
199
205
|
.to(this.privateKey.toAddress(), utxo.satoshis - (buildOptions.fee || 1000))
|
|
200
206
|
|
|
201
207
|
// Generate creation preimage
|
|
202
|
-
var p2pkhScript =
|
|
203
|
-
var creationPreimage =
|
|
208
|
+
var p2pkhScript = Script.fromHex(utxo.script)
|
|
209
|
+
var creationPreimage = sighash.sighashPreimage(
|
|
204
210
|
creationTx,
|
|
205
211
|
this.sighashType,
|
|
206
212
|
0,
|
|
207
213
|
p2pkhScript,
|
|
208
|
-
new
|
|
214
|
+
new BN(utxo.satoshis)
|
|
209
215
|
)
|
|
210
216
|
|
|
211
217
|
// Extract preimage fields for covenant construction
|
|
@@ -266,13 +272,13 @@ Builder.prototype.validateSpending = function(spendingTx, covenantUtxo) {
|
|
|
266
272
|
}
|
|
267
273
|
|
|
268
274
|
// Generate spending preimage
|
|
269
|
-
var covenantScript =
|
|
270
|
-
var spendingPreimage =
|
|
275
|
+
var covenantScript = Script.fromHex(covenantUtxo.script)
|
|
276
|
+
var spendingPreimage = sighash.sighashPreimage(
|
|
271
277
|
spendingTx,
|
|
272
278
|
this.sighashType,
|
|
273
279
|
0,
|
|
274
280
|
covenantScript,
|
|
275
|
-
new
|
|
281
|
+
new BN(covenantUtxo.satoshis)
|
|
276
282
|
)
|
|
277
283
|
|
|
278
284
|
var Preimage = require('./preimage')
|
|
@@ -293,15 +299,15 @@ Builder.prototype.validateSpending = function(spendingTx, covenantUtxo) {
|
|
|
293
299
|
}
|
|
294
300
|
|
|
295
301
|
// Run Script.Interpreter validation
|
|
296
|
-
var interpreter = new
|
|
297
|
-
var flags =
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
+
var interpreter = new Interpreter()
|
|
303
|
+
var flags = Interpreter.SCRIPT_VERIFY_P2SH |
|
|
304
|
+
Interpreter.SCRIPT_VERIFY_STRICTENC |
|
|
305
|
+
Interpreter.SCRIPT_VERIFY_DERSIG |
|
|
306
|
+
Interpreter.SCRIPT_VERIFY_LOW_S |
|
|
307
|
+
Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID
|
|
302
308
|
|
|
303
309
|
var unlockingScript = spendingTx.inputs[0].script
|
|
304
|
-
var lockingScript =
|
|
310
|
+
var lockingScript = Script.fromHex(covenantUtxo.script)
|
|
305
311
|
|
|
306
312
|
var interpreterResult = interpreter.verify(
|
|
307
313
|
unlockingScript,
|
|
@@ -309,7 +315,7 @@ Builder.prototype.validateSpending = function(spendingTx, covenantUtxo) {
|
|
|
309
315
|
spendingTx,
|
|
310
316
|
0,
|
|
311
317
|
flags,
|
|
312
|
-
new
|
|
318
|
+
new BN(covenantUtxo.satoshis)
|
|
313
319
|
)
|
|
314
320
|
|
|
315
321
|
if (!interpreterResult) {
|
|
@@ -347,7 +353,7 @@ Builder.prototype._buildFromTemplate = function(preimageData) {
|
|
|
347
353
|
* @private
|
|
348
354
|
*/
|
|
349
355
|
Builder.prototype._buildMultiFieldCovenant = function(preimageData) {
|
|
350
|
-
var script = new
|
|
356
|
+
var script = new Script()
|
|
351
357
|
|
|
352
358
|
// Duplicate preimage for multiple validations
|
|
353
359
|
script.add('OP_DUP')
|
|
@@ -359,7 +365,7 @@ Builder.prototype._buildMultiFieldCovenant = function(preimageData) {
|
|
|
359
365
|
script.add('OP_HASH256')
|
|
360
366
|
|
|
361
367
|
if (rule.expectedValue) {
|
|
362
|
-
var expectedHash =
|
|
368
|
+
var expectedHash = Hash.sha256sha256(Buffer.from(rule.expectedValue, 'hex'))
|
|
363
369
|
script.add(expectedHash)
|
|
364
370
|
script.add('OP_EQUALVERIFY')
|
|
365
371
|
}
|
|
@@ -381,12 +387,12 @@ Builder.prototype._buildMultiFieldCovenant = function(preimageData) {
|
|
|
381
387
|
* @private
|
|
382
388
|
*/
|
|
383
389
|
Builder.prototype._buildHashLockTemplate = function(preimageData, params) {
|
|
384
|
-
var script = new
|
|
390
|
+
var script = new Script()
|
|
385
391
|
|
|
386
392
|
script.add('OP_DUP')
|
|
387
393
|
script.add('OP_HASH256')
|
|
388
394
|
|
|
389
|
-
var expectedHash = params.hash ||
|
|
395
|
+
var expectedHash = params.hash || Hash.sha256sha256(preimageData.preimage)
|
|
390
396
|
script.add(expectedHash)
|
|
391
397
|
script.add('OP_EQUALVERIFY')
|
|
392
398
|
script.add('OP_DROP')
|
|
@@ -26,7 +26,14 @@
|
|
|
26
26
|
|
|
27
27
|
'use strict'
|
|
28
28
|
|
|
29
|
-
var
|
|
29
|
+
var sighash = require('../transaction/sighash')
|
|
30
|
+
var Input = require('../transaction/input')
|
|
31
|
+
var Interpreter = require('../script/interpreter')
|
|
32
|
+
var Signature = require('../crypto/signature')
|
|
33
|
+
var Hash = require('../crypto/hash')
|
|
34
|
+
var BN = require('../crypto/bn')
|
|
35
|
+
var Transaction = require('../transaction')
|
|
36
|
+
var Script = require('../script')
|
|
30
37
|
var path = require('path')
|
|
31
38
|
|
|
32
39
|
// Optional fs dependency for Node.js environments
|
|
@@ -65,7 +72,7 @@ function Covenant(privateKey, options) {
|
|
|
65
72
|
this.storageDir = options.storageDir || (typeof process !== 'undefined' ? path.join(process.cwd(), '.bsv-covenants') : '.bsv-covenants')
|
|
66
73
|
this.covenantUtxoPath = path.join(this.storageDir, 'covenant_utxos.json')
|
|
67
74
|
|
|
68
|
-
this.sighashType =
|
|
75
|
+
this.sighashType = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID
|
|
69
76
|
|
|
70
77
|
// The locking script this class builds does NOT constrain the spend (see the
|
|
71
78
|
// class doc). Require explicit acknowledgement so no one ships it as a real
|
|
@@ -100,7 +107,7 @@ Covenant.prototype.createFromP2PKH = function(utxo) {
|
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
// Create covenant creation transaction
|
|
103
|
-
var creationTx = new
|
|
110
|
+
var creationTx = new Transaction()
|
|
104
111
|
.from({
|
|
105
112
|
txId: utxo.txid,
|
|
106
113
|
outputIndex: utxo.vout,
|
|
@@ -110,19 +117,19 @@ Covenant.prototype.createFromP2PKH = function(utxo) {
|
|
|
110
117
|
.to(this.address, utxo.satoshis - 1000) // 1000 sat fee
|
|
111
118
|
|
|
112
119
|
// Get preimage for covenant creation
|
|
113
|
-
var p2pkhScript =
|
|
114
|
-
var creationPreimage =
|
|
120
|
+
var p2pkhScript = Script.fromHex(utxo.script)
|
|
121
|
+
var creationPreimage = sighash.sighashPreimage(
|
|
115
122
|
creationTx,
|
|
116
123
|
this.sighashType,
|
|
117
124
|
0,
|
|
118
125
|
p2pkhScript,
|
|
119
|
-
new
|
|
126
|
+
new BN(utxo.satoshis)
|
|
120
127
|
)
|
|
121
128
|
|
|
122
|
-
var preimageHash =
|
|
129
|
+
var preimageHash = Hash.sha256sha256(creationPreimage)
|
|
123
130
|
|
|
124
131
|
// Build covenant locking script
|
|
125
|
-
var covenantLockingScript = new
|
|
132
|
+
var covenantLockingScript = new Script()
|
|
126
133
|
.add('OP_DUP')
|
|
127
134
|
.add('OP_HASH256')
|
|
128
135
|
.add(preimageHash)
|
|
@@ -168,28 +175,28 @@ Covenant.prototype.createSpendingTx = function(covenantUtxo, outputAddress, outp
|
|
|
168
175
|
var outputSats = outputSatoshis || (covenantUtxo.satoshis - 500) // 500 sat fee
|
|
169
176
|
|
|
170
177
|
// Create spending transaction - manual input for custom scripts
|
|
171
|
-
var spendingTx = new
|
|
178
|
+
var spendingTx = new Transaction()
|
|
172
179
|
|
|
173
180
|
// Manually add input for custom covenant script
|
|
174
|
-
spendingTx.addInput(new
|
|
181
|
+
spendingTx.addInput(new Input({
|
|
175
182
|
prevTxId: covenantUtxo.txid,
|
|
176
183
|
outputIndex: covenantUtxo.vout,
|
|
177
|
-
script:
|
|
178
|
-
}),
|
|
184
|
+
script: Script.empty() // Will be set after signing
|
|
185
|
+
}), Script.fromHex(covenantUtxo.script), covenantUtxo.satoshis)
|
|
179
186
|
|
|
180
187
|
// Add output
|
|
181
188
|
spendingTx.to(outputAddr, outputSats)
|
|
182
189
|
|
|
183
|
-
var covenantScript =
|
|
190
|
+
var covenantScript = Script.fromHex(covenantUtxo.script)
|
|
184
191
|
|
|
185
192
|
// Create signature against covenant script
|
|
186
|
-
var covenantSignature =
|
|
193
|
+
var covenantSignature = sighash.sign(
|
|
187
194
|
spendingTx,
|
|
188
195
|
this.privateKey,
|
|
189
196
|
this.sighashType,
|
|
190
197
|
0,
|
|
191
198
|
covenantScript,
|
|
192
|
-
new
|
|
199
|
+
new BN(covenantUtxo.satoshis)
|
|
193
200
|
)
|
|
194
201
|
|
|
195
202
|
var fullSignature = Buffer.concat([
|
|
@@ -201,7 +208,7 @@ Covenant.prototype.createSpendingTx = function(covenantUtxo, outputAddress, outp
|
|
|
201
208
|
var originalPreimage = Buffer.from(covenantUtxo.originalPreimage, 'hex')
|
|
202
209
|
|
|
203
210
|
// Create unlocking script
|
|
204
|
-
var unlockingScript = new
|
|
211
|
+
var unlockingScript = new Script()
|
|
205
212
|
.add(fullSignature)
|
|
206
213
|
.add(originalPreimage)
|
|
207
214
|
|
|
@@ -217,15 +224,15 @@ Covenant.prototype.createSpendingTx = function(covenantUtxo, outputAddress, outp
|
|
|
217
224
|
* @returns {Object} Validation result
|
|
218
225
|
*/
|
|
219
226
|
Covenant.prototype.validate = function(spendingTx, covenantUtxo) {
|
|
220
|
-
var interpreter = new
|
|
221
|
-
var flags =
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
227
|
+
var interpreter = new Interpreter()
|
|
228
|
+
var flags = Interpreter.SCRIPT_VERIFY_P2SH |
|
|
229
|
+
Interpreter.SCRIPT_VERIFY_STRICTENC |
|
|
230
|
+
Interpreter.SCRIPT_VERIFY_DERSIG |
|
|
231
|
+
Interpreter.SCRIPT_VERIFY_LOW_S |
|
|
232
|
+
Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID
|
|
226
233
|
|
|
227
234
|
var unlockingScript = spendingTx.inputs[0].script
|
|
228
|
-
var lockingScript =
|
|
235
|
+
var lockingScript = Script.fromHex(covenantUtxo.script)
|
|
229
236
|
|
|
230
237
|
var result = interpreter.verify(
|
|
231
238
|
unlockingScript,
|
|
@@ -233,7 +240,7 @@ Covenant.prototype.validate = function(spendingTx, covenantUtxo) {
|
|
|
233
240
|
spendingTx,
|
|
234
241
|
0,
|
|
235
242
|
flags,
|
|
236
|
-
new
|
|
243
|
+
new BN(covenantUtxo.satoshis)
|
|
237
244
|
)
|
|
238
245
|
|
|
239
246
|
return {
|
|
@@ -366,7 +373,7 @@ Covenant.prototype._ensureStorageDir = function() {
|
|
|
366
373
|
* Static utility methods
|
|
367
374
|
*/
|
|
368
375
|
Covenant.reconstructP2pkhScript = function(address) {
|
|
369
|
-
return
|
|
376
|
+
return Script.buildPublicKeyHashOut(address).toHex()
|
|
370
377
|
}
|
|
371
378
|
|
|
372
379
|
module.exports = Covenant
|
|
@@ -1,129 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
var bsv = require('../..')
|
|
13
|
-
var BN = require('../crypto/bn')
|
|
14
|
-
var Hash = require('../crypto/hash')
|
|
15
|
-
var Signature = require('../crypto/signature')
|
|
16
|
-
|
|
17
|
-
// SIGHASH_ALL | SIGHASH_FORKID — the BSV default these covenants are built for.
|
|
18
|
-
var SIGHASH = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID // 0x41
|
|
19
|
-
|
|
20
|
-
// Post-Genesis consensus + STANDARD RELAY flags — what mainnet miners actually
|
|
21
|
-
// enforce. Includes SCRIPT_VERIFY_MINIMALDATA (every push must be minimal) and
|
|
22
|
-
// SCRIPT_VERIFY_LOW_S (canonical signatures). Verifying with these flags locally
|
|
23
|
-
// mirrors mainnet relay/consensus policy, so a covenant that passes here is
|
|
24
|
-
// expected to be accepted on broadcast — catch non-relayable scripts before then.
|
|
25
|
-
function flags () {
|
|
26
|
-
var I = bsv.Script.Interpreter
|
|
27
|
-
return I.SCRIPT_VERIFY_P2SH |
|
|
28
|
-
I.SCRIPT_VERIFY_STRICTENC |
|
|
29
|
-
I.SCRIPT_VERIFY_DERSIG |
|
|
30
|
-
I.SCRIPT_VERIFY_LOW_S |
|
|
31
|
-
I.SCRIPT_VERIFY_MINIMALDATA |
|
|
32
|
-
I.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY |
|
|
33
|
-
I.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY |
|
|
34
|
-
I.SCRIPT_ENABLE_SIGHASH_FORKID |
|
|
35
|
-
I.SCRIPT_ENABLE_MAGNETIC_OPCODES |
|
|
36
|
-
I.SCRIPT_ENABLE_MONOLITH_OPCODES
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Opt into post-Genesis script limits (needed by OP_PUSH_TX covenants).
|
|
41
|
-
* Thin wrapper over Interpreter.useGenesisLimits (added in 4.1.0).
|
|
42
|
-
*/
|
|
43
|
-
function enableGenesis (max) {
|
|
44
|
-
return bsv.Script.Interpreter.useGenesisLimits(max)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Verify an unlocking script against a locking script through the consensus
|
|
49
|
-
* interpreter. @returns {{ok:boolean, err:string}}
|
|
50
|
-
*/
|
|
51
|
-
function verify (unlockingScript, lockingScript, opts) {
|
|
52
|
-
opts = opts || {}
|
|
53
|
-
var interp = new bsv.Script.Interpreter()
|
|
54
|
-
var ok = interp.verify(
|
|
55
|
-
unlockingScript,
|
|
56
|
-
lockingScript,
|
|
57
|
-
opts.tx || new bsv.Transaction(),
|
|
58
|
-
opts.inputIndex || 0,
|
|
59
|
-
opts.flags || flags(),
|
|
60
|
-
new BN(opts.satoshis || 0)
|
|
61
|
-
)
|
|
62
|
-
return { ok: ok, err: interp.errstr || '' }
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Raw BIP-143 preimage (the serialization that is double-SHA256'd), not the digest. */
|
|
66
|
-
function rawPreimage (tx, inputIndex, lockingScript, satoshis, sighashType) {
|
|
67
|
-
return bsv.Transaction.sighash.sighashPreimage(
|
|
68
|
-
tx, sighashType || SIGHASH, inputIndex, lockingScript, new BN(satoshis))
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** Sighash digest = HASH256(rawPreimage) — useful for asserting OP_PUSH_TX linkage in JS. */
|
|
72
|
-
function sighashDigest (tx, inputIndex, lockingScript, satoshis, sighashType) {
|
|
73
|
-
return Hash.sha256sha256(rawPreimage(tx, inputIndex, lockingScript, satoshis, sighashType))
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** DER+sighash-byte signature over `lockingScript` for `inputIndex`. */
|
|
77
|
-
function signInput (tx, privateKey, inputIndex, lockingScript, satoshis, sighashType) {
|
|
78
|
-
sighashType = sighashType || SIGHASH
|
|
79
|
-
var sig = bsv.Transaction.sighash.sign(tx, privateKey, sighashType, inputIndex, lockingScript, new BN(satoshis))
|
|
80
|
-
return Buffer.concat([sig.toDER(), Buffer.from([sighashType])])
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Build a funding tx paying `satoshis` into `lockingScript`, plus a spending tx
|
|
85
|
-
* consuming it with the supplied outputs. Returns { funding, spend }; the caller
|
|
86
|
-
* sets spend.inputs[0] script.
|
|
87
|
-
*/
|
|
88
|
-
function fundAndSpend (lockingScript, satoshis, opts) {
|
|
89
|
-
opts = opts || {}
|
|
90
|
-
var funding = new bsv.Transaction().addOutput(
|
|
91
|
-
new bsv.Transaction.Output({ script: lockingScript, satoshis: satoshis }))
|
|
92
|
-
var spend = new bsv.Transaction()
|
|
93
|
-
spend.addInput(
|
|
94
|
-
new bsv.Transaction.Input({ prevTxId: funding.hash, outputIndex: 0, script: bsv.Script.empty() }),
|
|
95
|
-
lockingScript, satoshis)
|
|
96
|
-
if (opts.outputs) opts.outputs.forEach(function (o) { spend.addOutput(o) })
|
|
97
|
-
return { funding: funding, spend: spend }
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/** A P2PKH Output object for an address or public key. */
|
|
101
|
-
function p2pkhOutput (addressOrPubKey, satoshis) {
|
|
102
|
-
var addr = addressOrPubKey.toAddress ? addressOrPubKey.toAddress() : addressOrPubKey
|
|
103
|
-
return new bsv.Transaction.Output({ script: bsv.Script.buildPublicKeyHashOut(addr), satoshis: satoshis })
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** Minimal little-endian script-number Buffer (push as data to put a number on-stack). */
|
|
107
|
-
function scriptNum (n) {
|
|
108
|
-
// Minimal on-stack number: 0..16 and -1 use the dedicated opcodes (OP_0..OP_16,
|
|
109
|
-
// OP_1NEGATE) instead of a data push, so covenant scripts stay MINIMALDATA-clean
|
|
110
|
-
// (mainnet relay policy). Larger values use a minimal scriptNum push. The result
|
|
111
|
-
// is passed to Script.add(), which accepts an opcode number or a Buffer.
|
|
112
|
-
if (n === 0) return bsv.Opcode.OP_0
|
|
113
|
-
if (n === -1) return bsv.Opcode.OP_1NEGATE
|
|
114
|
-
if (n >= 1 && n <= 16) return bsv.Opcode['OP_' + n]
|
|
115
|
-
return new BN(n).toScriptNumBuffer()
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
module.exports = {
|
|
119
|
-
SIGHASH: SIGHASH,
|
|
120
|
-
flags: flags,
|
|
121
|
-
enableGenesis: enableGenesis,
|
|
122
|
-
verify: verify,
|
|
123
|
-
rawPreimage: rawPreimage,
|
|
124
|
-
sighashDigest: sighashDigest,
|
|
125
|
-
signInput: signInput,
|
|
126
|
-
fundAndSpend: fundAndSpend,
|
|
127
|
-
p2pkhOutput: p2pkhOutput,
|
|
128
|
-
scriptNum: scriptNum
|
|
129
|
-
}
|
|
2
|
+
// Moved to lib/covenant/helpers.js.
|
|
3
|
+
//
|
|
4
|
+
// lib/ordinals needs these primitives too, and importing them from
|
|
5
|
+
// lib/smart_contract was the only dependency from core code into the
|
|
6
|
+
// application layer. This path is retained because deep imports
|
|
7
|
+
// (require('@smartledger/bsv/lib/smart_contract/covenant_helpers')) are public
|
|
8
|
+
// API via the package.json exports map.
|
|
9
|
+
module.exports = require('../covenant/helpers')
|
|
@@ -9,8 +9,11 @@
|
|
|
9
9
|
* covenants (their preimage element / opcode count exceed pre-Genesis limits).
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
var
|
|
13
|
-
var
|
|
12
|
+
var Interpreter = require('../script/interpreter')
|
|
13
|
+
var BN = require('../crypto/bn')
|
|
14
|
+
var Transaction = require('../transaction')
|
|
15
|
+
var Opcode = require('../opcode')
|
|
16
|
+
var helpers = require('../covenant/helpers')
|
|
14
17
|
|
|
15
18
|
function opLabel (opcodenum) {
|
|
16
19
|
if (opcodenum === 0) return 'OP_0'
|
|
@@ -18,7 +21,7 @@ function opLabel (opcodenum) {
|
|
|
18
21
|
if (opcodenum === 76) return 'OP_PUSHDATA1'
|
|
19
22
|
if (opcodenum === 77) return 'OP_PUSHDATA2'
|
|
20
23
|
if (opcodenum === 78) return 'OP_PUSHDATA4'
|
|
21
|
-
try { return
|
|
24
|
+
try { return Opcode.fromNumber(opcodenum).toString() } catch (e) { return '0x' + opcodenum.toString(16) }
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
function hex (buf, max) {
|
|
@@ -32,7 +35,7 @@ function hex (buf, max) {
|
|
|
32
35
|
*/
|
|
33
36
|
function trace (unlock, lock, opts) {
|
|
34
37
|
opts = opts || {}
|
|
35
|
-
var interp = new
|
|
38
|
+
var interp = new Interpreter()
|
|
36
39
|
var steps = []
|
|
37
40
|
interp.stepListener = function (step, stack, altstack) {
|
|
38
41
|
steps.push({
|
|
@@ -44,10 +47,10 @@ function trace (unlock, lock, opts) {
|
|
|
44
47
|
}
|
|
45
48
|
var ok = interp.verify(
|
|
46
49
|
unlock, lock,
|
|
47
|
-
opts.tx || new
|
|
50
|
+
opts.tx || new Transaction(),
|
|
48
51
|
opts.inputIndex || 0,
|
|
49
52
|
typeof opts.flags === 'number' ? opts.flags : helpers.flags(),
|
|
50
|
-
new
|
|
53
|
+
new BN(opts.satoshis || 0)
|
|
51
54
|
)
|
|
52
55
|
return { ok: ok, err: interp.errstr || '', steps: steps }
|
|
53
56
|
}
|
|
@@ -18,15 +18,14 @@
|
|
|
18
18
|
* time (SmartContract.enableGenesis()).
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
var
|
|
22
|
-
var PushTx = require('./pushtx')
|
|
21
|
+
var PushTx = require('../covenant/pushtx')
|
|
23
22
|
var PELS = require('./pels')
|
|
24
23
|
var Token = require('./token')
|
|
25
|
-
var helpers = require('
|
|
24
|
+
var helpers = require('../covenant/helpers')
|
|
26
25
|
|
|
27
|
-
var Script =
|
|
28
|
-
var Opcode =
|
|
29
|
-
var Transaction =
|
|
26
|
+
var Script = require('../script')
|
|
27
|
+
var Opcode = require('../opcode')
|
|
28
|
+
var Transaction = require('../transaction')
|
|
30
29
|
var n = helpers.scriptNum
|
|
31
30
|
|
|
32
31
|
function toOutput (dest, satoshis) {
|
|
@@ -27,7 +27,10 @@
|
|
|
27
27
|
|
|
28
28
|
'use strict'
|
|
29
29
|
|
|
30
|
-
var
|
|
30
|
+
var Hash = require('../crypto/hash')
|
|
31
|
+
var Transaction = require('../transaction')
|
|
32
|
+
var Address = require('../address')
|
|
33
|
+
var Script = require('../script')
|
|
31
34
|
|
|
32
35
|
var SmartContract = {
|
|
33
36
|
Covenant: require('./covenant'),
|
|
@@ -44,9 +47,9 @@ var SmartContract = {
|
|
|
44
47
|
ScriptInterpreter: require('./script_interpreter'),
|
|
45
48
|
|
|
46
49
|
// Interpreter-verified custom locking scripts & OP_PUSH_TX covenants (v4.2.0)
|
|
47
|
-
CovenantHelpers: require('
|
|
50
|
+
CovenantHelpers: require('../covenant/helpers'),
|
|
48
51
|
Locks: require('./locks'),
|
|
49
|
-
PushTx: require('
|
|
52
|
+
PushTx: require('../covenant/pushtx'),
|
|
50
53
|
PELS: require('./pels'),
|
|
51
54
|
Token: require('./token'),
|
|
52
55
|
Authorizers: require('./authorizers'),
|
|
@@ -258,14 +261,14 @@ SmartContract.debugScriptExecution = function (unlockingScript, lockingScript, o
|
|
|
258
261
|
if (options.stepMode) {
|
|
259
262
|
return SmartContract.ScriptInterpreter.stepThroughScript(
|
|
260
263
|
SmartContract.ScriptInterpreter.parseScript(unlockingScript + ' ' + lockingScript),
|
|
261
|
-
new
|
|
264
|
+
new Transaction(),
|
|
262
265
|
true
|
|
263
266
|
)
|
|
264
267
|
} else {
|
|
265
268
|
return SmartContract.ScriptInterpreter.runFullEvaluation(
|
|
266
269
|
SmartContract.ScriptInterpreter.parseScript(unlockingScript),
|
|
267
270
|
SmartContract.ScriptInterpreter.parseScript(lockingScript),
|
|
268
|
-
new
|
|
271
|
+
new Transaction()
|
|
269
272
|
)
|
|
270
273
|
}
|
|
271
274
|
}
|
|
@@ -362,13 +365,13 @@ SmartContract.getEducationalResources = function () {
|
|
|
362
365
|
// Utility functions
|
|
363
366
|
SmartContract.utils = {}
|
|
364
367
|
SmartContract.utils.reconstructP2pkhScript = function (address) {
|
|
365
|
-
return
|
|
368
|
+
return Script.buildPublicKeyHashOut(address).toHex()
|
|
366
369
|
}
|
|
367
370
|
|
|
368
371
|
SmartContract.utils.createCovenantAddress = function (script) {
|
|
369
372
|
// Create P2SH address for covenant script
|
|
370
|
-
var scriptHash =
|
|
371
|
-
return
|
|
373
|
+
var scriptHash = Hash.sha256ripemd160(script.toBuffer())
|
|
374
|
+
return Address.fromScriptHash(scriptHash)
|
|
372
375
|
}
|
|
373
376
|
|
|
374
377
|
SmartContract.utils.decodeCompactSize = function (buffer, offset) {
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
* Each factory returns { lock: Script, unlock: fn, meta }.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
var bsv = require('../..')
|
|
8
7
|
var Hash = require('../crypto/hash')
|
|
9
|
-
var H = require('
|
|
8
|
+
var H = require('../covenant/helpers')
|
|
10
9
|
|
|
11
|
-
var Script =
|
|
12
|
-
var Opcode =
|
|
10
|
+
var Script = require('../script')
|
|
11
|
+
var Opcode = require('../opcode')
|
|
13
12
|
var signInput = H.signInput
|
|
14
13
|
var n = H.scriptNum
|
|
15
14
|
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
const
|
|
2
|
-
const opcode = bsv.Opcode;
|
|
1
|
+
const opcode = require('../opcode')
|
|
3
2
|
console.log('Opcode List:');
|
|
4
3
|
for (let key in opcode.map) {
|
|
5
4
|
const code = opcode.map[key];
|
|
6
5
|
console.log(`${key}: 0x${code.toString(16).padStart(2, '0')}`);
|
|
7
6
|
}
|
|
8
7
|
|
|
9
|
-
const Script =
|
|
8
|
+
const Script = require('../script')
|
|
10
9
|
console.log(Script);
|
|
11
10
|
console.log('\nSample Script using OP_CHECKSIG and OP_RETURN:');
|
|
12
11
|
const script = new Script()
|
|
@@ -17,12 +17,11 @@
|
|
|
17
17
|
* Requires post-Genesis limits (SmartContract.enableGenesis()).
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
var
|
|
21
|
-
var
|
|
22
|
-
var H = require('./covenant_helpers')
|
|
20
|
+
var P = require('../covenant/pushtx')
|
|
21
|
+
var H = require('../covenant/helpers')
|
|
23
22
|
|
|
24
|
-
var Script =
|
|
25
|
-
var Opcode =
|
|
23
|
+
var Script = require('../script')
|
|
24
|
+
var Opcode = require('../opcode')
|
|
26
25
|
var n = H.scriptNum
|
|
27
26
|
|
|
28
27
|
/**
|
|
@@ -13,7 +13,11 @@
|
|
|
13
13
|
|
|
14
14
|
'use strict'
|
|
15
15
|
|
|
16
|
-
var
|
|
16
|
+
var sighash = require('../transaction/sighash')
|
|
17
|
+
var BN = require('../crypto/bn')
|
|
18
|
+
var Transaction = require('../transaction')
|
|
19
|
+
var PrivateKey = require('../privatekey')
|
|
20
|
+
var Script = require('../script')
|
|
17
21
|
var crypto = require('crypto')
|
|
18
22
|
|
|
19
23
|
/**
|
|
@@ -800,12 +804,12 @@ Preimage.decodeCompactSize = function(buffer, offset) {
|
|
|
800
804
|
* @returns {Preimage} Preimage instance
|
|
801
805
|
*/
|
|
802
806
|
Preimage.fromTransaction = function(transaction, inputIndex, subscript, satoshis, sighashType) {
|
|
803
|
-
var preimageBuffer =
|
|
807
|
+
var preimageBuffer = sighash.sighashPreimage(
|
|
804
808
|
transaction,
|
|
805
809
|
sighashType,
|
|
806
810
|
inputIndex,
|
|
807
811
|
subscript,
|
|
808
|
-
new
|
|
812
|
+
new BN(satoshis)
|
|
809
813
|
)
|
|
810
814
|
|
|
811
815
|
return new Preimage(preimageBuffer, {
|
|
@@ -824,21 +828,21 @@ Preimage.fromTransaction = function(transaction, inputIndex, subscript, satoshis
|
|
|
824
828
|
*/
|
|
825
829
|
Preimage.createExample = function(sighashType) {
|
|
826
830
|
// Create a simple example transaction
|
|
827
|
-
var privateKey =
|
|
831
|
+
var privateKey = PrivateKey.fromRandom()
|
|
828
832
|
var address = privateKey.toAddress()
|
|
829
833
|
|
|
830
834
|
var utxo = {
|
|
831
835
|
txId: '0'.repeat(64),
|
|
832
836
|
outputIndex: 0,
|
|
833
|
-
script:
|
|
837
|
+
script: Script.buildPublicKeyHashOut(address).toHex(),
|
|
834
838
|
satoshis: 100000
|
|
835
839
|
}
|
|
836
840
|
|
|
837
|
-
var transaction = new
|
|
841
|
+
var transaction = new Transaction()
|
|
838
842
|
.from(utxo)
|
|
839
843
|
.to(address, 99000)
|
|
840
844
|
|
|
841
|
-
var subscript =
|
|
845
|
+
var subscript = Script.fromHex(utxo.script)
|
|
842
846
|
|
|
843
847
|
return Preimage.fromTransaction(transaction, 0, subscript, utxo.satoshis, sighashType)
|
|
844
848
|
}
|