7

Using an rpc client (e.g. bitcoin-cli), for a given transaction and index of an output of it, how can I tell if the output is currently an utxo, or if it has already been spent?

In the latter case, I'd also want to know the transaction which spent it.

I looked at the gettxout command, but it isn't clear to me how to extract the answer from the data it returns.

I'm running a full node with txindex=1.

2 Answers 2

8

If gettxout returns something, the output is unspent. If it returns nothing, the output either never existed or is spent.

You do not need -txindex for this.

5
  • I see. So, is there a way to tell which tx spent it? Also, is the Unconfirmed parameter relevant here in some way?
    – shx2
    Sep 10, 2016 at 8:06
  • No, there is nothing in Bitcoin Core that keeps track of which tx spent something. Once a UTXO is spent, it is simply removed from the database. If Unconfirmed is set to true, it will treat transactions in the mempool as if they were in a block (so it will list their outputs, and remove their inputs). Sep 10, 2016 at 8:24
  • The dev reference states: The gettxout RPC returns details about a transaction output. Only unspent transaction outputs (UTXOs) are guaranteed to be available. This means spent txos may be available, too. By playing with RPC, it seems like in practice if it doesn't return anything it's indeed unspent, but is that guaranteed? Is the dev reference wrong? bitcoin.org/en/developer-reference#gettxout
    – nopara73
    Oct 29, 2017 at 16:46
  • 1
    @nopara73 Yes, that's incorrect. It gives information about unspent outputs, and won't return anything for spent outputs. Oct 29, 2017 at 18:27
  • @PieterWuille Thanks, made a PR for the fix in the docs: github.com/bitcoin-dot-org/bitcoin.org/pull/1891
    – nopara73
    Oct 30, 2017 at 21:41
0

As @pieter-wuille already answered the first half of your question:

If gettxout returns something, the output is unspent. If it returns nothing, the output either never existed or is spent.

For that I'd add you can set the unconfirmed flag true, so it factors in unconfirmed transactions, too.

To answer the second part of your question, here's a sub-optimal way to find the transaction which spent your txo:
This assumes txindex=1 and prune=0.

To find out who spent the txout you can figure out the block it was confirmed with: getrawtransaction {txid} 1. From here on you can iterate through all the blocks to the last arrived one (getblock) and the mempool (getrawmempool), while checking every transaction:

foreach(var input in tx.inputs)
{
   if(input.prevout.txid == myTxo.txid && input.prevout.index == myTxo.index)
   {
      // tx spent the txo you were looking for
   }
}

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.