2

I want to calculate how many % of a block, and thus, transactions that are witness data. I need to calculate the size of the witness data in bytes in every transaction. And as I understand it, I cannot calculate this using existing size variables like vsize.

Will a loop through the "txinwitness" array of hex and do a byte length calculation on every one be enough? (Using NodeJS here)

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

3 Answers 3

2

Elaborating on Andrew's answer:

You can calculate it from size and vsize.

Transaction size

See BIP141

Transaction weight is defined as Base transaction size * 3 + Total transaction size (ie. the same method as calculating Block weight from Base size and Total size).

Virtual transaction size is defined as Transaction weight / 4 (rounded up to the next integer).

Base transaction size is the size of the transaction serialised with the witness data stripped.

Total transaction size is the transaction size in bytes serialized as described in BIP144, including base data and witness data.

Witness size

So, for example if you have a transaction that has a total size of 1200 bytes (including witness data), and a base size of 1000 bytes, the weight and virtual size are:

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

So, given size and vsize, you can calculate the size of witness data:

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

3

Will a loop through the "txinwitness" array of hex and do a byte length calculation on every one be enough?

That is not enough as there are extra data in witnesses that is not included in the txinwitness.

You can get the number of witness bytes and the number of non-witness bytes by solving a system of equations. The getrawtransaction RPC gives you two fields, size and weight. size is the total size in bytes as received over the wire. weight is the weight of the transaction as defined by BIP 141.

If you let x be the number of non-witness bytes, and y be the number of witness bytes, the definitions of size and weight gives you:

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

By plugging in the weight and size from the RPC, you can solve the system of equations for x and y to get the number of non-witness bytes and number of witness bytes respectively.

1
  • 1
    So x = (weight - size)/3, y = (4*size - weight)/3 Oct 22, 2018 at 17:49
0

If you use bitcoinjs-lib like I do, after signing inputs for tx you extractTransaction and get the object:

import { Psbt } from 'bitcoinjs-lib';

const psbt = new Psbt(...)

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

extractedTx is of following format:

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

ins here is of following format:

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

Sum witness buffers for each input and you will have your witness weight.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.