Compacted transaction. The serialization commonly used for Bitcoin transactions encodes many things somewhat inefficiently and has many pieces of flexibility which are infrequently used. These inefficiencies are only a few bytes here and there but since transactions are small they add up to a fairly large percentage. We can use a more efficient representation for storage on disk and communication over the network without any change to the consensus logic. This efficient representation can be negotiated on a per-peer basis (or is just local, in the case of disk storage), so it can easily evolve over time to adapt to new use patterns-- it isn't necessary to anticipate all future uses and be overly general at the cost of complexity or efficiency for currently common uses. Goals: byte aligned (no range-coder), fast to decode. Minimal state. Small for existing chain but moderately forward looking, e.g. support SW even though they aren't yet common. Several of the fields have a flag to "Use (N-th) prior value." which helps make some txn smaller. But what if the first usage sets this flag? We can define the initial value of the memory here in a useful way, without creating state that propagates from transaction to transaction. These initial values could be set according to chain params, or perhaps even signaled over the p2p protocol. State-- [txout value state] - 15th most common tx out value in the chain [seq last_3] = 0 [seq last_2] = MAX-1 [seq last_1] = MAX Data: [byte] bits 0..6 version, bit 7 is nlocktime presence. if version = 127, code a 32 bit version field after. Input coding [32 bytes input txid] [done/seq/vin byte] bit 7 is "is this the last input?", bit 6,5 = sequence number [0 = last_3] [1 = last_2] [2 = last_1] [3 = not the above] [32 bits sequence] any time a value is used it becomes last_1 and the rest are moved up. bit 4,3,2,1,0 = vin index 0..30, if 31 then code additional bytes (with highbit set for continuation) to represent index-31. [signature template byte] bit7 is "is this sighash all?", if not, signatures below are all 1 byte longer. the rest is per a signature template table: [0 = I dunno wtf this is, code a varint and the raw bytes, sighashall flag must be false] [1 = p2pk with canonical der sig] then 64 bytes. [2 = p2pkh with canonical der sig, and 02 pubkey] then 32+64=96 bytes [3 = p2pkh with canonical der sig, and 03 pubkey] then 32+64=96 bytes [4 = p2pkh with canonical der sig, and 04 pubkey and y&1] then 32+64=96 bytes [5 = p2pkh with canonical der sig, and 04 pubkey and !y&1] then 32+64=96 bytes [6 = P2SH-P2WPKH 02] 32+64=96 bytes [7 = P2SH-P2WPKH 03] 32+64=96 bytes [8 = P2WPKH 02] 32+64=96 bytes [9 = P2WPKH 03] 32+64=96 bytes [10 .. 105 = 1/2, 2/2, 1/3, 2/3, 3/3 multisig with 02/03 flags in p2sh/p2sh-sw/sw forms] [32 byte pubkeys] [sigs] [106 = n/m multisig] [bytes with 4 bits for n, 4 bits for m] [33 bytes pubkeys] [sigs] [107 = P2WSH-P2SH] [varint] [witness script] [signatures] (saves the p2sh redeem script) [...] (HTLC? multiple 'N-th last'?) [126 = last pubkey type] then 64 (+1 if not sighashall) bytes * n_signatures Output coding [output type] bit 7 is "is this the last output?", Bits 6,5,4 = [0 = I dunno wtf this is, code a varint and the raw bytes] [1 = p2pkh] [20 bytes] [2 = p2sh] [20 bytes] [3 = p2pk 04 byte && y&1] [32 bytes] (no p2pk 02/03 because savings vs type 0 is small) [4 = p2pk 04 byte && !y&1] [32 bytes] (.. and I think they're uncommon) [5 = SWv0] [32 bytes] [6 = SWv1] [32 bytes] [7 = SWv2] [32 bytes] Bits 3,2,1,0 [0 = value not in list] [value coded like utxo set] [1 = ...] -- [2 = ...] -- Top 14 most common txout values in the blockchain weighed by encoded length. ... [15 = last value in this txn which was coded coded w/ value code 0] a 2in2out p2pkh transaction would take say, 305 bytes, compared to say 380 bytes currently. -- roughly a 20% reduction. maybe saving 20GB disk space. For txn spending older coins with uncompressed p2pkh inputs, the savings is over 30%.