This article is the eighth part B– this time dedicated to SegWit – of a series of in-depth explanations on the more technical part of Bitcoin, accessible even to those who aren’t experts in coding.
The following continues a sort of guide designed to gradually enter what many call the “rabbit hole”.
As far as the bibliography is concerned, it is necessary to mention the book “Mastering Bitcoin” by Andreas M. Antonopoulos, from which the images have been taken.
Segregated Witness (SegWit)
This is an upgrade of the protocol and consensus rules, proposed and implemented as a soft-fork (BIP-9) activated on the main-net on August 1st, 2017. In cryptography the term Witness is used to describe a solution to a cryptographic puzzle: in Bitcoin, the Witness meets the conditions set on a UTXO.
A digital signature is a type of Witness but the term Witness is more widely used for what meets the conditions set on a UTXO, ergo generally for an unlocking script or scriptSig. Before SegWit, each transaction input was followed by the Witness who unlocked it: the Witness data was embedded in the transaction as part of each input. The term Segregated Witness simply means separating the signatures or unlock scripts of a specific output, moving them from the scriptSig field to a separate Witness data structure that accompanies the transaction. Clients can request transaction data with or without accompanying Witness data.
SegWit is a structural change that modifies several aspects of Bitcoin’s scalability, security, economic incentives and performance.
- Transaction malleability. The hash of the transaction no longer includes the Witness (only part of the transaction that could be modified by a third party), ergo the possibility of malleability attacks is removed (only the creator of the transaction can modify the data), greatly improving the implementation of other protocols that are based on the structure of advanced bitcoin transactions (payment channel, chained transaction, LN …).
- Script versioning. With SegWit scripts, each block script is preceded by a number of version scripts, which allows a backwards-compatible upgrade of the script language (e.g. using forks) to introduce new operands, syntax or semantics. The ability to improve the script language in a non-disruptive way will greatly accelerate Bitcoin’s rate of innovation.
- Network and social scaling. Witness data is a decisive contribution to the size of a transaction, in some cases (multisig or payment channels) more than 75%. Nodes can “prune” Witness data after validating signatures, or ignore them altogether in simplified payment verification (SPV): it is not necessary for Witness data to be transmitted to all nodes (and “distorted”).
- Signature Verification Optimization. It improves the signature functions (CHECKSIG, CHECKMULTISIG, etc) reducing the complexity of the algorithm. Before SegWit, the algorithm used to produce a signature required a number of hashing operations proportional to the size of the transaction: the hashes increased by O(n2) with respect to the number of signature operations, with a considerable burden of computation by all the nodes that verified the signatures (with SegWit the algorithm has changed reducing the complexity toO(n)).
- Offline Signing Improvement. SegWit signatures incorporate the value (amount) of each input into the signed hash. Before, an offline device (hardware wallet) would have to verify the amount of each input before signing the transaction (this was done by streaming a large amount of data on previous transactions referred to as input). Since the amount is part of the signed hash, an offline device does not need the previous transactions. If the amount does not match the signature will be invalid.
Segregated Witness is a change in how UTXOs are spent and therefore a per-output feature. A transaction can spend a SegWit output, traditional or both (it makes no sense to talk about SegWit transactions, but SegWit output), when a transaction spends a UTXO and thus must provide the Witness. In a traditional UTXO, the block script requires the Witness data to be provided inline, in the part of the transaction input that the UTXO spends. A UTXO SegWit instead specifies a block script that can be satisfied with Witness data outside the input (“segregated”).
It is a significant change in the way outputs and transactions are built. Such a change normally requires a simultaneous change in each Bitcoin node, wallet etc, to change the rules of consensus (hard fork). SegWit has been introduced in a much lighter, backwards-compatible (soft-fork) way: this kind of upgrade allows non-upgraded software to ignore changes and continue to operate without disruption. SegWit outputs are built so that even “old” systems (not SegWit-aware) can still validate them. These outputs can be spent with an empty signature, so the fact that there is no signature within the transaction (it is segregated) does not invalidate the transaction. The new wallets and miners, however, see the SegWit outputs and wait to find a valid witness for them within the transaction Witness data.
Example of a P2PKH output script:
DUP HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 EQUALVERIFY CHECKSIG
Segregated Witness would create a Pay-to-Witness-Public-Key-Hash (P2WPKH) output script:
Simpler than a traditional output script, it consists of two values that are pushed into the stack of the validation script. To an old (non-SegWit) Bitcoin client, the two pushed values look like an output that anyone can spend and that doesn’t require a signature (or rather, that can be spent with an empty signature). By the new clients (SegWit), the first number (0) is interpreted as the “version” (the Witness version) and the second part (20 bytes) as the equivalent of a block script known as the “Witness program” (the hash of the public key, as in P2PKH scripts).
To spend the SegWit output, the transaction does not have a signature on the input, but has an empty scriptSig and includes a Segregated Witness, outside the transaction itself.
It is important to note that P2WPKH should only be created by the receiver since the sender has no way of knowing if the receiver wallet has the ability to build SegWit transactions and spend P2WPKH output. In addition, these outputs must be built from the hash of a compressed public key, the non-compressed ones are not standard in SegWit and can be disabled by a future soft-fork.
The second type of Witness program corresponds to Pay-to-Script-Hash (P2SH) scripts. These scripts refer to the hashes of a redeem script that defines the multiple signatures (M-of-N) required to spend the funds. A SegWit-compatible wallet could create a Pay-to-Witness-Script-Hash (P2WSH) output script:
As in P2WPKH the script is simpler than the traditional one and consists of two pushed values on the stack: a Witness version (0) and a 32-byte hash SHA256 of the redeem script.
Both forms of Witness scripts, P2WPKH and P2WSH can be inserted into a P2SH address: P2SH(P2WPKH) and P2SH(P2WSH). Even after the activation of SegWit, it will take time until most wallets are upgraded (SegWit can be embedded in P2SH which makes it easily compatible with non-SegWit-aware wallets). Once SegWit is widely supported, it makes sense to encode Witness scripts into native SegWit addresses, rather than embed them in P2SH: this native SegWit address format is defined in BIP-173.