<p>Looking only at what you quote and describe, it seems to me that BlockSci is inspecting the <a href="https://bitcoin.stackexchange.com/a/120947/5406"><code>locktime</code> field</a> of transactions.</p>
<p>They appear to be inferring that an output may be a change output, if both the transaction that created an output and the transaction that spent the output use <a href="https://bitcoin.stackexchange.com/q/48384/5406">anti-fee sniping</a>. This seems somewhat silly to me, since anti-fee sniping is implemented by more than one wallet and this would also count e.g. if a user sends from Bitcoin Core to Electrum or if one Bitcoin Core user sent to another.</p>
<p>In a way, this is a primitive form of trying to recognize the wallet type and use that for change detection. There are however much stronger indicators for change outputs on Bitcoin Core.</p>

CC BY-SA 4.0
2024-02-19T05:38:00.640Z
Given the rest of the heuristics they use are more sensible, this heuristic seems as you put it "silly". Is there any other interpretation you can think of regarding the "output has been spent and it matches this transaction’s locktime behavior"? Because if it is like you suggest, even relatively unreliable heuristics like "the change address is always the last output" seem more sensible.
user2334659
CC BY-SA 4.0
2024-02-19T07:17:01.207Z
Well, in combination with the other outputs having different behavior that would work, but just by itself it’s a bit thin. There is a bunch of heuristics to describe change outputs here: https://en.bitcoin.it/wiki/Privacy#Change_address_detection, the anti-fee sniping behavior would be an example for wallet fingerprinting.
Murch
CC BY-SA 4.0
2024-02-19T08:32:49.150Z
I see, so it is saying that if my wallet implements anit-fee sniping but yours does not, then the output that is in future involved in a transaction that has anti-fee sniping must be from my wallet (therefore change). But if we both implement anit-fee sniping then this heuristic fails, right?
user2334659
CC BY-SA 4.0
2024-02-18T20:28:52.983Z
2024-02-18T20:28:52.983Z
Murch
<p>I know that Blocksci is no longer being actively developed but I was reading through some of the documentation about identifying change addresses and came across this:</p>
<pre><code>change.locktime = &lt;blocksci.heuristics.change.ChangeHeuristic object&gt;

    Bitcoin Core sets the locktime to the current block height to prevent fee sniping.
    If an output has been spent and it matches this transaction’s locktime behavior, it is 
    possibly the change output. (This heuristic will return unspent outputs as potential 
    candidates.)

</code></pre>
<p>source: <a href="https://citp.github.io/BlockSci/reference/heuristics/change.html#blocksci.heuristics.change.power_of_ten_value" rel="nofollow noreferrer">https://citp.github.io/BlockSci/reference/heuristics/change.html#blocksci.heuristics.change.power_of_ten_value</a></p>
<p>My understanding is that locktime is usually set to the current block + 1 in order to prevent a fee sniping attack conducted by miners where they remine the current block but with higher fee transactions.</p>
<p>However, I am struggling to understand how Blocksci makes the connection between locktime and whether an output is change. Is it saying that if the transaction locktime is say 100,000 and one particular output also has a locktime of 100,000 then it may be the change output? But why? If I have a change output I might not necessarily want to spend it straight away so why would the locktime be the same as for the initial transaction?</p>

CC BY-SA 4.0
2024-02-18T08:50:12.420Z
The `locktime` field is on the transaction, not on a specific output.
Murch
CC BY-SA 4.0
2024-02-18T09:41:30.683Z
I assume that the Blocksci documentation is referring to Check Lock Time Verify (CLTV) which is a per output time lock. Or are they referring to the locktime of the transaction and then the locktime of the next transaction that spends the output in question.
user2334659
CC BY-SA 4.0
2024-02-18T20:18:17.590Z
At least the quoted code comment appears to be referring to Bitcoin Core’s [anti-fee sniping](https://bitcoin.stackexchange.com/q/48384/5406) behavior which makes use of the `locktime` field on the transaction.
Murch
<change><output><locktime>
Identifying change addresses by locktime?
user2334659
# Identifying change addresses by locktime?

(Asked by: username_0 on 2024-02-18)

I know that Blocksci is no longer being actively developed but I was reading through some of the documentation about identifying change addresses and came across this:

```
change.locktime = <blocksci.heuristics.change.ChangeHeuristic object>

    Bitcoin Core sets the locktime to the current block height to prevent fee sniping.
    If an output has been spent and it matches this transaction’s locktime behavior, it is 
    possibly the change output. (This heuristic will return unspent outputs as potential 
    candidates.)

```

source: <https://citp.github.io/BlockSci/reference/heuristics/change.html#blocksci.heuristics.change.power_of_ten_value>

My understanding is that locktime is usually set to the current block + 1 in order to prevent a fee sniping attack conducted by miners where they remine the current block but with higher fee transactions.

However, I am struggling to understand how Blocksci makes the connection between locktime and whether an output is change. Is it saying that if the transaction locktime is say 100,000 and one particular output also has a locktime of 100,000 then it may be the change output? But why? If I have a change output I might not necessarily want to spend it straight away so why would the locktime be the same as for the initial transaction?

**Tags:** change, output, locktime

> **Comments:**
> **username_1**: The `locktime` field is on the transaction, not on a specific output.  
> **username_0**: I assume that the Blocksci documentation is referring to Check Lock Time Verify (CLTV) which is a per output time lock. Or are they referring to the locktime of the transaction and then the locktime of the next transaction that spends the output in question.  
> **username_1**: At least the quoted code comment appears to be referring to Bitcoin Core’s [anti-fee sniping](https://bitcoin.stackexchange.com/q/48384/5406) behavior which makes use of the `locktime` field on the transaction.  

---

## 1 answers

### Answer by username_1 on 2024-02-18. Score: 1 | Accepted answer

Looking only at what you quote and describe, it seems to me that BlockSci is inspecting the [`locktime` field](https://bitcoin.stackexchange.com/a/120947/5406) of transactions.

They appear to be inferring that an output may be a change output, if both the transaction that created an output and the transaction that spent the output use [anti-fee sniping](https://bitcoin.stackexchange.com/q/48384/5406). This seems somewhat silly to me, since anti-fee sniping is implemented by more than one wallet and this would also count e.g. if a user sends from Bitcoin Core to Electrum or if one Bitcoin Core user sent to another.

In a way, this is a primitive form of trying to recognize the wallet type and use that for change detection. There are however much stronger indicators for change outputs on Bitcoin Core.

> **Comments:**
> **username_0**: Given the rest of the heuristics they use are more sensible, this heuristic seems as you put it "silly". Is there any other interpretation you can think of regarding the "output has been spent and it matches this transaction’s locktime behavior"? Because if it is like you suggest, even relatively unreliable heuristics like "the change address is always the last output" seem more sensible.  
> **username_1**: Well, in combination with the other outputs having different behavior that would work, but just by itself it’s a bit thin. There is a bunch of heuristics to describe change outputs here: https://en.bitcoin.it/wiki/Privacy#Change_address_detection, the anti-fee sniping behavior would be an example for wallet fingerprinting.  
> **username_0**: I see, so it is saying that if my wallet implements anit-fee sniping but yours does not, then the output that is in future involved in a transaction that has anti-fee sniping must be from my wallet (therefore change). But if we both implement anit-fee sniping then this heuristic fails, right?  

---

