@smartledger/bsv 1.5.6-fix1 → 3.1.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 +111 -0
- package/README.md +38 -10
- package/bsv.min.js +8 -8
- package/index.js +11 -0
- package/lib/crypto/ecdsa.js +57 -38
- package/lib/crypto/smartledger_verify.js +42 -11
- package/lib/custom-script-helper.js +249 -0
- package/lib/script/interpreter.js +8 -8
- package/lib/smartminer.js +169 -0
- package/lib/smartutxo.js +200 -0
- package/lib/transaction/transaction.js +39 -0
- package/package.json +30 -5
- package/utilities/README.md +132 -0
- package/utilities/blockchain-state.js +332 -0
- package/utilities/blockchain-state.json +41 -0
- package/utilities/miner-simulator.js +620 -0
- package/utilities/mock-utxo-generator.js +149 -0
- package/utilities/raw-tx-examples.js +213 -0
- package/utilities/success-demo.js +193 -0
- package/utilities/transaction-examples.js +328 -0
- package/utilities/utxo-manager.js +162 -0
- package/utilities/wallet-setup.js +167 -0
- package/utilities/wallet.json +30 -0
- package/utilities/working-signature-demo.js +181 -0
- package/validation_test.js +97 -0
package/lib/smartutxo.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SmartLedger UTXO Management System
|
|
5
|
+
* Provides blockchain state management and UTXO tracking for testing and development
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Browser-compatible imports
|
|
9
|
+
let fs, path, crypto, blockchainState
|
|
10
|
+
|
|
11
|
+
// Only require Node.js modules in Node.js environment
|
|
12
|
+
if (typeof window === 'undefined' && typeof require === 'function') {
|
|
13
|
+
try {
|
|
14
|
+
fs = require('fs')
|
|
15
|
+
path = require('path')
|
|
16
|
+
crypto = require('crypto')
|
|
17
|
+
blockchainState = require('../utilities/blockchain-state')
|
|
18
|
+
} catch (e) {
|
|
19
|
+
// Fallback for environments where these modules aren't available
|
|
20
|
+
console.warn('SmartUTXO: Running in browser mode - some features may be limited')
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Comprehensive UTXO Management System for BSV development
|
|
26
|
+
*/
|
|
27
|
+
class SmartUTXOManager {
|
|
28
|
+
constructor(options = {}) {
|
|
29
|
+
this.options = options || {}
|
|
30
|
+
|
|
31
|
+
// Initialize blockchain state - this creates the file if needed
|
|
32
|
+
this.loadState()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Load blockchain state from file (initializes if needed)
|
|
37
|
+
*/
|
|
38
|
+
loadState() {
|
|
39
|
+
try {
|
|
40
|
+
const state = blockchainState.loadBlockchainState()
|
|
41
|
+
return state
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.log('⚠️ Could not load blockchain state:', error.message)
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Save blockchain state to file
|
|
50
|
+
*/
|
|
51
|
+
saveState() {
|
|
52
|
+
try {
|
|
53
|
+
const state = blockchainState.loadBlockchainState()
|
|
54
|
+
blockchainState.saveBlockchainState(state)
|
|
55
|
+
const utxoCount = Object.keys(state.globalUTXOSet || {}).length
|
|
56
|
+
console.log(`💾 Saved blockchain state with ${utxoCount} UTXOs`)
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.log('⚠️ Could not save blockchain state:', error.message)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get all UTXOs for a given address
|
|
64
|
+
* @param {string} address - Bitcoin address
|
|
65
|
+
* @returns {Array} Array of UTXO objects
|
|
66
|
+
*/
|
|
67
|
+
getUTXOsForAddress(address) {
|
|
68
|
+
try {
|
|
69
|
+
const state = blockchainState.loadBlockchainState()
|
|
70
|
+
|
|
71
|
+
// Check if wallet exists
|
|
72
|
+
if (!state.wallets || !state.wallets[address]) {
|
|
73
|
+
return []
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Return the wallet's UTXOs
|
|
77
|
+
return state.wallets[address].utxos || []
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.log('⚠️ Error getting UTXOs:', error.message)
|
|
80
|
+
return []
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Add a new UTXO to the system
|
|
86
|
+
* @param {Object} utxo - UTXO object {txid, vout, address, satoshis, script}
|
|
87
|
+
*/
|
|
88
|
+
addUTXO(utxo) {
|
|
89
|
+
try {
|
|
90
|
+
// Use the correct API: addUTXO(utxo, ownerAddress)
|
|
91
|
+
blockchainState.addUTXO(utxo, utxo.address)
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.log('⚠️ Error adding UTXO:', error.message)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Spend UTXOs (remove from available set)
|
|
99
|
+
* @param {Array} inputs - Array of input objects {txid, vout}
|
|
100
|
+
* @param {string} spentInTx - Optional transaction ID where UTXO was spent
|
|
101
|
+
*/
|
|
102
|
+
spendUTXOs(inputs, spentInTx = 'manual-spend') {
|
|
103
|
+
try {
|
|
104
|
+
for (const input of inputs) {
|
|
105
|
+
// Use the correct API: spendUTXO(txid, vout, spentInTx)
|
|
106
|
+
blockchainState.spendUTXO(input.txid, input.vout, spentInTx)
|
|
107
|
+
}
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.log('⚠️ Error spending UTXOs:', error.message)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Create mock UTXOs for testing
|
|
115
|
+
* @param {string} address - Target address
|
|
116
|
+
* @param {number} count - Number of UTXOs to create
|
|
117
|
+
* @param {number} satoshis - Satoshis per UTXO
|
|
118
|
+
* @returns {Array} Array of created UTXOs
|
|
119
|
+
*/
|
|
120
|
+
createMockUTXOs(address, count = 5, satoshis = 100000) {
|
|
121
|
+
const mockUTXOs = []
|
|
122
|
+
|
|
123
|
+
for (let i = 0; i < count; i++) {
|
|
124
|
+
const txid = crypto.randomBytes(32).toString('hex')
|
|
125
|
+
const vout = i
|
|
126
|
+
const script = `76a914${crypto.randomBytes(20).toString('hex')}88ac` // Mock P2PKH script
|
|
127
|
+
|
|
128
|
+
const utxo = {
|
|
129
|
+
txid,
|
|
130
|
+
vout,
|
|
131
|
+
address,
|
|
132
|
+
satoshis,
|
|
133
|
+
script
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
mockUTXOs.push(utxo)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return mockUTXOs
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get total balance for an address
|
|
144
|
+
* @param {string} address - Bitcoin address
|
|
145
|
+
* @returns {number} Total satoshis
|
|
146
|
+
*/
|
|
147
|
+
getBalance(address) {
|
|
148
|
+
try {
|
|
149
|
+
const state = blockchainState.loadBlockchainState()
|
|
150
|
+
|
|
151
|
+
// Check if wallet exists
|
|
152
|
+
if (!state.wallets || !state.wallets[address]) {
|
|
153
|
+
return 0
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Return the wallet's total value
|
|
157
|
+
return state.wallets[address].totalValue || 0
|
|
158
|
+
} catch (error) {
|
|
159
|
+
console.log('⚠️ Error getting balance:', error.message)
|
|
160
|
+
return 0
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Get blockchain statistics
|
|
166
|
+
* @returns {Object} Stats object
|
|
167
|
+
*/
|
|
168
|
+
getStats() {
|
|
169
|
+
try {
|
|
170
|
+
const state = blockchainState.getBlockchainStats() // This returns the full state
|
|
171
|
+
return {
|
|
172
|
+
totalUTXOs: state.metadata.totalUTXOs,
|
|
173
|
+
totalValue: state.metadata.totalValue,
|
|
174
|
+
totalWallets: state.metadata.totalWallets,
|
|
175
|
+
blockHeight: state.metadata.blockHeight,
|
|
176
|
+
lastUpdated: state.metadata.lastUpdated
|
|
177
|
+
}
|
|
178
|
+
} catch (error) {
|
|
179
|
+
console.log('⚠️ Error getting stats:', error.message)
|
|
180
|
+
return { totalUTXOs: 0, totalValue: 0, totalWallets: 0, blockHeight: 0 }
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Reset blockchain state
|
|
186
|
+
*/
|
|
187
|
+
reset() {
|
|
188
|
+
try {
|
|
189
|
+
const statePath = path.join(__dirname, '../utilities/blockchain-state.json')
|
|
190
|
+
if (fs.existsSync(statePath)) {
|
|
191
|
+
fs.unlinkSync(statePath)
|
|
192
|
+
console.log('🔄 Blockchain state reset')
|
|
193
|
+
}
|
|
194
|
+
} catch (error) {
|
|
195
|
+
console.log('⚠️ Could not reset blockchain state:', error.message)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
module.exports = SmartUTXOManager
|
|
@@ -24,6 +24,10 @@ var Output = require('./output')
|
|
|
24
24
|
var Script = require('../script')
|
|
25
25
|
var PrivateKey = require('../privatekey')
|
|
26
26
|
var BN = require('../crypto/bn')
|
|
27
|
+
var Interpreter = require('../script/interpreter')
|
|
28
|
+
|
|
29
|
+
// By default, we sign with sighash_forkid
|
|
30
|
+
var DEFAULT_SIGN_FLAGS = Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID
|
|
27
31
|
|
|
28
32
|
/**
|
|
29
33
|
* Represents a transaction, a set of inputs and outputs to change ownership of tokens
|
|
@@ -1205,4 +1209,39 @@ Transaction.prototype.isCoinbase = function () {
|
|
|
1205
1209
|
return (this.inputs.length === 1 && this.inputs[0].isNull())
|
|
1206
1210
|
}
|
|
1207
1211
|
|
|
1212
|
+
/**
|
|
1213
|
+
* Calculate the signature hash for an input
|
|
1214
|
+
*
|
|
1215
|
+
* @param {number} inputIndex - The index of the input to sign
|
|
1216
|
+
* @param {number} sighashType - The signature hash type (optional, defaults to ALL|FORKID)
|
|
1217
|
+
* @param {Script} subscript - The subscript to use (optional, derived from input)
|
|
1218
|
+
* @param {BN} satoshisBN - The amount in satoshis for this input (optional, derived from input)
|
|
1219
|
+
* @param {number} flags - Script verification flags (optional)
|
|
1220
|
+
* @return {Buffer} The signature hash for this input
|
|
1221
|
+
*/
|
|
1222
|
+
Transaction.prototype.sighash = function (inputIndex, sighashType, subscript, satoshisBN, flags) {
|
|
1223
|
+
sighashType = sighashType || (Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID)
|
|
1224
|
+
|
|
1225
|
+
// Get the input we're signing for
|
|
1226
|
+
var input = this.inputs[inputIndex]
|
|
1227
|
+
if (!input) {
|
|
1228
|
+
throw new Error('Input index ' + inputIndex + ' does not exist')
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
// If subscript not provided, derive it from the input
|
|
1232
|
+
if (!subscript && input.output) {
|
|
1233
|
+
subscript = input.output.script
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// If satoshisBN not provided, derive it from the input
|
|
1237
|
+
if (!satoshisBN && input.output) {
|
|
1238
|
+
satoshisBN = new BN(input.output.satoshis)
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
// Use default flags if not provided
|
|
1242
|
+
flags = flags || DEFAULT_SIGN_FLAGS
|
|
1243
|
+
|
|
1244
|
+
return Sighash.sighash(this, sighashType, inputIndex, subscript, satoshisBN, flags)
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1208
1247
|
module.exports = Transaction
|
package/package.json
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartledger/bsv",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"
|
|
5
|
-
"access": "public"
|
|
6
|
-
},
|
|
7
|
-
"description": "Security-hardened Bitcoin SV library - Complete drop-in replacement for bsv@1.5.6 with zero vulnerabilities",
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "Security-hardened Bitcoin SV library with custom script framework - Complete drop-in replacement for bsv@1.5.6 with zero vulnerabilities",
|
|
8
5
|
"author": "SmartLedger Technology <hello@smartledger.technology> (https://smartledger.technology)",
|
|
9
6
|
"homepage": "https://github.com/codenlighten/smartledger-bsv#readme",
|
|
10
7
|
"bugs": {
|
|
@@ -14,15 +11,38 @@
|
|
|
14
11
|
"scripts": {
|
|
15
12
|
"lint": "standard",
|
|
16
13
|
"test": "standard && mocha",
|
|
14
|
+
"test:signatures": "node validation_test.js",
|
|
17
15
|
"coverage": "nyc --reporter=text npm run test",
|
|
18
16
|
"build-bsv": "webpack index.js --config webpack.config.js",
|
|
19
17
|
"build-ecies": "webpack ecies/index.js --config webpack.subproject.config.js --output-library bsvEcies -o bsv-ecies.min.js",
|
|
20
18
|
"build-message": "webpack message/index.js --config webpack.subproject.config.js --output-library bsvMessage -o bsv-message.min.js",
|
|
21
19
|
"build-mnemonic": "webpack mnemonic/index.js --config webpack.subproject.config.js --output-library bsvMnemonic -o bsv-mnemonic.min.js",
|
|
20
|
+
"build-bundle": "webpack bundle-entry.js --config webpack.bundle.config.js",
|
|
22
21
|
"build": "npm run build-bsv && npm run build-ecies && npm run build-message && npm run build-mnemonic",
|
|
22
|
+
"build-all": "npm run build && npm run build-bundle",
|
|
23
23
|
"prepublishOnly": "NODE_OPTIONS=\"--openssl-legacy-provider\" npm run build"
|
|
24
24
|
},
|
|
25
25
|
"unpkg": "bsv.min.js",
|
|
26
|
+
"jsdelivr": "bsv.min.js",
|
|
27
|
+
"cdn": "bsv.min.js",
|
|
28
|
+
"files": [
|
|
29
|
+
"index.js",
|
|
30
|
+
"lib/",
|
|
31
|
+
"utilities/",
|
|
32
|
+
"ecies/",
|
|
33
|
+
"message/",
|
|
34
|
+
"mnemonic/",
|
|
35
|
+
"bsv.min.js",
|
|
36
|
+
"bsv-ecies.min.js",
|
|
37
|
+
"bsv-message.min.js",
|
|
38
|
+
"bsv-mnemonic.min.js",
|
|
39
|
+
"bsv.d.ts",
|
|
40
|
+
"validation_test.js",
|
|
41
|
+
"LICENSE",
|
|
42
|
+
"README.md",
|
|
43
|
+
"SECURITY.md",
|
|
44
|
+
"CHANGELOG.md"
|
|
45
|
+
],
|
|
26
46
|
"keywords": [
|
|
27
47
|
"bitcoin",
|
|
28
48
|
"bitcoin-sv",
|
|
@@ -35,6 +55,11 @@
|
|
|
35
55
|
"hardened",
|
|
36
56
|
"vulnerability-free",
|
|
37
57
|
"drop-in-replacement",
|
|
58
|
+
"utxo-management",
|
|
59
|
+
"blockchain-simulator",
|
|
60
|
+
"miner-simulator",
|
|
61
|
+
"testing-tools",
|
|
62
|
+
"development-framework",
|
|
38
63
|
"ecies",
|
|
39
64
|
"p2p",
|
|
40
65
|
"payment",
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# BSV Development Utilities
|
|
2
|
+
|
|
3
|
+
This folder contains utilities for BSV blockchain development and testing, including a complete blockchain miner simulation system for validating transactions and managing UTXO sets.
|
|
4
|
+
|
|
5
|
+
## Files Overview
|
|
6
|
+
|
|
7
|
+
### Core Utilities
|
|
8
|
+
|
|
9
|
+
- **`mock-utxo-generator.js`** - Generates mock UTXOs for testing and development
|
|
10
|
+
- Creates realistic mock transaction IDs
|
|
11
|
+
- Builds P2PKH script hex for addresses
|
|
12
|
+
- Generates properly formatted UTXO objects
|
|
13
|
+
|
|
14
|
+
- **`wallet-setup.js`** - Sets up consistent test wallet environments
|
|
15
|
+
- Creates deterministic test wallets with private keys and addresses
|
|
16
|
+
- Generates initial mock UTXOs
|
|
17
|
+
- Saves configuration to `wallet.json`
|
|
18
|
+
|
|
19
|
+
- **`utxo-manager.js`** - Manages UTXO state and transaction tracking
|
|
20
|
+
- Tracks spent and available UTXOs
|
|
21
|
+
- Updates wallet state after transactions
|
|
22
|
+
- Calculates available balance
|
|
23
|
+
- Maintains transaction history
|
|
24
|
+
|
|
25
|
+
### Blockchain Simulation
|
|
26
|
+
|
|
27
|
+
- **`blockchain-state.js`** - Global blockchain state manager
|
|
28
|
+
- Manages multiple wallet UTXO sets
|
|
29
|
+
- Tracks spent and available UTXOs globally
|
|
30
|
+
- Maintains blockchain metadata (block height, total value)
|
|
31
|
+
- Supports wallet registration and UTXO validation
|
|
32
|
+
|
|
33
|
+
- **`miner-simulator.js`** - Complete miner simulation system
|
|
34
|
+
- Accepts broadcast transactions
|
|
35
|
+
- Validates inputs against global UTXO set
|
|
36
|
+
- Verifies transaction signatures
|
|
37
|
+
- Checks transaction balance (inputs ≥ outputs + fees)
|
|
38
|
+
- Processes valid transactions and rejects invalid ones
|
|
39
|
+
- Updates blockchain state after successful transactions
|
|
40
|
+
|
|
41
|
+
- **`transaction-examples.js`** - Complete transaction flow demonstrations
|
|
42
|
+
- Simple P2PKH payments
|
|
43
|
+
- Transaction chaining
|
|
44
|
+
- Multi-output transactions
|
|
45
|
+
- Full broadcast → validate → process workflow
|
|
46
|
+
|
|
47
|
+
### Configuration
|
|
48
|
+
|
|
49
|
+
- **`wallet.json`** - Persistent wallet state and UTXO tracking
|
|
50
|
+
- Wallet credentials (private key, address)
|
|
51
|
+
- Current UTXO set
|
|
52
|
+
- Spent UTXO history
|
|
53
|
+
- Transaction metadata
|
|
54
|
+
|
|
55
|
+
- **`blockchain-state.json`** - Global blockchain database
|
|
56
|
+
- All wallet addresses and UTXO sets
|
|
57
|
+
- Global UTXO set (keyed by "txid:vout")
|
|
58
|
+
- Spent UTXO history
|
|
59
|
+
- Transaction processing history
|
|
60
|
+
- Blockchain metadata (block height, etc.)
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
### Quick Start
|
|
65
|
+
|
|
66
|
+
1. **Initialize a test wallet:**
|
|
67
|
+
```bash
|
|
68
|
+
node wallet-setup.js
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. **Import wallet into blockchain state:**
|
|
72
|
+
```bash
|
|
73
|
+
node blockchain-state.js import
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
3. **Run transaction examples:**
|
|
77
|
+
```bash
|
|
78
|
+
node transaction-examples.js # Run all examples
|
|
79
|
+
node transaction-examples.js 1 # Run single payment example
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
4. **Check blockchain state:**
|
|
83
|
+
```bash
|
|
84
|
+
node blockchain-state.js # Show blockchain stats
|
|
85
|
+
node miner-simulator.js # Show miner/mempool status
|
|
86
|
+
node utxo-manager.js # Show wallet UTXOs
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Transaction Flow
|
|
90
|
+
|
|
91
|
+
The complete transaction flow demonstrates real blockchain behavior:
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
// 1. Create transaction
|
|
95
|
+
const tx = new bsv.Transaction()
|
|
96
|
+
.from(utxo)
|
|
97
|
+
.to(recipientAddress, amount)
|
|
98
|
+
.change(senderAddress)
|
|
99
|
+
.fee(1000)
|
|
100
|
+
.sign(privateKey);
|
|
101
|
+
|
|
102
|
+
// 2. Broadcast to miner
|
|
103
|
+
const result = acceptTransaction(tx);
|
|
104
|
+
|
|
105
|
+
// 3. Miner validates:
|
|
106
|
+
// - UTXOs exist and unspent
|
|
107
|
+
// - Signatures are valid
|
|
108
|
+
// - Transaction balance is correct
|
|
109
|
+
// - No double spending
|
|
110
|
+
|
|
111
|
+
// 4. If valid: Update global UTXO set
|
|
112
|
+
// 5. If invalid: Reject with error details
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Advanced Usage
|
|
116
|
+
|
|
117
|
+
- **Multiple wallets:** Each wallet can be registered independently
|
|
118
|
+
- **Transaction validation:** Full BSV-compatible signature and balance checking
|
|
119
|
+
- **Double-spend prevention:** UTXOs tracked globally to prevent reuse
|
|
120
|
+
- **Block simulation:** Each processed transaction increments block height
|
|
121
|
+
|
|
122
|
+
## Dependencies
|
|
123
|
+
|
|
124
|
+
These utilities require the BSV library from the parent directory (`../index.js`).
|
|
125
|
+
|
|
126
|
+
## Purpose
|
|
127
|
+
|
|
128
|
+
These utilities provide a consistent testing environment for BSV development, particularly useful for:
|
|
129
|
+
- Transaction creation and verification testing
|
|
130
|
+
- UTXO management in multi-transaction scenarios
|
|
131
|
+
- Consistent test wallet environments
|
|
132
|
+
- Mock blockchain data generation
|