smartledger-bsv 3.0.2 → 3.1.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/bsv.min.js +6 -6
- package/index.js +1 -0
- package/lib/custom-script-helper.js +249 -0
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -102,6 +102,7 @@ if (typeof window === 'undefined' && typeof require === 'function') {
|
|
|
102
102
|
try {
|
|
103
103
|
bsv.SmartUTXO = require('./lib/smartutxo')
|
|
104
104
|
bsv.SmartMiner = require('./lib/smartminer')
|
|
105
|
+
bsv.CustomScriptHelper = require('./lib/custom-script-helper')
|
|
105
106
|
} catch (e) {
|
|
106
107
|
// Browser environment - these tools not available
|
|
107
108
|
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SmartLedger BSV Custom Script Helper
|
|
3
|
+
* Simplified API for custom script development
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const bsv = require('../index.js');
|
|
7
|
+
|
|
8
|
+
class CustomScriptHelper {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create a signature for any custom script
|
|
12
|
+
* @param {Transaction} transaction - The transaction object
|
|
13
|
+
* @param {PrivateKey} privateKey - Private key to sign with
|
|
14
|
+
* @param {number} inputIndex - Input index (0 for first input)
|
|
15
|
+
* @param {Script} lockingScript - The locking script being spent
|
|
16
|
+
* @param {number} satoshis - Amount in satoshis
|
|
17
|
+
* @param {number} sighashType - Signature hash type
|
|
18
|
+
* @returns {Buffer} Complete signature with sighash type
|
|
19
|
+
*/
|
|
20
|
+
static createSignature(transaction, privateKey, inputIndex, lockingScript, satoshis, sighashType = null) {
|
|
21
|
+
sighashType = sighashType || (bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID);
|
|
22
|
+
|
|
23
|
+
const signature = bsv.Transaction.sighash.sign(
|
|
24
|
+
transaction,
|
|
25
|
+
privateKey,
|
|
26
|
+
sighashType,
|
|
27
|
+
inputIndex,
|
|
28
|
+
lockingScript,
|
|
29
|
+
new bsv.crypto.BN(satoshis)
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return Buffer.concat([signature.toDER(), Buffer.from([sighashType])]);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Create a multi-signature locking script
|
|
37
|
+
* @param {number} m - Required signatures
|
|
38
|
+
* @param {PublicKey[]} publicKeys - Array of public keys
|
|
39
|
+
* @returns {Script} Multi-signature locking script
|
|
40
|
+
*/
|
|
41
|
+
static createMultisigScript(m, publicKeys) {
|
|
42
|
+
let script = new bsv.Script().add(bsv.Opcode[`OP_${m}`]);
|
|
43
|
+
|
|
44
|
+
for (const pubKey of publicKeys) {
|
|
45
|
+
script = script.add(pubKey.toBuffer());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return script
|
|
49
|
+
.add(bsv.Opcode[`OP_${publicKeys.length}`])
|
|
50
|
+
.add(bsv.Opcode.OP_CHECKMULTISIG);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Create an unlocking script for multi-signature
|
|
55
|
+
* @param {Buffer[]} signatures - Array of signatures
|
|
56
|
+
* @returns {Script} Unlocking script for multisig
|
|
57
|
+
*/
|
|
58
|
+
static createMultisigUnlocking(signatures) {
|
|
59
|
+
let script = new bsv.Script().add(bsv.Opcode.OP_0); // CHECKMULTISIG bug
|
|
60
|
+
|
|
61
|
+
for (const sig of signatures) {
|
|
62
|
+
script = script.add(sig);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return script;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Create a time-locked script (CHECKLOCKTIMEVERIFY)
|
|
70
|
+
* @param {number} lockTime - Block height or timestamp
|
|
71
|
+
* @param {Script} baseScript - Base script to execute after time lock
|
|
72
|
+
* @returns {Script} Time-locked script
|
|
73
|
+
*/
|
|
74
|
+
static createTimelockScript(lockTime, baseScript) {
|
|
75
|
+
const lockTimeBuffer = Buffer.from(lockTime.toString(16).padStart(8, '0'), 'hex').reverse();
|
|
76
|
+
|
|
77
|
+
return new bsv.Script()
|
|
78
|
+
.add(lockTimeBuffer)
|
|
79
|
+
.add(bsv.Opcode.OP_CHECKLOCKTIMEVERIFY)
|
|
80
|
+
.add(bsv.Opcode.OP_DROP)
|
|
81
|
+
.add(baseScript.toBuffer());
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Create a conditional script (IF/ELSE/ENDIF)
|
|
86
|
+
* @param {Script} ifScript - Script to execute if condition is true
|
|
87
|
+
* @param {Script} elseScript - Script to execute if condition is false
|
|
88
|
+
* @returns {Script} Conditional script
|
|
89
|
+
*/
|
|
90
|
+
static createConditionalScript(ifScript, elseScript = null) {
|
|
91
|
+
let script = new bsv.Script()
|
|
92
|
+
.add(bsv.Opcode.OP_IF)
|
|
93
|
+
.add(ifScript.toBuffer());
|
|
94
|
+
|
|
95
|
+
if (elseScript) {
|
|
96
|
+
script = script
|
|
97
|
+
.add(bsv.Opcode.OP_ELSE)
|
|
98
|
+
.add(elseScript.toBuffer());
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return script.add(bsv.Opcode.OP_ENDIF);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Create P2PKH script for a public key
|
|
106
|
+
* @param {PublicKey} publicKey - Public key
|
|
107
|
+
* @returns {Script} P2PKH locking script
|
|
108
|
+
*/
|
|
109
|
+
static createP2PKHScript(publicKey) {
|
|
110
|
+
return new bsv.Script()
|
|
111
|
+
.add(bsv.Opcode.OP_DUP)
|
|
112
|
+
.add(bsv.Opcode.OP_HASH160)
|
|
113
|
+
.add(publicKey.toAddress().hashBuffer)
|
|
114
|
+
.add(bsv.Opcode.OP_EQUALVERIFY)
|
|
115
|
+
.add(bsv.Opcode.OP_CHECKSIG);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Create P2PKH unlocking script
|
|
120
|
+
* @param {Buffer} signature - Signature
|
|
121
|
+
* @param {PublicKey} publicKey - Public key
|
|
122
|
+
* @returns {Script} P2PKH unlocking script
|
|
123
|
+
*/
|
|
124
|
+
static createP2PKHUnlocking(signature, publicKey) {
|
|
125
|
+
return new bsv.Script()
|
|
126
|
+
.add(signature)
|
|
127
|
+
.add(publicKey.toBuffer());
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get transaction preimage for covenant scripts
|
|
132
|
+
* @param {Transaction} transaction - The transaction
|
|
133
|
+
* @param {number} inputIndex - Input index
|
|
134
|
+
* @param {Script} lockingScript - Locking script
|
|
135
|
+
* @param {number} satoshis - Amount in satoshis
|
|
136
|
+
* @param {number} sighashType - Signature hash type
|
|
137
|
+
* @returns {Buffer} Transaction preimage
|
|
138
|
+
*/
|
|
139
|
+
static getPreimage(transaction, inputIndex, lockingScript, satoshis, sighashType = null) {
|
|
140
|
+
sighashType = sighashType || (bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID);
|
|
141
|
+
|
|
142
|
+
return bsv.Transaction.sighash.sighash(
|
|
143
|
+
transaction,
|
|
144
|
+
sighashType,
|
|
145
|
+
inputIndex,
|
|
146
|
+
lockingScript,
|
|
147
|
+
new bsv.crypto.BN(satoshis)
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Create a simple data push script
|
|
153
|
+
* @param {Buffer|string} data - Data to push
|
|
154
|
+
* @returns {Script} Data push script
|
|
155
|
+
*/
|
|
156
|
+
static createDataScript(data) {
|
|
157
|
+
if (typeof data === 'string') {
|
|
158
|
+
data = Buffer.from(data, 'utf8');
|
|
159
|
+
}
|
|
160
|
+
return new bsv.Script().add(data);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Create OP_RETURN data script
|
|
165
|
+
* @param {Buffer|string} data - Data for OP_RETURN
|
|
166
|
+
* @returns {Script} OP_RETURN script
|
|
167
|
+
*/
|
|
168
|
+
static createOpReturnScript(data) {
|
|
169
|
+
if (typeof data === 'string') {
|
|
170
|
+
data = Buffer.from(data, 'utf8');
|
|
171
|
+
}
|
|
172
|
+
return new bsv.Script()
|
|
173
|
+
.add(bsv.Opcode.OP_FALSE)
|
|
174
|
+
.add(bsv.Opcode.OP_RETURN)
|
|
175
|
+
.add(data);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Validate a transaction with custom scripts
|
|
180
|
+
* @param {Transaction} transaction - Transaction to validate
|
|
181
|
+
* @returns {boolean} True if valid
|
|
182
|
+
*/
|
|
183
|
+
static validateTransaction(transaction) {
|
|
184
|
+
try {
|
|
185
|
+
return transaction.verify();
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.error('Transaction validation error:', error.message);
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Validate a specific input script
|
|
194
|
+
* @param {Script} unlockingScript - Unlocking script
|
|
195
|
+
* @param {Script} lockingScript - Locking script
|
|
196
|
+
* @param {Transaction} transaction - Transaction
|
|
197
|
+
* @param {number} inputIndex - Input index
|
|
198
|
+
* @returns {boolean} True if script is valid
|
|
199
|
+
*/
|
|
200
|
+
static validateScript(unlockingScript, lockingScript, transaction, inputIndex) {
|
|
201
|
+
try {
|
|
202
|
+
const interpreter = new bsv.Script.Interpreter();
|
|
203
|
+
return interpreter.verify(
|
|
204
|
+
unlockingScript,
|
|
205
|
+
lockingScript,
|
|
206
|
+
transaction,
|
|
207
|
+
inputIndex,
|
|
208
|
+
bsv.Script.Interpreter.SCRIPT_VERIFY_P2SH |
|
|
209
|
+
bsv.Script.Interpreter.SCRIPT_VERIFY_STRICTENC |
|
|
210
|
+
bsv.Script.Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID |
|
|
211
|
+
bsv.Script.Interpreter.SCRIPT_ENABLE_MAGNETIC_OPCODES |
|
|
212
|
+
bsv.Script.Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES
|
|
213
|
+
);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error('Script validation error:', error.message);
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Create a transaction with ultra-low fees
|
|
222
|
+
* @param {Object[]} utxos - Array of UTXOs
|
|
223
|
+
* @param {Object[]} outputs - Array of outputs
|
|
224
|
+
* @param {number} feePerKb - Fee per KB (default: 10 sats = 0.01 sats/byte)
|
|
225
|
+
* @returns {Transaction} Transaction with ultra-low fees
|
|
226
|
+
*/
|
|
227
|
+
static createLowFeeTransaction(utxos, outputs, feePerKb = 10) {
|
|
228
|
+
let tx = new bsv.Transaction().feePerKb(feePerKb);
|
|
229
|
+
|
|
230
|
+
// Add inputs
|
|
231
|
+
for (const utxo of utxos) {
|
|
232
|
+
tx = tx.from(utxo);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Add outputs
|
|
236
|
+
for (const output of outputs) {
|
|
237
|
+
tx = tx.to(output.address, output.satoshis);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return tx;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Common signature hash types
|
|
245
|
+
CustomScriptHelper.SIGHASH_ALL = bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID;
|
|
246
|
+
CustomScriptHelper.SIGHASH_NONE = bsv.crypto.Signature.SIGHASH_NONE | bsv.crypto.Signature.SIGHASH_FORKID;
|
|
247
|
+
CustomScriptHelper.SIGHASH_SINGLE = bsv.crypto.Signature.SIGHASH_SINGLE | bsv.crypto.Signature.SIGHASH_FORKID;
|
|
248
|
+
|
|
249
|
+
module.exports = CustomScriptHelper;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smartledger-bsv",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "Security-hardened Bitcoin SV library - Complete drop-in replacement for bsv@1.5.6 with zero vulnerabilities",
|
|
3
|
+
"version": "3.1.1",
|
|
4
|
+
"description": "Security-hardened Bitcoin SV library with custom script framework - Complete drop-in replacement for bsv@1.5.6 with zero vulnerabilities",
|
|
5
5
|
"author": "SmartLedger Technology <hello@smartledger.technology> (https://smartledger.technology)",
|
|
6
6
|
"homepage": "https://github.com/codenlighten/smartledger-bsv#readme",
|
|
7
7
|
"bugs": {
|