indexd icon indicating copy to clipboard operation
indexd copied to clipboard

Example to calculate address balance

Open KryptoNova opened this issue 6 years ago • 5 comments

Hello,

I am working on a project that has many private keys that have balances in them. I do not want to have to go out to a public API to query for security concerns.

I see there is a way to get the unspent amounts for an address in the example. However, I am not seeing a way to connect the private key to it's address. I believe this is what I would have to do to determine how much BTC the private key is linked to.

Is the data structure in indexd able to perform this type of query against the blockchain?

Thanks in advance!

KryptoNova avatar Jan 13 '18 04:01 KryptoNova

I'm still learning about the nuts and bolts of the blockchain and have refined my understanding of the question I first posed. From what I understand, there is a public key that is stored in the blockchain along with the transaction. I understand that each private key can have two public addresses, compressed and uncompressed. The private key can be used to calculate it's associated public keys, but the public keys cannot be reversed to find the private key. Please correct me if I am wrong as I am still learning.

If this is the case, then as long as the public key is a searchable field in the database that is being parsed, then it should be possible to determine the unspents of a private key. Is the data being parsed able to be queried based on the public keys associated with the transactions?

KryptoNova avatar Jan 14 '18 04:01 KryptoNova

@KryptoNova the blockchain contains blocks, which each have transactions, which each have inputs and outputs.

Each output has a script (the output script) which is typically (but not always) of some form akin to:

  • P2PKH OP_DUP OP_HASH160 {hash160(pubKey)} OP_EQUALVERIFY OP_CHECKSIG
  • P2SH OP_HASH160 {hash160(scriptPubKey2)} OP_EQUAL
  • P2WPKH 0 {hash160(pubKey)}
  • P2WSH 0 {sha256(scriptPubKey2)}

By looking at the output scripts, you can build an index (aka database) of unspents outputs for each unique script, or each unique public key hash (hash160(pubKey)), or some combination. Rarely will you see the raw public key on its own.

dcousens avatar Jan 16 '18 00:01 dcousens

I think I understand what needs to be done to make this happen. Thank you for the enlightenment!

KryptoNova avatar Jan 16 '18 00:01 KryptoNova

@KryptoNova apologies, I thought this was question was for another project.

Is the data structure in indexd able to perform this type of query against the blockchain?

indexd has a script index. A script can be derived from an address. If you have an address, or many addresses, you can determine the balance using indexd.

I'll add an example here at some point.

dcousens avatar Jan 17 '18 05:01 dcousens

@KryptoNova and others who might be interested: bitcoinjs/regtest-server implements most of this functionality and may serve as your example: https://github.com/bitcoinjs/regtest-server/blob/b699cfad29e21272c7c644d9d66c5ad089d56be8/routes/1.js#L107-L112

  router.get('/a/:address/unspents', addressWare, (req, res) => {
    let { scId } = req.params
    indexd().utxosByScriptRange({
      scId, heightRange: [0, 0xffffffff], mempool: true
    }, DBLIMIT, res.easy)
  })

The result is an array of UTXO objects; you may sum the value field of each to find the unspent balance of the address in satoshis.

Note the addressWare middleware function for converting the address to a script ID.

bchociej avatar Mar 05 '21 04:03 bchociej