¿Cómo comprobar si se ha gastado una salida?

Usando un cliente rpc (p. ej bitcoin-cli.), para una transacción determinada y el índice de una salida de la misma, ¿cómo puedo saber si la salida es actualmente un utxo o si ya se ha gastado?

En el último caso, también me gustaría saber la transacción en la que se gastó.

Miré el gettxoutcomando, pero no tengo claro cómo extraer la respuesta de los datos que devuelve.

Estoy ejecutando un nodo completo con txindex=1.

Respuestas (2)

Si gettxoutdevuelve algo, la salida no se gasta. Si no devuelve nada, la salida nunca existió o se gastó.

No necesitas -txindexpara esto.

Ya veo. Entonces, ¿hay alguna manera de saber qué tx lo gastó? Además, ¿el Unconfirmedparámetro es relevante aquí de alguna manera?
No, no hay nada en Bitcoin Core que realice un seguimiento de qué tx gastó algo. Una vez que se gasta un UTXO, simplemente se elimina de la base de datos. Si Sin confirmar se establece en verdadero, tratará las transacciones en el mempool como si estuvieran en un bloque (por lo que enumerará sus salidas y eliminará sus entradas).
La referencia del desarrollador dice: The gettxout RPC returns details about a transaction output. Only unspent transaction outputs (UTXOs) are guaranteed to be available.Esto significa que los txos gastados también pueden estar disponibles. Al jugar con RPC, parece que en la práctica si no devuelve nada, de hecho no se gastó, pero ¿está garantizado? ¿La referencia del desarrollador es incorrecta? bitcoin.org/en/developer-reference#gettxout
@nopara73 Sí, eso es incorrecto. Brinda información sobre las salidas no gastadas y no devolverá nada por las salidas gastadas.
@PieterWuille Gracias, hice un PR para la corrección en los documentos: github.com/bitcoin-dot-org/bitcoin.org/pull/1891

Como @ pieter-wuille ya respondió la primera mitad de su pregunta:

Si gettxoutdevuelve algo, la salida no se gasta. Si no devuelve nada, la salida nunca existió o se gastó.

Para eso, agregaría que puede configurar el indicador no confirmado true, por lo que también tiene en cuenta las transacciones no confirmadas.

Para responder a la segunda parte de su pregunta, aquí hay una forma subóptima de encontrar la transacción que gastó su txo:
Esto supone txindex=1y prune=0.

Para saber quién gastó el txout puedes averiguar el bloque con el que se confirmó: getrawtransaction {txid} 1. A partir de aquí, puede recorrer todos los bloques hasta el último que llegó ( getblock) y el mempool ( getrawmempool), mientras verifica cada transacción:

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