How to check if an output has been spent?

3

1

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.

shx2

Posted 2016-09-10T07:36:32.017

Reputation: 633

Answers

6

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.

Pieter Wuille

Posted 2016-09-10T07:36:32.017

Reputation: 54 032

I see. So, is there a way to tell which tx spent it? Also, is the Unconfirmed parameter relevant here in some way?shx2 2016-09-10T08:06:49.193

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).Pieter Wuille 2016-09-10T08:24:56.070

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? https://bitcoin.org/en/developer-reference#gettxout

nopara73 2017-10-29T16:46:41.357

1@nopara73 Yes, that's incorrect. It gives information about unspent outputs, and won't return anything for spent outputs.Pieter Wuille 2017-10-29T18:27:12.977

@PieterWuille Thanks, made a PR for the fix in the docs: https://github.com/bitcoin-dot-org/bitcoin.org/pull/1891

nopara73 2017-10-30T21:41:18.143

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
   }
}

nopara73

Posted 2016-09-10T07:36:32.017

Reputation: 592