Cálculo del tamaño del testigo de una transacción

Quiero calcular el porcentaje de un bloque y, por lo tanto, las transacciones que son datos testigo. Necesito calcular el tamaño de los datos testigo en bytes en cada transacción. Y según tengo entendido, no puedo calcular esto usando variables de tamaño existentes como vsize.

¿Será suficiente un bucle a través de la matriz "txinwitness" de hexadecimal y hacer un cálculo de longitud de bytes en cada uno? (Usando NodeJS aquí)

Buffer.byteLength('03fbcc1c24903bc2fb1d73czef518b859232341c39e4515367653d80536d587b62d6', 'hex');

Respuestas (3)

Elaborando la respuesta de Andrew:

Puedes calcularlo a partir de sizey vsize.

Tamaño de la transacción

Ver BIP141

El peso de la transacción se define como Tamaño base de la transacción * 3 + Tamaño total de la transacción (es decir, el mismo método para calcular el peso del bloque a partir del tamaño base y el tamaño total).

El tamaño de la transacción virtual se define como Peso de la transacción / 4 (redondeado al siguiente entero).

El tamaño base de la transacción es el tamaño de la transacción serializada con los datos testigo eliminados.

El tamaño total de la transacción es el tamaño de la transacción en bytes serializados como se describe en BIP144, incluidos los datos base y los datos testigo.

Tamaño del testigo

Entonces, por ejemplo, si tiene una transacción que tiene un tamaño total de 1200 bytes (incluidos los datos testigo) y un tamaño base de 1000 bytes, el peso y el tamaño virtual son:

weight = 1000 bytes * 3 + 1200 bytes = 4200
vsize = 4200 / 4 = 1050 bytes

Entonces, dado sizey vsize, puede calcular el tamaño de los datos testigo:

witness size = (4/3) * (total - vsize)
witness size = 200

¿Será suficiente un bucle a través de la matriz "txinwitness" de hexadecimal y hacer un cálculo de longitud de bytes en cada uno?

Eso no es suficiente, ya que hay datos adicionales en los testigos que no están incluidos en el archivo txinwitness.

Puede obtener el número de bytes testigos y el número de bytes no testigos resolviendo un sistema de ecuaciones. El getrawtransactionRPC le da dos campos, sizey weight. sizees el tamaño total en bytes recibido por cable. weightes el peso de la transacción según lo definido por BIP 141.

Si deja xser el número de bytes no testigos y yel número de bytes testigos, las definiciones de sizey weightle da:

4x + 1y = weight
x + y = size

Al conectar weighty sizedesde el RPC, puede resolver el sistema de ecuaciones para xobtener yel número de bytes no testigos y el número de bytes testigos, respectivamente.

Entonces x = (peso - tamaño)/3, y = (4*tamaño - peso)/3

Si usa bitcoinjs-libcomo lo hago yo, después de firmar entradas para tx, extrae Transaction y obtiene el objeto:

import { Psbt } from 'bitcoinjs-lib';

const psbt = new Psbt(...)

const allInputs = psbt.finalizeAllInputs();
const extractedTx = allInputs.extractTransaction(increaseFeeRate, customFee);

extractTx tiene el siguiente formato:

interface SignedTransaction {
  ins: SignedTxInput[],
  locktime: number,
  outs: SignedTxOutput[],
  version: number
}

insaquí tiene el siguiente formato:

interface SignedTxInput {
  hash: Buffer,
  index: number,
  script: Buffer,
  sequence: number,
  witness: Buffer[],
}

Sume los búferes de testigo para cada entrada y tendrá su peso de testigo.