<p>Using a separate keychain for change addresses is one of those things where as a wallet author you think &quot;wait a minute.. But that doesn't make sense!&quot; and end up implementing it anyways because moving away from the standards would put too much cost on your users.</p>
<p>Technically you could have all the advantages of using a separate keychain by enforcing a simpler standard which doesn't require to backup two descriptors. For instance: use even derivation index for receive addresses and odd ones for change addresses.</p>
<p>I disagree with most of the advantages you listed of using 2 descriptors:</p>
<ul>
<li>you should not blindly trust unconfirmed coins received on change addresses, you always need to check if the transaction that created them is in fact entirely in your control. Otherwise someone can trivially double spend you by sending an unconfirmed transaction paying to one of your change addresses;</li>
<li>regarding privacy from public Electrum servers, wallets which use a different keychain for receive addresses use a unhardened derivation index to differentiate between change and receive addresses. So an Electrum server having your xpub for the receive keychain can trivially derive all your change addresses too. In any case if you give away all your receiving addresses to someone figuring out your change coins from your onchain activity is trivial in the first place;</li>
<li>you don't need to keep state, you can just use a better standard: the odd vs even indexes trick gives you this property;</li>
<li>same, this doesn't need two keychains, just a smarter standard.</li>
</ul>
<p>As per your questions:</p>
<ul>
<li>I think the main reason to keep the two-keychains standard is because <strong>everyone else is using it</strong>! That is if you want to introduce your new smarter standard, your user who want to import his descriptor backup in <strong>any other wallet</strong> who'd still be using the two-keychains standard might end up reusing a bunch of addresses. Since we now have <a href="https://github.com/bitcoin/bips/blob/master/bip-0389.mediawiki" rel="nofollow noreferrer">BIP389</a> to mitigate the cost of having to backup two keychains, the cost of introducing a new standard is not worth the risk to the user;</li>
<li>I am not aware of any coin selection algorithm where a coin is treated differently if it's a change output (except if unconfirmed of course). And i don't think it's relevant for the matter of using two keychains or not;</li>
<li>I don't have much historical info. Maybe <a href="https://github.com/wizardsardine/liana/issues/18" rel="nofollow noreferrer">this Liana issue</a> from two years ago where i pondered using a new better standard for handling change addresses and ended up settling on using BIP389 for the reason detailed above. Another argument given there is &quot;be explicit in the descriptor itself how to derive receive/change addresses&quot;.</li>
</ul>

CC BY-SA 4.0
2024-08-08T19:50:37.963Z
2024-08-08T19:50:37.963Z
Antoine Poinsot
<p>I'm trying to make sure I understand the question: <strong>Why Do We Use Change Descriptors when Building Wallets?</strong></p>
<p>Context: I work on the <a href="https://bitcoindevkit.org/" rel="nofollow noreferrer">Bitcoin Development Kit</a>, where one of our core types is the <code>Wallet</code> type. It has typically required 2 descriptors (an external descriptor and a change (internal) descriptor). This idea is standard practice and used widely in the industry, but when pressing myself to write about it in our <a href="https://bitcoindevkit.github.io/book-of-bdk/" rel="nofollow noreferrer">documentation</a>, I was left wondering if I really knew why this was the case. Furthermore, users that request the Wallet be usable with only one descriptor had strong opinions about how the practice of using 2 descriptors was maybe outdated and not required under certain circumstances. One user told us that it was a mistake to double down on the internal/external descriptor schism, and that it was a relic of the past of people that use electrum wallets.</p>
<p>As a library maintainer, this is the sort of thing I want to have a solid grasp on. I'm also leading our documentation efforts, and plan on including a page on this.</p>
<p>Here is my current understanding and questions.</p>
<h4>Advantages of using 2 descriptors</h4>
<ul>
<li>It potentially allows you accept 0-conf coins when they are coming to change addresses, because you must have been the one to initiate that transaction and will not double-spend yourself.</li>
<li>Privacy when using a public electrum server: in cases where you might send a whole xpub to an electrum server, you're better off not giving up your whole keychain but only half? (at this point it seems trivial to reconstruct transaction history but still, I guess not giving it out is better than doing it).</li>
<li>Having only 1 descriptor forces you to keep track of addresses you've given out when building transactions, because otherwise your wallet might use an external address already given out as change, and if this address given out to someone ends up being used by them, you'll double transactions at that address.</li>
<li>In cases where a wallet is recovered, change addresses can still be labeled as change.</li>
</ul>
<h3>Questions I Still Have</h3>
<ul>
<li>Are there other pitfalls users of single-descriptor wallets should be aware of in the case where wallets use more private sync tools like private Electrum servers and CBF, and using modern wallet practices that never give out repeat addresses?</li>
<li>Does the &quot;change&quot; keychain come into coin selection at all in Core? For example, are there algos for coin selection where knowing if a UTXO is part of the change keychain rather than the external keychain matters? If so, how does it come into play?</li>
<li>Any other historical info that's good to know and take into consideration for builders of wallet would be appreciated.</li>
</ul>
<p>Thank you!</p>

CC BY-SA 4.0
2024-08-08T19:30:09.330Z
Hi, it would be helpful if you added links to the feedback from you got from these users with strong opinions.
Antoine Poinsot
CC BY-SA 4.0
2024-08-09T12:18:24.470Z
There were some more discussions on Discord servers, but here is one issue related to this: https://github.com/bitcoindevkit/bdk/issues/1511
thunderbiscuit
<wallet><bip32-hd-wallets>
Understanding the advantages/pitfalls of using one/two keychains for wallets
thunderbiscuit
# Understanding the advantages/pitfalls of using one/two keychains for wallets

(Asked by: username_0 on 2024-08-08)

I'm trying to make sure I understand the question: **Why Do We Use Change Descriptors when Building Wallets?**

Context: I work on the [Bitcoin Development Kit](https://bitcoindevkit.org/), where one of our core types is the `Wallet` type. It has typically required 2 descriptors (an external descriptor and a change (internal) descriptor). This idea is standard practice and used widely in the industry, but when pressing myself to write about it in our [documentation](https://bitcoindevkit.github.io/book-of-bdk/), I was left wondering if I really knew why this was the case. Furthermore, users that request the Wallet be usable with only one descriptor had strong opinions about how the practice of using 2 descriptors was maybe outdated and not required under certain circumstances. One user told us that it was a mistake to double down on the internal/external descriptor schism, and that it was a relic of the past of people that use electrum wallets.

As a library maintainer, this is the sort of thing I want to have a solid grasp on. I'm also leading our documentation efforts, and plan on including a page on this.

Here is my current understanding and questions.

#### Advantages of using 2 descriptors

* It potentially allows you accept 0-conf coins when they are coming to change addresses, because you must have been the one to initiate that transaction and will not double-spend yourself.
* Privacy when using a public electrum server: in cases where you might send a whole xpub to an electrum server, you're better off not giving up your whole keychain but only half? (at this point it seems trivial to reconstruct transaction history but still, I guess not giving it out is better than doing it).
* Having only 1 descriptor forces you to keep track of addresses you've given out when building transactions, because otherwise your wallet might use an external address already given out as change, and if this address given out to someone ends up being used by them, you'll double transactions at that address.
* In cases where a wallet is recovered, change addresses can still be labeled as change.

### Questions I Still Have

* Are there other pitfalls users of single-descriptor wallets should be aware of in the case where wallets use more private sync tools like private Electrum servers and CBF, and using modern wallet practices that never give out repeat addresses?
* Does the "change" keychain come into coin selection at all in Core? For example, are there algos for coin selection where knowing if a UTXO is part of the change keychain rather than the external keychain matters? If so, how does it come into play?
* Any other historical info that's good to know and take into consideration for builders of wallet would be appreciated.

Thank you!

**Tags:** wallet, bip32-hd-wallets

> **Comments:**
> **username_1**: Hi, it would be helpful if you added links to the feedback from you got from these users with strong opinions.  
> **username_0**: There were some more discussions on Discord servers, but here is one issue related to this: https://github.com/bitcoindevkit/bdk/issues/1511  

---

## 1 answers

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

Using a separate keychain for change addresses is one of those things where as a wallet author you think "wait a minute.. But that doesn't make sense!" and end up implementing it anyways because moving away from the standards would put too much cost on your users.

Technically you could have all the advantages of using a separate keychain by enforcing a simpler standard which doesn't require to backup two descriptors. For instance: use even derivation index for receive addresses and odd ones for change addresses.

I disagree with most of the advantages you listed of using 2 descriptors:

* you should not blindly trust unconfirmed coins received on change addresses, you always need to check if the transaction that created them is in fact entirely in your control. Otherwise someone can trivially double spend you by sending an unconfirmed transaction paying to one of your change addresses;
* regarding privacy from public Electrum servers, wallets which use a different keychain for receive addresses use a unhardened derivation index to differentiate between change and receive addresses. So an Electrum server having your xpub for the receive keychain can trivially derive all your change addresses too. In any case if you give away all your receiving addresses to someone figuring out your change coins from your onchain activity is trivial in the first place;
* you don't need to keep state, you can just use a better standard: the odd vs even indexes trick gives you this property;
* same, this doesn't need two keychains, just a smarter standard.

As per your questions:

* I think the main reason to keep the two-keychains standard is because **everyone else is using it**! That is if you want to introduce your new smarter standard, your user who want to import his descriptor backup in **any other wallet** who'd still be using the two-keychains standard might end up reusing a bunch of addresses. Since we now have [BIP389](https://github.com/bitcoin/bips/blob/master/bip-0389.mediawiki) to mitigate the cost of having to backup two keychains, the cost of introducing a new standard is not worth the risk to the user;
* I am not aware of any coin selection algorithm where a coin is treated differently if it's a change output (except if unconfirmed of course). And i don't think it's relevant for the matter of using two keychains or not;
* I don't have much historical info. Maybe [this Liana issue](https://github.com/wizardsardine/liana/issues/18) from two years ago where i pondered using a new better standard for handling change addresses and ended up settling on using BIP389 for the reason detailed above. Another argument given there is "be explicit in the descriptor itself how to derive receive/change addresses".


---

