Blockstream / esplora

Explorer for Bitcoin and Liquid
MIT License
986 stars 394 forks source link

Question on API tx order for same block & low priority suggestions #165

Open ildarmgt opened 4 years ago

ildarmgt commented 4 years ago

Hi, thanks for great API and explorer.

When using /api/address/:address/txs/chain or /block/:hash/txs is the order API lists tx that were in same block always based on order within that block?

Documentation does mention sorted with newest first but since blocks confirm its tx at same time, I wasn't sure.

I would like to use some logic that depends on placement within the block for tie breaking beyond block_height, and I imagine various embedded protocols could use too.

Requesting possibly the entire block's worth of tx with /block/:hash/txs[/:start_index] would be a lot of redundant info just to find order or to get txid's within a block for merkle proof. Is it possible to find the order of my tx's by txid within same block another way?

I just wanted to get a confirmation on the order used in API but possible suggestions:

Thanks!

shesek commented 4 years ago

is the order API lists tx that were in same block always based on order within that block?

For GET /block/:hash/txs, yes - it will be the same order as they appear within the block.

For GET /api/address/:address/txs/chain, they will be sorted based on block height in descending order, but there's no guarantee about the order of transactions within the same block.

endpoint that has only provides all txid for a block

This already exists, GET /block/:hash/txids.

if people want to provide more confidence in api results, is it possible to have an endpoint for only the hashes needed for a specific txid merkle proof to the root in the header?

This exists too, see GET /tx/:txid/merkle-proof (Electrum's merkle SPV proof format) and GET /tx/:txid/merkleblock-proof (bitcoind's merkleblock SPV proof format -- this was added very recently and still not available on the live API).


You can find out the position of the transaction within the block using two methods:

  1. Get the list of txids from /block/:hash/txids and look for your txid in the list.

    For example, in JavaScript: fetch('https://blockstream.info/api/block/<your-blockhash>/txids').then(r => r.json()).then(txids => console.log(txids.indexOf("<your-txid>")))

  2. But there's an even easier way - the Electrum SPV merkle proof includes the position of the transaction within the block, under the pos field.

    For example, in JavaScript: fetch('https://blockstream.info/api/tx/<your-txid>/merkle-proof').then(r => r.json()).then(proof => console.log(proof.pos))

landabaso commented 1 year ago

I am writing to follow up. I have encountered the same uncertainty and I believe it could be beneficial to all users if this aspect was clarified in a bit more detail in the docs.

For context, while working with transactions to compute the UTXOs of a scriptPubKey, I had initially assumed that the transaction order would be maintained even when they belong to the same block.

See these transactions: https://blockstream.info/api/address/19a7HGg32ecPQo49rDeM2NSFJHPqrwSJto/txs

I anticipated new transactions to be listed first based on a 'newest first' order. However, when I observed two transactions from the same block (block height: 427572), the ordering was not respected.

These are the transaction IDs:

be443ef0b78d98719741ce9f4811c152dc8644b9beb50b5713a257d8d2acd1ee 226a267701ccf308aed00835e5c0a7121ba781a0abfddaa6f10914e841a11217

I expected 226a267701ccf308aed00835e5c0a7121ba781a0abfddaa6f10914e841a11217 to be older than be443ef0b78d98719741ce9f4811c152dc8644b9beb50b5713a257d8d2acd1ee. However, it seems the older transaction spends from an output of the 'newer' one, which contradicts the chronological order of transactions.

See:

https://blockstream.info/tx/226a267701ccf308aed00835e5c0a7121ba781a0abfddaa6f10914e841a11217

While this isn't a problem per se, it introduces a level of ambiguity that could affect how developers parse responses to compute UTXOs.

Thanks!

EDIT: Can we assume that the responses are deterministic? This means that even if the order of transactions is wrong within the same block, it won't change when new transactions are added.