Skip to content

Conversation

@0xsatoshi99
Copy link

Summary

Fixes parsing of transactions and PSBTs with zero inputs.

Problem

When parsing a transaction with 0 inputs, the byte sequence 00 01 (vinLen=0, voutLen=1) was incorrectly interpreted as the segwit marker/flag bytes. This caused:

  • Transaction.fromBuffer() to fail on zero-input transactions
  • Psbt.fromBase64() to fail when deserializing PSBTs with no inputs

Solution

After detecting potential segwit marker/flag (00 01), validate the interpretation by checking:

  1. If vinLen would be 0 - a segwit tx with 0 inputs is semantically invalid (no witnesses needed)
  2. If the buffer is too small to contain the claimed number of inputs (minimum 41 bytes per input)

If either check fails, rewind and parse as a non-segwit transaction.

Testing

const { Psbt } = require("bitcoinjs-lib");
const psbt = new Psbt();
psbt.addOutput({ address: "1BM1sAcrfV6d4zPKytzziu4McLQDsFC2Qc", value: 100000n });
const base64 = psbt.toBase64();
Psbt.fromBase64(base64); // Now works!

// bitcoin-cli generated PSBT also works
Psbt.fromBase64("cHNidP8BACwCAAAAAAEAoHJOGAkAABl2qRRxekyQdFd6Ba+UJxwysknSmKItmIisAAAAAAAA");

All 2660 existing tests pass.

Fixes #2293


Contribution by Gittensor, learn more at https://gittensor.io/

When parsing a transaction with 0 inputs, the byte sequence 00 01
(vinLen=0, voutLen=1) was incorrectly interpreted as segwit marker/flag.

This fix validates the segwit interpretation by checking:
1. If vinLen would be 0 (segwit tx with 0 inputs is invalid)
2. If the buffer is too small to contain the claimed number of inputs

If either check fails, fall back to non-segwit parsing.

Fixes bitcoinjs#2293
@0xsatoshi99
Copy link
Author

0xsatoshi99 commented Dec 1, 2025

@junderw Can you plz check this PR and let me know your feedback? Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't serialize or deserialize PSBT with no inputs

1 participant