@smartledger/bsv 9.0.0 → 9.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 +137 -0
- package/README.md +152 -1041
- package/STABILITY.md +134 -0
- package/bsv-gdaf.min.js +53 -48
- package/bsv-ltp.min.js +23 -18
- package/bsv-smartcontract.min.js +18 -18
- package/bsv.bundle.js +53 -48
- package/bsv.min.js +53 -48
- 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/docs/proposals/10.0.0-package-split.md +131 -0
- package/index.js +5 -0
- package/lib/block/merkleblock.js +19 -5
- package/lib/hdprivatekey.js +15 -0
- package/lib/script/interpreter.js +109 -1
- package/lib/smart_contract/builder.js +14 -0
- package/lib/util/deprecate.js +159 -0
- package/package.json +19 -82
- package/version.js +1 -1
- package/.mocharc.json +0 -5
- package/test/address.js +0 -629
- package/test/block/block.js +0 -239
- package/test/block/blockheader.js +0 -270
- package/test/block/merkleblock.js +0 -207
- package/test/build/bundle_crypto_shim.js +0 -104
- package/test/build/bundle_externals.js +0 -125
- package/test/build/bundle_smoke.js +0 -55
- package/test/build/esbuild_main.js +0 -65
- package/test/build/esm_wrapper.js +0 -97
- package/test/build/exports_resolution.js +0 -84
- package/test/build/version_sync.js +0 -14
- package/test/cli/smoke.js +0 -261
- package/test/consensus/base58-vectors.js +0 -120
- package/test/consensus/sv-script-vectors.js +0 -81
- package/test/consensus/sv-sighash-vectors.js +0 -51
- package/test/consensus/sv-tx-vectors.js +0 -48
- package/test/credentials-test.js +0 -332
- package/test/crypto/backend_selection.js +0 -126
- package/test/crypto/bn.js +0 -168
- package/test/crypto/ecdsa.js +0 -426
- package/test/crypto/elliptic-fixed.js +0 -61
- package/test/crypto/hash.browser.js +0 -121
- package/test/crypto/hash.js +0 -122
- package/test/crypto/point.js +0 -193
- package/test/crypto/random.js +0 -105
- package/test/crypto/security.js +0 -176
- package/test/crypto/shamir.js +0 -177
- package/test/crypto/shamir_rngcap.js +0 -29
- package/test/crypto/signature.js +0 -399
- package/test/data/bip69.json +0 -215
- package/test/data/bitcoin-sv/README.md +0 -170
- package/test/data/bitcoin-sv/base58_encode_decode.json +0 -14
- package/test/data/bitcoin-sv/base58_keys_invalid.json +0 -152
- package/test/data/bitcoin-sv/base58_keys_valid.json +0 -452
- package/test/data/bitcoin-sv/script_tests.json +0 -2591
- package/test/data/bitcoin-sv/sighash.json +0 -1003
- package/test/data/bitcoin-sv/tx_invalid.json +0 -285
- package/test/data/bitcoin-sv/tx_valid.json +0 -367
- package/test/data/bitcoind/base58_keys_invalid.json +0 -152
- package/test/data/bitcoind/base58_keys_valid.json +0 -452
- package/test/data/bitcoind/blocks.json +0 -27
- package/test/data/bitcoind/script_tests.json +0 -2244
- package/test/data/bitcoind/sig_canonical.json +0 -7
- package/test/data/bitcoind/sig_noncanonical.json +0 -22
- package/test/data/bitcoind/tx_invalid.json +0 -177
- package/test/data/bitcoind/tx_valid.json +0 -224
- package/test/data/blk86756-testnet.dat +0 -0
- package/test/data/blk86756-testnet.js +0 -12
- package/test/data/blk86756-testnet.json +0 -684
- package/test/data/brc220-batch-vector.json +0 -129
- package/test/data/ecdsa.json +0 -230
- package/test/data/merkleblocks.js +0 -486
- package/test/data/messages.json +0 -22
- package/test/data/sighash.json +0 -1004
- package/test/data/tx_creation.json +0 -85
- package/test/didweb/relationships.js +0 -144
- package/test/ecies/bitcore-ecies.js +0 -178
- package/test/ecies/electrum-ecies.js +0 -206
- package/test/encoding/base58.js +0 -131
- package/test/encoding/base58check.js +0 -145
- package/test/encoding/bufferreader.js +0 -328
- package/test/encoding/bufferwriter.js +0 -160
- package/test/encoding/varint.js +0 -104
- package/test/gdaf/anchor_no_key_leak.js +0 -146
- package/test/gdaf/anchor_spv.js +0 -163
- package/test/gdaf/canonicalization.js +0 -106
- package/test/gdaf/canonicalize.js +0 -140
- package/test/gdaf/zk_prover.js +0 -204
- package/test/hdkeys.js +0 -365
- package/test/hdprivatekey.js +0 -339
- package/test/hdpublickey.js +0 -293
- package/test/index.js +0 -16
- package/test/ltp/ids.js +0 -74
- package/test/ltp/right.js +0 -198
- package/test/ltp/verify_failclosed.js +0 -134
- package/test/message/message.js +0 -190
- package/test/mnemonic/data/fixtures.json +0 -300
- package/test/mnemonic/mnemonic.js +0 -277
- package/test/mnemonic/mocha.opts +0 -1
- package/test/mnemonic/pbkdf2.test.js +0 -43
- package/test/networks.js +0 -207
- package/test/notaryhash/batch_leaf.js +0 -140
- package/test/notaryhash/batch_vector.js +0 -282
- package/test/notaryhash/certificate.js +0 -249
- package/test/notaryhash/encoding.js +0 -186
- package/test/notaryhash/interop.js +0 -112
- package/test/notaryhash/merkle.js +0 -181
- package/test/notaryhash/script.js +0 -270
- package/test/notaryhash/verify.js +0 -342
- package/test/opcode.js +0 -186
- package/test/ordinals/bsv20.js +0 -337
- package/test/ordinals/inscription.js +0 -329
- package/test/ordinals/ordlock.js +0 -567
- package/test/privatekey.js +0 -540
- package/test/publickey.js +0 -411
- package/test/regressions.js +0 -215
- package/test/script/chronicle.js +0 -543
- package/test/script/defaults.js +0 -160
- package/test/script/genesis_limits.js +0 -203
- package/test/script/interpreter.js +0 -776
- package/test/script/script.js +0 -1259
- package/test/script/string_ops.js +0 -88
- package/test/security/fail_closed_contracts.js +0 -104
- package/test/security/threat_model_coverage.js +0 -31
- package/test/smart_contract/covenants.js +0 -207
- package/test/smart_contract/dsl_debugger.js +0 -92
- package/test/smart_contract/extract_field.js +0 -61
- package/test/smart_contract/nonenforcing_guard.js +0 -44
- package/test/smart_contract/ordinal_transfer.js +0 -71
- package/test/smart_contract/preimage.js +0 -98
- package/test/smart_contract/sighash_marketplace.js +0 -98
- package/test/smart_contract/token_generalized.js +0 -175
- package/test/spv/headerchain.js +0 -86
- package/test/spv/merkleproof.js +0 -133
- package/test/statuslist/failclosed.js +0 -78
- package/test/transaction/deserialize.js +0 -33
- package/test/transaction/input/input.js +0 -92
- package/test/transaction/input/multisig.js +0 -174
- package/test/transaction/input/multisigscripthash.js +0 -111
- package/test/transaction/input/publickey.js +0 -68
- package/test/transaction/input/publickeyhash.js +0 -59
- package/test/transaction/output.js +0 -185
- package/test/transaction/sighash.js +0 -91
- package/test/transaction/signature.js +0 -127
- package/test/transaction/transaction.js +0 -1299
- package/test/transaction/unspentoutput.js +0 -97
- package/test/types/dts_drift.js +0 -124
- package/test/types/surface_honesty.js +0 -102
- package/test/util/id.js +0 -72
- package/test/util/js.js +0 -76
- package/test/util/preconditions.js +0 -79
- package/test/vcjwt/interop.js +0 -126
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it */
|
|
4
|
-
|
|
5
|
-
// Regression guard for the StatusList2021 revocation-bypass bug. Before the fix,
|
|
6
|
-
// getCredentialStatusEntry / updateStatusList read the revocation bitstring from
|
|
7
|
-
// the JWT payload WITHOUT verifying the signature — so anyone who could substitute
|
|
8
|
-
// the list JWT could flip a revoked credential back to "valid". These tests assert
|
|
9
|
-
// the status-list reads now fail closed.
|
|
10
|
-
|
|
11
|
-
var expect = require('chai').expect
|
|
12
|
-
var didweb = require('../../lib/didweb')
|
|
13
|
-
var statuslist = require('../../lib/statuslist')
|
|
14
|
-
var vcjwt = require('../../lib/vcjwt')
|
|
15
|
-
|
|
16
|
-
function tamperEncodedList (listVcJwt, newEncodedList) {
|
|
17
|
-
var parts = listVcJwt.split('.')
|
|
18
|
-
var payload = JSON.parse(vcjwt.base64UrlDecode(parts[1]).toString())
|
|
19
|
-
payload.vc.credentialSubject.encodedList = newEncodedList
|
|
20
|
-
var tamperedPayload = Buffer.from(JSON.stringify(payload)).toString('base64url')
|
|
21
|
-
return parts[0] + '.' + tamperedPayload + '.' + parts[2] // keep original signature
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
describe('StatusList2021 fails closed (revocation-bypass regression)', function () {
|
|
25
|
-
var keys, docs, resolver, verifyOpts, listJwt
|
|
26
|
-
|
|
27
|
-
before(async function () {
|
|
28
|
-
keys = await didweb.generateIssuerKeys({ alg: 'ES256' })
|
|
29
|
-
docs = didweb.buildDidWebDocuments({
|
|
30
|
-
domain: 'example.com',
|
|
31
|
-
p256: { jwk: keys.publicJwk, kid: keys.kid }
|
|
32
|
-
})
|
|
33
|
-
resolver = async function () { return { jwks: docs.jwks } }
|
|
34
|
-
verifyOpts = { expectedIssuerDid: docs.did, didResolver: resolver }
|
|
35
|
-
var created = await statuslist.createStatusList({ issuerDid: docs.did, privateJwk: keys.privateJwk })
|
|
36
|
-
listJwt = created.listVcJwt
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('reads a genuine, verified status list', async function () {
|
|
40
|
-
var status = await statuslist.getCredentialStatusEntry(Object.assign({ listVcJwt: listJwt, index: 7 }, verifyOpts))
|
|
41
|
-
expect(status).to.equal('valid')
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('rejects a list whose bitstring was tampered without re-signing (bypass closed)', async function () {
|
|
45
|
-
// Build a bitstring that marks index 7 as revoked, then splice it in WITHOUT
|
|
46
|
-
// the issuer's signature — exactly the substitution attack the bug allowed.
|
|
47
|
-
var zlib = require('zlib')
|
|
48
|
-
var buf = Buffer.alloc(Math.ceil(100000 / 8), 0)
|
|
49
|
-
buf[0] = 0xff
|
|
50
|
-
var forgedEncoded = zlib.gzipSync(buf).toString('base64')
|
|
51
|
-
var forgedJwt = tamperEncodedList(listJwt, forgedEncoded)
|
|
52
|
-
|
|
53
|
-
var threw = false
|
|
54
|
-
try {
|
|
55
|
-
await statuslist.getCredentialStatusEntry(Object.assign({ listVcJwt: forgedJwt, index: 7 }, verifyOpts))
|
|
56
|
-
} catch (e) { threw = true }
|
|
57
|
-
expect(threw, 'tampered list must be rejected').to.equal(true)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('refuses to read without a pinned expectedIssuerDid', async function () {
|
|
61
|
-
var threw = false
|
|
62
|
-
try {
|
|
63
|
-
await statuslist.getCredentialStatusEntry({ listVcJwt: listJwt, index: 7, didResolver: resolver })
|
|
64
|
-
} catch (e) { threw = true }
|
|
65
|
-
expect(threw).to.equal(true)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
it('rejects a list signed by a different (attacker) issuer under the victim DID', async function () {
|
|
69
|
-
var attacker = await didweb.generateIssuerKeys({ alg: 'ES256' })
|
|
70
|
-
var attackerList = await statuslist.createStatusList({ issuerDid: docs.did, privateJwk: attacker.privateJwk })
|
|
71
|
-
// Resolver returns the VICTIM's key for docs.did; attacker's signature must fail.
|
|
72
|
-
var threw = false
|
|
73
|
-
try {
|
|
74
|
-
await statuslist.getCredentialStatusEntry(Object.assign({ listVcJwt: attackerList.listVcJwt, index: 7 }, verifyOpts))
|
|
75
|
-
} catch (e) { threw = true }
|
|
76
|
-
expect(threw).to.equal(true)
|
|
77
|
-
})
|
|
78
|
-
})
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var Transaction = require('../../lib/transaction')
|
|
4
|
-
|
|
5
|
-
var vectorsValid = require('../data/bitcoind/tx_valid.json')
|
|
6
|
-
var vectorsInvalid = require('../data/bitcoind/tx_invalid.json')
|
|
7
|
-
|
|
8
|
-
describe('Transaction deserialization', function () {
|
|
9
|
-
describe('valid transaction test case', function () {
|
|
10
|
-
var index = 0
|
|
11
|
-
vectorsValid.forEach(function (vector) {
|
|
12
|
-
it('vector #' + index, function () {
|
|
13
|
-
if (vector.length > 1) {
|
|
14
|
-
var hexa = vector[1]
|
|
15
|
-
Transaction(hexa).serialize(true).should.equal(hexa)
|
|
16
|
-
index++
|
|
17
|
-
}
|
|
18
|
-
})
|
|
19
|
-
})
|
|
20
|
-
})
|
|
21
|
-
describe('invalid transaction test case', function () {
|
|
22
|
-
var index = 0
|
|
23
|
-
vectorsInvalid.forEach(function (vector) {
|
|
24
|
-
it('invalid vector #' + index, function () {
|
|
25
|
-
if (vector.length > 1) {
|
|
26
|
-
var hexa = vector[1]
|
|
27
|
-
Transaction(hexa).serialize(true).should.equal(hexa)
|
|
28
|
-
index++
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
})
|
|
32
|
-
})
|
|
33
|
-
})
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var should = require('chai').should()
|
|
4
|
-
var expect = require('chai').expect
|
|
5
|
-
var _ = require('../../../lib/util/_')
|
|
6
|
-
|
|
7
|
-
var bsv = require('../../..')
|
|
8
|
-
var errors = bsv.errors
|
|
9
|
-
var PrivateKey = bsv.PrivateKey
|
|
10
|
-
var Address = bsv.Address
|
|
11
|
-
var Script = bsv.Script
|
|
12
|
-
var Networks = bsv.Networks
|
|
13
|
-
var Input = bsv.Transaction.Input
|
|
14
|
-
|
|
15
|
-
describe('Transaction.Input', function () {
|
|
16
|
-
var privateKey = new PrivateKey('KwF9LjRraetZuEjR8VqEq539z137LW5anYDUnVK11vM3mNMHTWb4')
|
|
17
|
-
var publicKey = privateKey.publicKey
|
|
18
|
-
var address = new Address(publicKey, Networks.livenet)
|
|
19
|
-
var output = {
|
|
20
|
-
address: '33zbk2aSZYdNbRsMPPt6jgy6Kq1kQreqeb',
|
|
21
|
-
prevTxId: '66e64ef8a3b384164b78453fa8c8194de9a473ba14f89485a0e433699daec140',
|
|
22
|
-
outputIndex: 0,
|
|
23
|
-
script: new Script(address),
|
|
24
|
-
satoshis: 1000000
|
|
25
|
-
}
|
|
26
|
-
var coinbase = {
|
|
27
|
-
prevTxId: '0000000000000000000000000000000000000000000000000000000000000000',
|
|
28
|
-
outputIndex: 0xFFFFFFFF,
|
|
29
|
-
script: new Script(),
|
|
30
|
-
satoshis: 1000000
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
var coinbaseJSON = JSON.stringify({
|
|
34
|
-
prevTxId: '0000000000000000000000000000000000000000000000000000000000000000',
|
|
35
|
-
outputIndex: 4294967295,
|
|
36
|
-
script: ''
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('has abstract methods: "getSignatures", "isFullySigned", "addSignature", "clearSignatures"', function () {
|
|
40
|
-
var input = new Input(output)
|
|
41
|
-
_.each(['getSignatures', 'isFullySigned', 'addSignature', 'clearSignatures'], function (method) {
|
|
42
|
-
expect(function () {
|
|
43
|
-
return input[method]()
|
|
44
|
-
}).to.throw(errors.AbstractMethodInvoked)
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
|
-
it('detects coinbase transactions', function () {
|
|
48
|
-
new Input(output).isNull().should.equal(false)
|
|
49
|
-
var ci = new Input(coinbase)
|
|
50
|
-
ci.isNull().should.equal(true)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
describe('instantiation', function () {
|
|
54
|
-
it('works without new', function () {
|
|
55
|
-
var input = Input()
|
|
56
|
-
should.exist(input)
|
|
57
|
-
})
|
|
58
|
-
it('fails with no script info', function () {
|
|
59
|
-
expect(function () {
|
|
60
|
-
var input = new Input({})
|
|
61
|
-
input.toString()
|
|
62
|
-
}).to.throw('Need a script to create an input')
|
|
63
|
-
})
|
|
64
|
-
it('fromObject should work', function () {
|
|
65
|
-
var jsonData = JSON.parse(coinbaseJSON)
|
|
66
|
-
var input = Input.fromObject(jsonData)
|
|
67
|
-
should.exist(input)
|
|
68
|
-
input.prevTxId.toString('hex').should.equal(jsonData.prevTxId)
|
|
69
|
-
input.outputIndex.should.equal(jsonData.outputIndex)
|
|
70
|
-
})
|
|
71
|
-
it('fromObject should work', function () {
|
|
72
|
-
var input = Input.fromObject(JSON.parse(coinbaseJSON))
|
|
73
|
-
var obj = input.toObject()
|
|
74
|
-
Input.fromObject(obj).should.deep.equal(input)
|
|
75
|
-
obj.script = 42
|
|
76
|
-
Input.fromObject.bind(null, obj).should.throw('Invalid argument type: script')
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('_estimateSize returns correct size', function () {
|
|
81
|
-
var input = new Input(output)
|
|
82
|
-
input._estimateSize().should.equal(66)
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
it('defaults isFinal correctly', function () {
|
|
86
|
-
new Input(output).isFinal().should.equal(true)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
it('handles isFinal when sequence number is set to non default value', function () {
|
|
90
|
-
new Input({ ...output, sequenceNumber: 0 }).isFinal().should.equal(false)
|
|
91
|
-
})
|
|
92
|
-
})
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var should = require('chai').should()
|
|
4
|
-
var _ = require('../../../lib/util/_')
|
|
5
|
-
|
|
6
|
-
var bsv = require('../../..')
|
|
7
|
-
var Transaction = bsv.Transaction
|
|
8
|
-
var PrivateKey = bsv.PrivateKey
|
|
9
|
-
var Address = bsv.Address
|
|
10
|
-
var Script = bsv.Script
|
|
11
|
-
var Signature = bsv.crypto.Signature
|
|
12
|
-
var MultiSigInput = bsv.Transaction.Input.MultiSig
|
|
13
|
-
|
|
14
|
-
describe('MultiSigInput', function () {
|
|
15
|
-
var privateKey1 = new PrivateKey('KwF9LjRraetZuEjR8VqEq539z137LW5anYDUnVK11vM3mNMHTWb4')
|
|
16
|
-
var privateKey2 = new PrivateKey('L4PqnaPTCkYhAqH3YQmefjxQP6zRcF4EJbdGqR8v6adtG9XSsadY')
|
|
17
|
-
var privateKey3 = new PrivateKey('L4CTX79zFeksZTyyoFuPQAySfmP7fL3R41gWKTuepuN7hxuNuJwV')
|
|
18
|
-
var public1 = privateKey1.publicKey
|
|
19
|
-
var public2 = privateKey2.publicKey
|
|
20
|
-
var public3 = privateKey3.publicKey
|
|
21
|
-
var address = new Address('33zbk2aSZYdNbRsMPPt6jgy6Kq1kQreqeb')
|
|
22
|
-
|
|
23
|
-
var output = {
|
|
24
|
-
txId: '66e64ef8a3b384164b78453fa8c8194de9a473ba14f89485a0e433699daec140',
|
|
25
|
-
outputIndex: 0,
|
|
26
|
-
script: new Script('5221025c95ec627038e85b5688a9b3d84d28c5ebe66e8c8d697d498e20fe96e3b1ab1d2102cdddfc974d41a62f1f80081deee70592feb7d6e6cf6739d6592edbe7946720e72103c95924e02c240b5545089c69c6432447412b58be43fd671918bd184a5009834353ae'),
|
|
27
|
-
satoshis: 1000000
|
|
28
|
-
}
|
|
29
|
-
it('can count missing signatures', function () {
|
|
30
|
-
var transaction = new Transaction()
|
|
31
|
-
.from(output, [public1, public2, public3], 2)
|
|
32
|
-
.to(address, 1000000)
|
|
33
|
-
var input = transaction.inputs[0]
|
|
34
|
-
|
|
35
|
-
input.countSignatures().should.equal(0)
|
|
36
|
-
|
|
37
|
-
transaction.sign(privateKey1)
|
|
38
|
-
input.countSignatures().should.equal(1)
|
|
39
|
-
input.countMissingSignatures().should.equal(1)
|
|
40
|
-
input.isFullySigned().should.equal(false)
|
|
41
|
-
|
|
42
|
-
transaction.sign(privateKey2)
|
|
43
|
-
input.countSignatures().should.equal(2)
|
|
44
|
-
input.countMissingSignatures().should.equal(0)
|
|
45
|
-
input.isFullySigned().should.equal(true)
|
|
46
|
-
})
|
|
47
|
-
it('can count missing signatures, signed with key 3 and 1', function () {
|
|
48
|
-
var transaction = new Transaction()
|
|
49
|
-
.from(output, [public1, public2, public3], 2)
|
|
50
|
-
.to(address, 1000000)
|
|
51
|
-
var input = transaction.inputs[0]
|
|
52
|
-
|
|
53
|
-
input.countSignatures().should.equal(0)
|
|
54
|
-
|
|
55
|
-
transaction.sign(privateKey3)
|
|
56
|
-
input.countSignatures().should.equal(1)
|
|
57
|
-
input.countMissingSignatures().should.equal(1)
|
|
58
|
-
input.isFullySigned().should.equal(false)
|
|
59
|
-
|
|
60
|
-
transaction.sign(privateKey1)
|
|
61
|
-
input.countSignatures().should.equal(2)
|
|
62
|
-
input.countMissingSignatures().should.equal(0)
|
|
63
|
-
input.isFullySigned().should.equal(true)
|
|
64
|
-
})
|
|
65
|
-
it('returns a list of public keys with missing signatures', function () {
|
|
66
|
-
var transaction = new Transaction()
|
|
67
|
-
.from(output, [public1, public2, public3], 2)
|
|
68
|
-
.to(address, 1000000)
|
|
69
|
-
var input = transaction.inputs[0]
|
|
70
|
-
|
|
71
|
-
_.every(input.publicKeysWithoutSignature(), function (publicKeyMissing) {
|
|
72
|
-
var serialized = publicKeyMissing.toString()
|
|
73
|
-
return serialized === public1.toString() ||
|
|
74
|
-
serialized === public2.toString() ||
|
|
75
|
-
serialized === public3.toString()
|
|
76
|
-
}).should.equal(true)
|
|
77
|
-
transaction.sign(privateKey1)
|
|
78
|
-
_.every(input.publicKeysWithoutSignature(), function (publicKeyMissing) {
|
|
79
|
-
var serialized = publicKeyMissing.toString()
|
|
80
|
-
return serialized === public2.toString() ||
|
|
81
|
-
serialized === public3.toString()
|
|
82
|
-
}).should.equal(true)
|
|
83
|
-
})
|
|
84
|
-
it('can clear all signatures', function () {
|
|
85
|
-
var transaction = new Transaction()
|
|
86
|
-
.from(output, [public1, public2, public3], 2)
|
|
87
|
-
.to(address, 1000000)
|
|
88
|
-
.sign(privateKey1)
|
|
89
|
-
.sign(privateKey2)
|
|
90
|
-
|
|
91
|
-
var input = transaction.inputs[0]
|
|
92
|
-
input.isFullySigned().should.equal(true)
|
|
93
|
-
input.clearSignatures()
|
|
94
|
-
input.isFullySigned().should.equal(false)
|
|
95
|
-
})
|
|
96
|
-
it('can estimate how heavy is the output going to be', function () {
|
|
97
|
-
var transaction = new Transaction()
|
|
98
|
-
.from(output, [public1, public2, public3], 2)
|
|
99
|
-
.to(address, 1000000)
|
|
100
|
-
var input = transaction.inputs[0]
|
|
101
|
-
input._estimateSize().should.equal(188)
|
|
102
|
-
})
|
|
103
|
-
it('uses SIGHASH_ALL|FORKID by default', function () {
|
|
104
|
-
var transaction = new Transaction()
|
|
105
|
-
.from(output, [public1, public2, public3], 2)
|
|
106
|
-
.to(address, 1000000)
|
|
107
|
-
var input = transaction.inputs[0]
|
|
108
|
-
var sigs = input.getSignatures(transaction, privateKey1, 0)
|
|
109
|
-
sigs[0].sigtype.should.equal(Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID)
|
|
110
|
-
})
|
|
111
|
-
it('roundtrips to/from object', function () {
|
|
112
|
-
var transaction = new Transaction()
|
|
113
|
-
.from(output, [public1, public2, public3], 2)
|
|
114
|
-
.to(address, 1000000)
|
|
115
|
-
.sign(privateKey1)
|
|
116
|
-
var input = transaction.inputs[0]
|
|
117
|
-
var roundtrip = new MultiSigInput(input.toObject())
|
|
118
|
-
roundtrip.toObject().should.deep.equal(input.toObject())
|
|
119
|
-
})
|
|
120
|
-
it('roundtrips to/from object when not signed', function () {
|
|
121
|
-
var transaction = new Transaction()
|
|
122
|
-
.from(output, [public1, public2, public3], 2)
|
|
123
|
-
.to(address, 1000000)
|
|
124
|
-
var input = transaction.inputs[0]
|
|
125
|
-
var roundtrip = new MultiSigInput(input.toObject())
|
|
126
|
-
roundtrip.toObject().should.deep.equal(input.toObject())
|
|
127
|
-
})
|
|
128
|
-
it('can parse list of signature buffers, from TX signed with key 1 and 2', function () {
|
|
129
|
-
var transaction = new Transaction('010000000140c1ae9d6933e4a08594f814ba73a4e94d19c8a83f45784b1684b3a3f84ee666000000009200473044022012bd2f15e56ab1b63d5ee23e194ed995ad4b81a21bcb8e0d913e5e791c07f7280220278bdb6b54cdc608193c869affe28dc2f700902218122770faff25c56142102b01483045022100e74e9955e042aca36f4f3ad907a0926c5b85e5d9608b0678a78a9cbc0259c7a2022053ff761e5f9a80558db7023e45c4979ac3c19a423f0184fb0596d3da308cc4b501ffffffff0140420f000000000017a91419438da7d16709643be5abd8df62ca4034a489a78700000000')
|
|
130
|
-
|
|
131
|
-
var inputObj = transaction.inputs[0].toObject()
|
|
132
|
-
inputObj.output = output
|
|
133
|
-
transaction.inputs[0] = new Transaction.Input(inputObj)
|
|
134
|
-
|
|
135
|
-
inputObj.signatures = MultiSigInput.normalizeSignatures(
|
|
136
|
-
transaction,
|
|
137
|
-
transaction.inputs[0],
|
|
138
|
-
0,
|
|
139
|
-
transaction.inputs[0].script.chunks.slice(1).map(function (s) { return s.buf }),
|
|
140
|
-
[public1, public2, public3]
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
transaction.inputs[0] = new MultiSigInput(inputObj, [public1, public2, public3], 2)
|
|
144
|
-
|
|
145
|
-
transaction.inputs[0].signatures[0].publicKey.should.deep.equal(public1)
|
|
146
|
-
transaction.inputs[0].signatures[1].publicKey.should.deep.equal(public2)
|
|
147
|
-
should.equal(transaction.inputs[0].signatures[2], undefined)
|
|
148
|
-
transaction.inputs[0].isValidSignature(transaction, transaction.inputs[0].signatures[0]).should.equal(true)
|
|
149
|
-
transaction.inputs[0].isValidSignature(transaction, transaction.inputs[0].signatures[1]).should.equal(true)
|
|
150
|
-
})
|
|
151
|
-
it('can parse list of signature buffers, from TX signed with key 3 and 1', function () {
|
|
152
|
-
var transaction = new Transaction('010000000140c1ae9d6933e4a08594f814ba73a4e94d19c8a83f45784b1684b3a3f84ee666000000009300483045022100fc39ce4f51b2766ec8e978296e0594ea4578a3eb2543722fd4053e92bf16e6b1022030f739868397a881b019508b9c725a5c69a3652cb8928027748e93e67dfaef5501483045022100e74e9955e042aca36f4f3ad907a0926c5b85e5d9608b0678a78a9cbc0259c7a2022053ff761e5f9a80558db7023e45c4979ac3c19a423f0184fb0596d3da308cc4b501ffffffff0140420f000000000017a91419438da7d16709643be5abd8df62ca4034a489a78700000000')
|
|
153
|
-
|
|
154
|
-
var inputObj = transaction.inputs[0].toObject()
|
|
155
|
-
inputObj.output = output
|
|
156
|
-
transaction.inputs[0] = new Transaction.Input(inputObj)
|
|
157
|
-
|
|
158
|
-
inputObj.signatures = MultiSigInput.normalizeSignatures(
|
|
159
|
-
transaction,
|
|
160
|
-
transaction.inputs[0],
|
|
161
|
-
0,
|
|
162
|
-
transaction.inputs[0].script.chunks.slice(1).map(function (s) { return s.buf }),
|
|
163
|
-
[public1, public2, public3]
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
transaction.inputs[0] = new MultiSigInput(inputObj, [public1, public2, public3], 2)
|
|
167
|
-
|
|
168
|
-
transaction.inputs[0].signatures[0].publicKey.should.deep.equal(public1)
|
|
169
|
-
should.equal(transaction.inputs[0].signatures[1], undefined)
|
|
170
|
-
transaction.inputs[0].signatures[2].publicKey.should.deep.equal(public3)
|
|
171
|
-
transaction.inputs[0].isValidSignature(transaction, transaction.inputs[0].signatures[0]).should.equal(true)
|
|
172
|
-
transaction.inputs[0].isValidSignature(transaction, transaction.inputs[0].signatures[2]).should.equal(true)
|
|
173
|
-
})
|
|
174
|
-
})
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
require('chai').should()
|
|
4
|
-
var _ = require('../../../lib/util/_')
|
|
5
|
-
|
|
6
|
-
var bsv = require('../../..')
|
|
7
|
-
var Transaction = bsv.Transaction
|
|
8
|
-
var PrivateKey = bsv.PrivateKey
|
|
9
|
-
var Address = bsv.Address
|
|
10
|
-
var Script = bsv.Script
|
|
11
|
-
var Signature = bsv.crypto.Signature
|
|
12
|
-
var MultiSigScriptHashInput = bsv.Transaction.Input.MultiSigScriptHash
|
|
13
|
-
|
|
14
|
-
describe('MultiSigScriptHashInput', function () {
|
|
15
|
-
var privateKey1 = new PrivateKey('KwF9LjRraetZuEjR8VqEq539z137LW5anYDUnVK11vM3mNMHTWb4')
|
|
16
|
-
var privateKey2 = new PrivateKey('L4PqnaPTCkYhAqH3YQmefjxQP6zRcF4EJbdGqR8v6adtG9XSsadY')
|
|
17
|
-
var privateKey3 = new PrivateKey('L4CTX79zFeksZTyyoFuPQAySfmP7fL3R41gWKTuepuN7hxuNuJwV')
|
|
18
|
-
var public1 = privateKey1.publicKey
|
|
19
|
-
var public2 = privateKey2.publicKey
|
|
20
|
-
var public3 = privateKey3.publicKey
|
|
21
|
-
var address = new Address('33zbk2aSZYdNbRsMPPt6jgy6Kq1kQreqeb')
|
|
22
|
-
|
|
23
|
-
var output = {
|
|
24
|
-
address: '33zbk2aSZYdNbRsMPPt6jgy6Kq1kQreqeb',
|
|
25
|
-
txId: '66e64ef8a3b384164b78453fa8c8194de9a473ba14f89485a0e433699daec140',
|
|
26
|
-
outputIndex: 0,
|
|
27
|
-
script: new Script(address),
|
|
28
|
-
satoshis: 1000000
|
|
29
|
-
}
|
|
30
|
-
it('can count missing signatures', function () {
|
|
31
|
-
var transaction = new Transaction()
|
|
32
|
-
.from(output, [public1, public2, public3], 2)
|
|
33
|
-
.to(address, 1000000)
|
|
34
|
-
var input = transaction.inputs[0]
|
|
35
|
-
|
|
36
|
-
input.countSignatures().should.equal(0)
|
|
37
|
-
|
|
38
|
-
transaction.sign(privateKey1)
|
|
39
|
-
input.countSignatures().should.equal(1)
|
|
40
|
-
input.countMissingSignatures().should.equal(1)
|
|
41
|
-
input.isFullySigned().should.equal(false)
|
|
42
|
-
|
|
43
|
-
transaction.sign(privateKey2)
|
|
44
|
-
input.countSignatures().should.equal(2)
|
|
45
|
-
input.countMissingSignatures().should.equal(0)
|
|
46
|
-
input.isFullySigned().should.equal(true)
|
|
47
|
-
})
|
|
48
|
-
it('returns a list of public keys with missing signatures', function () {
|
|
49
|
-
var transaction = new Transaction()
|
|
50
|
-
.from(output, [public1, public2, public3], 2)
|
|
51
|
-
.to(address, 1000000)
|
|
52
|
-
var input = transaction.inputs[0]
|
|
53
|
-
|
|
54
|
-
_.every(input.publicKeysWithoutSignature(), function (publicKeyMissing) {
|
|
55
|
-
var serialized = publicKeyMissing.toString()
|
|
56
|
-
return serialized === public1.toString() ||
|
|
57
|
-
serialized === public2.toString() ||
|
|
58
|
-
serialized === public3.toString()
|
|
59
|
-
}).should.equal(true)
|
|
60
|
-
transaction.sign(privateKey1)
|
|
61
|
-
_.every(input.publicKeysWithoutSignature(), function (publicKeyMissing) {
|
|
62
|
-
var serialized = publicKeyMissing.toString()
|
|
63
|
-
return serialized === public2.toString() ||
|
|
64
|
-
serialized === public3.toString()
|
|
65
|
-
}).should.equal(true)
|
|
66
|
-
})
|
|
67
|
-
it('can clear all signatures', function () {
|
|
68
|
-
var transaction = new Transaction()
|
|
69
|
-
.from(output, [public1, public2, public3], 2)
|
|
70
|
-
.to(address, 1000000)
|
|
71
|
-
.sign(privateKey1)
|
|
72
|
-
.sign(privateKey2)
|
|
73
|
-
|
|
74
|
-
var input = transaction.inputs[0]
|
|
75
|
-
input.isFullySigned().should.equal(true)
|
|
76
|
-
input.clearSignatures()
|
|
77
|
-
input.isFullySigned().should.equal(false)
|
|
78
|
-
})
|
|
79
|
-
it('can estimate how heavy is the output going to be', function () {
|
|
80
|
-
var transaction = new Transaction()
|
|
81
|
-
.from(output, [public1, public2, public3], 2)
|
|
82
|
-
.to(address, 1000000)
|
|
83
|
-
var input = transaction.inputs[0]
|
|
84
|
-
input._estimateSize().should.equal(297)
|
|
85
|
-
})
|
|
86
|
-
it('uses SIGHASH_ALL|FORKID by default', function () {
|
|
87
|
-
var transaction = new Transaction()
|
|
88
|
-
.from(output, [public1, public2, public3], 2)
|
|
89
|
-
.to(address, 1000000)
|
|
90
|
-
var input = transaction.inputs[0]
|
|
91
|
-
var sigs = input.getSignatures(transaction, privateKey1, 0)
|
|
92
|
-
sigs[0].sigtype.should.equal(Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID)
|
|
93
|
-
})
|
|
94
|
-
it('roundtrips to/from object', function () {
|
|
95
|
-
var transaction = new Transaction()
|
|
96
|
-
.from(output, [public1, public2, public3], 2)
|
|
97
|
-
.to(address, 1000000)
|
|
98
|
-
.sign(privateKey1)
|
|
99
|
-
var input = transaction.inputs[0]
|
|
100
|
-
var roundtrip = new MultiSigScriptHashInput(input.toObject())
|
|
101
|
-
roundtrip.toObject().should.deep.equal(input.toObject())
|
|
102
|
-
})
|
|
103
|
-
it('roundtrips to/from object when not signed', function () {
|
|
104
|
-
var transaction = new Transaction()
|
|
105
|
-
.from(output, [public1, public2, public3], 2)
|
|
106
|
-
.to(address, 1000000)
|
|
107
|
-
var input = transaction.inputs[0]
|
|
108
|
-
var roundtrip = new MultiSigScriptHashInput(input.toObject())
|
|
109
|
-
roundtrip.toObject().should.deep.equal(input.toObject())
|
|
110
|
-
})
|
|
111
|
-
})
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var bsv = require('../../..')
|
|
4
|
-
var Transaction = bsv.Transaction
|
|
5
|
-
var PrivateKey = bsv.PrivateKey
|
|
6
|
-
|
|
7
|
-
describe('PublicKeyInput', function () {
|
|
8
|
-
var utxo = {
|
|
9
|
-
txid: '7f3b688cb224ed83e12d9454145c26ac913687086a0a62f2ae0bc10934a4030f',
|
|
10
|
-
vout: 0,
|
|
11
|
-
address: 'n4McBrSkw42eYGX5YMACGpkGUJKL3jVSbo',
|
|
12
|
-
scriptPubKey: '2103c9594cb2ebfebcb0cfd29eacd40ba012606a197beef76f0269ed8c101e56ceddac',
|
|
13
|
-
amount: 50,
|
|
14
|
-
confirmations: 104,
|
|
15
|
-
spendable: true
|
|
16
|
-
}
|
|
17
|
-
var privateKey = PrivateKey.fromWIF('cQ7tSSQDEwaxg9usnnP1Aztqvm9nCQVfNWz9kU2rdocDjknF2vd6')
|
|
18
|
-
var address = privateKey.toAddress()
|
|
19
|
-
utxo.address.should.equal(address.toString())
|
|
20
|
-
|
|
21
|
-
var destKey = new PrivateKey()
|
|
22
|
-
|
|
23
|
-
it('will correctly sign a publickey out transaction', function () {
|
|
24
|
-
var tx = new Transaction()
|
|
25
|
-
tx.from(utxo)
|
|
26
|
-
tx.to(destKey.toAddress(), 10000)
|
|
27
|
-
tx.sign(privateKey)
|
|
28
|
-
tx.inputs[0].script.toBuffer().length.should.be.above(0)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('count can count missing signatures', function () {
|
|
32
|
-
var tx = new Transaction()
|
|
33
|
-
tx.from(utxo)
|
|
34
|
-
tx.to(destKey.toAddress(), 10000)
|
|
35
|
-
var input = tx.inputs[0]
|
|
36
|
-
input.isFullySigned().should.equal(false)
|
|
37
|
-
tx.sign(privateKey)
|
|
38
|
-
input.isFullySigned().should.equal(true)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('it\'s size can be estimated', function () {
|
|
42
|
-
var tx = new Transaction()
|
|
43
|
-
tx.from(utxo)
|
|
44
|
-
tx.to(destKey.toAddress(), 10000)
|
|
45
|
-
var input = tx.inputs[0]
|
|
46
|
-
input._estimateSize().should.equal(114)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('it\'s signature can be removed', function () {
|
|
50
|
-
var tx = new Transaction()
|
|
51
|
-
tx.from(utxo)
|
|
52
|
-
tx.to(destKey.toAddress(), 10000)
|
|
53
|
-
var input = tx.inputs[0]
|
|
54
|
-
tx.sign(privateKey)
|
|
55
|
-
input.isFullySigned().should.equal(true)
|
|
56
|
-
input.clearSignatures()
|
|
57
|
-
input.isFullySigned().should.equal(false)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('returns an empty array if private key mismatches', function () {
|
|
61
|
-
var tx = new Transaction()
|
|
62
|
-
tx.from(utxo)
|
|
63
|
-
tx.to(destKey.toAddress(), 10000)
|
|
64
|
-
var input = tx.inputs[0]
|
|
65
|
-
var signatures = input.getSignatures(tx, new PrivateKey(), 0)
|
|
66
|
-
signatures.length.should.equal(0)
|
|
67
|
-
})
|
|
68
|
-
})
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
require('chai').should()
|
|
4
|
-
|
|
5
|
-
var bsv = require('../../..')
|
|
6
|
-
var Transaction = bsv.Transaction
|
|
7
|
-
var PrivateKey = bsv.PrivateKey
|
|
8
|
-
var Address = bsv.Address
|
|
9
|
-
var Script = bsv.Script
|
|
10
|
-
var Networks = bsv.Networks
|
|
11
|
-
|
|
12
|
-
describe('PublicKeyHashInput', function () {
|
|
13
|
-
var privateKey = new PrivateKey('KwF9LjRraetZuEjR8VqEq539z137LW5anYDUnVK11vM3mNMHTWb4')
|
|
14
|
-
var publicKey = privateKey.publicKey
|
|
15
|
-
var address = new Address(publicKey, Networks.livenet)
|
|
16
|
-
|
|
17
|
-
var output = {
|
|
18
|
-
address: '33zbk2aSZYdNbRsMPPt6jgy6Kq1kQreqeb',
|
|
19
|
-
txId: '66e64ef8a3b384164b78453fa8c8194de9a473ba14f89485a0e433699daec140',
|
|
20
|
-
outputIndex: 0,
|
|
21
|
-
script: new Script(address),
|
|
22
|
-
satoshis: 1000000
|
|
23
|
-
}
|
|
24
|
-
it('can count missing signatures', function () {
|
|
25
|
-
var transaction = new Transaction()
|
|
26
|
-
.from(output)
|
|
27
|
-
.to(address, 1000000)
|
|
28
|
-
var input = transaction.inputs[0]
|
|
29
|
-
|
|
30
|
-
input.isFullySigned().should.equal(false)
|
|
31
|
-
transaction.sign(privateKey)
|
|
32
|
-
input.isFullySigned().should.equal(true)
|
|
33
|
-
})
|
|
34
|
-
it('it\'s size can be estimated', function () {
|
|
35
|
-
var transaction = new Transaction()
|
|
36
|
-
.from(output)
|
|
37
|
-
.to(address, 1000000)
|
|
38
|
-
var input = transaction.inputs[0]
|
|
39
|
-
input._estimateSize().should.equal(148)
|
|
40
|
-
})
|
|
41
|
-
it('it\'s signature can be removed', function () {
|
|
42
|
-
var transaction = new Transaction()
|
|
43
|
-
.from(output)
|
|
44
|
-
.to(address, 1000000)
|
|
45
|
-
var input = transaction.inputs[0]
|
|
46
|
-
|
|
47
|
-
transaction.sign(privateKey)
|
|
48
|
-
input.clearSignatures()
|
|
49
|
-
input.isFullySigned().should.equal(false)
|
|
50
|
-
})
|
|
51
|
-
it('returns an empty array if private key mismatches', function () {
|
|
52
|
-
var transaction = new Transaction()
|
|
53
|
-
.from(output)
|
|
54
|
-
.to(address, 1000000)
|
|
55
|
-
var input = transaction.inputs[0]
|
|
56
|
-
var signatures = input.getSignatures(transaction, new PrivateKey(), 0)
|
|
57
|
-
signatures.length.should.equal(0)
|
|
58
|
-
})
|
|
59
|
-
})
|