edgecase
Author: StJohn Piano
Published: 2020-09-12
Datafeed Article 175
This article has been digitally signed by Edgecase Datafeed.
1188 words - 477 lines - 12 pages





Parts


- Description
- Notes
- Recipe
- Examples




Description


This recipe describes a method of looking up the unspent outputs associated with a Bitcoin address.

The unspent outputs can be used:
- to calculate the balance of the address.
- as inputs to a new Bitcoin transaction.




Notes


Bitcoin is stored in a Bitcoin address.

An address holds "unspent outputs", which have been created by previous Bitcoin transactions.

(The sum of the values in the unspent outputs) = (the amount of bitcoin that is held in the address).

Any unspent output used as an input in a transaction becomes "spent".








Recipe


Block explorers usually:
- allow a user to look up an address and see a list of all related transactions.
- look up a transaction and get information about its inputs and outputs.

These two features can be used to derive the list of unspent outputs in an address.



1) Look up the address on a block explorer.

The address page should contain a list of transactions in which this address appears. This list will probably be in reverse chronological order and may be paginated.



2) Create lists

Make a list of inputs. Label each input.
Example: A1/T1/Input0 (Address 1, Transaction 1, Input 0)

Make a list of outputs. Label each output.
Example: A1/T1/Output0 (Address 1, Transaction 1, Output 0)



3) Look up each transaction on the block explorer.

Find these details for each of its inputs:
- txid
- previous_output_index
- satoshi_value

Notes:
- The txid is the txid of the previous transaction that created this input, not the current transaction, which spends it. When the input was created, it was an "unspent output".
- The previous_output_index is the implicit 0-indexed position of the input in the previous transaction's output list.

Add each input to the list of inputs.

Example:

A1/T1/Input0:
- txid:
9d64ba7c5afdb3caa79bb79c35dde09af70b27829241b2823e4ffb918c75d153
- previous_output_index: 0
- satoshi_value: 1000000


Find these details for each of its outputs:
- txid
- address
- satoshi_value
- output_index (the 0-indexed position of the output in the transaction's output list)

Notes:
- The txid is the txid of the current transaction. The other details are specific to the output.
- If the output list is long, it can be difficult to count the output_index without making a mistake. Suggestion: Copy the output list to a new text file and add an "output_index" field for each output, starting at 0, and incrementing by 1 each time.

Add each output to the list of outputs.

Example:
A1/T1/Output0:
- txid:
585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea
- address:
12YCFdpsRDvEHNcj5rsmvJ5G2XXkW1icJP
- satoshi_value: 474300
- output_index: 0


The block explorer may use different names for the various details.



4) Create a second list of outputs.

Go through the first list. Copy over any outputs that sent bitcoin to the address to this second list.



5) Remove any spent outputs.

Remove all outputs from the second list of outputs where:
- the output's txid is identical to a txid of an input in the list of inputs.
and
- the output's output_index is identical to the same input's previous_output_index.



6) Result.

The second output list should now contain only unspent outputs.

The balance of the address can be calculated by summing the satoshi_values of the unspent outputs.

Each of these unspent outputs can be used as an input in a new Bitcoin transaction (assuming of course that you have the Bitcoin private key that controls the address).










Examples


This recipe was written during the previous project Creating and signing a standard Bitcoin transaction with two inputs and two outputs, so I was able to test these examples while some of the test addresses still contained unspent outputs.



I'll use this block explorer:
live.blockcypher.com

I'll look up the unspent outputs in address A1:
1BB66Gx4833uKx8Lo2k8Mt4TRk42WTr7cZ


Search for A1 in the block explorer.

Address page:
live.blockcypher.com/btc/address/1BB66Gx4833uKx8Lo2k8Mt4TRk42WTr7cZ

Currently, there are 2 transactions listed, with these txids:
585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea

9d64ba7c5afdb3caa79bb79c35dde09af70b27829241b2823e4ffb918c75d153


Each transaction has 1 input and 2 outputs.

The transactions are in reverse chronological order.

The balance is 0, so we know that this address contains 0 unspent outputs. Nonetheless, we'll go through the recipe, and confirm that it produces 0 unspent outputs. Afterwards, we'll use the same procedure on an address with a non-zero balance.



Each txid is a link to a page for the corresponding transaction.

Transaction pages:

live.blockcypher.com/btc/tx/585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea

live.blockcypher.com/btc/tx/9d64ba7c5afdb3caa79bb79c35dde09af70b27829241b2823e4ffb918c75d153

For each transaction, click Advanced Details / API Call. This supplies the raw transaction information in JSON format.

This particular block explorer uses these names in the inputs:
- "prev_hash" (txid)
- "output_index" (previous_output_index)
- "output_value" (satoshi_value)

In the transaction, it uses the name "hash" instead of "txid".

And in the outputs, it:
- supplies an "addresses" list instead of a single "address" for the output.
- uses the name "value" instead of "satoshi_value".



List of inputs:

A1/T1/Input0: (Address 1, Transaction 1, Input 0)
- txid:
9d64ba7c5afdb3caa79bb79c35dde09af70b27829241b2823e4ffb918c75d153
- previous_output_index: 0
- satoshi_value: 1000000


A1/T2/Input0:
- txid:
3825d2a6007b788adca311c4a3c8c6d085b2c3e74deca17eb2d7f73f236217d8
- previous_output_index: 2
- satoshi_value: 31634145




List of outputs:

A1/T1/Output0:
- txid:
585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea
- address:
12YCFdpsRDvEHNcj5rsmvJ5G2XXkW1icJP
- satoshi_value: 474300
- output_index: 0


A1/T1/Output1:
- txid:
585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea
- address:
1H5SUR7Fv7x252WuJPqBjewwpeHuJ218Ky
- satoshi_value: 500000
- output_index: 1


A1/T2/Output0:
- txid:
9d64ba7c5afdb3caa79bb79c35dde09af70b27829241b2823e4ffb918c75d153
- address:
1BB66Gx4833uKx8Lo2k8Mt4TRk42WTr7cZ
- satoshi_value: 1000000
- output_index: 0


A1/T2/Output1:
- txid:
9d64ba7c5afdb3caa79bb79c35dde09af70b27829241b2823e4ffb918c75d153
- address:
1FMfKo3ArFcuaFHXw5zmgYCeLpqefVQdg8
- satoshi_value: 30604848
- output_index: 1




Second list of outputs (those that sent bitcoin to address A1):

A1/T2/Output0:
- txid:
9d64ba7c5afdb3caa79bb79c35dde09af70b27829241b2823e4ffb918c75d153
- address:
1BB66Gx4833uKx8Lo2k8Mt4TRk42WTr7cZ
- satoshi_value: 1000000
- output_index: 0




Look through the list of inputs. If any input has the same txid and output_index, then this output has been spent.

Yup, here it is:

A1/T1/Input0:
- txid:
9d64ba7c5afdb3caa79bb79c35dde09af70b27829241b2823e4ffb918c75d153
- previous_output_index: 0
- satoshi_value: 1000000




So: Address A1 contains no unspent outputs. It therefore has a balance of 0 bitcoin, and cannot supply any inputs for a new Bitcoin transaction.



Now, let's go through the recipe again, but with address A2 from the previous project.

Address A2:
12YCFdpsRDvEHNcj5rsmvJ5G2XXkW1icJP


Search for A2 in the block explorer.

Address page:
live.blockcypher.com/btc/address/12YCFdpsRDvEHNcj5rsmvJ5G2XXkW1icJP

Currently, there is 1 transaction listed, with this txid:
585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea


The balance is 0.004743, so we know that this address contains at least unspent output.

Transaction page:
live.blockcypher.com/btc/tx/585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea

Click Advanced Details / API Call. This leads to a page containing the raw transaction information in JSON format.



List of inputs:

A2/T1/Input0:
- txid:
9d64ba7c5afdb3caa79bb79c35dde09af70b27829241b2823e4ffb918c75d153
- previous_output_index: 0
- satoshi_value: 1000000




List of outputs:

A2/T1/Output0:
- txid:
585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea
- address:
12YCFdpsRDvEHNcj5rsmvJ5G2XXkW1icJP
- satoshi_value: 474300
- output_index: 0


A2/T1/Output1:
- txid:
585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea
- address:
1H5SUR7Fv7x252WuJPqBjewwpeHuJ218Ky
- satoshi_value: 500000
- output_index: 1




Second list of outputs (those that sent bitcoin to address A2):

A2/T1/Output0:
- txid:
585f054c01139bdae20ff8fa233c4cda47db6d891a387e37dfd56f9cb39d1bea
- address:
12YCFdpsRDvEHNcj5rsmvJ5G2XXkW1icJP
- satoshi_value: 474300
- output_index: 0




Look through the list of inputs. If any input has the same txid and output_index, then this output has been spent.

Nope. This output is unspent.

The bitcoin in address A2 is the sum of the values of the unspent outputs stored in the address.

In this case, the sum is the satoshi_value of A2/T1/Output0: 474300 satoshi (0.00474300 bitcoin).

This unspent output can be used as an input for a new Bitcoin transaction.