News

List unspent transaction outputs by address on Bitcoin with Amazon Managed Blockchain Query

Published

on

To create an application that interacts with the Bitcoin blockchain, whether it is a wallet, a Sort them marketplace or a BTC exchange, you need to be able to reliably access the Bitcoin network. For example, you will need to read critical data from the blockchain that serves as input for properly constructed Bitcoin transactions. The most fundamental of these data needs is retrieving transaction output data for a given wallet from the Bitcoin network, which serves a variety of use cases. For example, fetch unspent transaction outputs (UTXOs) to consume as input for outgoing BTC transactions, fetch all UTXOs for a given wallet to calculate a BTC balance, collect spent outputs to return a list of transactions Bitcoin passes and more. There are several options for recovering this data, including third-party data providers and node operators or running your own Bitcoin Core node.

Managing your own Bitcoin Core node prioritizes independence and auditability and allows you to monitor transaction output data for a limited set of wallets (comprising n number of addresses). However, using self-managed Bitcoin Core nodes as they are limits the scale at which transaction output data can be retrieved. In contrast, Amazon Managed Blockchain (AMB) uses cloud-scale indexing and storage to provide a low-latency API for data across an unlimited set of wallets. AMB query offers convenience, ease of scaling, and pricing efficiency for Bitcoin workloads, helping you eliminate the heavy undifferentiated work that comes with managing Bitcoin nodes and performing large-scale network data mining.

In this post, we will focus on how to use the blockchain data APIs available in AMB Query to provide reliable and cost-effective access to Bitcoin data at scale, including transaction output data. Furthermore, Access to the AMB provides serverless access to a fleet of Bitcoin nodes that you can use to broadcast your Bitcoin transactions after fetching UTXOs ready to be spent from AMB Query.

AMB Query and ListFilteredTransactionEvents API

AMB Query provides a set of developer-friendly APIs that provide current and historical blockchain data from multiple public blockchains, including Bitcoin. With AMB Query, developers can free themselves from the heavy undifferentiated workload of node operations, blockchain data indexing, and ETL (extraction, transformation, and loading) and focus their efforts on differentiated functionality for their application. With AMB Query, you can now use the ListFilteredTransactionEvents API to query the outputs of spent or unspent transactions for an address or set of addresses on the Bitcoin network and its testnet, providing an alternative to the built-in method not spent JSON-RPC API in the Bitcoin Core node implementation.

THE ListFilteredTransactionEvents The API allows developers to do the following:

  • Recovers unspent transaction outputs for a given address or set of addresses to facilitate the process of building Bitcoin transactions
  • Retrieves expense transaction output information to populate dashboards or wallet interfaces
  • Filter transaction events related to unspent outputs based on timestamp and finality state

Before demonstrating ListFilteredTransactionEvents functionality in a code example, it’s important to clarify the fundamentals of the unspent transaction output (UTXO) model that Bitcoin uses, and why you’ll inevitably need an API like ListFilteredTransactionEvents when creating a Bitcoin application.

Understand 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 populating the unspent transaction outputs for a given wallet. In Bitcoin, each new BTC transaction consumes unspent outputs from previous transactions and, in turn, results in new unspent outputs to be consumed in future transactions. This concept is best illustrated by analyzing the anatomy of a Bitcoin transaction:

{
    "txid" : "c80b343d2ce2b5d829c2de9854c7c8d423c0e33bda264c4013\
              8d834aab4c0638",
    "hash" : "c80b343d2ce2b5d829c2de9854c7c8d423c0e33bda264c40138d834aab4c0638",
    "size" : 85,
    "vsize" : 85,
    "version" : 1,
    "locktime" : 0,
    "vin" : [
        {
            "txid" : "3f4fa19803dec4d6a84fae3821da7ac7577080ef75\
                      451294e71f9b20e0ab1e7b",
            "vout" : 0,
            "scriptSig" : {
                "asm" : "",
                "hex" : ""
            },
            "sequence" : 4294967295
        }
    ],
    "vout" : [
        {
            "value" : 49.99990000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 cbc20a7664f2f69e5355a\
                         a427045bc15e7c6c772 OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a914cbc20a7664f2f69e5355aa427045bc15e\
                         7c6c77288ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "mz6KvC4aoUeo6wSxtiVQTo7FDwPnkp6URG"
                ]
            }
        }
    ]
}

THE vin The object defines the value (BTC) entered into the transaction, which refers to one or more of the above vout objects. These vout items are the unspent value from previous Bitcoin transactions. Each new Bitcoin transaction will take unspent transaction outputs from previous transactions in the file vin object, then define new vout items to spend (send) to other wallets.

THE vout the array defines the list of outputs for the transaction, including the recipient, value (in BTC), and more. The total value of vout entries will generally equal the sum of the vin value and will often define the change as a vout to be returned to the sender of the transaction. This results in new unspent output (vout) that the sender can spend on another transaction. Although the previous transaction example uses a single vin AND voutit is normal for each transaction to have more vin AND vout defined items.

As you can deduce from the construction of a Bitcoin transaction, to calculate the total spendable balance of a given wallet it is necessary to calculate the sum of the total unspent transaction outputs (vouts) for a given wallet. In the absence of an API to provide this information, you would have to make a large amount of requests to a Bitcoin node to retrieve everything vin AND vout within your wallet transactions and perform calculations to determine what the spent and unspent results are. This information is also a prerequisite for constructing a valid Bitcoin transaction. With AMB Query, it is easy to retrieve an output list of spent and unspent transactions for a given set of addresses, as shown in the next section.

How to use AMB Query to get a list of unspent transaction output

THE ListFilteredTransactionEvents The API takes a list of addresses and returns any applicable Bitcoin transactions VOUT events, both spent and unspent, relating to those addresses. The data is returned in the following format, which provides key properties you can use to populate a Bitcoin transaction with any number of unspent outputs:

HTTP/1.1 200
Content-type: application/json

{
   "events": [ 
      { 
         "blockchainInstant": { 
            "time": number
         },
         "confirmationStatus": "string",
         "contractAddress": "string",
         "eventType": "string",
         "from": "string",
         "network": "string",
         "spentVoutIndex": number,
         "spentVoutTransactionHash": "string",
         "spentVoutTransactionId": "string",
         "to": "string",
         "tokenId": "string",
         "transactionHash": "string",
         "transactionId": "string",
         "value": "string",
         "voutIndex": number,
         "voutSpent": boolean
      }
   ],
   "nextToken": "string"
}

In the above response format document you will find several properties related to the outputs of spent and unspent transactions. When retrieving the outputs of spent transactions, spentVoutTransactionHash, spentVoutTransactionIdAND spentVoutIndex define transaction identifiers and array location of spent output (vout) so you can easily determine the source of that output. For unspent transaction outputs, the properties transactionHash, transactionIdAND voutIndex define the transaction identifiers and array location of the unspent output in the main transaction. Also, the flag confirmationStatus defines whether the transaction containing the output is considered final on the Bitcoin blockchain. In AMB Query, the finality of a transaction is defined as equal to or greater than six confirmations, or blocks mined after the block containing the transaction. Transactions considered final under this criterion will be flagged FINALwhile unconfirmed transactions will be flagged NONFINAL.

To better illustrate the API response, the JavaScript code example 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 the node version manager (nvm) and Node.js installed on your computer. You can find installation instructions for your operating system in the nvm file GitHub repository.
  • Use the node –version command and confirm that you are using it Node version v18.12.0 (LTS) or higher. If necessary, you can use the nvm install 18.12.0 command, followed by the nvm use 18.12.0 command to perform the installation.
  • Environment variables AWS_ACCESS_KEY_ID AND AWS_SECRET_ACCESS_KEY must contain the credentials associated with the account. Export these variables as strings to your client using the following commands. Replace the values ​​in the following code with the appropriate values ​​from AWS Identity and Access Management (IAM) user accounts.

Copy the following two code snippets to your local working directory, containing the code example (index.js) and package.json, which contains a dependency, the official AWS SDK module for AMB Query:

What follows is the package.json code:

{
  "name": "query-bitcoin",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@aws-sdk/client-managedblockchain-query": "^3.538.0"
  }
}

What follows is the index.js code:

const { ManagedBlockchainQueryClient, ListFilteredTransactionEventsCommand } = require("@aws-sdk/client-managedblockchain-query");

const listUnspentOutputs = async (addresses) => { 
  const client = new ManagedBlockchainQueryClient({ region: "us-east-1" });
  
  const input = { // ListFilteredTransactionEventsInput
    addressIdentifierFilter: { 
      "transactionEventToAddress": [ ...addresses ]
    }, // list addresses to get events for 
    network: "BITCOIN_TESTNET", // define the network, testnet or mainnet
    sort: { // sort order
      sortOrder: "ASCENDING",
    },
    maxResults: Number("250"),
    "voutFilter": { 
      "voutSpent": false // retrieve only unspent outputs
   }
  };

  const command = new ListFilteredTransactionEventsCommand(input);

  try {
    const data = await client.send(command);
    console.log(data);
  } catch (error) {
    console.error(error);
  } 
}

listUnspentOutputs(['tb1qfrpw8av77mrmcf03epn5evfhv59z0t793jdh6t']) // input the Bitcoin addresses of your choice here

To use this code, run the following command from your working directory, replacing the address defined in the file index.js with the addresses of your choice, if you wish:

npm i && node index.js

With the filter set to only unspent transactions in the previous code example, the result would look like this:

events: [
    {
      blockchainInstant: [Object],
      confirmationStatus: 'FINAL',
      eventType: 'BITCOIN_VOUT',
      network: 'BITCOIN_TESTNET',
      to: 'tb1qfrpw8av77mrmcf03epn5evfhv59z0t793jdh6t',
      tokenId: 'btc',
      transactionHash: '195d8c08bda48315b4ba3690264dcee36a7862f98c15d3dde9cf57bbbdf6c6ad',
      transactionId: '438961c65220ca0c9427614f9dcd2a7ca8a1e638e7702debae6aa28417045ce7',
      value: '0.00001',
      voutIndex: 0,
      voutSpent: false
    },
    {
      blockchainInstant: [Object],
      confirmationStatus: 'FINAL',
      eventType: 'BITCOIN_VOUT',
      network: 'BITCOIN_TESTNET',
      to: 'tb1qfrpw8av77mrmcf03epn5evfhv59z0t793jdh6t',
      tokenId: 'btc',
      transactionHash: 'c1f2b279e50142fbbf62282e51c3e0a2f04247173f3b9dceef15345e12aa5db2',
      transactionId: '0ec51620a146b9d3e61b35fd68c7fa3e124a1b4bd2d582177fe9529a8c59158b',
      value: '0.00001',
      voutIndex: 0,
      voutSpent: false
    },
    {
      blockchainInstant: [Object],
      confirmationStatus: 'FINAL',
      eventType: 'BITCOIN_VOUT',
      network: 'BITCOIN_TESTNET',
      to: 'tb1qfrpw8av77mrmcf03epn5evfhv59z0t793jdh6t',
      tokenId: 'btc',
      transactionHash: '347994d54743989fb65e8845d6d10b8cea87b0d4aa6c98dfcdd063735711be8a',
      transactionId: '8ce1bbf94989cc23a13d5bf2d44dbba51b2f50a4ab759cf1309e97a3eb7d5b76',
      value: '0.00001',
      voutIndex: 0,
      voutSpent: false
    },
    {
      blockchainInstant: [Object],
      confirmationStatus: 'FINAL',
      eventType: 'BITCOIN_VOUT',
      network: 'BITCOIN_TESTNET',
      to: 'tb1qfrpw8av77mrmcf03epn5evfhv59z0t793jdh6t',
      tokenId: 'btc',
      transactionHash: 'd307359bbc4d68542f2c9c2bce73094280ad304b7240715305fcb3f80323308d',
      transactionId: '17ae7be33a27ab9bee81b91428abca423824e68be8e944399809a5f0fe197c90',
      value: '0.00001545',
      voutIndex: 0,
      voutSpent: false
    }
  ]
}

In the response, you can see that the transaction identifiers (transactionHash AND transactionId), valueAND voutIndex they are defined for any unspent output, which can serve as input to build future Bitcoin transactions.

You can change the filters in the query to retrieve different data, for example, retrieving both unspent and spent outputs, or limiting the time range for which to retrieve data. For more information on these filters, refer to Request body. Requests to the AMB Query APIs are billed per request based on price tiers per million requests. You can view the latest news pricing information for each API to calculate the cost of requests to AMB Query.

Conclusion

In this post, we’ve outlined the fundamentals of the UTXO model made prevalent by Bitcoin, how UTXOs are critical to Bitcoin transactions, and how to retrieve UTXO data using AMB Query. For more information about the AMB query, see What is Amazon Managed Blockchain (AMB) Query? To learn more about other managed blockchain offerings, see Blockchain operated by Amazon.

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 consortium-led private blockchain solutions and public blockchain use cases such as NFTs and DeFi, Forrest helps clients identify and implement high-impact blockchain solutions.

Fuente

Leave a Reply

Your email address will not be published. Required fields are marked *

Información básica sobre protección de datos Ver más

  • Responsable: Miguel Mamador.
  • Finalidad:  Moderar los comentarios.
  • Legitimación:  Por consentimiento del interesado.
  • Destinatarios y encargados de tratamiento:  No se ceden o comunican datos a terceros para prestar este servicio. El Titular ha contratado los servicios de alojamiento web a Banahosting que actúa como encargado de tratamiento.
  • Derechos: Acceder, rectificar y suprimir los datos.
  • Información Adicional: Puede consultar la información detallada en la Política de Privacidad.

Trending

Exit mobile version