Segwit txin. Witness data association

0

I am trying to learn more about the bitcoin protocol and I am writing some python software to make a light wallet. I have advanced quite far and I have come across something that I dont really understand while reading about segregated witness protocol changes in terms of transactions.

https://bitcoincore.org/en/segwit_wallet_dev/

If you go here and read the part with a heading "Transaction Serialization" the text reads like so:

If a txin is not associated with any witness data, its corresponding witness field is an exact 0x00, indicating that the number of witness stack items is zero.

How do I know if an input I am using in my script is associated with witness data? I have tried using public API's to look at the outputs I am using and I cant understand what it means. I see witness fields associated with the inputs of the transaction that produced the outputs I am trying to include in my transaction but not the other way around..

cryptodescriptor

Posted 2018-11-05T18:10:17.373

Reputation: 35

Are you trying to create a transaction, or trying to parse an existing one?Pieter Wuille 2018-11-05T18:11:39.790

Trying to create a transaction. I would use the addresses to determine it but I know that it is impossible to tell a P2SH from a P2SH-P2WPKHcryptodescriptor 2018-11-05T18:15:42.947

You need to know what you're signing. Obviously you can't create a signature without the private key; equally you need to know whether it's a multisig or P2SH or P2WPKH or whatever script you're signing. The address is never enough.Pieter Wuille 2018-11-05T18:24:01.680

Understood. So if I have a bech32 or a p2sh-p2wpkh the input I possess will always be classed as being associated with witness data? But with a legacy address it will be never associated?cryptodescriptor 2018-11-05T18:27:43.453

1Spending a segwit output always requires a witness. Spending a non-segwit output never requires a witness. But I don't see how this information is helpful; you still need to know exactly how to construct the scriptSig and witness anyway, which depends on the type of script you're spending. It just so happens that all segwit scripts need a non-empty witness while others don't.Pieter Wuille 2018-11-05T18:30:56.210

I'm just trying to get my head around dynamically changing the serialization format based on if I want to spend an output from a segwit or none segwit address.cryptodescriptor 2018-11-05T18:39:08.837

The serialization doesn't depend on the output; only the data being serialized does. The zero byte just indicates "empty witness", in every situation (either spending a segwit or non-segwit output). An non-empty witness can not occur in a valid transaction that spends a non-segwit output, but your serializer shouldn't care about that.Pieter Wuille 2018-11-05T19:09:37.713

I'm starting to understand. Thankyoucryptodescriptor 2018-11-05T19:59:34.650

One more thing. I should probably open another question but I think it would be a repeat of https://bitcoin.stackexchange.com/questions/61290/what-is-ment-by-the-value-of-the-output-spent-by-this-input-in-bip-143. If I have multiple inputs what would the amount be for the hash preImage? I'm thinking the amount of the last input but I am not sure. It isn't very clear.

cryptodescriptor 2018-11-05T20:26:24.413

The amount being spent by the input you're signing for.Pieter Wuille 2018-11-05T20:27:57.067

But in the examples in https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki he has multiple inputs but he is only signing once. This is so confusing.

cryptodescriptor 2018-11-05T20:33:08.973

In the signature(s) for input 1, you sign the amount that input 1 is spending. In the signature(s) for input 2, you sign the amount that input 2 is spending, etc.Pieter Wuille 2018-11-05T20:41:48.743

Did not realize you have to sign each input separately. That is frustrating.cryptodescriptor 2018-11-05T20:56:48.777

It's really the only way. Each input can spend unrelated outputs (each from a different address, with different keys - all those keys need to sign off to authorize the transaction). It's also why there is a scriptSig/witness per input, and not one globally for the whole transaction. There is ongoing research on how to integrate multisignature schemes into Bitcoin, which would permit a single signature that proves all keys signed off, but that won't be available anytime soon.Pieter Wuille 2018-11-06T01:27:43.190

Answers

0

How do I know if an input I am using in my script is associated with witness data? I have tried using public API's to look at the outputs I am using and I cant understand what it means. I see witness fields associated with the inputs of the transaction that produced the outputs I am trying to include in my transaction but not the other way around.

I believe your confusion is due to this line

If a txin is not associated with any witness data, its corresponding witness field is an exact 0x00, indicating that the number of witness stack items is zero.

not applying to the serialization format, but to the contents.

A witness is always serialized as:

  • A variable-length integer indicating the number of witness stack items n.
  • For each of the n stack items:
    • A variable-length integer indicating the size of the stack element b
    • A b-byte array with the contents of that stack element.

A corollary is that an empty witness is always serialized as just a 0x00 byte (indicating that there are zero stack items).

So your serialization and parsing code does not need to know whether a particular txin has associated witness data. It just serializes/parses the witness, which may be empty.

It so happens that the validity rules require that the witness for a non-segwit spend always has to be empty, and as a result, the serialization of such a witness will always be just 0x00.

Pieter Wuille

Posted 2018-11-05T18:10:17.373

Reputation: 54 032