From f30268751775d4c93b3955fecade1b6d10f87227 Mon Sep 17 00:00:00 2001 From: Gabriel Cardona Date: Fri, 8 Jun 2018 15:37:49 -0700 Subject: [PATCH] P2MS --- index.js | 2 +- package.json | 2 +- test/TransactionBuilder.js | 862 ++++++++++++++++++-------- test/fixtures/TransactionBuilder.json | 247 ++++++++ 4 files changed, 838 insertions(+), 275 deletions(-) diff --git a/index.js b/index.js index 1f69af92..fffe296e 100755 --- a/index.js +++ b/index.js @@ -25,7 +25,7 @@ let cmd = require('node-cmd'); // let ProgressBar = require('progress'); program - .version('0.9.7'); + .version('0.9.8'); program .command('new ') diff --git a/package.json b/package.json index 8c686363..0a1aa87b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bitbox-cli", - "version": "0.9.7", + "version": "0.9.8", "description": "A development framework for Bitcoin Cash", "author": "@bitboxearth", "main": "index.js", diff --git a/test/TransactionBuilder.js b/test/TransactionBuilder.js index ed65133d..ee4ca34f 100644 --- a/test/TransactionBuilder.js +++ b/test/TransactionBuilder.js @@ -268,278 +268,594 @@ describe('#TransactionBuilder', () => { }); }); - // describe('#P2PKH', () => { - // describe('#toOne', () => { - // describe('#Mainnet', () => { - // fixtures.scripts.p2pkh.toOne.mainnet.forEach((fixture) => { - // it(`should create 1-to-1 P2PKH transaction on mainnet`, () => { - // let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv); - // let transactionBuilder = new BITBOX.TransactionBuilder(); - // let keyPair = BITBOX.HDNode.toKeyPair(hdnode); - // let txHash = fixture.txHash; - // // original amount of satoshis in vin - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, fixture.vout); - // // get byte count to calculate fee. paying 1 sat/byte - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 1 }); - // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - // let sendAmount = originalAmount - byteCount; - // // add output w/ address and amount to send - // let redeemScript - // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); - // - // // build tx - // let tx = transactionBuilder.build(); - // // output rawhex - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - // - // describe('#Testnet', () => { - // fixtures.scripts.p2pkh.toOne.testnet.forEach((fixture) => { - // it(`should create 1-to-1 P2PKH transaction on testnet`, () => { - // let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv, 'testnet'); - // let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); - // let keyPair = BITBOX.HDNode.toKeyPair(hdnode); - // let txHash = fixture.txHash; - // // original amount of satoshis in vin - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, fixture.vout); - // // get byte count to calculate fee. paying 1 sat/byte - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 1 }); - // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - // let sendAmount = originalAmount - (byteCount * 15); - // // add output w/ address and amount to send - // let redeemScript - // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); - // - // // build tx - // let tx = transactionBuilder.build(); - // // output rawhex - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - // }); - // - // describe('#toMany', () => { - // describe('#Mainnet', () => { - // fixtures.scripts.p2pkh.toMany.mainnet.forEach((fixture) => { - // it(`should create 1-to-2 P2PKH transaction on mainnet`, () => { - // let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv); - // let transactionBuilder = new BITBOX.TransactionBuilder(); - // let keyPair = BITBOX.HDNode.toKeyPair(hdnode); - // let txHash = fixture.txHash; - // // original amount of satoshis in vin - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, fixture.vout); - // // get byte count to calculate fee. paying 1 sat/byte - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 2 }); - // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - // let sendAmount = originalAmount - byteCount; - // // add output w/ address and amount to send - // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); - // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); - // let redeemScript - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); - // // build tx - // let tx = transactionBuilder.build(); - // // output rawhex - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - // - // describe('#Testnet', () => { - // fixtures.scripts.p2pkh.toMany.testnet.forEach((fixture) => { - // // TODO pass in tesnet network config - // it(`should create 1-to-2 P2PKH transaction on testnet`, () => { - // let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv); - // let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); - // let keyPair = BITBOX.HDNode.toKeyPair(hdnode); - // let txHash = fixture.txHash; - // // original amount of satoshis in vin - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, fixture.vout); - // // get byte count to calculate fee. paying 1 sat/byte - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 2 }); - // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - // let sendAmount = originalAmount - (byteCount * 15); - // // add output w/ address and amount to send - // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); - // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); - // let redeemScript - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); - // // build tx - // let tx = transactionBuilder.build(); - // // output rawhex - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - // }); - // - // describe('#manyToMany', () => { - // describe('#Mainnet', () => { - // fixtures.scripts.p2pkh.manyToMany.mainnet.forEach((fixture) => { - // it(`should create 2-to-2 P2PKH transaction on mainnet`, () => { - // let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); - // let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); - // let transactionBuilder = new BITBOX.TransactionBuilder(); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; - // transactionBuilder.addInput(txHash, 0); - // transactionBuilder.addInput(txHash, 1); - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 2 }); - // let sendAmount = originalAmount - byteCount; - // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); - // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); - // let keyPair1 = BITBOX.HDNode.toKeyPair(node1); - // let keyPair2 = BITBOX.HDNode.toKeyPair(node2); - // let redeemScript; - // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); - // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - // - // describe('#Testnet', () => { - // fixtures.scripts.p2pkh.manyToMany.testnet.forEach((fixture) => { - // it(`should create 2-to-2 P2PKH transaction on testnet`, () => { - // let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); - // let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); - // let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; - // transactionBuilder.addInput(txHash, 0); - // transactionBuilder.addInput(txHash, 1); - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 2 }); - // let sendAmount = originalAmount - (byteCount * 15); - // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); - // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); - // let keyPair1 = BITBOX.HDNode.toKeyPair(node1); - // let keyPair2 = BITBOX.HDNode.toKeyPair(node2); - // let redeemScript; - // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); - // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - // }); - // - // describe('#fromMany', () => { - // describe('#Mainnet', () => { - // fixtures.scripts.p2pkh.fromMany.mainnet.forEach((fixture) => { - // it(`should create 2-to-1 P2PKH transaction on mainnet`, () => { - // let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); - // let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); - // let transactionBuilder = new BITBOX.TransactionBuilder(); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; - // transactionBuilder.addInput(txHash, 0); - // transactionBuilder.addInput(txHash, 1); - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 1 }); - // let sendAmount = originalAmount - byteCount; - // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); - // let keyPair1 = BITBOX.HDNode.toKeyPair(node1); - // let keyPair2 = BITBOX.HDNode.toKeyPair(node2); - // let redeemScript; - // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); - // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - // - // describe('#Testnet', () => { - // fixtures.scripts.p2pkh.fromMany.testnet.forEach((fixture) => { - // it(`should create 2-to-1 P2PKH transaction on testnet`, () => { - // let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); - // let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); - // let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; - // transactionBuilder.addInput(txHash, 0); - // transactionBuilder.addInput(txHash, 1); - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 1 }); - // let sendAmount = originalAmount - (byteCount * 15); - // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); - // let keyPair1 = BITBOX.HDNode.toKeyPair(node1); - // let keyPair2 = BITBOX.HDNode.toKeyPair(node2); - // let redeemScript; - // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); - // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - // }); - // }); - // - // describe('#op_return', () => { - // describe('#Mainnet', () => { - // fixtures.nulldata.mainnet.forEach((fixture) => { - // it(`should create transaction w/ OP_RETURN output on mainnet`, () => { - // let node = BITBOX.HDNode.fromXPriv(fixture.xpriv); - // let transactionBuilder = new BITBOX.TransactionBuilder(); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, 0); - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 5 }); - // let sendAmount = originalAmount - byteCount; - // transactionBuilder.addOutput(fixture.output, sendAmount); - // let data = fixture.data; - // let buf = BITBOX.Script.nullData.output.encode(Buffer.from(data, 'ascii')); - // transactionBuilder.addOutput(buf, 0); - // let keyPair = BITBOX.HDNode.toKeyPair(node); - // let redeemScript; - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amount); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - // - // describe('#Testnet', () => { - // fixtures.nulldata.testnet.forEach((fixture) => { - // it(`should create transaction w/ OP_RETURN output on testnet`, () => { - // let node = BITBOX.HDNode.fromXPriv(fixture.xpriv); - // let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, 0); - // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 5 }); - // let sendAmount = originalAmount - byteCount; - // transactionBuilder.addOutput(fixture.output, sendAmount); - // let data = fixture.data; - // let buf = BITBOX.Script.nullData.output.encode(Buffer.from(data, 'ascii')); - // transactionBuilder.addOutput(buf, 0); - // let keyPair = BITBOX.HDNode.toKeyPair(node); - // let redeemScript; - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amount); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); + describe('#P2PKH', () => { + describe('#toOne', () => { + describe('#Mainnet', () => { + fixtures.scripts.p2pkh.toOne.mainnet.forEach((fixture) => { + it(`should create 1-to-1 P2PKH transaction on mainnet`, () => { + let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let keyPair = BITBOX.HDNode.toKeyPair(hdnode); + let txHash = fixture.txHash; + // original amount of satoshis in vin + let originalAmount = fixture.amount; + transactionBuilder.addInput(txHash, fixture.vout); + // get byte count to calculate fee. paying 1 sat/byte + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 1 }); + // amount to send to receiver. It's the original amount - 1 sat/byte for tx size + let sendAmount = originalAmount - byteCount; + // add output w/ address and amount to send + let redeemScript + transactionBuilder.addOutput(fixture.outputs[0], sendAmount); + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); + + // build tx + let tx = transactionBuilder.build(); + // output rawhex + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + describe('#Testnet', () => { + fixtures.scripts.p2pkh.toOne.testnet.forEach((fixture) => { + it(`should create 1-to-1 P2PKH transaction on testnet`, () => { + let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv, 'testnet'); + let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + let keyPair = BITBOX.HDNode.toKeyPair(hdnode); + let txHash = fixture.txHash; + // original amount of satoshis in vin + let originalAmount = fixture.amount; + transactionBuilder.addInput(txHash, fixture.vout); + // get byte count to calculate fee. paying 1 sat/byte + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 1 }); + // amount to send to receiver. It's the original amount - 1 sat/byte for tx size + let sendAmount = originalAmount - (byteCount * 15); + // add output w/ address and amount to send + let redeemScript + transactionBuilder.addOutput(fixture.outputs[0], sendAmount); + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); + + // build tx + let tx = transactionBuilder.build(); + // output rawhex + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + }); + + describe('#toMany', () => { + describe('#Mainnet', () => { + fixtures.scripts.p2pkh.toMany.mainnet.forEach((fixture) => { + it(`should create 1-to-2 P2PKH transaction on mainnet`, () => { + let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let keyPair = BITBOX.HDNode.toKeyPair(hdnode); + let txHash = fixture.txHash; + // original amount of satoshis in vin + let originalAmount = fixture.amount; + transactionBuilder.addInput(txHash, fixture.vout); + // get byte count to calculate fee. paying 1 sat/byte + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 2 }); + // amount to send to receiver. It's the original amount - 1 sat/byte for tx size + let sendAmount = originalAmount - byteCount; + // add output w/ address and amount to send + transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); + transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); + let redeemScript + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); + // build tx + let tx = transactionBuilder.build(); + // output rawhex + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + describe('#Testnet', () => { + fixtures.scripts.p2pkh.toMany.testnet.forEach((fixture) => { + // TODO pass in tesnet network config + it(`should create 1-to-2 P2PKH transaction on testnet`, () => { + let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv); + let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + let keyPair = BITBOX.HDNode.toKeyPair(hdnode); + let txHash = fixture.txHash; + // original amount of satoshis in vin + let originalAmount = fixture.amount; + transactionBuilder.addInput(txHash, fixture.vout); + // get byte count to calculate fee. paying 1 sat/byte + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 2 }); + // amount to send to receiver. It's the original amount - 1 sat/byte for tx size + let sendAmount = originalAmount - (byteCount * 15); + // add output w/ address and amount to send + transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); + transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); + let redeemScript + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); + // build tx + let tx = transactionBuilder.build(); + // output rawhex + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + }); + + describe('#manyToMany', () => { + describe('#Mainnet', () => { + fixtures.scripts.p2pkh.manyToMany.mainnet.forEach((fixture) => { + it(`should create 2-to-2 P2PKH transaction on mainnet`, () => { + let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let txHash = fixture.txHash; + let originalAmount = fixture.amounts[0] + fixture.amounts[1]; + transactionBuilder.addInput(txHash, 0); + transactionBuilder.addInput(txHash, 1); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 2 }); + let sendAmount = originalAmount - byteCount; + transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); + transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); + let keyPair1 = BITBOX.HDNode.toKeyPair(node1); + let keyPair2 = BITBOX.HDNode.toKeyPair(node2); + let redeemScript; + transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); + transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + describe('#Testnet', () => { + fixtures.scripts.p2pkh.manyToMany.testnet.forEach((fixture) => { + it(`should create 2-to-2 P2PKH transaction on testnet`, () => { + let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + let txHash = fixture.txHash; + let originalAmount = fixture.amounts[0] + fixture.amounts[1]; + transactionBuilder.addInput(txHash, 0); + transactionBuilder.addInput(txHash, 1); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 2 }); + let sendAmount = originalAmount - (byteCount * 15); + transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); + transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); + let keyPair1 = BITBOX.HDNode.toKeyPair(node1); + let keyPair2 = BITBOX.HDNode.toKeyPair(node2); + let redeemScript; + transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); + transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + }); + + describe('#fromMany', () => { + describe('#Mainnet', () => { + fixtures.scripts.p2pkh.fromMany.mainnet.forEach((fixture) => { + it(`should create 2-to-1 P2PKH transaction on mainnet`, () => { + let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let txHash = fixture.txHash; + let originalAmount = fixture.amounts[0] + fixture.amounts[1]; + transactionBuilder.addInput(txHash, 0); + transactionBuilder.addInput(txHash, 1); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 1 }); + let sendAmount = originalAmount - byteCount; + transactionBuilder.addOutput(fixture.outputs[0], sendAmount); + let keyPair1 = BITBOX.HDNode.toKeyPair(node1); + let keyPair2 = BITBOX.HDNode.toKeyPair(node2); + let redeemScript; + transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); + transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + describe('#Testnet', () => { + fixtures.scripts.p2pkh.fromMany.testnet.forEach((fixture) => { + it(`should create 2-to-1 P2PKH transaction on testnet`, () => { + let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + let txHash = fixture.txHash; + let originalAmount = fixture.amounts[0] + fixture.amounts[1]; + transactionBuilder.addInput(txHash, 0); + transactionBuilder.addInput(txHash, 1); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 1 }); + let sendAmount = originalAmount - (byteCount * 15); + transactionBuilder.addOutput(fixture.outputs[0], sendAmount); + let keyPair1 = BITBOX.HDNode.toKeyPair(node1); + let keyPair2 = BITBOX.HDNode.toKeyPair(node2); + let redeemScript; + transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); + transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + }); + }); + + describe('#op_return', () => { + describe('#Mainnet', () => { + fixtures.nulldata.mainnet.forEach((fixture) => { + it(`should create transaction w/ OP_RETURN output on mainnet`, () => { + let node = BITBOX.HDNode.fromXPriv(fixture.xpriv); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let txHash = fixture.txHash; + let originalAmount = fixture.amount; + transactionBuilder.addInput(txHash, 0); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 5 }); + let sendAmount = originalAmount - byteCount; + transactionBuilder.addOutput(fixture.output, sendAmount); + let data = fixture.data; + let buf = BITBOX.Script.nullData.output.encode(Buffer.from(data, 'ascii')); + transactionBuilder.addOutput(buf, 0); + let keyPair = BITBOX.HDNode.toKeyPair(node); + let redeemScript; + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amount); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + describe('#Testnet', () => { + fixtures.nulldata.testnet.forEach((fixture) => { + it(`should create transaction w/ OP_RETURN output on testnet`, () => { + let node = BITBOX.HDNode.fromXPriv(fixture.xpriv); + let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + let txHash = fixture.txHash; + let originalAmount = fixture.amount; + transactionBuilder.addInput(txHash, 0); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 5 }); + let sendAmount = originalAmount - byteCount; + transactionBuilder.addOutput(fixture.output, sendAmount); + let data = fixture.data; + let buf = BITBOX.Script.nullData.output.encode(Buffer.from(data, 'ascii')); + transactionBuilder.addOutput(buf, 0); + let keyPair = BITBOX.HDNode.toKeyPair(node); + let redeemScript; + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amount); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + }); + + describe('#P2PMS', () => { + describe('#toOne', () => { + describe('#Mainnet', () => { + fixtures.scripts.p2ms.toOne.mainnet.forEach((fixture) => { + it(`should create 1-to-1 1-of-2 P2MS transaction on mainnet`, () => { + let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + let node3 = BITBOX.HDNode.fromXPriv(fixture.xprivs[2]); + let node4 = BITBOX.HDNode.fromXPriv(fixture.xprivs[3]); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let txid = fixture.txHash; + let originalAmount = fixture.amount; + let pubKey1 = BITBOX.HDNode.toPublicKey(node1); + let pubKey2 = BITBOX.HDNode.toPublicKey(node2); + let buf1 = BITBOX.Script.multisig.output.encode(1, [pubKey1, pubKey2]); + transactionBuilder.addInput(txid, 0, transactionBuilder.DEFAULT_SEQUENCE, buf1); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 3 }, { P2PKH: 3 }); + let pubKey3 = BITBOX.HDNode.toPublicKey(node3); + let pubKey4 = BITBOX.HDNode.toPublicKey(node4); + let buf2 = BITBOX.Script.multisig.output.encode(1, [pubKey3, pubKey4]); + let sendAmount = originalAmount - byteCount; + transactionBuilder.addOutput(buf2, sendAmount); + let redeemScript + let keyPair = BITBOX.HDNode.toKeyPair(node1); + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + // describe('#Testnet', () => { + // fixtures.scripts.p2ms.toOne.testnet.forEach((fixture) => { + // it(`should create 1-to-1 P2MS transaction on testnet`, () => { + // let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv, 'testnet'); + // let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + // let keyPair = BITBOX.HDNode.toKeyPair(hdnode); + // let txHash = fixture.txHash; + // // original amount of satoshis in vin + // let originalAmount = fixture.amount; + // transactionBuilder.addInput(txHash, fixture.vout); + // // get byte count to calculate fee. paying 1 sat/byte + // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 1 }); + // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size + // let sendAmount = originalAmount - (byteCount * 15); + // // add output w/ address and amount to send + // let redeemScript + // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); + // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); + // + // // build tx + // let tx = transactionBuilder.build(); + // // output rawhex + // let hex = tx.toHex(); + // assert.equal(hex, fixture.hex); + // }); + // }); + // }); + }); + + describe('#toMany', () => { + describe('#Mainnet', () => { + fixtures.scripts.p2ms.toMany.mainnet.forEach((fixture) => { + it(`should create 1-to-2 P2MS transaction on mainnet`, () => { + let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + let node3 = BITBOX.HDNode.fromXPriv(fixture.xprivs[2]); + let node4 = BITBOX.HDNode.fromXPriv(fixture.xprivs[3]); + let node5 = BITBOX.HDNode.fromXPriv(fixture.xprivs[4]); + let node6 = BITBOX.HDNode.fromXPriv(fixture.xprivs[5]); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let txid = fixture.txHash; + let originalAmount = fixture.amount; + let pubKey1 = BITBOX.HDNode.toPublicKey(node1); + let pubKey2 = BITBOX.HDNode.toPublicKey(node2); + let buf1 = BITBOX.Script.multisig.output.encode(1, [pubKey1, pubKey2]); + transactionBuilder.addInput(txid, 0, transactionBuilder.DEFAULT_SEQUENCE, buf1); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 3 }, { P2PKH: 3 }); + let sendAmount = originalAmount - byteCount; + let pubKey3 = BITBOX.HDNode.toPublicKey(node3); + let pubKey4 = BITBOX.HDNode.toPublicKey(node4); + let buf2 = BITBOX.Script.multisig.output.encode(1, [pubKey3, pubKey4]); + transactionBuilder.addOutput(buf2, Math.floor(sendAmount / 2)); + let pubKey5 = BITBOX.HDNode.toPublicKey(node5); + let pubKey6 = BITBOX.HDNode.toPublicKey(node6); + let buf3 = BITBOX.Script.multisig.output.encode(1, [pubKey5, pubKey6]); + transactionBuilder.addOutput(buf3, Math.floor(sendAmount / 2)); + let redeemScript + let keyPair = BITBOX.HDNode.toKeyPair(node1); + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + // describe('#Testnet', () => { + // fixtures.scripts.p2ms.toMany.testnet.forEach((fixture) => { + // // TODO pass in tesnet network config + // it(`should create 1-to-2 P2MS transaction on testnet`, () => { + // let hdnode = BITBOX.HDNode.fromXPriv(fixture.xpriv); + // let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + // let keyPair = BITBOX.HDNode.toKeyPair(hdnode); + // let txHash = fixture.txHash; + // // original amount of satoshis in vin + // let originalAmount = fixture.amount; + // transactionBuilder.addInput(txHash, fixture.vout); + // // get byte count to calculate fee. paying 1 sat/byte + // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 2 }); + // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size + // let sendAmount = originalAmount - (byteCount * 15); + // // add output w/ address and amount to send + // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); + // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); + // let redeemScript + // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); + // // build tx + // let tx = transactionBuilder.build(); + // // output rawhex + // let hex = tx.toHex(); + // assert.equal(hex, fixture.hex); + // }); + // }); + // }); + }); + + describe('#manyToMany', () => { + describe('#Mainnet', () => { + fixtures.scripts.p2ms.manyToMany.mainnet.forEach((fixture) => { + it(`should create 2-to-2 P2MS transaction on mainnet`, () => { + let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + let node3 = BITBOX.HDNode.fromXPriv(fixture.xprivs[2]); + let node4 = BITBOX.HDNode.fromXPriv(fixture.xprivs[3]); + let node5 = BITBOX.HDNode.fromXPriv(fixture.xprivs[4]); + let node6 = BITBOX.HDNode.fromXPriv(fixture.xprivs[5]); + let node7 = BITBOX.HDNode.fromXPriv(fixture.xprivs[6]); + let node8 = BITBOX.HDNode.fromXPriv(fixture.xprivs[7]); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let txid = fixture.txHash; + let originalAmount = fixture.amount; + let pubKey1 = BITBOX.HDNode.toPublicKey(node1); + let pubKey2 = BITBOX.HDNode.toPublicKey(node2); + let buf1 = BITBOX.Script.multisig.output.encode(1, [pubKey1, pubKey2]); + transactionBuilder.addInput(txid, 0, transactionBuilder.DEFAULT_SEQUENCE, buf1); + let pubKey3 = BITBOX.HDNode.toPublicKey(node3); + let pubKey4 = BITBOX.HDNode.toPublicKey(node4); + let buf2 = BITBOX.Script.multisig.output.encode(1, [pubKey3, pubKey4]); + transactionBuilder.addInput(txid, 1, transactionBuilder.DEFAULT_SEQUENCE, buf2); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 3 }, { P2PKH: 3 }); + let sendAmount = originalAmount - byteCount; + let pubKey5 = BITBOX.HDNode.toPublicKey(node5); + let pubKey6 = BITBOX.HDNode.toPublicKey(node6); + let buf3 = BITBOX.Script.multisig.output.encode(1, [pubKey5, pubKey6]); + transactionBuilder.addOutput(buf3, Math.floor(sendAmount / 2)); + let pubKey7 = BITBOX.HDNode.toPublicKey(node7); + let pubKey8 = BITBOX.HDNode.toPublicKey(node8); + let buf4 = BITBOX.Script.multisig.output.encode(1, [pubKey7, pubKey8]); + transactionBuilder.addOutput(buf4, Math.floor(sendAmount / 2)); + let redeemScript + let keyPair1 = BITBOX.HDNode.toKeyPair(node1); + let keyPair2 = BITBOX.HDNode.toKeyPair(node3); + transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount / 2); + transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount / 2); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + // describe('#Testnet', () => { + // fixtures.scripts.p2ms.manyToMany.testnet.forEach((fixture) => { + // it(`should create 2-to-2 P2MS transaction on testnet`, () => { + // let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + // let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + // let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + // let txHash = fixture.txHash; + // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; + // transactionBuilder.addInput(txHash, 0); + // transactionBuilder.addInput(txHash, 1); + // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 2 }); + // let sendAmount = originalAmount - (byteCount * 15); + // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); + // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); + // let keyPair1 = BITBOX.HDNode.toKeyPair(node1); + // let keyPair2 = BITBOX.HDNode.toKeyPair(node2); + // let redeemScript; + // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); + // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); + // let tx = transactionBuilder.build(); + // let hex = tx.toHex(); + // assert.equal(hex, fixture.hex); + // }); + // }); // }); - // }); - // }); + }); + + describe('#fromMany', () => { + describe('#Mainnet', () => { + fixtures.scripts.p2ms.fromMany.mainnet.forEach((fixture) => { + it(`should create 2-to-1 P2MS transaction on mainnet`, () => { + let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + let node3 = BITBOX.HDNode.fromXPriv(fixture.xprivs[2]); + let node4 = BITBOX.HDNode.fromXPriv(fixture.xprivs[3]); + let node5 = BITBOX.HDNode.fromXPriv(fixture.xprivs[4]); + let node6 = BITBOX.HDNode.fromXPriv(fixture.xprivs[5]); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let txid = fixture.txHash; + let originalAmount = fixture.amount; + let pubKey1 = BITBOX.HDNode.toPublicKey(node1); + let pubKey2 = BITBOX.HDNode.toPublicKey(node2); + let buf1 = BITBOX.Script.multisig.output.encode(1, [pubKey1, pubKey2]); + transactionBuilder.addInput(txid, 0, transactionBuilder.DEFAULT_SEQUENCE, buf1); + let pubKey3 = BITBOX.HDNode.toPublicKey(node3); + let pubKey4 = BITBOX.HDNode.toPublicKey(node4); + let buf2 = BITBOX.Script.multisig.output.encode(1, [pubKey3, pubKey4]); + transactionBuilder.addInput(txid, 1, transactionBuilder.DEFAULT_SEQUENCE, buf2); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 3 }, { P2PKH: 3 }); + let sendAmount = originalAmount - byteCount; + let pubKey5 = BITBOX.HDNode.toPublicKey(node5); + let pubKey6 = BITBOX.HDNode.toPublicKey(node6); + let buf3 = BITBOX.Script.multisig.output.encode(1, [pubKey5, pubKey6]); + transactionBuilder.addOutput(buf3, sendAmount); + let redeemScript + let keyPair1 = BITBOX.HDNode.toKeyPair(node1); + let keyPair2 = BITBOX.HDNode.toKeyPair(node3); + transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount / 2); + transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount / 2); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + // describe('#Testnet', () => { + // fixtures.scripts.p2ms.fromMany.testnet.forEach((fixture) => { + // it(`should create 2-to-1 P2MS transaction on testnet`, () => { + // let node1 = BITBOX.HDNode.fromXPriv(fixture.xprivs[0]); + // let node2 = BITBOX.HDNode.fromXPriv(fixture.xprivs[1]); + // let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + // let txHash = fixture.txHash; + // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; + // transactionBuilder.addInput(txHash, 0); + // transactionBuilder.addInput(txHash, 1); + // let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 1 }); + // let sendAmount = originalAmount - (byteCount * 15); + // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); + // let keyPair1 = BITBOX.HDNode.toKeyPair(node1); + // let keyPair2 = BITBOX.HDNode.toKeyPair(node2); + // let redeemScript; + // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); + // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); + // let tx = transactionBuilder.build(); + // let hex = tx.toHex(); + // assert.equal(hex, fixture.hex); + // }); + // }); + // }); + }); + }); + + describe('#op_return', () => { + describe('#Mainnet', () => { + fixtures.nulldata.mainnet.forEach((fixture) => { + it(`should create transaction w/ OP_RETURN output on mainnet`, () => { + let node = BITBOX.HDNode.fromXPriv(fixture.xpriv); + let transactionBuilder = new BITBOX.TransactionBuilder(); + let txHash = fixture.txHash; + let originalAmount = fixture.amount; + transactionBuilder.addInput(txHash, 0); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 5 }); + let sendAmount = originalAmount - byteCount; + transactionBuilder.addOutput(fixture.output, sendAmount); + let data = fixture.data; + let buf = BITBOX.Script.nullData.output.encode(Buffer.from(data, 'ascii')); + transactionBuilder.addOutput(buf, 0); + let keyPair = BITBOX.HDNode.toKeyPair(node); + let redeemScript; + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amount); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + + describe('#Testnet', () => { + fixtures.nulldata.testnet.forEach((fixture) => { + it(`should create transaction w/ OP_RETURN output on testnet`, () => { + let node = BITBOX.HDNode.fromXPriv(fixture.xpriv); + let transactionBuilder = new BITBOX.TransactionBuilder('testnet'); + let txHash = fixture.txHash; + let originalAmount = fixture.amount; + transactionBuilder.addInput(txHash, 0); + let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 5 }); + let sendAmount = originalAmount - byteCount; + transactionBuilder.addOutput(fixture.output, sendAmount); + let data = fixture.data; + let buf = BITBOX.Script.nullData.output.encode(Buffer.from(data, 'ascii')); + transactionBuilder.addOutput(buf, 0); + let keyPair = BITBOX.HDNode.toKeyPair(node); + let redeemScript; + transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amount); + let tx = transactionBuilder.build(); + let hex = tx.toHex(); + assert.equal(hex, fixture.hex); + }); + }); + }); + }); }); diff --git a/test/fixtures/TransactionBuilder.json b/test/fixtures/TransactionBuilder.json index 3f60d42d..6a06ccd7 100644 --- a/test/fixtures/TransactionBuilder.json +++ b/test/fixtures/TransactionBuilder.json @@ -964,6 +964,253 @@ } ] } + }, + "p2ms": { + "toOne": { + "mainnet": [ + { + "xprivs": [ + "xprvA7icF82QxB8Yceytan3gExmvk42pVxyV5wty9bCfe6xsh8VQQ89njqLUNwXUjcJNouTsNVFQWtFotRQiUecs344U6bvYzWgybRKX8Pe7VD4", + "xprvA7icF82QxB8Yf9QoKWYgv1HurbMjjFJqoprJRd2pPBy7BZiY4LXzDQcvyCtc7xvafRaF5qm8MBj9njwxFVhiXi2M7qNJQ2K8UAbsJmzh7z8", + "xprvA7icF82QxB8YjC4eCEsfMeNdnax3TtPB7hawSuYu1awBMGkbF3fKtnM6oJhiwL44dtDeK6EKCcTLAncL4itTfQ2SZFUVM8GFnPixxNwf2XJ", + "xprvA7icF82QxB8YmMUJS1g9XrKua1pqDnsoTzAeQyxPWFQxzJkbuD9aHEYxJkPXFxMpxRSRGKJoj6ek2JLtgtBx9AQx2efL59BbNdqCzeBGR5H" + ], + "txHash": "acd63b6ff8a7487767a12e13d810f01fd293bdbc11a6dc3bcd5d1f9fe8399449", + "hex": "0200000001499439e89f1f5dcd3bdca611bcbd93d21ff010d8132ea1677748a7f86f3bd6ac000000004a00483045022100a22833ce480af0e72abfd9c1fe1e3396f4671f531c7617d5c0d1a1c8b11b74e502205bcf3eb315e576141e825ddd9210a14fce823302fc57b69a4f1ad5d2d440a79241ffffffff01551c00000000000047512103d493e03c12ddda479aa7cff3c7d64d8bd0d66722957f1e67263fa8c7a7b1582c2102c345e1af9c49dc2b2073de92f3ab63c83fae641f6df9b43e0e59dfd0c771206952ae00000000", + "amount": 7809 + }, + { + "xprivs": [ + "xprvA7icF82QxB8YjC4eCEsfMeNdnax3TtPB7hawSuYu1awBMGkbF3fKtnM6oJhiwL44dtDeK6EKCcTLAncL4itTfQ2SZFUVM8GFnPixxNwf2XJ", + "xprvA7icF82QxB8YmMUJS1g9XrKua1pqDnsoTzAeQyxPWFQxzJkbuD9aHEYxJkPXFxMpxRSRGKJoj6ek2JLtgtBx9AQx2efL59BbNdqCzeBGR5H", + "xprvA7icF82QxB8YoTSEMJKFtmosaMU7n2f3PWpb5aWAKr3SbLuSdvkiYJzzaF8oPtdfFyfA3LPsV95rE4VdPCgwm8EJSprV2w9RnuRJMgRZVpu", + "xprvA7icF82QxB8Yr3ie7TD2hTaUxiMLbGx812oKj5PdMp9YcNQHHsGEjszyhSqEDSWYkGe1rJCKSmhx3m2do5yxhxGmhsUCwPQJ8Ria74MCHcg" + ], + "txHash": "1ffc187932d0142a4db94a4c2993ca46f378b16a1facb9c40680dcae68c3dcf4", + "hex": "0200000001f4dcc368aedc8006c4b9ac1f6ab178f346ca93294c4ab94d2a14d0327918fc1f00000000490047304402200fd3e5936fe61c6a650f1516cce980fa00cf4f545075004908ed7b22668a341d02204609d421b3c633c345747979310de9f581b3fcca3fc464d5f2ce6cd0c924766a41ffffffff01291a00000000000047512103972ad18a53b2b7049e46c9fd8ff866ffe6b24d9c1742bb53bcca89058164957621031e5d210ff49df1fc2408fd7d8679949f4684d9dc1c90016e65dc0c02e707176252ae00000000", + "amount": 7253 + }, + { + "xprivs": [ + "xprvA7icF82QxB8YoTSEMJKFtmosaMU7n2f3PWpb5aWAKr3SbLuSdvkiYJzzaF8oPtdfFyfA3LPsV95rE4VdPCgwm8EJSprV2w9RnuRJMgRZVpu", + "xprvA7icF82QxB8Yr3ie7TD2hTaUxiMLbGx812oKj5PdMp9YcNQHHsGEjszyhSqEDSWYkGe1rJCKSmhx3m2do5yxhxGmhsUCwPQJ8Ria74MCHcg", + "xprvA7icF82QxB8Yv1LagKeMmX1HmDCzRZPXRvKMCFTXQ1X4vkWcG3oh9bSUEGQJTkQfKvTfv7aNW2xTCqJJtfUPErc973PtE7S5hRVn8bRTmpb", + "xprvA7icF82QxB8YxP2Eh13mcngwEY7Q9Cr4BpzPGkLCPMMhSVq3ci7WTZiCGRP7mdQyXRff9cSMvDxsa8byxAPAHLVmec1h2KmGocUc6povdxq" + ], + "txHash": "508a1d84a74707bc542cf7cb977d1b4b03828842e9484c54528e1799131c4f81", + "hex": "0200000001814f1c1399178e52544c48e9428882034b1b7d97cbf72c54bc0747a7841d8a50000000004a00483045022100b6bc83766db9fdd2d4f89819681b73f3d2f6775db2cb8961d3cfb22922cc007e02204ac624fb6834299edfb96a1d8ebef9266e8f166c1eee37b5f2c47e9b368f2fae41ffffffff01fd170000000000004751210352f6a58f1c3d2d430f9a87b58db407c21d183ae35d65fb4bf1dff73adafac87c2103938520f916c41f69319c47c1eebab77bc56317593026e7eace061cbbc2b2601852ae00000000", + "amount": 6697 + }, + { + "xprivs": [ + "xprvA7icF82QxB8Yv1LagKeMmX1HmDCzRZPXRvKMCFTXQ1X4vkWcG3oh9bSUEGQJTkQfKvTfv7aNW2xTCqJJtfUPErc973PtE7S5hRVn8bRTmpb", + "xprvA7icF82QxB8YxP2Eh13mcngwEY7Q9Cr4BpzPGkLCPMMhSVq3ci7WTZiCGRP7mdQyXRff9cSMvDxsa8byxAPAHLVmec1h2KmGocUc6povdxq", + "xprvA7icF82QxB8Z17gjh7ZAujh5C6AMjrvycPJNyoJj3ynczXeuPMttF5PxHJXaQFkmzjJsx3d3SAwm6XMXyy9WAUcGB4kZqpRzZz5xyGN6yVt", + "xprvA7icF82QxB8Z2kQZmnrLde27PryauLg9FDz1nuKnJ98tDhgEvuvUmg4Yp375eFfq3aeCKy9wK3Zo5QZbtvybpxWRipjyaTsi832Tithb5Rk" + ], + "txHash": "759d93b196f517c8375c10057af8cd7ee6538916be1d8f3deab264880a2ce614", + "hex": "020000000114e62c0a8864b2ea3d8f1dbe168953e67ecdf87a05105c37c817f596b1939d75000000004a0048304502210092a2d41bd33e08f4ebf0425d434ae50b13bb6c92e4df4e3adedd41cf9106aac50220516edd08cfd77b334a19ce4522e4c2f763a54dc5c2fe90779e17b87a0a08840d41ffffffff01d1150000000000004751210397909868c652014d9824ba033a27e453de6075c418fd05c357daa88e7c4047f72103b112b1e3cbe64285750f7a297c4e32a4fd0c8c20c128fd4adbfaccd9b1c3b82952ae00000000", + "amount": 6141 + }, + { + "xprivs": [ + "xprvA7icF82QxB8Z17gjh7ZAujh5C6AMjrvycPJNyoJj3ynczXeuPMttF5PxHJXaQFkmzjJsx3d3SAwm6XMXyy9WAUcGB4kZqpRzZz5xyGN6yVt", + "xprvA7icF82QxB8Z2kQZmnrLde27PryauLg9FDz1nuKnJ98tDhgEvuvUmg4Yp375eFfq3aeCKy9wK3Zo5QZbtvybpxWRipjyaTsi832Tithb5Rk", + "xprvA7icF82QxB8Z5Ve4zHqKvW6SSRxcSpFRq2fkoczMBJ8NHPLYbXRab68jCVcZHnMNch5bG3R7afp2vmp5eU5xbTcfoxRNGtCUcnJVAqqK1pr", + "xprvA7icF82QxB8Z6hnNyC1D6iouWF2bD4zBsPd7DVUhnmEKajejhawXYZtZqntoBZeJqSqmsYW6Vyusy4YZzMiCcRNqccJZDkVYrEzQACpXxea" + ], + "txHash": "3c10a4a508aa1c8aef11dcf4c042df2c78cea886e94812501f3b4e0f7e28f881", + "hex": "020000000181f8287e0f4e3b1f501248e986a8ce782cdf42c0f4dc11ef8a1caa08a5a4103c00000000490047304402200e571182a812701b29d972a939a9be4d6d940759208bca37cc78aacdb5ca24260220460c07a7babb91a156f4ea6766bb4c815a9e0151d0ed5f86f5bcea3ee858a23141ffffffff01a51300000000000047512102304924636622fda4b7fe3ebfe1f1de274bba81df41768f53d7cc3a45c75ad44e21022db65557063bad6a76a23c5d1b82d8cf8b28bbb83df24a6abc21815d60fa048552ae00000000", + "amount": 5585 + } + ], + "testnet": [ + { + "xpriv": "tprv8jwG6YA1fGe7Ut879xQ9NMTwK9oWx4huSvQuix8bEorixxkhkSJd55B7mfQAQeALoEpWWQ5GW2qCmBjAnnyTCyMXoJYUGuQLQLPN367M98Y", + "txHash": "adcda2424f8768bdf3d5064e9a71a61d6d80b22bcc12f5eae0372822aac4c293", + "hex": "020000000193c2c4aa222837e0eaf512cc2bb2806d1da6719a4e06d5f3bd68874f42a2cdad000000006b483045022100dce87e98844fe01c7f0bffeb3ec6dbd92cada2751570653abb5db5bb1c40eeec02202eeac6d4f79f4774b40c121c6b99b8f431357a17dc8bae39003a16a8246a2bae4121037e04aa55787df424b4f1160aa64c65f64b2daa69e53d16c75b9a40708b01651dffffffff0140a0eb0b000000001976a9143cb6602d5ab7dc5c283f34c361fe9ce152f5c46888ac00000000", + "amount": 199994240, + "vout": 0, + "outputs": [ + "bchtest:qq7tvcpdt2machpg8u6vxc07nns49awydqag2n4uw7" + ] + } + ] + }, + "toMany": { + "mainnet": [ + { + "xprivs": [ + "xprvA7icF82QxB8Z5Ve4zHqKvW6SSRxcSpFRq2fkoczMBJ8NHPLYbXRab68jCVcZHnMNch5bG3R7afp2vmp5eU5xbTcfoxRNGtCUcnJVAqqK1pr", + "xprvA7icF82QxB8Z6hnNyC1D6iouWF2bD4zBsPd7DVUhnmEKajejhawXYZtZqntoBZeJqSqmsYW6Vyusy4YZzMiCcRNqccJZDkVYrEzQACpXxea", + "xprvA7icF82QxB8ZAzaHKF19HrwBcV4sbe4BaNdzbWMnKjifQ9A1bQhg4LFegaaR1pAGDYfKU7HPjix6W5UUAJk55puhC4gzUkH4au5XGNfCZax", + "xprvA7icF82QxB8ZDSWnLYH55gcoT6Mpy7AMCDTAYD2Z5PhdPTpzUnhk9evSsx868rjSWU1aKcNRPLDK7RhoqAMbQGPHz9HNngSitJERJ45UU93", + "xprvA7icF82QxB8ZFT5zjYeRn5MqFuJi1NSBoqxswndCCTEpNGtrVDgi3XdjKudZVDdarksmNT4HWAUNitSE2UZBVQJcg5bJsXM6DmGoDCrhJr9", + "xprvA7icF82QxB8ZHXGFm7g66kN4muMAefDfQ7DNWRWg1hpR7LSYXBr5XkWGhWocvv5pbDQBNjGsPzSGawdeaJ7YHsXyevbVFpagBwk1tjdMFVg" + ], + "txHash": "79decc7af8dff5f52a60805f8c8c2f93dd02c9570c495d904a5acac3438cccc4", + "hex": "0200000001c4cc8c43c3ca5a4a905d490c57c902dd932f8c8c5f80602af5f5dff87accde7900000000490047304402205c664b27664811115baacadab141b018de2a99942779a82439a0edc6a4e29fac0220204aa68174a491919215b986804776d99927118cb05f37bfa2391a18de0f97c741ffffffff02bc08000000000000475121030115a43c16094f6d7f8073ba143ccd9432ee8791e6f07eaa721861588e0824ae21027fd154f8d42d3bc8e2d38b4827af21559b64462764ed7814225e9c0c25e398f652aebc08000000000000475121026c3bc32ad1d20263f2bbe62cf3e10b1c2f7ecf1aced0c6b715a3c13b2d5214572102897a1fad02686122c53910196048ec5e7ac5875259134bc2f0e79749be3a086252ae00000000", + "amount": 5029 + }, + { + "xprivs": [ + "xprvA7icF82QxB8afyTitZSe1STeqkJZR7FhCDvtuWj8TQbKSJ1zTa33J8eDNNr6C64K11uqfoXtxvSbpZRK6zcRHwfduotzr2Xkrtv15gL2tuF", + "xprvA7icF82QxB8agTiBFt1v93qkgVEw9WKrsSd3JNFsXwTwHXSkeqTEHwt8abErLRMzNgSZpRGmarNWCPK2i9zxs646UA4ucAmGmzDvfKph6N5", + "xprvA7icF82QxB8amGM6RAFtS267PedatbG4RirAjRtCXpuahyC2EvHqBB5cWSx4F25obHHeBWJRhZikPbc7tpD2s5ERY5kGmptRy3uKuLyaYB2", + "xprvA7icF82QxB8aokYDbRNNVPMfLS1EauHLyNdAAPPm9Zv9RJePu12Q9UHv9Zkrsx4m6iz6egQj6cEaa15XKBiYBvMwe3GdofvtTRWhPzfYnrb", + "xprvA7icF82QxB8aqFgUdDrV4UNdN24SMgMgtn3iNeDKxNCfe9BuE7phr7twxaBe4WTMGHv9QiMaQ1zx86bMsLhZ586zfXN8zXk6dEVCRLSrdP8", + "xprvA7icF82QxB8asxrc5oRcUf2hsFxDn8e4CKyC4rZs3VyVXGmVaVXqeAXMcCrNS4LgjGAsUGZ2rH1rbd6fbdzMTUQmoZqPydR891aHG3e4ydu" + ], + "txHash": "fe358d444fd8c77e9dc57d1d8f3b8578a6cb796ae3463e66b7a910d5fd86d321", + "hex": "020000000121d386fdd510a9b7663e46e36a79cba678853b8f1d7dc59d7ec7d84f448d35fe000000004a00483045022100914f9ca1c592816dbe3e2c327f27ab538be21361b9fa60c4f52100e3f3fa576b02207f56adb3fb3b329a4b0577ef270d60c35bc2d2cade8350af8a5fe1d76621a95a41ffffffff02ce5100000000000047512102741d365bfe3b58d83ef7f8e2c86252985827675851ad6363f9130537703258f021030ef6c971891cf527b875365b2e5a80553df6f34fa8d9a654a141e035377d509052aece5100000000000047512102cb05940a62c705b919504a725c68897d60e01c7324325f040c8dcae5947ee7cb2103f83da8f3d924b136d3a6d16b30b9d8787a8f24b3f091057bba6c7acae13db02d52ae00000000", + "amount": 42440 + } + ], + "testnet": [ + { + "xpriv": "tprv8jwG6YA1fGe7jgUsatzgsqH941oUDZs9FejN6rVRZcMaL4nPoShBwD6LNFThDNNg1zpVe1k4zHeK82KJMU4iJMCeEbinn86QuFd5eXutaUL", + "txHash": "4edb662b14424d7bbbbe4b9fd1533d49690aefb2a15af8fa0704eab1ce41210b", + "hex": "02000000010b2141ceb1ea0407faf85aa1b2ef0a69493d53d19f4bbebb7b4d42142b66db4e000000006b483045022100bf8c2e6b8d3bcbfbaa64a5e9c2cbe5ce71471f87ff1d9f6a0bcec1c58c4a8a2102201504868d60e6f75ccda4c3fe899df0094d878fe8ca5ec55893da5f61517b49a04121029cc6fa90d901a5474249facbb32b187a1de63e853c43b272752109abdef19728ffffffff0201b3f505000000001976a914b3a223ad62ca6c8669a69a508216cd374612cb5688ac01b3f505000000001976a914b4e71aaf9bf4afd806d0560b17995c873ef61e9e88ac00000000", + "amount": 199979840, + "vout": 0, + "outputs": [ + "bchtest:qze6ygadvt9xepnf56d9pqske5m5vykt2c7vwv30af", + "bchtest:qz6wwx40n062lkqx6ptqk9uetjrnaas7ncmajyntv0" + ] + } + ] + }, + "manyToMany": { + "mainnet": [ + { + "xprivs": [ + "xprvA7icF82QxB8ZSikvkLNigfv5GsTvoSTSdBTJPEmYPPzF4iDh1QH49BhBFjo7MMcKnKX3SV5NX4nraBb6WEaQ3nhz6WnC6SoHyhNE7rqfUUy", + "xprvA7icF82QxB8ZT7mE7ajBr4nB8YzC1twv5G3YigJhxWUgxkVcKYg94cwz6qBLmR432toM5e6FjbtwNaYtHtS7VnX5fiuv7EeJZDgEC1zUmgo", + "xprvA7icF82QxB8ZVYj2s97gKjfXgGQW4JRLpPVetJEAyMQfkGjXCr7T7k6k43kLT8i5sBYddcyJCRWwgPW5cLWVs75Tmp7r48xV4UKTZLCyjsC", + "xprvA7icF82QxB8Za3ECXZak1o1ZjNXaRya8jEEy24RmNLmMenYAYWrcxUeZumSsD1GchmREkmQVBKwyLxhjwJipfRSGC5gjL4rMRrcLZed6iWT", + "xprvA7icF82QxB8Zd5EjUqP76EVzN5ghDFVqAWcAfw176mtqYRR9p6gT8mkzqtQRyizHCu55K5DkFmhvEnBD16111ZNo9nc1iVZ4TasN8HLbY7R", + "xprvA7icF82QxB8ZeSGJaHz1zrjKtgCtxCikjsEUrxC4qJRLEi2NeDcuUSQQRYPDjdXs3Gi81pZC2557LmhuRZmdBvDUebcbnrGDRapEGFkHLqW", + "xprvA7icF82QxB8ZhCBfx1ChAiHQyhpKLXFW18aApsPbnJXs3RpiGwujWQ6BabCYKv8G6CGKf3ueamQktSJafxqcasw5UmLAbTLiQsb2KGR5iqS", + "xprvA7icF82QxB8ZjkYazQf32kyRe7sxvp5nQjXFaza3cpn3G114GJFnUUsdMFBKsqXr8k8PirqttG6oCx2GyWWC91y2TxupieShaPrP8kxkvhL" + ], + "txHash": "465d8d6c5eb93673003c23f83a75b3299ac9f5ff542888a15d5f57dd9a40277a", + "hex": "02000000027a27409add575f5da1882854fff5c99a29b3753af8233c007336b95e6c8d5d46000000004a00483045022100b05a9489303710e4452fde06b1c633a65ea0761febc837befdee1d3dd3ee212d0220425ff8bc7524d8ee1746fd954f91b4c1c003004f301195d10e9a4a6b4a9948e541ffffffff7a27409add575f5da1882854fff5c99a29b3753af8233c007336b95e6c8d5d4601000000490047304402206126c73a56325d91418d6ca170857c064683ca1e33fdd5bc2a42a208e786ba8202205e0161a154e7d096ddd0826fa656d9dee919327c8e5057509ff52bfc4437db2641ffffffff027a0500000000000047512102884ab5b78c33c329216f32cfcdbf4e28ca12e80b18ec870656f591e21c2b2e112103caaa33a304947e48f2f655e3fc61f97ae805d061bcd754b9a2d29f851a39cb7752ae7a0500000000000047512102c9ad08d76e91f86c18bfaec7a95b181473aa5a60b77a74b3d754d7e8205b802821032b5f7309c3fbf5e8622af41d2d580baeaa82aaa0359264641ca1fe68d8ef721152ae00000000", + "amount": 3360 + }, + { + "xprivs": [ + "xprvA7icF82QxB8Zd5EjUqP76EVzN5ghDFVqAWcAfw176mtqYRR9p6gT8mkzqtQRyizHCu55K5DkFmhvEnBD16111ZNo9nc1iVZ4TasN8HLbY7R", + "xprvA7icF82QxB8ZeSGJaHz1zrjKtgCtxCikjsEUrxC4qJRLEi2NeDcuUSQQRYPDjdXs3Gi81pZC2557LmhuRZmdBvDUebcbnrGDRapEGFkHLqW", + "xprvA7icF82QxB8ZhCBfx1ChAiHQyhpKLXFW18aApsPbnJXs3RpiGwujWQ6BabCYKv8G6CGKf3ueamQktSJafxqcasw5UmLAbTLiQsb2KGR5iqS", + "xprvA7icF82QxB8ZjkYazQf32kyRe7sxvp5nQjXFaza3cpn3G114GJFnUUsdMFBKsqXr8k8PirqttG6oCx2GyWWC91y2TxupieShaPrP8kxkvhL", + "xprvA7icF82QxB8ZmLmyGp37AvuZXr3UstaTLfrmFFjU2ErqiMsC9Kdve6swjLFhUwYvLhpzpFwKsiZfhmVwpectgECUNyi37nSbwwDWKDHjTvj", + "xprvA7icF82QxB8Zpn5Sc8BXbEw8XnsEp7tTnL2TxStNi6X6FLUFUiT7bFDwHBasNa9CuJQr7GSZpMstNPoGDehkA1FbURJJ7gucugcDtmMTrFK", + "xprvA7icF82QxB8Zrq5wQjiUBjFPoJQ1Kb6iHCkYj91HbzwgeXMyDFJnphVsVHmYhf9hkfruwvGEAosXGBSuaEkGQnGcwBpqmG7YavZxh9TmEPd", + "xprvA7icF82QxB8ZudKk3LeAN395qr6ZW8V2fbeXapaxWb4wXu5sM85YC2WFpx9pRHwo8xJJTP3Kga3rHUvzVMcFHJ1rnGiyr8h7B7dxuVFpPXx" + ], + "txHash": "771ff329749dcf5ded610473448c214ffd258a20310815b8a6b6cb4eb263007d", + "hex": "02000000027d0063b24ecbb6a6b8150831208a25fd4f218c44730461ed5dcf9d7429f31f7700000000490047304402205d6b5c9bdcb8abf8fa39addb6c72d6119a938b1a413d0120b37d284f7497964602200997f6354b0244e6037ccf14fcc5e9a4d7851f4ef048579a1ec4b6f1fe349bc641ffffffff7d0063b24ecbb6a6b8150831208a25fd4f218c44730461ed5dcf9d7429f31f7701000000490047304402203f16418056acc7da5ef56c4d400483cd11809efd0be929a9269aa0129c8ac64d02200326b7762302ec28ce35a3bd43e9c8ad8e0b3732de5903372cabc4e5f63d596241ffffffff02640400000000000047512102a3008eb0646c09ab639195424b50c78921884a81830ea22b375f540a8bd0dbb72102594aac157629a75bb0708a1b4b4925acf8e2d428885e19e466cf248b6472dcff52ae64040000000000004751210230d01cbbe3697e3d1c451075f25bc44651cba89528337dd81be313879e44a78121029c06bc585ec0053a54c61e896efad1b78cb161998a6f9a1beba42ab6effb704d52ae00000000", + "amount": 2804 + }, + { + "xprivs": [ + "xprvA7icF82QxB8ZmLmyGp37AvuZXr3UstaTLfrmFFjU2ErqiMsC9Kdve6swjLFhUwYvLhpzpFwKsiZfhmVwpectgECUNyi37nSbwwDWKDHjTvj", + "xprvA7icF82QxB8Zpn5Sc8BXbEw8XnsEp7tTnL2TxStNi6X6FLUFUiT7bFDwHBasNa9CuJQr7GSZpMstNPoGDehkA1FbURJJ7gucugcDtmMTrFK", + "xprvA7icF82QxB8Zrq5wQjiUBjFPoJQ1Kb6iHCkYj91HbzwgeXMyDFJnphVsVHmYhf9hkfruwvGEAosXGBSuaEkGQnGcwBpqmG7YavZxh9TmEPd", + "xprvA7icF82QxB8ZudKk3LeAN395qr6ZW8V2fbeXapaxWb4wXu5sM85YC2WFpx9pRHwo8xJJTP3Kga3rHUvzVMcFHJ1rnGiyr8h7B7dxuVFpPXx", + "xprvA7icF82QxB8ZwjkrvDtZRCS4vmpHAKP7cyuHLxLSuxQZZGquJywom4u9PL1xzHpTxdApy9GcCgeC5VGVoWF3CrTXMjsyP2L8m8Uv8tDv3Zb", + "xprvA7icF82QxB8a1Tca3RzwNHZEhP2hL1NaQjvx3DQoR3pjcxGncv5vQTDCm158LqBcChNbqNeYQv92qtcDDjVCGNnMXoGxfPyyhgTGdbTxp4X", + "xprvA7icF82QxB8a2nzGik1BRWErM5NV7sFyTJPy9FnoJ567vXUaw9aFwW2yoYTi7iVtavNyWi8pZ4QxQ2WZHB3xYaTeD7U9jyvmZBkDn2vcvBY", + "xprvA7icF82QxB8a79yLazYJQM3RcFoANDSrWGvHm1MaWUwieDc71oU2cPgpKdYi61Ws7hB8WUzkSeVHgUJZubN7x2yXfrawDZcTq4QFMiXTy7P" + ], + "txHash": "072d3807b2d8d4457bcb002f7a89bf6dc28060bce9c56b967dadda0ecc4d345e", + "hex": "02000000025e344dcc0edaad7d966bc5e9bc6080c26dbf897a2f00cb7b45d4d8b207382d070000000049004730440220569f1cf2117b59a07c51cef449ba72d94da88ce7cd56739723d320fb9339a3db022043192a89e8da3208679605416d3a954b989fa6e9b6bdc136669057c38b28b7c041ffffffff5e344dcc0edaad7d966bc5e9bc6080c26dbf897a2f00cb7b45d4d8b207382d0701000000490047304402204b190b056738e6c7013ee5762c05b457dc6d122a4bd7dfacb2bf217ecac45433022020c5309f1d964fba4c1126e814abf6b112746d5cd72d85284eb3361ed5097bbf41ffffffff024e030000000000004751210394ca39f76f6dd3c719af0db9a7ffae8161b56e77e18d309e7007bc0a25513ab321027aa6e28597035e83a63112d9e24b1fc93b97d977d9500d8cf1869af22ecc366e52ae4e0300000000000047512102f5b01c6f2f669511677b52fcf6496a4835af592bf42202cb3fa658f7a436dc6f210333c0256189f893c614841e35258c7a8a3655cc90fe0462d285e595348fa8d76552ae00000000", + "amount": 2248 + }, + { + "xprivs": [ + "xprvA7icF82QxB8a9EusuXsq6Ls4xmpQdfxrAEnGX7CWNyXKEP33geYTbjxamr4FRoibZLkM5UmgUkLdPjyytR4zHXt9D1ec77ABatvWo9g53Pm", + "xprvA7icF82QxB8aBiUyo3GwQ5YkKutJ99oxpZUWTcPEECJtxp96mgH7fToCRCEqdyTt5GtHp31MoVzHBwxHWSQ5XeLWtTfP3PmX4SFMxFLEPpF", + "xprvA7icF82QxB8aECVR1KjwrzQ4uw7hcnNeCZh74CRUwCky9jioBqoD6QWDTeG6GAatVZghKoUKVhz1JjvAGQaUiGdw7Qpu6EVw75QJ2kxXdgs", + "xprvA7icF82QxB8aGGtkokgs5ik22YDEjDRFcAszqyrfwCBp1WaSGF8KvyDtjMDEHuVu4uN5bi1tqdCQzGsR8ZAdXZPNxmFXYSno4PeW4Z6stMf", + "xprvA7icF82QxB8aKkFq4h9cpmLJBqH1GGP2MLZ8pJounMv3vzk2GvWFDqne8vs6AnTRZVwK5EeAD7K6ujTAzwVzNPQ8Ez2XDazNVoX2HDpZ7BY", + "xprvA7icF82QxB8aNHcfqUQUvpYMaRTKSm2Ly5qi4qMcsqTfcRHR1mgs941jgk1NufCdzz5GekNbMu5ny5CBbmydD7SRtFvQZ6UU46yDUAurVEU", + "xprvA7icF82QxB8aPNXLbLsVuYr9W4DR9zDE6RJc6rWqUQmW6ymW7ZSgtyqBBKzh13TJY1eg9nSX8qho9kGh7M11wZhrwZTuxdB4xm9nFpUJyeA", + "xprvA7icF82QxB8aRo1sxU2h4CRhzB9ehC8R1u3BhcePdr8miKZmpHRSN76AfCPNMx7gVuTFmdQjxQCnd9TC96S9KWPrztsQLQ7X5KyXSJhG6EY" + ], + "txHash": "97ed1e1c73d7578987b9f85be8568028d68028eab4b7fe570821bcd529db91f1", + "hex": "0200000002f191db29d5bc210857feb7b4ea2880d6288056e85bf8b9878957d7731c1eed97000000004a00483045022100ae0442907471df30176d834387a5898abf6743bbe341295ce2cc0f7d8c572daf0220752125f1c6298384ec346463ad226556e65fef8cafaa0291fa7fa93bd1eafcd841fffffffff191db29d5bc210857feb7b4ea2880d6288056e85bf8b9878957d7731c1eed970100000049004730440220049940ca13fd92e9560f13229d987db47d34e9ba08fc5911536331f951767d8302207322da684129f48a29110c90ba0c852cd7df0180a8022b5608b1afb39d538d7941ffffffff0210550000000000004751210215aec25e5447c77a8346d99f96da5f6f9590f5fe1d113f5312fd9fa1e2fd93702103fa11d7e027d59bd4894fbbbfa8d3da86ad132fd9f496ffaa78cbd0c0e5597a7452ae105500000000000047512102ea9e02bc7052f6ffad02788fb1dd3355de79478445d1829bb105a7ed91890d4e210373097499d6ebfc5fe6187679e7f85252717b86137a0965347e389d98827d832252ae00000000", + "amount": 44108 + }, + { + "xprivs": [ + "xprvA7icF82QxB8aKkFq4h9cpmLJBqH1GGP2MLZ8pJounMv3vzk2GvWFDqne8vs6AnTRZVwK5EeAD7K6ujTAzwVzNPQ8Ez2XDazNVoX2HDpZ7BY", + "xprvA7icF82QxB8aNHcfqUQUvpYMaRTKSm2Ly5qi4qMcsqTfcRHR1mgs941jgk1NufCdzz5GekNbMu5ny5CBbmydD7SRtFvQZ6UU46yDUAurVEU", + "xprvA7icF82QxB8aPNXLbLsVuYr9W4DR9zDE6RJc6rWqUQmW6ymW7ZSgtyqBBKzh13TJY1eg9nSX8qho9kGh7M11wZhrwZTuxdB4xm9nFpUJyeA", + "xprvA7icF82QxB8aRo1sxU2h4CRhzB9ehC8R1u3BhcePdr8miKZmpHRSN76AfCPNMx7gVuTFmdQjxQCnd9TC96S9KWPrztsQLQ7X5KyXSJhG6EY", + "xprvA7icF82QxB8aU6ZMaoR5MkaGAnq9PBLow93o4nEBEzUm8Kt5kKUmGdQ3wW54MDQs9Vd8R8cxEAfqpwnmyQ8fXyqA8cp66ZPbjqFnQdNfD3A", + "xprvA7icF82QxB8aYANEgoCt9nuLYp2UM2TdxC9ozSTgEuGiJtruwe9fDXpGC2iRKnq7VmT1mLE6jKfKVBkDXTjbL45rLuecH78PpFRsDwidH3T", + "xprvA7icF82QxB8aZHgQaTE4idmmgkVMDBvmQFK4FMiRSLVbo1RuATNAsfHGGrh6zHBckKF34onhw9PUHn6uphcapSL8tDWPqP5nxMQJjitM2un", + "xprvA7icF82QxB8acaHzRxbstodMQMDaFfEvU2aY9uGiSaKYeTbgdHYQpHwJucQP11yo2e9k1UgS1YLzW9Vdx5UaqmZdF5oW53ApVSy5RFxHEQx" + ], + "txHash": "b24d8ee0a2a9910230f884c483aeee3daa1f9cc3130b26477f7705d3c22cfbe3", + "hex": "0200000002e3fb2cc2d305777f47260b13c39c1faa3deeae83c484f8300291a9a2e08e4db2000000004a00483045022100c91481b92cab1c71768667b17cf78763087ab77ccaf00adce6c04b3a686754280220146259289a49231259336d93fe00b60822c6b3bdbefb3ccc4eb7ed7a270b403541ffffffffe3fb2cc2d305777f47260b13c39c1faa3deeae83c484f8300291a9a2e08e4db2010000004a00483045022100f543ff0ea644a57e53f8298584bca7237d59fbe22ec053ea3cde3712a7d17a0f022068f57ccb0550fbc974fe53ae3bd6d9e4ea273537e642cb5453f36ccdd0d1c3e741ffffffff02fa53000000000000475121026282c31e790d31a9749f802a25521c6fddd3a817c2a01bebd2a686f212a490412103015d0deaca4e1ac92eb7e9da839d8c2f001c9b984c36b86d7529405dc406d49952aefa530000000000004751210225de384fe688ffdf18426c790369976bcb717ef80627740117067a513dfd072e21023e2202f82e19bcc6830e1bf658a3656680bc8b6c212e866137a8ffffc9e1a26f52ae00000000", + "amount": 43552 + } + ], + "testnet": [ + { + "xprivs": [ + "tprv8jwG6YA1fGe7kqL9HPxnBAJtzwzRmUq5qYAgA37BWw2PCFn3Tr56qikGoMpXxdPJ8vD7JokXN4rmLuygZMQ5nRTFUSodZtsD735UTDn99ff", + "tprv8jwG6YA1fGe7phE5EFsL5bSMK2EG4UvxHZb69tuajqGqmUas2R4JCA3G9gHeHGt8w71MVDEH7G1pYnqE2GhECtRFDYWpEovnnnnqdRhvS5e" + ], + "txHash": "a0367edacec483e77e2401ed73e035d4fe65b8c456b66175280701cd486af271", + "hex": "020000000271f26a48cd0107287561b656c4b865fed435e073ed01247ee783c4ceda7e36a0000000006a47304402207ff1867ad6e9b7dc7a1d3968113e20965c0ff77ad739e12b17e5dce7fe76e57502202e656dc0f57c3e7884228fe6c0f6161de74842fe2dc4b40296d0e49e118c778a412103206d484ae9751634d0a059acfbee14de2967f9da04159ac8fdd6fa8f1cb486f7ffffffff71f26a48cd0107287561b656c4b865fed435e073ed01247ee783c4ceda7e36a0010000006b483045022100b9115cf9024e5d61a17e6002fb5f9a71c9ecc1f50604c266638bda197579511d0220035b31d1a51a72136c1813e3a90a1e785f94650dc78bd0f0e9f8bbd4422e82d541210318a9bba01a9b343b3469af1ecd27815bdb6797c0eb21b1734a0d0f47290f44faffffffff020ca8f505000000001976a91439890e01e03442581056f0e3f606083cb552f66488ac0ca8f505000000001976a91443802909a4a51575217b553bb5b2670631fdc3cb88ac00000000", + "amounts": [ + 99988225, + 99988225 + ], + "outputs": [ + "bchtest:qqucjrspuq6yykqs2mcw8asxpq7t25hkvslhf9dam4", + "bchtest:qppcq2gf5jj32afp0d2nhddjvurrrlwrevm37d6avt" + ] + } + ] + }, + "fromMany": { + "mainnet": [ + { + "xprivs": [ + "xprvA7icF82QxB8aU6ZMaoR5MkaGAnq9PBLow93o4nEBEzUm8Kt5kKUmGdQ3wW54MDQs9Vd8R8cxEAfqpwnmyQ8fXyqA8cp66ZPbjqFnQdNfD3A", + "xprvA7icF82QxB8aYANEgoCt9nuLYp2UM2TdxC9ozSTgEuGiJtruwe9fDXpGC2iRKnq7VmT1mLE6jKfKVBkDXTjbL45rLuecH78PpFRsDwidH3T", + "xprvA7icF82QxB8aZHgQaTE4idmmgkVMDBvmQFK4FMiRSLVbo1RuATNAsfHGGrh6zHBckKF34onhw9PUHn6uphcapSL8tDWPqP5nxMQJjitM2un", + "xprvA7icF82QxB8acaHzRxbstodMQMDaFfEvU2aY9uGiSaKYeTbgdHYQpHwJucQP11yo2e9k1UgS1YLzW9Vdx5UaqmZdF5oW53ApVSy5RFxHEQx", + "xprvA7icF82QxB8afyTitZSe1STeqkJZR7FhCDvtuWj8TQbKSJ1zTa33J8eDNNr6C64K11uqfoXtxvSbpZRK6zcRHwfduotzr2Xkrtv15gL2tuF", + "xprvA7icF82QxB8agTiBFt1v93qkgVEw9WKrsSd3JNFsXwTwHXSkeqTEHwt8abErLRMzNgSZpRGmarNWCPK2i9zxs646UA4ucAmGmzDvfKph6N5" + ], + "txHash": "d7e6963e4de6dc2462d8ca646a1a59cc081cd971a46dcdd89dc1c5311febe93a", + "hex": "02000000023ae9eb1f31c5c19dd8cd6da471d91c08cc591a6a64cad86224dce64d3e96e6d7000000004a0048304502210092f065e61a2b53058924a4f7c519330293853946cad1da7a39f829bc7c5dd98b02202c2cae05b369858f85ea1fe4f79b13c68cde7034a282b57f203b361a372ac16441ffffffff3ae9eb1f31c5c19dd8cd6da471d91c08cc591a6a64cad86224dce64d3e96e6d701000000490047304402205d2c75bc692c94eee9eacc5b357774ebe493b788ad6495669e6cd2f2092864e3022020c92a82245f05e46f32038ca4ce0a27791525f41d5e1b2ecc9b23da1ea9c3a841ffffffff01c8a500000000000047512103a955ad3dae2078c2693ea07768add0ddc7c4e9720a09228b50801b3d5a973cd821034f1aa7c5bf81cb52aa795a24f1d6bedd81601710dd7691ddeeeb293a29929c0152ae00000000", + "amount": 42996 + } + ], + "testnet": [ + { + "xprivs": [ + "tprv8jwG6YA1fGe7r2bbsoGrUt7gSo8auZgv6aSaS59FVjZjRiJkK1SYqPGY3vr9gMEXvfKNzRNjW6VjMRpt3GVwXXF6gT8SgNfdSMarW2mU5JC", + "tprv8jwG6YA1fGe7u7wh93Si5YXPWAm6mZD4MMqEmdPiYzgWUCC3BDJ6Sg8XR14Rw4QmyBFu5fSF7ksjDU3Xk94KAjSY6P3f372X5uk9T3iSugg" + ], + "txHash": "812391dbaf4dc6b39dcbbb85a613a183aea48fb994212449bdbd4dd1b74b3518", + "hex": "020000000218354bb7d14dbdbd49242194b98fa4ae83a113a685bbcb9db3c64dafdb912381000000006a473044022058c446eec373bb5cae046e12a57cbf5f0b85f7c5a022b88ca17e77f72c2f8d7b022049cfdcb56bf6291db71c5fcbe82812f1e1a98c5e083c405b855b9532eb055f85412103dbd4cae70953a0c34550d59120bc8aa6ed6c01adf833c1d9d3118247f6175084ffffffff18354bb7d14dbdbd49242194b98fa4ae83a113a685bbcb9db3c64dafdb912381010000006a473044022045df2a8ccca97dedeb22bf74fc890bc6a2d2998147621b78a208938bf43a2fc4022077b4b5b21a04d27629535e7a44d3e96bf6d10bf84a20d68c1fccdaca41eb5fc8412103b744479db3b9b26ae110236568fdaff6637bb0e7a874154bf3060468fc5de09dffffffff012c3ceb0b000000001976a91456f61499e2617482f2a63e8aceae5e8cc4c16b5a88ac00000000", + "amounts": [ + 99985420, + 99985420 + ], + "outputs": [ + "bchtest:qpt0v9yeufshfqhj5clg4n4wt6xvfstttgw0zrer9n" + ] + } + ] + } } }, "nulldata": {