One Bitcoin transaction, three allocation assumptions, side by side
Forensia shows how proportional, input-order and reverse-order allocation each split one input across a transaction’s outputs. These are accounting assumptions. None is an observed path or evidence of ownership.
A Bitcoin transaction often takes in several coins and pays out several coins. When one of the incoming coins is the one you care about, the natural question is where it went. Bitcoin does not answer that. Inside a transaction all the incoming value is pooled, and the outputs are paid from the pool.
Any statement such as "70 percent of it went to this output" therefore rests on a rule somebody chose. Different rules give different answers for the same transaction. Forensia now shows three common rules next to each other for a single transaction, so you can see how much a tracing result depends on the rule.
The comparison is a sensitivity check. It does not say which rule is right, it does not show an actual path, and it says nothing about who owns any address.
#Plain languagePouring two jugs into one bowl
Pour a jug of 60 and a jug of 40 into one bowl. Then fill a glass of 30, a glass of 60, and leave 10 behind as the fee. How much of the first jug is in each glass? The water is mixed. You can only answer by adopting a convention.
| Convention | Glass of 30 | Glass of 60 | Fee of 10 |
|---|---|---|---|
| Proportional: every destination gets the same share of the first jug | 18 | 36 | 6 |
| Input order: the first jug is used up first | 30 | 30 | 0 |
| Reverse input order: the second jug is used up first | 0 | 50 | 10 |
Each row adds up to 60, the size of the first jug. Each row is a complete alternative. The three rows are not three findings to combine. The numbers are made up to show the arithmetic. The test suite uses the same example.
#How it worksOpening the comparison on a Bitcoin transaction
- Look up a confirmed Bitcoin transaction by its transaction ID.
- On Overview, open Compare allocation assumptions.
- Read the Reference line. It names the input used as the reference and its value in satoshis. It is the largest input, chosen by value, not by suspicion.
- Read the table. Each row is a destination: Output 1, Output 2 and so on, then Transaction fee. The columns are Recorded value, Proportional, Input order and Reverse input order.
- Choose Inspect transaction source to open the exact source record the figures came from.
If the comparison cannot be made, the section says why and shows no table. If a later local evidence check finds that the displayed inputs or outputs disagree with the saved response, the section is retitled Allocation comparison needs review and the table is hidden.
A real case from local review, transaction 0d3f47806931b388a70a64c156471881ee3a779b622221416a854c782f45cf91 in block 800000, has two inputs of 629,189,407 and 2,240,260 satoshis, eleven outputs and a fee of 34,431 satoshis. The larger input is the reference. Four of its twelve rows:
| Destination | Recorded | Proportional | Input order | Reverse input order |
|---|---|---|---|---|
| Output 1 | 4,915,512 | 4,898,073 | 4,915,512 | 2,675,252 |
| Output 10 | 1,969,851 | 1,962,862 | 154,022 | 1,969,851 |
| Output 11 | 390,000 | 388,616 | 0 | 390,000 |
| Transaction fee | 34,431 | 34,308 | 0 | 34,431 |
Output 11 receives nothing from the reference under one rule and its whole value under another. Each column still totals 629,189,407.
#Technical detailInputs, ordering, rounding and the conditions for abstaining
Source
The figures come from one request to an Esplora-style Bitcoin index: GET /tx/ followed by the transaction ID. The default source is the mempool.space public API, or a configured self-hostable equivalent. The comparison makes no additional request. The fields read are txid, status.confirmed, status.block_height, status.block_hash, fee, each vin entry’s prevout.value and is_coinbase flag, and each vout entry’s value and address or script.
The comparison is computed from the activity rows built from that response. Rows carry positional IDs, utxo-input:txid:index and utxo-output:txid:index, so order is taken from the transaction and not from display order.
Preconditions
No allocation is calculated unless every one of these holds:
- Bitcoin mainnet, a transaction lookup, and a 64-character hex transaction ID.
- The transaction is confirmed, with a block height and block hash.
- Exactly one captured transaction source record matches the request for this transaction ID.
- The input count and the output count are each between 1 and 16.
- There is exactly one row for every position, numbered from zero, with no gaps and no duplicates.
- Every row is a successful UTXO row for this transaction at the captured block height, is not flagged as having conflicting source records, and references the transaction source.
- No input is a coinbase (newly mined) input, and no input has an unknown previous output.
- Every amount is a whole number of satoshis no greater than 2,100,000,000,000,000.
- Total inputs minus total outputs equals the reported fee exactly.
The reference input
The reference is the entire largest input. The scan replaces the current choice only on a strictly greater value, so the lowest index wins a tie. That input’s whole value is the reference amount. Every other input contributes zero to it.
The three models
The fee is appended as one more destination after the last output, so value that went to miners is not silently assigned to recipients.
| Column | Model in the core library | Rule |
|---|---|---|
| Proportional | haircut | The reference is spread over all outputs and the fee in proportion to their values. Integer rounding follows output order. |
| Input order | fifo | Inputs are consumed in recorded order and fill outputs in recorded order. The fee is filled last. |
| Reverse input order | lifo | Input order is reversed. Output order stays the same and the fee is still last. |
All arithmetic is in integer satoshis with no floating point. Every model conserves the reference amount: its column sums to the reference exactly, fee included. With a single input the three columns are identical, because there is nothing to order and nothing to dilute. The first review case, f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16, behaves that way: one input of 5,000,000,000 satoshis, outputs of 1,000,000,000 and 4,000,000,000, zero fee, same answer in every column.
No change-output guess feeds into this. All outputs are treated alike.
Checking the displayed rows against the saved response
On local and private profiles, Sources, then Capture integrity & local evidence, then Check local evidence reads the saved transaction response from the browser vault after its size and SHA-256 are verified. It compares the transaction ID, confirmation state, input and output counts, fee, block height and block hash, and then each row: index, participant, integer value, status and source reference. It finally requires outputs plus fee to equal inputs.
| Condition | Outcome |
|---|---|
| Every row, the fee and the block match | Bitcoin inputs and outputs match saved response |
| Any compared field differs | Conflict. The table is hidden. Report, saving the result and combined raw export are blocked. |
| Body missing or expired, unconfirmed, coinbase or missing previous output, or some rows not displayed | Incomplete. No complete match is claimed. |
| Response over 1 MiB, more than 16 inputs or outputs, or more than 512 activity rows | Check limit. Left unchecked. |
A contradiction in a row that was checked is reported even if another row is missing. In one test an input and an output are both altered so the totals still balance. The response hash passes and the row comparison still catches it.
#LimitsAssumptions are not paths, and not ownership
- The reference is always the whole largest input. You cannot pick another input or part of one, and being the reference does not mark it as stolen or suspicious.
- Input order is the order recorded in the transaction. It is not a claim about time, intent or who controlled the inputs.
- When the columns agree, that is not proof of a path. When they diverge, that shows the result is sensitive to the assumption.
- The comparison covers one transaction. Modeled amounts are not carried across hops and never become edges in the Connections view.
- Transactions with more than 16 inputs or outputs, coinbase transactions and unconfirmed transactions are not compared.
- A match in the saved-response check is consistency with one provider’s response. Previous-output values, scripts and consensus rules are not verified independently, and later spends and wallet totals are outside it.
- Only two real transactions were checked end to end in local review. That is not a broad multi-input test corpus.
- No address is grouped with another, and no owner is identified, by anything in this view.