MetacoSA / NBitcoin

Comprehensive Bitcoin library for the .NET framework.
MIT License
1.85k stars 839 forks source link

Non-segwit inputs are not serialized in PSBTs #1171

Open Jossec101 opened 1 year ago

Jossec101 commented 1 year ago

It looks like that after getting the base64 string of a PSBT the non-witness UTXO fields are not serialised hence empty/null after deserialising back to the PSBT object.

Looks like orphanTxOut is not used much https://github.com/MetacoSA/NBitcoin/blob/fb13874fa43b881b55db9325b1e92a3d77e0bdbb/NBitcoin/BIP174/PSBTInput.cs#L20

If I retrieve a PSBTInput object, named input an do input.GetCoin().TxOutis filled if the PSBT was generated programatically from code (.i.e. PSBT Builder), this is because the orphanTxOut is filled.

image

However, after deserialising back from a base64 PSBT, orphanTxOut is no longer present and therefore I cannot get the Coin of a non-segwit input. This is happening in the picture below.

image

Hope I explained well enough 👯

Jossec101 commented 1 year ago

I managed to make it work by adding the NonWitnessUtxo by hand using Nbxplorer


foreach (var item1Input in result.Item1.Inputs)
          {
              item1Input.NonWitnessUtxo =                (await  _nbXplorerService.GetTransactionAsync(item1Input.PrevOut.Hash, default)).Transaction;

          }
NicolasDorier commented 1 year ago

@Jossec101 if you are using NBXplorer, this endpoint https://github.com/dgarage/NBXplorer/blob/master/docs/API.md#create-partially-signed-bitcoin-transaction has alwaysIncludeNonWitnessUTXO.

Else, you are correct, the TransactionBuilder's PSBT doesn't include the NonWitnessUtxo, because it has no knowledge about it. (The Coin abstraction can't have any transaction attached to it)

Jossec101 commented 1 year ago

I guess an improvement to the builder should programatically allow to add the NonWitnessUtxo for serialisation, it serialised to base64 well after adding it manually.

NicolasDorier commented 1 year ago

The problem is that it doesn't have this information. There is no way to feed the previous transactions to the builder.