bitcoinjs/bitcoinjs-lib

No inputs were signed

Closed this issue · 6 comments

A2DNEW commented

Hi
My wallet have 50 btc
I use below code for send transaction:

const total = 50;
const send = 30;
const fee = 1;

psbt.addInput({
      hash: 'yyy1',
      index: 0,
      nonWitnessUtxo: Buffer.from(
        'xxx1',
        'hex',
      ),
    });

    psbt.addOutput({
      address: 'recevier',
      value: send,
    });

    psbt.addOutput({
      address: 'sender',
      value: total - send - fee,
    });
    
    psbt.signAllInputs(alice);
    psbt.setMaximumFeeRate(fee);
    psbt.finalizeAllInputs();

For first time, send transaction works fine
But for second transaction for send 20 btc to another address (with new hash and nonWitnessUtxo after first transaction) i get error:

No inputs were signed

index: 0, should probably be index: 1, for the second transaction.

index: 0, is saying "This is the index of the output in the previous transaction that this input is spending."

It is NOT saying "This is the index of this input"

A2DNEW commented

index: 0, should probably be index: 1, for the second transaction.

index: 0, is saying "This is the index of the output in the previous transaction that this input is spending."

It is NOT saying "This is the index of this input"

Thank you
But how can I find correct index?
Because for first transaction I use 0, and for second and third transaction I use 1

The first psbt.addOutput is index 0

The second psbt.addOutput is index 1

    psbt.addOutput({ // When referring to this output in a new transaction's input, this is index 0
      address: 'recevier',
      value: send,
    });

    psbt.addOutput({ // When referring to this output in a new transaction's input, this is index 1
      address: 'sender',
      value: total - send - fee,
    });
A2DNEW commented

The first psbt.addOutput is index 0

The second psbt.addOutput is index 1

    psbt.addOutput({ // When referring to this output in a new transaction's input, this is index 0
      address: 'recevier',
      value: send,
    });

    psbt.addOutput({ // When referring to this output in a new transaction's input, this is index 1
      address: 'sender',
      value: total - send - fee,
    });

Thank you
I blockcypher for get hex data
But this website is not free
How can I generate hex?

After psbt.finalizeAllInputs(); you can do psbt.extractTransaction().toHex() to get the hex.

You can get UTXOs from here: https://mempool.space/docs/api/rest#get-address-utxo

And you can get raw transactions from the txid here: https://mempool.space/docs/api/rest#get-transaction-raw

You can run your own mempool instance easily as well, see their Github if you'd like to run your own Bitcoin node with a full REST API with mempool.

I am not sure about the rate limits of mempool's public instance.

To generate the hex data for a Bitcoin transaction without using Blockcypher, you can use bitcoinjs-lib to create, sign, and serialize the transaction. Here's a detailed example of how you can achieve this:

Step-by-Step Guide to Generate Hex Data for a Bitcoin Transaction

  1. Install bitcoinjs-lib:
    Make sure you have bitcoinjs-lib installed in your project. If not, you can install it using npm:

    npm install bitcoinjs-lib
  2. Create and Sign a Bitcoin Transaction:
    Use the following example to create, sign, and generate the hex data for a Bitcoin transaction.

Example Code

const bitcoin = require('bitcoinjs-lib');
const network = bitcoin.networks.testnet; // Use bitcoin.networks.bitcoin for mainnet

// Replace these with your own values
const senderAddress = 'YOUR_SENDER_ADDRESS';
const senderWIF = 'YOUR_SENDER_PRIVATE_KEY_WIF';
const receiverAddress = 'RECEIVER_ADDRESS';
const sendAmount = 100000; // Amount in satoshis to send
const feeAmount = 500; // Fee in satoshis
const utxo = {
  txid: 'YOUR_UTXO_TXID',
  vout: 0, // Index of the output in the previous transaction
  value: 150000, // Value of the UTXO in satoshis
  scriptPubKey: 'YOUR_UTXO_SCRIPT_PUB_KEY', // ScriptPubKey of the UTXO
};

// Create a key pair from the sender's WIF
const keyPair = bitcoin.ECPair.fromWIF(senderWIF, network);

// Create a new PSBT
const psbt = new bitcoin.Psbt({ network });

// Add the input (the UTXO we are spending)
psbt.addInput({
  hash: utxo.txid,
  index: utxo.vout,
  witnessUtxo: {
    script: Buffer.from(utxo.scriptPubKey, 'hex'),
    value: utxo.value,
  },
  // Non-SegWit UTXOs need a scriptSig
  // redeemScript: ... (only needed for P2SH)
});

// Add the outputs
psbt.addOutput({
  address: receiverAddress,
  value: sendAmount,
});

psbt.addOutput({
  address: senderAddress,
  value: utxo.value - sendAmount - feeAmount,
});

// Sign the transaction
psbt.signInput(0, keyPair);

// Finalize the transaction
psbt.finalizeAllInputs();

// Get the raw transaction hex
const rawTxHex = psbt.extractTransaction().toHex();

console.log('Raw Transaction Hex:', rawTxHex);

Explanation

  1. Create a Key Pair:
    The key pair is created from the sender's private key in WIF (Wallet Import Format).

  2. Create a New PSBT:
    A new PSBT (Partially Signed Bitcoin Transaction) object is created. The network is set to testnet in this example. For mainnet, use bitcoin.networks.bitcoin.

  3. Add Input:
    The UTXO to be spent is added as an input to the PSBT. The witnessUtxo field is used for SegWit transactions. If the UTXO is non-SegWit, you might need to add a scriptSig instead.

  4. Add Outputs:
    Two outputs are added. The first one sends the specified amount to the receiver, and the second one returns the change to the sender's address.

  5. Sign the Transaction:
    The transaction input is signed using the key pair.

  6. Finalize the Transaction:
    The inputs are finalized, and the raw transaction hex is extracted.

Running the Example

Replace the placeholder values (e.g., YOUR_SENDER_ADDRESS, YOUR_SENDER_PRIVATE_KEY_WIF, etc.) with your actual data. Run the script, and it will output the raw transaction hex.

This approach allows you to generate and sign Bitcoin transactions without relying on third-party services like Blockcypher.