diff --git a/bip-codeshark-jl2012-segwit.mediawiki b/bip-codeshark-jl2012-segwit.mediawiki new file mode 100644 index 00000000..1fc711d8 --- /dev/null +++ b/bip-codeshark-jl2012-segwit.mediawiki @@ -0,0 +1,277 @@ +
+ BIP: x + Title: Segregated Witness (Consensus layer) + Author: + Status: Draft + Type: Standards Track + Created: 2015-12 ++ +==Abstract== + +This BIP defines a new structure called a "witness" that is committed to blocks separately from the transaction merkle tree. This structure contains data required to check transaction validity but not required to determine transaction effects. In particular, scripts and signatures are moved into this new structure. + +The witness is committed in a tree that is nested into the block's existing merkle root via the coinbase transaction for the purpose of making this BIP soft fork compatible. A future hard fork can place this tree in its own branch. + +==Motivation== + +The entirety of the transaction's effects are determined by output consumption (spends) and new output creation. Other transaction data, and signatures in particular, are only required to validate the blockchain state, not to determine it. + +By removing this data from the transaction structure committed to the transaction merkle tree, several problems are fixed: + +# '''Nonintentional malleability becomes impossible'''. Since signature data is no longer part of the transaction hash, changes to how the transaction was authorized is no longer relevant to transaction identification. As a solution of transaction malleability, this is superior to the canonical signature approach (BIP62): +#* It prevents involuntary transaction malleability for any type of scripts, as long as all inputs are signed (with at least one CHECKSIG or MULTICHECKSIG operation) +#* In the case of a n-of-m MULTICHECKSIG script, a transaction is malleable only with agreement of n private key holders (as opposed to only 1 private key holder with BIP62) +#* It prevents involuntary transaction malleability due to unknown ECDSA signature malleability +#* It allows creation of unconfirmed transaction dependency chains without counterparty risk +# '''Transmission of signature data becomes optional'''. It is needed only if a peer is trying to validate a transaction, instead of just to prove its existence. This also improves prviacy of SPV clients as using the same bandwidth they could request for more transactions for obscuration. +# '''Some constriants could be bypassed with a soft fork''' by moving part of the transaction data to a structure unknown to current protocol, for example: +#* Size of witness could be ignored / discounted when calculating the block size, effectively increasing the block size to some extent +#* Hard coded constants, such as maximum data push size (520 bytes) or sigops limit could be reevaluated or removed +#* New script system could be introduced without any limitation from the existing script semantic + +==Specification== + +Maybe a seperate BIP +
+* CTransaction gets, in addition to vin and vout, a vwit, which +contains a CTxInWitness object for each input. A CTxInWitness contains a CScriptWitness object +and can potentially be extended to contain other kinds of witness data. +A CScriptWitness is a vector of byte vectors (nominally: the input stack to the program, no longer +encoded as a CScript, but just the resulting stack directly). + +* A new serialization for CTransaction is defined: http://blockhawk.net/diagrams/witnesstx.png +(int32 nVersion, +0x00 marker, 0x01 flag, vector+ +=== Commitment structure === + +UPDATE NEEDED +A new block rule is added which requires a commitment (a merkle root +computed similarly to the normal transaction one) to the witness +hashes to be present as the last 32 bytes of +block.vtx[0].vin[0].scriptSig (it doesn't need to be a push). This +hopefully does not conflict with any other existing commitment +schemes. To make it extensible, an extra merkle path can be provided +(in the coinbase's "witness" field) so that coinbase commitment can be +used for multiple things. +, vector , +vector , int32 nLockTime) instead of (int32 nVersion, +vector , vector , int32 nLockTime). This will never parse +as a valid transaction (even if parsing succeeds, it means it's +interpreted as a transaction with no inputs and 1 output). If all +witnesses are empty, the old serialization format is used. +- Rationale for not having an independent CWitnessTransaction with +its own serialization: this would require separate "tx" and "block" +messages, and all RPC calls operating on raw transactions would need +to be duplicated, or need inefficinent or nondeterministic guesswork +to know which type is to be used. +- Rationale for not using just a single 0x00 byte as marker: that +would lead to empty transactions (no inputs, no outputs, which are +used in some tests) to be interpreted as new serialized data. +- Rationale for the 0x01 flag byte in between: this will allow us to +easily add more extra non-committed data to transactions (like txouts +being spent, ...). It can be interpreted as a bitvector. + +* A new message 'havewitness' is sent after receiving 'verack' to +indicate that a node can provide witness if requested (similar to +'sendheaders') + +* New inv types MSG_WITNESS_TX and MSG_WITNESS_BLOCK are added, only +for use in getdata. Inv itself still use just MSG_TX and MSG_BLOCK, +similar to MSG_FILTERED_BLOCK. +- Rationale for not advertizing witnessness in invs: we don't always +use invs anymore (with 'sendheaders' BIP 130), plus it's not useful: +implicitly, every transaction and block have a witness, old ones just +have empty ones. + +* Transactions' GetHash is always computed on the old non-witness +serialization. A new CTransaction::GetWitnessHash is added which is +computed from the witness-serialization (this means that transactions +with an empty witness have witness hash equal to normal hash). +
+ // Validation for witness commitments. + // * We compute the witness hash (which is the hash including witnesses) of all the block's transactions, except the + // coinbase (where 0x0000....0000 is used instead). + // * We build a merkle tree with all those witness hashes as leaves (similar to the hashMerkleRoot in the block header). + // * The first coinbase scriptSig minimal push of 41 bytes for which the first 4 bytes are {0xaa, 0x21, 0xa9, 0xed} is + // treated as a commitment header. If no such push is present, the block is invalid. If multiple are present, the first + // is used. + // * The first 4 bytes of the commitment header are just magic identifier bytes, and have no further meaning. + // * The next 4 bytes describe a nonce. + // * The next 1 byte describes the number of levels in a Merkle tree. + // * locator = SHA256('WitnessV1\x00\x00\x00\x00\x00\x00\x00' || nonce). The first levels bits of locator, interpreted + // in little endian, are assumed to be the position in the leaves of this Merkle tree where the witness commitment + // goes. + // * The last 32 bytes of the commitment header are its root hash. + // * The coinbase's input's witness must consist of a single byte array of 32 * levels bytes, and are assumed to be + // the Merkle path to connect the witness root hash to the commitment root hash. + + // No witness data is allowed in blocks that don't commit to witness data, as this would otherwise leave room from spam. ++ +=== Block size limit === +2-4-8? Discount for witness data? + +=== Witness program === + +* A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a single push of 2 to 41 bytes gets a new special meaning. The byte vector pushed by it is called the "witness program". +** In case the scriptPubKey pushes a witness program directly, the scriptSig must be exactly empty. +** In case the redeemScript pushes a witness program, the scriptSig must be exactly the single push of the redeemScript. + +* The first byte of a witness program is the "version byte", an unsigned integer. +** If the version byte is 0, the rest of the witness program is the actual script. +*** The script is executed after normal script evaluation but with data from the witness rather than the scriptSig. +*** The program must not fail, and result in exactly a single TRUE on the stack. +** If the version byte is 1, the rest of the witness program must be 32 bytes, as a SHA256 hash of the actual script. +*** The witness must consist of an input stack to feed to the program, followed by the serialized program. +*** The serialized program is popped off the initial witness stack. Hash of the serialized program must match the hash pushed in the witness program. +*** The serialized program is deserialized, and executed after normal script evaluation with the remaining witness stack. +*** The script must not fail, and result in exactly a single TRUE on the stack. +** If the witness version byte is 2 or above, no further interpretation of the witness program or witness happens. + +=== Other consensus critical constraints === + +== Block size analysis == +Definitions: +
+ Core block size (CBS): The block size as seen by a non-upgrading full node + Witness size (WS): The total size of witness in a block + Total block size (TBS): CBS + WS + Witness discount (WD): A discount factor for witness for calculationg of VBS (1 = no discount) + Virtual block size (VBS): CBS + (WS * WD) + Witness adoption (WA): Proportion of new format transactions among all transactions + Prunable ratio (PR): Proportion of signature data size in a transaction ++ +With some transformation it could be shown that: +
+ TBS = CBS / (1 - WA * PR) + = VBS / (1 - WA * PR * (1 - WD)) ++ +In order to keep the proposal as a soft fork, the CBS must not have a upper limit higher than 1MB. + +TBS is a function of only CBS, PR, and WA. + +The PR heavily depends on the transaction script type and input-output ratio. For example, the PR of 1-in 2-out P2PKH and 1-in 1-out 2-of-2 multisig P2SH are about 47% and 72% respectively. According to the data presented by Pieter Wuille on 7 December 2015, the current average PR on the blockchain is about 60%. + + + +== Examples == + +=== Version 0 witness program === + +The following example is a version 0 witness program, equivalent to the existing Pay-to-Pubkey-Hash (P2PKH) output. + + witness: