0

First some explanation

I have made 2 raw transactions via Electrum using my Nano S Ledger as seed and exported them to .txn files.

let rawTx1 = "02000000000101bf00f7aca2e0d393ad0a762224ad4cd5a10d9950804fbc5a22fe970918301179000000001716001400ce8131595e014b45ec6ca49495d547ab8bd872fdffffff02a08601000000000017a91457fd0d41e459a4227b8932327786cf512d99399987bc72ca...";
let rawTx2 = "02000000000101bf00f7aca2e0d393ad0a762224ad4cd5a10d9950804fbc5a22fe970918301179000000001716001400ce8131595e014b45ec6ca49495d547ab8bd872fdffffff02a08601000000000017a914a66dff1bf27dd1a5944b5bc9ff2b0f410efb64cd87bc72ca...";

Then I turned them into UTXO objects using the splitTransaction() function:

const UTXO1 = await btc.splitTransaction(rawTx1, true);
const UTXO2 = await btc.splitTransaction(rawTx2, true);

Next, I get the Wallet public keys I used for these transactions:

const wallet_1 = await btc.getWalletPublicKey("m/49'/1'/1'", false, true);
const wallet_2 = await btc.getWalletPublicKey("m/49'/1'/2'", false, true);

So transaction 1 was made with wallet 1 and transaction 2 with wallet 2. According to LedgerJS, I have to respect that order when calling the signP2SH() function:

btc.signP2SHTransaction([[UTXO1, 1, wallet_1.publicKey], [UTXO2, 1, wallet_2.publicKey]],
    ["m/49'/1'/1'", "m/49'/1'/2'"],
    btc.serializeTransactionOutputs(???).toString('hex')
);

Here,

[UTXO1, 1, wallet_1.publicKey]

are the Transaction object, output index, and redeem script in that order. And

["m/49'/1'/1'", "m/49'/1'/2'"]

are the derivation paths of both of my wallets.

My question is about the third line:

btc.serializeTransactionOutputs(???).toString('hex')

I know for a single transaction from a single wallet, I just toss in the UTXO1 in there:

btc.serializeTransactionOutputs(UTXO1).toString('hex')

But now that I have multiple UTXO's, I don't know what to fill in there anymore. Any ideas?

EDIT

Thanks to @Pierre Pollastri's answer I figured out the hashed script form.

So this code

const outputScript1 = btc.serializeTransactionOutputs(UTXO1).toString('hex')
const outputScript2 = btc.serializeTransactionOutputs(UTXO2).toString('hex')

produces the Output script for both UTXO's. Since we are processing two transactions we need to merge these output scripts. These scripts look as follows:

outputScript1 = 02404b4c000000000017a914c436f95c2ab5062dbc884a7c76ac805b58c00fe5879eaa7f000000000017a914429b7a8975c97dad6f90604faf732d9c7045279a87
outputScript2 = 02404b4c000000000017a914c436f95c2ab5062dbc884a7c76ac805b58c00fe587ee337e000000000017a914284c4c58d659cd485a283b48b4dc79da7571043587

They both start with 02, which indicates that each script handles 2 transactions. So what I did was simply change 02 into 04, remove the 02 from the 2nd script and then concatenate the 2nd script after the 1st script:

finalScript = 04404b4c000000000017a914c436f95c2ab5062dbc884a7c76ac805b58c00fe5879eaa7f000000000017a914429b7a8975c97dad6f90604faf732d9c7045279a87404b4c000000000017a914c436f95c2ab5062dbc884a7c76ac805b58c00fe587ee337e000000000017a914284c4c58d659cd485a283b48b4dc79da7571043587

Then call the function as stated above:

btc.signP2SHTransaction([[UTXO1, 1, wallet_1.publicKey], [UTXO2, 1, wallet_2.publicKey]],
    ["m/49'/1'/1'", "m/49'/1'/2'"],
    finalScript
);

It worked and I was able to sign the transaction :)

1

The third parameter is just your outputs script (actually it's the whole outputs part of a transaction) so depending on which address you want to send the funds it will change.

It's using the same format as in bitcoin transactions. The data are serialized like this

TYPE | Description VARINT | Number of outputs to create 8 byte | Amount to send to the first output VARINT | Size of the output script x bytes | The actual output script

In most case you can consider that VARINT is only 1 byte (special cases if you data is bigger than 255 bytes but if that's the case you probably have an issue somewhere :P)

Regarding the output script depending on which address you want to send you have different type of scripts to use.

btc.serializeTransactionOutputs(???).toString('hex') is just serializing the outputs part of the transaction from a split transaction. If you use it on an existing transaction you're basically sending to the same addresses (the same amounts to the same addresses).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.