Skip to content

Instantly share code, notes, and snippets.

@cgcardona
Last active June 9, 2018 20:03
Show Gist options
  • Save cgcardona/b8b8eb84d9aa632da72f19c887bae9b3 to your computer and use it in GitHub Desktop.
Save cgcardona/b8b8eb84d9aa632da72f19c887bae9b3 to your computer and use it in GitHub Desktop.
4-to-5 Inputs 1. P2PK 2. P2PKH 3. 1-of-2 P2MS 4. P2SH Outputs 1. P2PK 2. P2PKH 3. 1-of-2 P2MS 4. P2SH 5. "BCHForEveryone" w/ OP_RETURN
let BITBOXCli = require('bitbox-cli/lib/bitbox-cli').default;
let BITBOX = new BITBOXCli();
let hdnode = BITBOX.HDNode.fromXPriv('xpriv');
let transactionBuilder = new BITBOX.TransactionBuilder();
let originalAmount = 21732;
let txid = 'b7cb6dee60b70952c9a5285fd978957ff857140844ad81cff2cca7ddb87e0028';
let byteCount = BITBOX.BitcoinCash.getByteCount({ P2PKH: 5 }, { P2PKH: 5 });
let sendAmount = originalAmount - byteCount;
// P2PK input
let node1 = BITBOX.HDNode.derivePath(hdnode, "0/0");
let pubKey1 = BITBOX.HDNode.toPublicKey(node1);
let buf1 = BITBOX.Script.pubKey.output.encode(pubKey1);
transactionBuilder.addInput(txid, 0, transactionBuilder.DEFAULT_SEQUENCE, buf1);
// P2PKH input
let node2 = BITBOX.HDNode.derivePath(hdnode, "0/1");
transactionBuilder.addInput(txid, 1);
// P2MS input
let node3 = BITBOX.HDNode.derivePath(hdnode, "0/2");
let node4 = BITBOX.HDNode.derivePath(hdnode, "0/3");
let pubKey3 = BITBOX.HDNode.toPublicKey(node3);
let pubKey4 = BITBOX.HDNode.toPublicKey(node4);
let buf3 = BITBOX.Script.multisig.output.encode(1, [pubKey3, pubKey4]);
transactionBuilder.addInput(txid, 2, transactionBuilder.DEFAULT_SEQUENCE, buf3);
// P2SH input
let node5 = BITBOX.HDNode.derivePath(hdnode, "0/5");
let identifier5 = BITBOX.HDNode.toIdentifier(node5);
let buf5 = BITBOX.Script.encode([
BITBOX.Script.opcodes.OP_DUP,
BITBOX.Script.opcodes.OP_HASH160,
identifier5,
BITBOX.Script.opcodes.OP_EQUALVERIFY,
BITBOX.Script.opcodes.OP_CHECKSIG
])
let scriptHash5 = BITBOX.Crypto.hash160(buf5);
let data5 = BITBOX.Script.scriptHash.output.encode(scriptHash5);
transactionBuilder.addInput(txid, 3, transactionBuilder.DEFAULT_SEQUENCE, data5);
// P2PK output
let node6 = BITBOX.HDNode.derivePath(hdnode, "0/6");
let pubKey6 = BITBOX.HDNode.toPublicKey(node6);
let buf6 = BITBOX.Script.pubKey.output.encode(pubKey6);
transactionBuilder.addOutput(buf6, Math.floor(sendAmount / 4));
// P2PKH output
let node7 = BITBOX.HDNode.derivePath(hdnode, "0/7");
transactionBuilder.addOutput(BITBOX.HDNode.toCashAddress(node7), Math.floor(sendAmount / 4));
// P2MS output
let node8 = BITBOX.HDNode.derivePath(hdnode, "0/8");
let node9 = BITBOX.HDNode.derivePath(hdnode, "0/9");
let pubKey8 = BITBOX.HDNode.toPublicKey(node8);
let pubKey9 = BITBOX.HDNode.toPublicKey(node9);
let buf8 = BITBOX.Script.multisig.output.encode(1, [pubKey8, pubKey9]);
transactionBuilder.addOutput(buf8, Math.floor(sendAmount / 4));
// P2SH output
let node10 = BITBOX.HDNode.derivePath(hdnode, "0/10");
let identifier10 = BITBOX.HDNode.toIdentifier(node10);
let buf10 = BITBOX.Script.encode([
BITBOX.Script.opcodes.OP_DUP,
BITBOX.Script.opcodes.OP_HASH160,
identifier10,
BITBOX.Script.opcodes.OP_EQUALVERIFY,
BITBOX.Script.opcodes.OP_CHECKSIG
])
let scriptHash10 = BITBOX.Crypto.hash160(buf10);
let data10 = BITBOX.Script.scriptHash.output.encode(scriptHash10);
transactionBuilder.addOutput(data10, Math.floor(sendAmount / 4));
// nulldata output
let nullData = "BCHForEveryone";
let nullBuffer = BITBOX.Script.nullData.output.encode(Buffer.from(nullData, 'ascii'));
transactionBuilder.addOutput(nullBuffer, 0);
let redeemScript;
// sign P2PK
let keyPair1 = BITBOX.HDNode.toKeyPair(node1);
transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount / 4);
// sign P2PKH
let keyPair2 = BITBOX.HDNode.toKeyPair(node2);
transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount / 4);
// sign P2PKH
let keyPair3 = BITBOX.HDNode.toKeyPair(node3);
transactionBuilder.sign(2, keyPair3, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount / 4);
// sign P2SH
let keyPair5 = BITBOX.HDNode.toKeyPair(node5);
transactionBuilder.sign(3, keyPair5, buf5, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount / 4);
let tx = transactionBuilder.build();
let hex = tx.toHex();
BITBOX.RawTransactions.sendRawTransaction(hex).then((result) => { console.log(result); }, (err) => { console.log(err); });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment