¿Cuánto difiere el peso de 2 de 3 entradas de firmas múltiples entre P2SH y P2SH-P2WSH?

Estoy tratando de calcular el peso de una entrada P2SH-P2WSH de 2 de 3 firmas múltiples. Encontré la pregunta relacionada Predecir el tamaño de transacción de múltiples firmas , que calculé m=2, n=3aquí:

pubkeySize=33
sigSize=72

SizeOfRedeemScript = 1+n*(1+pubkeySize)+1+1
// 2-of-3: SizeOfRedeemScript = 1+3*(1+33)+1+1 = 105

SizeOfScriptSig = 1+m*(1+sigSize)+SizeOfPushDataFor(RedeemScript)+SizeOfRedeemScript
// 2-of-3: SizeOfScriptSig = 1+2*(1+72)+2+105 = 1 + 146 + 2 + 105 = 254

sizeOf(input) = 32+4+SizeOfCsuintFor(SizeOfScriptSig) + SizeOfScriptSig + 4
// 2-of-3: sizeOf(input) = 32+4+3+254+4 = 297

El tamaño de la entrada 2 de 3 en P2SH tiene de 293 a 297 bytes 1 . Por lo tanto, esto correspondería a hasta 297*4 bytes = 1188 wu.

¿Cómo calcularía el peso correspondiente para una entrada P2SH-P2WSH de 2 de 3 firmas múltiples?


1 Tenga en cuenta que si ambas firmas tienen 71 bytes, el scriptSig tiene 252 bytes , que como longitud se puede codificar en 1 byte , pero en el peor de los casos, ambas firmas tienen 72 bytes y la longitud del scriptSig necesita 3 bytes.

Respuestas (2)

Para calcular el peso del bloque, debe conocer el tamaño en bytes de los datos no testigos y el tamaño en bytes de los datos testigos.

Con una entrada P2SH-P2WSH, su scriptSig siempre tendrá 36 bytes. Esto hace que el tamaño en bytes de las entradas sea 36 + 36 + 4 = 76. Los testigos contienen sus firmas y guiones, por lo que el testigo de esa entrada será 1+m*(1 + sigSize) + SizeOfVarIntFor(RedeemScript) + SizeOfRedeemScript. Para una entrada multisig 2 de 3, tendrá 1 + 2*(1 + 72) + 2 + 105 = 254el tamaño en bytes de su testigo.

La fórmula para calcular el peso del bloque es base size * 3 + total size. El tamaño base es el tamaño de todos los datos que no son testigos, por lo que su tamaño base es de 76 bytes. El tamaño total es el tamaño de todos los datos, incluidos los testigos, por lo que su tamaño total será 76 + 254 = 330. Reemplazando esto en la fórmula se obtiene 76 * 3 + 330 = 558. Por lo tanto, el peso de P2SH-P2WSH 2-of-3 multisig es 558.

* Tenga en cuenta que SizeOfVarIntFor(RedeemScript)en realidad son dos bytes porque necesita usar OP_PUSHDATA1 ya que la longitud del script de redención es mayor a 75 bytes.

Si SizeOfVarIntFor(RedeemScript)serían dos bytes porque el script redimido tiene más de 75 bytes, ¿no se aplicaría lo mismo SizeOfVarIntFor(SizeOfScriptSig)ya que SizeOfScriptSigtiene 251?
@Murch No. Hay dos formas de representar el tamaño de las cosas en las transacciones. Dentro de un script en sí, en realidad usamos códigos de operación pushdata. Necesitamos dos bytes para scripts de más de 75 bytes porque luego necesitamos usar el código de operación OP_PUSHDATA1 antes del byte de tamaño. Sin embargo, para tamaños de cosas fuera de scripts como SizeOfScriptSig, usamos enteros sin signo de tamaño compacto. El csuint solo necesita un byte adicional además del número en sí cuando el número en sí necesita más de 1 byte. Puedes ver cómo funciona csuint aquí: bitcoin.org/en/…

Las diferencias entre P2SH, P2SH-P2WSH y P2WSH son las siguientes:

  • P2SH: el scriptPubKey tiene un programa P2SH. El scriptSig proporciona los argumentos de script correspondientes y el script de redención para satisfacer el programa P2SH.
  • P2SH-P2WSH: el scriptPubKey tiene un programa P2SH. El scriptSig tiene el programa testigo y lo reenvía a la pila de testigos para su evaluación. La pila testigo proporciona los argumentos del script y el script testigo.
  • P2WSH: scriptPubKey tiene un programa testigo, scriptSig está vacío y la pila testigo proporciona los argumentos del script y el script testigo.
  • La pila testigo es idéntica para las entradas P2SH-P2WSH y P2WSH equivalentes.

Entonces, para calcular el tamaño de un multigrado P2SH-P2WSH, los argumentos del script y el script de canje se mueven a la pila de testigos como argumentos del script y script de testigo, y debe agregar el costo del script de reenvío.

El scriptSig en P2SH-P2WSH se compone de scriptLength witnessProgramLength witnessVersion hashLength hasho varInt PUSHBYTES OP_0 PUSHBYTES <hash>. La longitud de scriptSig se puede expresar en un varInt de 1 byte, por lo que scriptSig en total toma 1 + 1 + 1 + 1 + 32 = 36 B. Esto significa que los bytes que no son testigos de la entrada son el punto de salida (32 +4 B), scriptSig (36 B) y nSequence (4 B), que suman 76 B en total.

La pila testigo tiene el recuento de los elementos testigo (1 WU), los tres argumentos del script, un elemento ficticio vacío porque OP_CHECKMULTISIG muestra un elemento adicional de la pila y las dos firmas (1+2×(1+72) = 147 WU ), y el script testigo, witnessScriptLength OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG(1+1+3×(1+33)+1+1 = 106 WU).

En conjunto, el tamaño vs de una entrada 2 de 3 P2SH-P2WSH es, por lo tanto:

txid:vout:scriptSig:nSeq::witLength:scriptArgs:witScript
 32 +  4 +    36   +  4  +    1    +    147   +    106  = 76 + 254/4 = 139.5 vB 

Los detalles completos de los tres tipos se encuentran a continuación para su conveniencia.

P2SH

El tamaño de una entrada multigrado 2 de 3 basada en P2SH resulta ser 293, 296 o 297 bytes, como se describe en la pregunta.

PREVOUT:
  hash (32 bytes)
  index (4 bytes)
SCRIPTSIG:
  length (varInt 1 or 3 bytes)
  signatures¹ (1+2×(1+72²) bytes = 147 bytes)
    dummy-OP_0 
    m×(PUSHBYTES+sig)
  OP_PUSHDATA1 len(redeemscript) (2 bytes)
  redeemscript (1+3×(1+33)+1+1 = 105 bytes)
    OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
nSequence (4 bytes)

32 + 4 + 3 + 1 + 2×(1+72) + 2 + 1 + 3×(1+33) + 1 + 1 + 4 =
36 + 3 + 147 + 2 + 105 + 4 = 297 B

Dado que las firmas pueden tener 71 o 72 bytes, resulta que la entrada necesita un varInt de 1 byte para expresar la longitud de scriptSig para dos firmas de r baja. Si una o ambas firmas tienen una r alta, se necesita una varInt de 3 bytes para expresar la longitud de scriptSig.

P2SH-P2WSH

El peso de un P2SH-P2WSH 2 de 3 resulta ser 556–558 WU, lo que se traduce en 139,0–139,5 vB.

PREVOUT:
  hash (32 bytes)
  index (4 bytes)
SCRIPTSIG:
  length (varInt 1 byte)
  witness program: (1 + 1 + 1 + 32 = 35 bytes)
    length
    version (OP_0) 
    PUSHBYTES <32-byte hash>
nSequence (4 bytes)
WITNESS STACK:
  item count (1 WU)
  script arguments (1 + 2×(1+72²) WU)
    dummy-empty-element¹
    m×(varInt+sig)
  witnessScript (1+1+3×(1+33)+1+1 = 106 WU)
    length (varInt 1 WU)
    OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
  
32 + 4 + 1 + 1 + 1 + 1 + 32 + 4
+ [1 + 1 + 2×(1+72) + 1+1+3×(1+33)+1+1]/4
= 36 + 1 + 35 + 4 + [1 + 147 + 106]/4
= 76 + [254]/4
= 76 + 63.5
= 139.5 vB

P2WSH

El P2WSH tiene la misma pila de testigos que el P2SH-P2WSH, por lo que evita que los 35 B eludan el script de redención. El peso de un P2WSH 2 de 3 resulta ser 416-418 WU, lo que se traduce en 104,0–104,5 vB.

PREVOUT:
  hash (32 bytes)
  index (4 bytes)
SCRIPTSIG:
  length (varInt 1 byte)
nSequence (4 bytes)
WITNESS STACK:
  item count (1 WU)
  script arguments (1 + 2×(1+72²) WU)
    dummy-empty-element¹ 
    m×(varInt+sig)
  witnessScript (1+1+3×(1+33)+1+1 = 106 WU)
    length (varInt 1 WU)
    OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG

32 + 4 + 1 + 4
+ [1 + 1 + 2×(1+72) + 1 + 1 + 3×(1+33) + 1 + 1]/4
= 36 + 1 + 4 + [1 + 147 + 106]/4
= 41 + [254]/4
= 41 + 63.5 
= 104.5 vB

¹ OP_CHECKMULTISIG extrae un elemento adicional de la pila
² Las firmas pueden tener 71 o 72 bytes (o rara vez incluso más pequeñas)