Skip to content

Error in multisig transaction with ledger and local key #52

@kleash

Description

@kleash

Hi,

I am trying to do a multisig p2sh transaction, signing first by ledger and then by locally stored key.

This is my current code mostly based on Multi Sig guide and P2SH ledger example

Code:

'use strict';

const fs = require('fs');
const bcoin = require('bcoin');
const assert = require('assert');
const KeyRing = bcoin.wallet.WalletKey;
const Script = bcoin.Script;
const MTX = bcoin.MTX;
const TX = bcoin.TX;
const Amount = bcoin.Amount;
const Coin = bcoin.Coin;

const bledger = require('../lib/bledger');
const {LedgerBcoin, LedgerTXInput} = bledger;
const {Device} = bledger.USB;

const NETWORK = 'testnet';
const compressed = true;

// Read keys from local system
const secret1 = fs.readFileSync(`./${NETWORK}-key1.wif`).toString();
const ring1 = KeyRing.fromSecret(secret1);

(async () => {

    // LEDGER INIT CODE --START
    const device = await Device.requestDevice();
    device.set({timeout: 50000});
    await device.open();
    const path = 'm/44\'/0\'/0\'';
    const path1 = `${path}/1/1`;
    const bcoinApp = new LedgerBcoin({device});
    const hdpub1 = await bcoinApp.getPublicKey(path1);
    const pub1 = hdpub1.publicKey;
    // LEDGER INIT CODE --FINISH

    //Create Script
    const [pk1, pk2] = [hdpub1.publicKey, ring1.publicKey];
    const [m, n] = [2, 2];

    const redeem = Script.fromMultisig(m, n, [pk1, pk2]);
    // p2sh script
    const script = Script.fromScripthash(redeem.hash160());
    const changeAddr = script.getAddress().toBase58(NETWORK);

    // tx info
    const sendTo = '2N4MrGXsu2PtDFMXZrvG34YQxK4Y77bmk7g';
    const txInfo = {
        // How much we received with this transaction
        value: Amount.fromBTC('0.0002').toValue(),

        // prevout txid and vout
        hash: 'aa253ca490d7f1c914246ad459a89c997291da9ca3dc7ec749f6555d2a5aabdf',
        index: 0
    };

    const coin = Coin.fromJSON({
        version: 1,
        height: -1,
        value: txInfo.value,
        coinbase: false,

        script: script.toJSON(),
        hash: txInfo.hash,
        index: txInfo.index
    });

    // Now we create mutable transaction object for signing with ledger
    const spend1 = new MTX();
    spend1.script = redeem;

    // send
    spend1.addOutput({
        address: sendTo,
        value: Amount.fromBTC('0.0001').toValue()
    });


    // send change to ourselves
    spend1.addOutput({
        address: changeAddr,
        value: Amount.fromBTC('0.00005').toValue()
    });

    spend1.addCoin(coin);

    const ledgerInputs = [];

    // Hex of input transaction
    const tx = TX.fromRaw(Buffer.from("01000000000101cdede91d7a739ba4100a46d3287fc20fa683720a39ca2b6e8f474a24570ab86a000000001716001409785e5b583363e2cfcff123be008fef302bd151ffffffff023cf30e000000000017a91470329ef305289ecfe4f2bc6448a6bac4b16b99b887204e00000000000017a9149fd0d66463fafe0ce272189faa4d196ab816ccf787024830450221008a727b5cf7d1f66f1cb3a3311937827a10818d6f8fd6320ebd55df7c5a6d0755022066a4a2f236f01ec6827e7627e5381f1f5ffee56b404d81b44d14ab86b593141d012102e054e792bf5c8e49d2ad73c60a2882e4a34f42db79b0981f95062718dff95a0b00000000", 'hex'))

    const ledgerInput = new LedgerTXInput({
        tx: tx,
        index: 0,
        redeem: redeem,
        path: path,
        publicKey: pub1
    });

    ledgerInputs.push(ledgerInput);

    await bcoinApp.signTransaction(spend1, ledgerInputs);

    //Get raw txn signed by ledger
    const raw = spend1.toRaw();

    // use raw tx to be signed by local key
    const spend2 = MTX.fromRaw(raw);
    spend2.script = redeem;

    // Because input already exists in transaction
    // we only need to provide Coin to CoinView
    spend2.view.addCoin(coin);

    // now we sign
    spend2.signInput(0, coin, ring1);

    //Check if transaction is valid
    assert(spend2.verify(), 'Transaction isnt valid.');

    console.log(spend2.toRaw().toString('hex'));


    await device.close();
})().catch((e) => {
    console.error(e);
    process.exit(1);
});

Currently, It's throwing me following error:

Error: Could not template input.
    at LedgerBcoin.applySignature (/ledger/bcoin/bledger/lib/ledger/ledgerbcoin.js:370:13)
    at LedgerBcoin._signTransaction (/ledger/bcoin/bledger/lib/ledger/ledgerbcoin.js:340:19)

Any pointers on what I am doing wrong?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions