How is SegWit a soft fork?

17

4

Reading this section of BIP144, I noticed the followng statement:

Parsers supporting this BIP will be able to distinguish between the old serialization format (without the witness) and this one. The marker byte is set to zero so that this structure will never parse as a valid transaction in a parser that does not support this BIP. If parsing were to succeed, such a transaction would contain no inputs and a single output.

And this is in fact confirmed by this line in Bitcoin Core which is executed for every transaction found in a block during the CheckBlock call.

As far as I understand, this should mean that old clients that see a block containing a SegWit transaction would consider that transaction invalid and hence discard the whole block. Is that correct? What am I missing?

Simone Bronzini

Posted 2017-03-15T17:13:30.440

Reputation: 434

Actually, the line of code you're citing checks whether a transaction has 0 inputs, which is not allowed ever. To see the code that decides whether a witness is present, look at primitives/transaction.h.Pieter Wuille 2017-03-16T16:04:07.747

2@PieterWuille Yes, I was citing that line to reinforce the fact that old clients seeing the marker as '0x00' would interpret it as as the varint that specifies the number of inputs and hence refuse the transaction because it has zero inputsSimone Bronzini 2017-03-16T17:53:29.193

Yes, I know. But again, you're confusing the abstract object with the serialization. In a transaction, 0 inputs is invalid. But the conversion from bytes to transaction object is elsewhere. A segwit transaction does not have 0 inputs, it just uses an encoding that looks like 0 inputs to old clients. Look in primitives/transaction.h for the deserialization code.Pieter Wuille 2017-03-16T18:35:04.850

2That makes no sense, if it looks like 0 inputs to the old client and 0 inputs is never valid, then indeed it will look invalid to the old client, won't it? In any case, that seems to be a minor point. If the transaction now doesn't contain the signatures, how could it possibly look valid to someone not seeing the signatures?relG 2017-05-03T10:46:19.247

@relG SegWit scripts look like ANYONECANSPEND scripts to old clients (i.e. everyone can spend a script which consists only of OP_0 <32-byte push> without needing a signature) so old clients that will see an ANYONECANSPEND output being spent with no signature will consider it a perfectly valid transactionsSimone Bronzini 2017-05-03T10:57:41.250

So can't, indeed, anyone spend it, at least from the point of view of the old nodes? And then there will be a fork of the network, cause someone except the legit user will spend it, and the new nodes reading the segwit witness will not accept this send, but the old ones will?relG 2017-05-03T11:03:58.233

A softfork is defined as a consensus change that converges as long as majority of the hashrate adopts it. Yes, a non-witness transaction spending a segwit output without signature would be valid to old nodes, but 1) they won't see that (such a transaction is nonstandard to everyone) 2) such a transaction won't be mined (same as 2) and thus 3) the majority chain will not accept such transactions.Pieter Wuille 2017-05-16T17:40:56.500

Answers

13

You're confusing transactions (the abstract object) and their serialization (the bytes on the wire in the P2P protocol or on disk).

Sure, SegWit introduces an extension to the P2P protocol (BIP144), which relays witnesses along with transactions, and old clients wouldn't understand such messages.

But old clients don't see them. Witnesses are only included when the requester asks for them, which old clients don't do. For them, new clients remove the witnesses before relay. Exactly because the witness of a transaction does not contribute to its txid, it is in fact possible to remove them before relay, without invalidating them. That is what makes it a soft fork.

Pieter Wuille

Posted 2017-03-15T17:13:30.440

Reputation: 54 032

Ok, I see, so if I understand correctly, when an old client receives a block it will receive the block stripped of all witness-related data. Is that correct?Simone Bronzini 2017-03-15T17:44:14.183

2Indeed, it looks like (and is) a totally old style block to them.Pieter Wuille 2017-03-15T18:42:38.900

3how can? the old style block contains signature (witness) but the new and stripped one does not.Nghia Bui 2017-07-05T17:26:45.160

2The new one contains empty signatures, which are valid according to the old rules, for spending SegWit outputs. SegWit just introduces an extra field to transaction (the witness), which does not contribute to the txid. The old scriptSig field is still there, but just unused for SegWit spends.Pieter Wuille 2017-07-05T17:31:52.523

7If a block contains empty signatures, how can the transactions be verified?Nghia Bui 2017-07-06T00:35:33.877

7To an old client, all spends from SegWit outputs look like anyone-can-spend outputs, which are valid to spend without signature. Old spends still have signatures, which validate. New clients will also validate SegWit spends, by using the signatures from the witness.Pieter Wuille 2017-07-06T00:41:31.990

@PieterWuille, And how is this different from SegWit2?Pacerier 2017-10-26T02:11:46.483

SegWit2X is an incompatible change to Bitcoin's rules sought by a number of companies, which will likely become a separate currency. It has nothing to do with Segwit.Pieter Wuille 2017-10-26T07:20:19.333

Why is the empty signature there in the first place? Isn't it wasting space?Jus12 2017-11-13T20:23:45.857

Yes, 1 byte of waste per input, which can be trivially removed by using a compressed transaction format. There are dozens of ways more inefficiencies exist - 4 bytes for timestamps, sequence numbers in all inputs, locktimes in all outputs, DER encoded signatures... each of those accounts for far more waste in terms of naively-counted block space. But for backward compatibility reasons it's not really worth the effort to fix them.Pieter Wuille 2017-11-13T20:44:36.600