Skip to content

Latest commit

 

History

History
72 lines (61 loc) · 2.71 KB

savings.org

File metadata and controls

72 lines (61 loc) · 2.71 KB

Cross-input-aggregation savings

Savings in an average taproot transaction

# Transaction with segwit v1 spends and outputs.
# Outputs size in bytes and weight units.
def tx_size(n_inputs, n_outputs):
    assert(n_inputs <= 252 and n_outputs <= 252)
    return list(map(lambda mult: (
        mult*(
            4     # version
            + 1   # number of inputs
            + n_inputs * (
                32 + 4 # prevout
                + 1    # script len
                + 4)   # sequence
            + 1   # number of outputs
            + n_outputs * (
                8       # amount
                + 1     # script len
                + 34)   # script
             + 4)  # locktime
         + 2 # witness flag & marker
         + n_inputs * (
             1       # witness stack items
             + 1     # witness item len
             + 64)), # BIP-340 sig
      [1, 4]))


# 365 day moving average according to
# - https://transactionfee.info/charts/inputs-per-transaction/ and
# - https://transactionfee.info/charts/outputs-per-transaction/
# retrieved 2025-02-28.
n_inputs = 2.26
n_outputs = 2.69


size = tx_size(n_inputs, n_outputs)
half_agged = map(lambda s: s - n_inputs*32, size)
full_agged = map(lambda s: s - (n_inputs-1)*64, size)
both_agged = map(lambda s: s - (n_inputs-1)*64 - 32, size)
max_agged = map(lambda s: s - n_inputs*64, size)

def savings(name, agged_sizes):
    return [name] + ["%.1f%%" % ((1 - a/b)*100) for (a,b) in zip(agged_sizes, size)]

[
    [ "", "bytes", "weight units" ],
    None,
    savings("half aggregation", half_agged),
    savings("full aggregation", full_agged),
    savings("both", both_agged),
    savings("max (like infinite large full agged coinjoin)", max_agged)
]
bytesweight units
half aggregation19.6%7.1%
full aggregation21.8%7.9%
both30.5%11.0%
max (like infinite large full agged coinjoin)39.1%14.1%

Graftroot

Spending a taproot-like output via graftroot requires a 64-byte signature of the script that the signers delegate control to. In comparison, opening a taproot commitment only requires revealing the 32-byte “internal” pubkey (if the committed script is at depth zero). With half- or full-aggregation of signatures outside script, the graftroot signature can be aggregated just like key-spend signatures. As a result, graftroot spends would be equal to or more efficient that taproot script spends.