AWS Database Blog
List unspent transaction outputs by address on Bitcoin with Amazon Managed Blockchain Query
In order to build an application that interacts with the Bitcoin blockchain, whether it be a wallet, an Ordinals marketplace, or a BTC exchange, you must be able to reliably access the Bitcoin network. For example, you will need to read critical data from the blockchain that acts as input for properly constructed Bitcoin transactions. The most foundational of these data needs is retrieving data pertaining to transaction outputs for a given wallet from the Bitcoin network, which serves a variety of use cases. For example, retrieving unspent transaction outputs (UTXOs) to be consumed as inputs for outgoing transactions of BTC, retrieving all UTXOs for a given wallet to calculate a balance in BTC, gathering spent outputs to render a list of past Bitcoin transactions, and more. There are multiple options for retrieving this data, including third-party data providers and node operators or running your own Bitcoin Core node.
Operating your own Bitcoin Core node prioritizes independence and verifiability, and allows you to track transaction output data for a limited set of wallets (comprising n number of addresses). However, using self-managed Bitcoin Core nodes as is limits the scale at which you can retrieve transaction output data. In contrast, Amazon Managed Blockchain (AMB) uses cloud scale indexing and storage to provide a low-latency API for data pertaining to an unlimited set of wallets. AMB Query offers convenience, ease of scale, and pricing efficiency for Bitcoin workloads, helping you shed the undifferentiated heavy lifting of managing Bitcoin nodes and performing data extractions from the network at scale.
In this post, we focus on how to use the blockchain data APIs available in AMB Query to provide reliable, cost-effective access to Bitcoin data at scale, including transaction output data. Furthermore, AMB Access provides serverless access to a fleet of Bitcoin nodes that you can use to broadcast your Bitcoin transactions after you have retrieved UTXOs ready to spend from AMB Query.
AMB Query and the ListFilteredTransactionEvents API
AMB Query provides a set of developer-friendly APIs that serve current and historical blockchain data from multiple public blockchains, including Bitcoin. With AMB Query, developers can shed the undifferentiated heavy lifting of node operations, blockchain data indexing, and ETL (extract, transform, and load), and focus their efforts on differentiated features for their application. With AMB Query, you can now use the ListFilteredTransactionEvents API to query for spent or unspent transaction outputs for an address or set of addresses on the Bitcoin network and its testnet, providing an alternative to the built-in listunspent JSON-RPC API in the Bitcoin Core node implementation.
The ListFilteredTransactionEvents
API allows developers to do the following:
- Retrieve unspent transaction outputs for a given address or set of addresses to ease the process of constructing Bitcoin transactions
- Retrieve spent transaction output information to populate dashboards or wallet interfaces
- Filter transaction events pertaining to unspent outputs by timestamp and finality status
Before demonstrating ListFilteredTransactionEvents
functionality in a code sample, it’s important to disambiguate the fundamentals of the unspent transaction output (UTXO) model employed by Bitcoin and why you will inevitably require an API like ListFilteredTransactionEvents
when building a Bitcoin application.
Understanding the unspent transaction output (UTXO) model
The Bitcoin blockchain uses the UTXO accounting method, so tasks such as calculating a spendable balance of BTC or populating a transaction to spend BTC begin with compiling the unspent transaction outputs for a given wallet. In Bitcoin, each new transaction of BTC consumes unspent outputs from previous transactions, and in turn results in new unspent outputs to be consumed by future transactions. This concept is best illustrated by analyzing the anatomy of a Bitcoin transaction:
The vin
object defines the value (BTC) going into the transaction, which refers to one or more of the previous vout
objects. These vout
objects are the unspent value out from previous Bitcoin transactions. Each new Bitcoin transaction will take unspent transaction outputs from previous transactions in the vin
object, and then define new vout
entries to spend (send) them to other wallets.
The vout
array defines the list of outputs for the transaction, including the recipient, value (in BTC), and more. The total value of the vout
entries will generally be equal to the sum of the value of vin, and will often define change as a vout
to return to the sender of the transaction. This results in new unspent outputs (vout
) for the sender to spend in another transaction. Although the preceding transaction example uses a single vin
and vout
, it is common for each transaction to have multiple vin
and vout
entries defined.
As you can infer from the construction of a Bitcoin transaction, calculating the total spendable balance of a given wallet requires calculating the sum of the total unspent transaction outputs (vout) for a given wallet. In the absence of an API to provide this insight, you would have to make a large quantity of requests to a Bitcoin node to retrieve all vin
and vout
within transactions pertaining to your wallet and perform calculations to determine which are spent or unspent outputs. This information is also a prerequisite to constructing a valid Bitcoin transaction. With AMB Query, it is straightforward to retrieve a list of spent and unspent transaction outputs for a given set of addresses, which is illustrated in the next section.
How to use AMB Query to get a list of unspent transaction outputs
The ListFilteredTransactionEvents
API takes a list of addresses and returns any applicable Bitcoin transaction VOUT
events, both spent and unspent, pertaining to those addresses. Data is returned in the following format, which provides the key properties that you may use to populate a Bitcoin transaction with any number of those unspent outputs:
In the preceding response format document, you will find several properties pertaining to spent and unspent transaction outputs. When retrieving spent transaction outputs, spentVoutTransactionHash
, spentVoutTransactionId
, and spentVoutIndex
define the transaction identifiers and the array position of the spent output (vout
) so you can easily determine the origin of that output. For unspent transaction outputs, the properties transactionHash
, transactionId
, and voutIndex
define the transaction identifiers and the array position of the unspent output in the parent transaction. Additionally, the flag confirmationStatus
defines whether the transaction containing the output is considered final on the Bitcoin blockchain. In AMB Query, a transaction’s finality is defined as equal to or greater than six confirmations, or blocks mined after the block in which the transaction is contained. Transactions considered final according to this criterion will be marked FINAL
, whereas unconfirmed transactions will be marked NONFINAL
.
To better illustrate the response from the API, the JavaScript code sample defines a simple script to retrieve a list of unspent transaction outputs for a single Bitcoin address on the Bitcoin testnet. To run these Node.js examples, the following prerequisites apply:
- You must have node version manager (nvm) and Node.js installed on your machine. You can find installation instructions for your OS in the nvm GitHub repo.
- Use the node –version command and confirm that you are using Node version v18.12.0 (LTS) or higher. If required, you can use the nvm install 18.12.0 command, followed by the nvm use 18.12.0 command to install.
- The environment variables
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
must contain the credentials that are associated with the account. Export these variables as strings on your client by using the following commands. Replace the values in the following code with appropriate values from the AWS Identity and Access Management (IAM) user account.
Copy the following two code snippets to your local working directory, containing the code sample (index.js)
and package.json, which contains one dependency, the official AWS SDK module for AMB Query:
The following is the package.json
code:
The following is the index.js
code:
To use this code, run the following command from your working directory, replacing the address defined in the index.js
with the addresses of your choice, if desired:
npm i && node index.js
With the filter set for unspent transactions only in the preceding code sample, the result will be similar to the following:
In the response, you can see that the transaction identifiers (transactionHash
and transactionId
), value
, and voutIndex
are defined for each unspent output, which can serve as inputs for constructing future Bitcoin transactions.
You can modify the filters in your query to retrieve different data, such as retrieving both unspent and spent outputs, or restricting the timespan for which to retrieve data. For more information about these filters, refer to Request Body. Requests to AMB Query APIs are billed per request based on pricing buckets per million requests. You can view the latest pricing information for each API to calculate the cost of requests to AMB Query.
Conclusion
In this post, we outlined the fundamentals of the UTXO model made prevalent by Bitcoin, how UTXOs are central to transactions in Bitcoin, and how to retrieve UTXO data using AMB Query. To learn more about AMB Query, see What is Amazon Managed Blockchain (AMB) Query? To learn more about other Managed Blockchain offerings, see Amazon Managed Blockchain.
About the author
Forrest Colyer manages the Web3/Blockchain Specialist Solutions Architecture team that supports the Amazon Managed Blockchain (AMB) service. Forrest and his team support customers at every stage of their adoption journey, from proof of concept to production, providing deep technical expertise and strategic guidance to help bring blockchain workloads to life. Through his experience with private blockchain solutions led by consortia and public blockchain use cases like NFTs and DeFi, Forrest helps enable customers to identify and implement high-impact blockchain solutions.