smartledger-bsv 3.2.0 → 3.2.2
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/README.md +289 -55
- package/bsv-covenant.min.js +10 -0
- package/bsv-script-helper.min.js +10 -0
- package/bsv-security.min.js +31 -0
- package/bsv-smartcontract.min.js +37 -0
- package/bsv.bundle.js +9 -9
- package/bsv.min.js +8 -8
- package/build/bsv-covenant.min.js +10 -0
- package/build/bsv-script-helper.min.js +10 -0
- package/build/bsv-security.min.js +31 -0
- package/build/bsv-smartcontract.min.js +37 -0
- package/build/bsv.bundle.js +39 -0
- package/build/bsv.min.js +37 -0
- package/build/webpack.bundle.config.js +22 -0
- package/build/webpack.config.js +18 -0
- package/build/webpack.covenant.config.js +27 -0
- package/build/webpack.script-helper.config.js +27 -0
- package/build/webpack.security.config.js +23 -0
- package/build/webpack.smartcontract.config.js +25 -0
- package/build/webpack.subproject.config.js +6 -0
- package/bundle-entry.js +265 -0
- package/covenant-entry.js +44 -0
- package/docs/pushtx-key-insights.md +106 -0
- package/index.js +13 -5
- package/lib/smart_contract/API_REFERENCE.md +111 -3
- package/lib/smart_contract/index.js +44 -1
- package/lib/smart_contract/script_interpreter.js +236 -0
- package/lib/smart_contract/script_utils.js +16 -4
- package/lib/smart_contract/stack_examiner.js +129 -0
- package/package.json +50 -19
- package/script-helper-entry.js +49 -0
- package/security-entry.js +70 -0
- package/smartcontract-entry.js +133 -0
- package/tests/bundle-completeness-test.html +131 -0
- package/tests/bundle-demo.html +476 -0
- package/tests/smartcontract-test.html +239 -0
- package/tests/standalone-modules-test.html +260 -0
- package/tests/test.html +612 -0
- package/tests/unpkg-demo.html +194 -0
- package/docs/nchain.md +0 -958
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
entry: path.join(__dirname, '/bundle-entry.js'),
|
|
5
|
+
output: {
|
|
6
|
+
library: 'bsv',
|
|
7
|
+
libraryTarget: 'umd',
|
|
8
|
+
globalObject: 'typeof self !== \'undefined\' ? self : this',
|
|
9
|
+
path: path.join(__dirname, '/'),
|
|
10
|
+
filename: 'bsv.bundle.js'
|
|
11
|
+
},
|
|
12
|
+
node: {
|
|
13
|
+
crypto: 'empty',
|
|
14
|
+
stream: 'empty',
|
|
15
|
+
Buffer: true
|
|
16
|
+
},
|
|
17
|
+
mode: 'production',
|
|
18
|
+
optimization: {
|
|
19
|
+
minimize: true
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
var path = require('path')
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
entry: path.join(__dirname, '/index.js'),
|
|
5
|
+
output: {
|
|
6
|
+
library: 'bsv',
|
|
7
|
+
libraryTarget: 'umd',
|
|
8
|
+
globalObject: 'typeof self !== \'undefined\' ? self : this',
|
|
9
|
+
path: path.join(__dirname, '/'),
|
|
10
|
+
filename: 'bsv.min.js'
|
|
11
|
+
},
|
|
12
|
+
node: {
|
|
13
|
+
crypto: 'empty',
|
|
14
|
+
stream: 'empty',
|
|
15
|
+
Buffer: true
|
|
16
|
+
},
|
|
17
|
+
mode: 'production'
|
|
18
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
mode: 'production',
|
|
5
|
+
entry: './covenant-entry.js',
|
|
6
|
+
output: {
|
|
7
|
+
path: path.resolve(__dirname, '.'),
|
|
8
|
+
filename: 'bsv-covenant.min.js',
|
|
9
|
+
library: 'bsvCovenant',
|
|
10
|
+
libraryTarget: 'var'
|
|
11
|
+
},
|
|
12
|
+
externals: {
|
|
13
|
+
// Don't bundle BSV - it should be loaded separately
|
|
14
|
+
'../index.js': 'bsv'
|
|
15
|
+
},
|
|
16
|
+
node: {
|
|
17
|
+
fs: 'empty',
|
|
18
|
+
path: 'empty',
|
|
19
|
+
crypto: 'empty',
|
|
20
|
+
stream: 'empty',
|
|
21
|
+
assert: 'empty',
|
|
22
|
+
http: 'empty',
|
|
23
|
+
https: 'empty',
|
|
24
|
+
os: 'empty',
|
|
25
|
+
url: 'empty'
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
mode: 'production',
|
|
5
|
+
entry: './script-helper-entry.js',
|
|
6
|
+
output: {
|
|
7
|
+
path: path.resolve(__dirname, '.'),
|
|
8
|
+
filename: 'bsv-script-helper.min.js',
|
|
9
|
+
library: 'bsvScriptHelper',
|
|
10
|
+
libraryTarget: 'var'
|
|
11
|
+
},
|
|
12
|
+
externals: {
|
|
13
|
+
// Don't bundle BSV - it should be loaded separately
|
|
14
|
+
'../index.js': 'bsv'
|
|
15
|
+
},
|
|
16
|
+
node: {
|
|
17
|
+
fs: 'empty',
|
|
18
|
+
path: 'empty',
|
|
19
|
+
crypto: 'empty',
|
|
20
|
+
stream: 'empty',
|
|
21
|
+
assert: 'empty',
|
|
22
|
+
http: 'empty',
|
|
23
|
+
https: 'empty',
|
|
24
|
+
os: 'empty',
|
|
25
|
+
url: 'empty'
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
mode: 'production',
|
|
5
|
+
entry: './security-entry.js',
|
|
6
|
+
output: {
|
|
7
|
+
path: path.resolve(__dirname, '.'),
|
|
8
|
+
filename: 'bsv-security.min.js',
|
|
9
|
+
library: 'bsvSecurity',
|
|
10
|
+
libraryTarget: 'var'
|
|
11
|
+
},
|
|
12
|
+
node: {
|
|
13
|
+
fs: 'empty',
|
|
14
|
+
path: 'empty',
|
|
15
|
+
crypto: 'empty',
|
|
16
|
+
stream: 'empty',
|
|
17
|
+
assert: 'empty',
|
|
18
|
+
http: 'empty',
|
|
19
|
+
https: 'empty',
|
|
20
|
+
os: 'empty',
|
|
21
|
+
url: 'empty'
|
|
22
|
+
}
|
|
23
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
entry: path.join(__dirname, '/smartcontract-entry.js'),
|
|
5
|
+
output: {
|
|
6
|
+
library: 'bsvSmartContract',
|
|
7
|
+
libraryTarget: 'umd',
|
|
8
|
+
globalObject: 'typeof self !== \'undefined\' ? self : this',
|
|
9
|
+
path: path.join(__dirname, '/'),
|
|
10
|
+
filename: 'bsv-smartcontract.min.js'
|
|
11
|
+
},
|
|
12
|
+
externals: {
|
|
13
|
+
// Don't bundle BSV - expect it to be loaded separately
|
|
14
|
+
'./index.js': 'bsv'
|
|
15
|
+
},
|
|
16
|
+
node: {
|
|
17
|
+
crypto: 'empty',
|
|
18
|
+
stream: 'empty',
|
|
19
|
+
Buffer: true
|
|
20
|
+
},
|
|
21
|
+
mode: 'production',
|
|
22
|
+
optimization: {
|
|
23
|
+
minimize: true
|
|
24
|
+
}
|
|
25
|
+
}
|
package/bundle-entry.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SmartLedger BSV Complete Bundle
|
|
3
|
+
*
|
|
4
|
+
* This bundle includes:
|
|
5
|
+
* - Core BSV library with all cryptographic functions
|
|
6
|
+
* - Message signing and verification
|
|
7
|
+
* - HD wallets and mnemonic generation
|
|
8
|
+
* - ECIES encryption/decryption
|
|
9
|
+
* - SmartLedger security enhancements
|
|
10
|
+
* - All dependencies bundled for standalone usage
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* <script src="bsv.bundle.js"></script>
|
|
14
|
+
* <script>
|
|
15
|
+
* // Everything available under 'bsv' namespace
|
|
16
|
+
* const key = new bsv.PrivateKey();
|
|
17
|
+
* const message = new bsv.Message('hello');
|
|
18
|
+
* const mnemonic = new bsv.Mnemonic();
|
|
19
|
+
* const encrypted = bsv.ECIES.encrypt(data, publicKey);
|
|
20
|
+
* </script>
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
'use strict'
|
|
24
|
+
|
|
25
|
+
// Load main BSV library
|
|
26
|
+
var bsv = require('./index.js')
|
|
27
|
+
|
|
28
|
+
// Attach Message functionality
|
|
29
|
+
try {
|
|
30
|
+
const Message = require('./lib/message/message.js')
|
|
31
|
+
bsv.Message = Message
|
|
32
|
+
|
|
33
|
+
// Make it available globally for consistency with separate modules
|
|
34
|
+
if (typeof window !== 'undefined') {
|
|
35
|
+
window.bsvMessage = Message
|
|
36
|
+
}
|
|
37
|
+
} catch (e) {
|
|
38
|
+
console.warn('Message module not available:', e.message)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Attach Mnemonic functionality with browser crypto polyfill
|
|
42
|
+
try {
|
|
43
|
+
// Provide crypto polyfill for browser environment
|
|
44
|
+
if (typeof window !== 'undefined' && typeof crypto !== 'undefined' && crypto.subtle) {
|
|
45
|
+
// Browser environment - provide HMAC polyfill
|
|
46
|
+
const originalCrypto = require('crypto')
|
|
47
|
+
if (!originalCrypto.createHmac) {
|
|
48
|
+
originalCrypto.createHmac = function(algorithm, key) {
|
|
49
|
+
return {
|
|
50
|
+
update: function(data) { this._data = data; return this; },
|
|
51
|
+
digest: function(encoding) {
|
|
52
|
+
// Simple fallback - in production you'd want proper HMAC
|
|
53
|
+
const hash = bsv.crypto.Hash.sha256(Buffer.concat([
|
|
54
|
+
Buffer.isBuffer(key) ? key : Buffer.from(key),
|
|
55
|
+
Buffer.isBuffer(this._data) ? this._data : Buffer.from(this._data)
|
|
56
|
+
]));
|
|
57
|
+
return encoding === 'hex' ? hash.toString('hex') : hash;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const Mnemonic = require('./lib/mnemonic/mnemonic.js')
|
|
65
|
+
bsv.Mnemonic = Mnemonic
|
|
66
|
+
|
|
67
|
+
// Make it available globally for consistency with separate modules
|
|
68
|
+
if (typeof window !== 'undefined') {
|
|
69
|
+
window.bsvMnemonic = Mnemonic
|
|
70
|
+
}
|
|
71
|
+
} catch (e) {
|
|
72
|
+
console.warn('Mnemonic module not available:', e.message)
|
|
73
|
+
console.warn('This is expected in browser environments without crypto polyfills')
|
|
74
|
+
|
|
75
|
+
// Provide a minimal mnemonic alternative for browsers
|
|
76
|
+
if (typeof window !== 'undefined') {
|
|
77
|
+
bsv.Mnemonic = function() {
|
|
78
|
+
throw new Error('Full mnemonic functionality requires Node.js crypto. Use separate bsv-mnemonic.min.js for browser support.');
|
|
79
|
+
};
|
|
80
|
+
bsv.Mnemonic.fromString = function() {
|
|
81
|
+
throw new Error('Full mnemonic functionality requires Node.js crypto. Use separate bsv-mnemonic.min.js for browser support.');
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Attach ECIES functionality
|
|
87
|
+
try {
|
|
88
|
+
const ECIES = require('./lib/ecies/index.js')
|
|
89
|
+
bsv.ECIES = ECIES
|
|
90
|
+
bsv.crypto.ECIES = ECIES
|
|
91
|
+
|
|
92
|
+
// Make it available globally for consistency with separate modules
|
|
93
|
+
if (typeof window !== 'undefined') {
|
|
94
|
+
window.bsvEcies = ECIES
|
|
95
|
+
}
|
|
96
|
+
} catch (e) {
|
|
97
|
+
console.warn('ECIES module not available:', e.message)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Include SmartContract interface with debug tools (forced for bundle)
|
|
101
|
+
try {
|
|
102
|
+
const SmartContract = require('./lib/smart_contract')
|
|
103
|
+
bsv.SmartContract = SmartContract
|
|
104
|
+
console.log('SmartContract interface loaded in bundle with', Object.keys(SmartContract).length, 'methods')
|
|
105
|
+
} catch (e) {
|
|
106
|
+
console.warn('SmartContract module not available:', e.message)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Include CovenantInterface for advanced covenant development
|
|
110
|
+
try {
|
|
111
|
+
const CovenantInterface = require('./lib/covenant-interface.js')
|
|
112
|
+
bsv.CovenantInterface = CovenantInterface
|
|
113
|
+
console.log('CovenantInterface loaded in bundle')
|
|
114
|
+
} catch (e) {
|
|
115
|
+
console.warn('CovenantInterface module not available:', e.message)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Include CustomScriptHelper for simplified script development
|
|
119
|
+
try {
|
|
120
|
+
const CustomScriptHelper = require('./lib/custom-script-helper.js')
|
|
121
|
+
bsv.CustomScriptHelper = CustomScriptHelper
|
|
122
|
+
console.log('CustomScriptHelper loaded in bundle')
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.warn('CustomScriptHelper module not available:', e.message)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// SmartLedger security modules (matching index.js structure)
|
|
128
|
+
bsv.SmartLedger = {
|
|
129
|
+
version: bsv.version,
|
|
130
|
+
hardenedBy: bsv.hardenedBy,
|
|
131
|
+
baseVersion: bsv.baseVersion,
|
|
132
|
+
securityFeatures: bsv.securityFeatures,
|
|
133
|
+
SmartVerify: bsv.crypto.SmartVerify,
|
|
134
|
+
EllipticFixed: bsv.crypto.EllipticFixed
|
|
135
|
+
}
|
|
136
|
+
bsv.SmartVerify = bsv.crypto.SmartVerify
|
|
137
|
+
bsv.EllipticFixed = bsv.crypto.EllipticFixed
|
|
138
|
+
|
|
139
|
+
// Internal usage, exposed for testing/advanced tweaking (matching index.js)
|
|
140
|
+
if (bsv.Transaction && bsv.Transaction.sighash === undefined) {
|
|
141
|
+
try {
|
|
142
|
+
bsv.Transaction.sighash = require('./lib/transaction/sighash')
|
|
143
|
+
} catch (e) {
|
|
144
|
+
console.warn('Transaction.sighash not available:', e.message)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Enhanced bundle information
|
|
149
|
+
bsv.bundle = {
|
|
150
|
+
version: bsv.version,
|
|
151
|
+
includes: [
|
|
152
|
+
'core-bsv',
|
|
153
|
+
'message-signing',
|
|
154
|
+
'hd-wallets',
|
|
155
|
+
'mnemonic-generation',
|
|
156
|
+
'ecies-encryption',
|
|
157
|
+
'smartledger-security',
|
|
158
|
+
'smartcontract-interface',
|
|
159
|
+
'debug-tools',
|
|
160
|
+
'covenant-interface',
|
|
161
|
+
'custom-script-helper',
|
|
162
|
+
'advanced-sighash'
|
|
163
|
+
],
|
|
164
|
+
size: 'complete',
|
|
165
|
+
type: 'all-in-one'
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// SmartLedger bundle namespace
|
|
169
|
+
bsv.SmartLedgerBundle = {
|
|
170
|
+
version: bsv.version,
|
|
171
|
+
hardenedBy: bsv.hardenedBy,
|
|
172
|
+
bundleIncludes: bsv.bundle.includes,
|
|
173
|
+
|
|
174
|
+
// Quick access methods
|
|
175
|
+
generateKeys: function() {
|
|
176
|
+
const privateKey = new bsv.PrivateKey()
|
|
177
|
+
return {
|
|
178
|
+
privateKey: privateKey,
|
|
179
|
+
publicKey: privateKey.toPublicKey(),
|
|
180
|
+
address: privateKey.toAddress()
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
generateMnemonic: function() {
|
|
185
|
+
if (!bsv.Mnemonic) {
|
|
186
|
+
throw new Error('Mnemonic functionality not available in bundle')
|
|
187
|
+
}
|
|
188
|
+
// Generate 24-word mnemonic by default (256-bit entropy)
|
|
189
|
+
return new bsv.Mnemonic(256)
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
createMessage: function(text) {
|
|
193
|
+
if (!bsv.Message) {
|
|
194
|
+
throw new Error('Message functionality not available in bundle')
|
|
195
|
+
}
|
|
196
|
+
return new bsv.Message(text)
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
encrypt: function(data, publicKey) {
|
|
200
|
+
if (!bsv.ECIES) {
|
|
201
|
+
throw new Error('ECIES functionality not available in bundle')
|
|
202
|
+
}
|
|
203
|
+
return bsv.ECIES.encrypt(data, publicKey)
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
// SmartContract debug tools (NEW v3.2.1)
|
|
207
|
+
examineScript: function(scriptASM) {
|
|
208
|
+
if (!bsv.SmartContract || !bsv.SmartContract.examineStack) {
|
|
209
|
+
throw new Error('SmartContract debug tools not available in bundle')
|
|
210
|
+
}
|
|
211
|
+
const script = bsv.Script.fromASM(scriptASM)
|
|
212
|
+
return bsv.SmartContract.examineStack(script)
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
interpretScript: function(scriptASM) {
|
|
216
|
+
if (!bsv.SmartContract || !bsv.SmartContract.interpretScript) {
|
|
217
|
+
throw new Error('SmartContract debug tools not available in bundle')
|
|
218
|
+
}
|
|
219
|
+
const script = bsv.Script.fromASM(scriptASM)
|
|
220
|
+
return bsv.SmartContract.interpretScript(script)
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
getScriptMetrics: function(scriptASM) {
|
|
224
|
+
if (!bsv.SmartContract || !bsv.SmartContract.getScriptMetrics) {
|
|
225
|
+
throw new Error('SmartContract metrics not available in bundle')
|
|
226
|
+
}
|
|
227
|
+
const script = bsv.Script.fromASM(scriptASM)
|
|
228
|
+
return bsv.SmartContract.getScriptMetrics(script)
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
optimizeScript: function(scriptASM) {
|
|
232
|
+
if (!bsv.SmartContract || !bsv.SmartContract.optimizeScript) {
|
|
233
|
+
throw new Error('SmartContract optimizer not available in bundle')
|
|
234
|
+
}
|
|
235
|
+
const script = bsv.Script.fromASM(scriptASM)
|
|
236
|
+
return bsv.SmartContract.optimizeScript(script)
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
// Covenant development (NEW v3.2.1)
|
|
240
|
+
createCovenant: function(config) {
|
|
241
|
+
if (!bsv.CovenantInterface) {
|
|
242
|
+
throw new Error('CovenantInterface not available in bundle')
|
|
243
|
+
}
|
|
244
|
+
const covenantInterface = new bsv.CovenantInterface()
|
|
245
|
+
return covenantInterface.createCovenantTransaction(config)
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
// Custom script development (NEW v3.2.1)
|
|
249
|
+
createCustomSignature: function(transaction, privateKey, inputIndex, lockingScript, satoshis, sighashType) {
|
|
250
|
+
if (!bsv.CustomScriptHelper) {
|
|
251
|
+
throw new Error('CustomScriptHelper not available in bundle')
|
|
252
|
+
}
|
|
253
|
+
return bsv.CustomScriptHelper.createSignature(transaction, privateKey, inputIndex, lockingScript, satoshis, sighashType)
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
// Advanced sighash access (NEW v3.2.1)
|
|
257
|
+
calculateSighash: function(transaction, sighashType, inputNumber, subscript, satoshisBN) {
|
|
258
|
+
if (!bsv.Transaction || !bsv.Transaction.sighash) {
|
|
259
|
+
throw new Error('Advanced sighash functionality not available in bundle')
|
|
260
|
+
}
|
|
261
|
+
return bsv.Transaction.sighash.sighash(transaction, sighashType, inputNumber, subscript, satoshisBN)
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
module.exports = bsv
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SmartLedger BSV Covenant Interface - Standalone Module
|
|
3
|
+
*
|
|
4
|
+
* Advanced covenant development framework for Bitcoin SV
|
|
5
|
+
* Requires main BSV library to be loaded first.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* <script src="bsv.min.js"></script>
|
|
9
|
+
* <script src="bsv-covenant.min.js"></script>
|
|
10
|
+
* <script>
|
|
11
|
+
* const covenant = new bsvCovenant.CovenantInterface();
|
|
12
|
+
* const tx = covenant.createCovenantTransaction(config);
|
|
13
|
+
* </script>
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
'use strict'
|
|
17
|
+
|
|
18
|
+
// Verify BSV library is available
|
|
19
|
+
if (typeof bsv === 'undefined') {
|
|
20
|
+
throw new Error('CovenantInterface requires BSV library. Load bsv.min.js first.');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Load CovenantInterface
|
|
24
|
+
const CovenantInterface = require('./lib/covenant-interface.js');
|
|
25
|
+
|
|
26
|
+
// Browser compatibility
|
|
27
|
+
if (typeof window !== 'undefined') {
|
|
28
|
+
window.bsvCovenant = {
|
|
29
|
+
CovenantInterface: CovenantInterface,
|
|
30
|
+
version: bsv.version || 'unknown'
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Also attach to main bsv object if available
|
|
34
|
+
if (typeof bsv !== 'undefined') {
|
|
35
|
+
bsv.CovenantInterface = CovenantInterface;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log('CovenantInterface standalone module loaded');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
CovenantInterface: CovenantInterface,
|
|
43
|
+
version: bsv.version || 'unknown'
|
|
44
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# PUSHTX Key Insights and Application to SmartLedger-BSV
|
|
2
|
+
|
|
3
|
+
This document extracts the critical insights from nChain's PUSHTX whitepaper that informed our implementation and security considerations for SmartLedger-BSV's smart contract capabilities.
|
|
4
|
+
|
|
5
|
+
## Core PUSHTX Concept
|
|
6
|
+
|
|
7
|
+
**Original Innovation**: Developed by Y. Chan and D. Kramer at nChain (2017)
|
|
8
|
+
|
|
9
|
+
**Fundamental Principle**: Generate a signature in-script on a data element and use OP_CHECKSIG to verify it. When verification passes, it proves the message constructed by OP_CHECKSIG is identical to the data element on the stack, effectively "pushing" the current spending transaction to the stack.
|
|
10
|
+
|
|
11
|
+
## Key Technical Components
|
|
12
|
+
|
|
13
|
+
### 1. Signature Generation Building Block
|
|
14
|
+
|
|
15
|
+
**ECDSA Formula**: `s = k^(-1)(z + ra) mod n`
|
|
16
|
+
- `z`: Double SHA256 of message to be signed
|
|
17
|
+
- `k`: Ephemeral key (must be fixed)
|
|
18
|
+
- `r`: x-coordinate of ephemeral key point
|
|
19
|
+
- `a`: Private key (must be fixed)
|
|
20
|
+
- `n`: Curve order
|
|
21
|
+
|
|
22
|
+
**Critical Security Requirements**:
|
|
23
|
+
- Both private key `a` and ephemeral key `k` must be fixed in locking script
|
|
24
|
+
- Public key must be fixed to prevent malleability
|
|
25
|
+
- SIGHASH flag should be fixed for restrictiveness
|
|
26
|
+
|
|
27
|
+
### 2. Message Construction Building Block
|
|
28
|
+
|
|
29
|
+
**Signed Message Components** (11 items total):
|
|
30
|
+
1. Version (4 bytes) - Optional
|
|
31
|
+
2. Hash of input outpoints (32 bytes) - Infeasible due to circular reference
|
|
32
|
+
3. Hash of input sequences (32 bytes) - Optional, recommend flexible
|
|
33
|
+
4. Input outpoint (36 bytes) - Infeasible due to circular reference
|
|
34
|
+
5. Previous locking script length - Optional
|
|
35
|
+
6. Previous locking script - Infeasible due to circular reference
|
|
36
|
+
7. Previous output value (8 bytes) - Optional
|
|
37
|
+
8. Sequence number (4 bytes) - Optional
|
|
38
|
+
9. Hash of outputs (32 bytes) - Optional if known, otherwise infeasible
|
|
39
|
+
10. Locktime (4 bytes) - Optional
|
|
40
|
+
11. SIGHASH flag (4 bytes) - Recommend fixed
|
|
41
|
+
|
|
42
|
+
## Security Analysis Insights
|
|
43
|
+
|
|
44
|
+
### Formal Security Claims
|
|
45
|
+
|
|
46
|
+
**Claim 1**: Computational infeasibility to construct alternative message `m'` that validates with same signature `(r,s)`, assuming hash function is preimage and collision resistant.
|
|
47
|
+
|
|
48
|
+
**Claim 2**: Public key must be fixed to prevent signature malleability.
|
|
49
|
+
|
|
50
|
+
**Claim 3**: Ephemeral key `k` must be fixed to prevent transaction ID changes.
|
|
51
|
+
|
|
52
|
+
**Claim 4**: SIGHASH flag should be fixed to prevent unintended transaction modifications.
|
|
53
|
+
|
|
54
|
+
## Application to SmartLedger-BSV
|
|
55
|
+
|
|
56
|
+
### Implementation Considerations
|
|
57
|
+
|
|
58
|
+
1. **Script Size Optimization**:
|
|
59
|
+
- nChain's example shows ~1KB transaction sizes with optimizations
|
|
60
|
+
- Endianness reversal operations add significant overhead (~500 bytes)
|
|
61
|
+
- Alt stack usage can save ~200 bytes by storing constants
|
|
62
|
+
|
|
63
|
+
2. **Perpetually Enforcing Locking Scripts (PELS)**:
|
|
64
|
+
- Enable conditions that persist across spending chains
|
|
65
|
+
- Useful for covenant-style smart contracts
|
|
66
|
+
- Critical for maintaining contract state across transactions
|
|
67
|
+
|
|
68
|
+
3. **Transaction Fee Handling**:
|
|
69
|
+
- Can use SIGHASH_SINGLE|ANYONECANPAY for fee flexibility
|
|
70
|
+
- Alternative: Build fee deduction into locking script logic
|
|
71
|
+
- Diminishing output values can limit total spend iterations
|
|
72
|
+
|
|
73
|
+
### Integration with SmartContract Interface
|
|
74
|
+
|
|
75
|
+
Our SmartLedger-BSV implementation leverages these PUSHTX principles in:
|
|
76
|
+
|
|
77
|
+
- **Transaction validation**: Ensuring spending transactions meet contract conditions
|
|
78
|
+
- **State preservation**: Maintaining contract state across transaction chains
|
|
79
|
+
- **Security enforcement**: Preventing unauthorized modifications to contract logic
|
|
80
|
+
- **Covenant implementation**: Creating self-enforcing contract conditions
|
|
81
|
+
|
|
82
|
+
## Key Takeaways for Development
|
|
83
|
+
|
|
84
|
+
1. **Security First**: Fixed keys and parameters prevent malleability attacks
|
|
85
|
+
2. **Optimization Matters**: Script size directly impacts transaction costs
|
|
86
|
+
3. **Flexibility vs Security**: Balance between enforceable constraints and spending flexibility
|
|
87
|
+
4. **Circular Reference Challenges**: Some transaction fields cannot be predetermined
|
|
88
|
+
5. **Hash Function Assumptions**: Security relies on SHA256 preimage and collision resistance
|
|
89
|
+
|
|
90
|
+
## Technical Specifications Used
|
|
91
|
+
|
|
92
|
+
- **Curve**: secp256k1
|
|
93
|
+
- **Hash Function**: Double SHA256
|
|
94
|
+
- **Signature Format**: DER encoding with canonical s values (s ≤ n/2)
|
|
95
|
+
- **Bitcoin SV Version**: Tested on v1.0.8 regtest
|
|
96
|
+
|
|
97
|
+
## Implementation Notes
|
|
98
|
+
|
|
99
|
+
- All example scripts from nChain paper are for testing only
|
|
100
|
+
- Mainnet deployment requires thorough security review
|
|
101
|
+
- Endianness handling adds significant complexity
|
|
102
|
+
- Alt stack optimization can reduce script size substantially
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
*This document synthesizes key insights from nChain's WP1605 "PUSHTX and Its Building Blocks" that directly informed SmartLedger-BSV's smart contract implementation and security model.*
|
package/index.js
CHANGED
|
@@ -97,17 +97,25 @@ bsv.SmartLedger = {
|
|
|
97
97
|
bsv.SmartVerify = require('./lib/crypto/smartledger_verify')
|
|
98
98
|
bsv.EllipticFixed = require('./lib/crypto/elliptic-fixed')
|
|
99
99
|
|
|
100
|
-
// SmartLedger Development & Testing Tools
|
|
100
|
+
// SmartLedger Development & Testing Tools
|
|
101
|
+
try {
|
|
102
|
+
// SmartContract Framework - now available in both Node.js and browser
|
|
103
|
+
bsv.SmartContract = require('./lib/smart_contract')
|
|
104
|
+
} catch (e) {
|
|
105
|
+
// SmartContract not available - use standalone bsv-smartcontract.min.js
|
|
106
|
+
if (typeof window === 'undefined') {
|
|
107
|
+
console.warn('SmartContract module not available:', e.message)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Node.js specific tools (advanced development tools)
|
|
101
112
|
if (typeof window === 'undefined' && typeof require === 'function') {
|
|
102
113
|
try {
|
|
103
114
|
bsv.SmartUTXO = require('./lib/smartutxo')
|
|
104
115
|
bsv.SmartMiner = require('./lib/smartminer')
|
|
105
116
|
bsv.CustomScriptHelper = require('./lib/custom-script-helper')
|
|
106
|
-
|
|
107
|
-
// Smart Contract Framework
|
|
108
|
-
bsv.SmartContract = require('./lib/smart_contract')
|
|
109
117
|
} catch (e) {
|
|
110
|
-
//
|
|
118
|
+
// Advanced tools not available
|
|
111
119
|
}
|
|
112
120
|
}
|
|
113
121
|
|