2

I need to calculate fees for each transaction in block.

I retrieve raw block data and use bitcoinjs-lib library to decode it to Block object:

const block = Bitcoin.Block.fromHex(data.rawblock);

It has an array of Transaction objects. However, while these transactions' outs have values, ins have only hash and script.

How should I process this data so I can get total in and out amounts and calculate transaction fee?

2 Answers 2

2
+50

You will, by default, only see the values of the outputs and not the inputs. To gather all values for inputs, you will need to loop through your inputs and use an API to gather the transactions where the inputs were once outputs.

I used the BitPay insight API and left some notes in the code below:

var Bitcoin = require('bitcoinjs-lib');
var request = require('request');

function getRawBlock(blockHash) {
  return new Promise((resolve, reject) => {
    request('https://insight.bitpay.com/api/rawblock/' + blockHash, // hitting an insight API to get the full block
      (error, response, body) => {
        try {
          var block = JSON.parse(body); // result is in JSON
          resolve(block.rawblock)
        } catch(error) {
          reject(error)
        }
      })
  })
}

function getTransaction(transactionId) {
  return new Promise((resolve, reject) => {
    request('https://insight.bitpay.com/api/tx/' + transactionId, // hitting an insight API to get the full transaction
      (error, response, body) => {
        try {
          var transaction = JSON.parse(body); // result is in JSON
          resolve(transaction);
        } catch(e) {
          reject(e)
        }
      });
  })
}

getRawBlock('000000000000000000aabc9831a830ab8542137c68998368b86f9127432767d5')
  .then((rawBlock) => {

    var block = Bitcoin.Block.fromHex(rawBlock); // use bitcoinjs-lib to convert the raw block to usable data
    var transactions = block.transactions; // transactions reside here
    var transaction = transactions[1]; // using second transaction as an example since the first one is miner reward
    // you can loop the transactions the way you like

    var inputs = transaction.ins; // will need to use the API to get the outputs that each input once was
    var outputs = transaction.outs; // no need to hit API for outputs, value is in outputs[i].value

    var inputsWork = inputs.map((i) => { // map the inputs to an array of promises which we can run later
      return new Promise((resolve, reject) => {
        var transactionId = Buffer.from(i.hash).reverse().toString('hex'); // derive the transaction id this way
        var outputIndex = i.index; // output index is also needed
        getTransaction(transactionId)
          .then((transaction) => { //this transaction belongs to the looped input (i)
            var outputs = transaction.vout; // get outputs of transaction
            var output = outputs.find((i) => (i.n === outputIndex)); // match the input/output indexes
            resolve(output.value); // resolve with our output value
          })
      })
    });

    Promise.all(inputsWork)
      .then((inputValues) => { // execute array of promises for inputs

        var totalInputs = inputValues.reduce((a,b) => (a+b)); // add up the input amounts
        var totalOutputs = outputs.reduce((a,b) => (a.value+b.value)); // add up the output amounts
        totalOutputs = totalOutputs / 100000000; // outputs in satoshis

        var feesIncurred = totalInputs - totalOutputs; // fees of a transaction is input amount - output amount
        console.log(feesIncurred); // log the fees to your console
      })

  })

Cheers!

1

How should I process this data so I can get total in and out amounts and calculate transaction fee?

Each in contains a (hash, index) to a previous output in the blockchain. Assuming you have a full node with txindex=1 meaning there's a full index of all previous transactions. You can use (hash, index) to find the original UTXO that carries the actual value.

Therefore, transaction fees = sum of previous outputs - sum of current outputs

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.