diff --git a/src/payments/embed.js b/src/payments/embed.js index c636c80..ea2c8e9 100644 --- a/src/payments/embed.js +++ b/src/payments/embed.js @@ -19,7 +19,7 @@ function p2data (a, opts) { !a.data && !a.output ) throw new TypeError('Not enough data') - opts = opts || { validate: true } + opts = Object.assign({ validate: true }, opts || {}) typef({ network: typef.maybe(typef.Object), diff --git a/src/payments/p2ms.js b/src/payments/p2ms.js index 15de44e..5c90a4d 100644 --- a/src/payments/p2ms.js +++ b/src/payments/p2ms.js @@ -24,7 +24,7 @@ function p2ms (a, opts) { !(a.pubkeys && a.m !== undefined) && !a.signatures ) throw new TypeError('Not enough data') - opts = opts || { validate: true } + opts = Object.assign({ validate: true }, opts || {}) function isAcceptableSignature (x) { return bscript.isCanonicalScriptSignature(x) || (opts.allowIncomplete && (x === OPS.OP_0)) diff --git a/src/payments/p2pk.js b/src/payments/p2pk.js index 4073d52..b930612 100644 --- a/src/payments/p2pk.js +++ b/src/payments/p2pk.js @@ -16,7 +16,7 @@ function p2pk (a, opts) { !a.input && !a.signature ) throw new TypeError('Not enough data') - opts = opts || { validate: true } + opts = Object.assign({ validate: true }, opts || {}) typef({ network: typef.maybe(typef.Object), diff --git a/src/payments/p2pkh.js b/src/payments/p2pkh.js index 0ab9fa0..e9248a2 100644 --- a/src/payments/p2pkh.js +++ b/src/payments/p2pkh.js @@ -18,7 +18,7 @@ function p2pkh (a, opts) { !a.pubkey && !a.input ) throw new TypeError('Not enough data') - opts = opts || { validate: true } + opts = Object.assign({ validate: true }, opts || {}) typef({ network: typef.maybe(typef.Object), diff --git a/src/payments/p2sh.js b/src/payments/p2sh.js index b642154..4741936 100644 --- a/src/payments/p2sh.js +++ b/src/payments/p2sh.js @@ -26,7 +26,7 @@ function p2sh (a, opts) { !a.redeem && !a.input ) throw new TypeError('Not enough data') - opts = opts || { validate: true } + opts = Object.assign({ validate: true }, opts || {}) typef({ network: typef.maybe(typef.Object), diff --git a/src/payments/p2wpkh.js b/src/payments/p2wpkh.js index c47c354..1483bd8 100644 --- a/src/payments/p2wpkh.js +++ b/src/payments/p2wpkh.js @@ -21,7 +21,7 @@ function p2wpkh (a, opts) { !a.pubkey && !a.witness ) throw new TypeError('Not enough data') - opts = opts || { validate: true } + opts = Object.assign({ validate: true }, opts || {}) typef({ address: typef.maybe(typef.String), diff --git a/src/payments/p2wsh.js b/src/payments/p2wsh.js index 8c45022..a26e706 100644 --- a/src/payments/p2wsh.js +++ b/src/payments/p2wsh.js @@ -28,7 +28,7 @@ function p2wsh (a, opts) { !a.redeem && !a.witness ) throw new TypeError('Not enough data') - opts = opts || { validate: true } + opts = Object.assign({ validate: true }, opts || {}) typef({ network: typef.maybe(typef.Object), diff --git a/test/fixtures/embed.json b/test/fixtures/embed.json index ccc0e70..40e43cd 100644 --- a/test/fixtures/embed.json +++ b/test/fixtures/embed.json @@ -5,6 +5,7 @@ "arguments": { "output": "OP_RETURN a3b147dbe4a85579fc4b5a1811e76620560e07267e62b9a0d6858f9127735cadd82f67e06c24dbc4" }, + "options": {}, "expected": { "data": [ "a3b147dbe4a85579fc4b5a1811e76620560e07267e62b9a0d6858f9127735cadd82f67e06c24dbc4" @@ -35,6 +36,14 @@ { "exception": "Not enough data", "arguments": {} + }, + { + "description": "First OP is not OP_RETURN", + "exception": "Output is invalid", + "options": {}, + "arguments": { + "output": "OP_1 OP_2 OP_ADD" + } } ], "dynamic": { diff --git a/test/fixtures/p2ms.json b/test/fixtures/p2ms.json index d5bb0c8..8ea033e 100644 --- a/test/fixtures/p2ms.json +++ b/test/fixtures/p2ms.json @@ -5,6 +5,7 @@ "arguments": { "output": "OP_2 030000000000000000000000000000000000000000000000000000000000000001 030000000000000000000000000000000000000000000000000000000000000002 OP_2 OP_CHECKMULTISIG" }, + "options": {}, "expected": { "m": 2, "n": 2, @@ -239,6 +240,7 @@ { "description": "n !== output pubkeys", "exception": "Output is invalid", + "options": {}, "arguments": { "output": "OP_1 030000000000000000000000000000000000000000000000000000000000000001 OP_2 OP_CHECKMULTISIG" } @@ -266,6 +268,7 @@ }, { "exception": "Pubkeys mismatch", + "options": {}, "arguments": { "pubkeys": [ "030000000000000000000000000000000000000000000000000000000000000001" @@ -325,6 +328,7 @@ { "description": "Missing OP_0", "exception": "Input is invalid", + "options": {}, "arguments": { "m": 2, "pubkeys": [ diff --git a/test/fixtures/p2pk.json b/test/fixtures/p2pk.json index a9e1063..58f51cb 100644 --- a/test/fixtures/p2pk.json +++ b/test/fixtures/p2pk.json @@ -5,6 +5,7 @@ "arguments": { "output": "030000000000000000000000000000000000000000000000000000000000000001 OP_CHECKSIG" }, + "options": {}, "expected": { "pubkey": "030000000000000000000000000000000000000000000000000000000000000001", "signature": null, @@ -97,6 +98,7 @@ }, { "exception": "Pubkey mismatch", + "options": {}, "arguments": { "pubkey": "030000000000000000000000000000000000000000000000000000000000000001", "output": "030000000000000000000000000000000000000000000000000000000000000002 OP_CHECKSIG" diff --git a/test/fixtures/p2pkh.json b/test/fixtures/p2pkh.json index 118111d..44c20fe 100644 --- a/test/fixtures/p2pkh.json +++ b/test/fixtures/p2pkh.json @@ -5,6 +5,7 @@ "arguments": { "address": "134D6gYy8DsR5m4416BnmgASuMBqKvogQh" }, + "options": {}, "expected": { "hash": "168b992bcfc44050310b3a94bd0771136d0b28d1", "output": "OP_DUP OP_HASH160 168b992bcfc44050310b3a94bd0771136d0b28d1 OP_EQUALVERIFY OP_CHECKSIG", @@ -103,6 +104,7 @@ { "description": "Unexpected OP_DUP", "exception": "Output is invalid", + "options": {}, "arguments": { "output": "OP_DUP OP_DUP 168b992bcfc44050310b3a94bd0771136d0b28d137 OP_EQUALVERIFY" } diff --git a/test/fixtures/p2sh.json b/test/fixtures/p2sh.json index 44611a5..e6fe2ae 100644 --- a/test/fixtures/p2sh.json +++ b/test/fixtures/p2sh.json @@ -5,6 +5,7 @@ "arguments": { "address": "3GETYP4cuSesh2zsPEEYVZqnRedwe4FwUT" }, + "options": {}, "expected": { "hash": "9f840a5fc02407ef0ad499c2ec0eb0b942fb0086", "output": "OP_HASH160 9f840a5fc02407ef0ad499c2ec0eb0b942fb0086 OP_EQUAL", @@ -182,6 +183,7 @@ { "description": "Expected OP_HASH160", "exception": "Output is invalid", + "options": {}, "arguments": { "output": "OP_HASH256 ffffffffffffffffffffffffffffffffffffffff OP_EQUAL" } diff --git a/test/fixtures/p2wpkh.json b/test/fixtures/p2wpkh.json index 7341907..f667bdc 100644 --- a/test/fixtures/p2wpkh.json +++ b/test/fixtures/p2wpkh.json @@ -5,6 +5,7 @@ "arguments": { "address": "bc1qafk4yhqvj4wep57m62dgrmutldusqde8adh20d" }, + "options": {}, "expected": { "hash": "ea6d525c0c955d90d3dbd29a81ef8bfb79003727", "output": "OP_0 ea6d525c0c955d90d3dbd29a81ef8bfb79003727", @@ -108,6 +109,7 @@ }, { "exception": "Pubkey mismatch", + "options": {}, "arguments": { "pubkey": "030000000000000000000000000000000000000000000000000000000000000001", "witness": [ diff --git a/test/fixtures/p2wsh.json b/test/fixtures/p2wsh.json index 2f7b9cc..0870278 100644 --- a/test/fixtures/p2wsh.json +++ b/test/fixtures/p2wsh.json @@ -5,6 +5,7 @@ "arguments": { "address": "bc1q6rgl33d3s9dugudw7n68yrryajkr3ha9q8q24j20zs62se4q9tsqdy0t2q" }, + "options": {}, "expected": { "hash": "d0d1f8c5b1815bc471aef4f4720c64ecac38dfa501c0aac94f1434a866a02ae0", "output": "OP_0 d0d1f8c5b1815bc471aef4f4720c64ecac38dfa501c0aac94f1434a866a02ae0", @@ -221,6 +222,7 @@ }, { "exception": "Output is invalid", + "options": {}, "arguments": { "output": "OP_HASH256 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff OP_EQUAL" } diff --git a/test/fixtures/transaction_builder.json b/test/fixtures/transaction_builder.json index 7a3a8d2..4ddc5cb 100644 --- a/test/fixtures/transaction_builder.json +++ b/test/fixtures/transaction_builder.json @@ -1491,7 +1491,7 @@ ], "fromTransaction": [ { - "description": "Transaction w/ P2SH(P2MS 2/2) -> OP_RETURN | 1 OP_0, no signatures", + "description": "Transaction w/ P2SH(P2MS 2/2) -> OP_RETURN | 1 OP_0 fixes to 2 OP_0, no signatures", "network": "testnet", "incomplete": true, "inputs": [ @@ -1807,11 +1807,10 @@ "scriptSig": "OP_0 OP_0 OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae" }, { - "filterOP_0": true, "pubKeyIndex": 0, "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx", - "scriptSig": "OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae", - "scriptSigFiltered": "OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae" + "scriptSigBefore": "OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae", + "scriptSig": "OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae" } ] } diff --git a/test/transaction_builder.js b/test/transaction_builder.js index 93f407e..88294fb 100644 --- a/test/transaction_builder.js +++ b/test/transaction_builder.js @@ -489,27 +489,12 @@ describe('TransactionBuilder', function () { input.signs.forEach(function (sign) { // rebuild the transaction each-time after the first if (tx) { - // do we filter OP_0's beforehand? - if (sign.filterOP_0) { - const scriptSig = tx.ins[i].script - - // ignore OP_0 on the front, ignore redeemScript - const signatures = bscript.decompile(scriptSig) - .slice(1, -1) - .filter(x => x !== ops.OP_0) - - // rebuild/replace the scriptSig without them - const replacement = payments.p2sh({ - redeem: payments.p2ms({ - output: redeemScript, - signatures - }, { allowIncomplete: true }) - }).input - assert.strictEqual(bscript.toASM(replacement), sign.scriptSigFiltered) - - tx.ins[i].script = replacement + // manually override the scriptSig? + if (sign.scriptSigBefore) { + tx.ins[i].script = bscript.fromASM(sign.scriptSigBefore) } - // now import it + + // rebuild txb = TransactionBuilder.fromTransaction(tx, network) } @@ -518,6 +503,7 @@ describe('TransactionBuilder', function () { // update the tx tx = txb.buildIncomplete() + // now verify the serialized scriptSig is as expected assert.strictEqual(bscript.toASM(tx.ins[i].script), sign.scriptSig) })