Just a heads-up:
I was running an experiment and I've got a question that I can't seem to figure out on my own.
I'm gonna share some real data here (nothing sensitive like private keys). I won't be using this wallet again.
So here's what I did:
I set up a completely isolated computer with Bitcoin Core, and made a wallet there.
I got an address: bc1qfrmthac4es7fpw5yhl7cu9kvedsgj7levwxv5g and sent some sats to it.
Next, I backed up the encrypted wallet.dat file onto a different USB stick.
I also used the listdescriptors command to get the wallet descriptors:
Then I tried to import those descriptors into Sparrow wallet to create a watch-only wallet.
Sparrow didn't let me add two descriptors in one wallet, so I had to look it up and found out I could import the descriptor like this:
Check out the <0;1> in the path; I think it's meant to get both receiving and change addresses.
To my surprise, it seemed to work fine, but...
I then thought it would be good to import the descriptors back into my full node (Bitcoin Core) for a watch-only wallet there too, so I went ahead and did that:
Now here's where it gets weird:
In Bitcoin Core, when I create a new address, it looks right, but the Receive addresses there seem to be what Sparrow labels as Change addresses.
So simply put:
Bitcoin Core -> Receive Address = Sparrow -> Change Address
My question is:
Even if the answer is something basic like I messed up the descriptors while importing or maybe Sparrow doesn't handle the <0;1> properly, what could be going on?
Question about Change and Receiving Addresses
7 replies 426 views
SwiftMinerSenior Member
Posts: 259 · Reputation: 1036
#2Jul 8, 2017, 09:29 PM
I think the whole thing actually comes down to how different wallets interpret the instructions for generating addresses. Bitcoin Core actually separates receiving and change addresses based on specific paths. However, when using a combined instruction (<0;1>) in another wallet like Sparrow it may not make consider same distinctions.
Think of it kinda like giving directions. Bitcoin Core follows the directions exactly, while Sparrow might take a slightly different route even with the same map. This discrepancy can actually lead to differences in how addresses are generated and displayed. Don't forget the wallet considers which would be displayed as change and which as receiving.
yield_forkFull Member
Posts: 162 · Reputation: 728
#3Jul 9, 2017, 12:01 AM
Try importing only the receiving descriptor in Sparrow Wallet, like this:
You don't need to import the change descriptor, Sparrow wallet will automatically calculate the change path using the extended public key.
See, in my case (using another descriptor I just generated for testing) Sparrow correctly imported both receiving and change addresses from the descriptor containing the xpub:
Edit: Descriptor I used for this test for anyone who wants to compare the addresses:
Thank you both for the answers, it's true that it worked when I changed my descriptor to one that didn't include <0;1> at the end.
I am very happy the issue is resolved, and it looks like the post I randomly found on Google was wrong. I am trying to find it for reference, but I can't...
Anyway, again, thank you both.
I will lock the topic soon.
gr3g.0rbitHero Member
Posts: 1025 · Reputation: 2646
#5Jul 9, 2017, 02:04 AM
I think it's correct but a bug is somehow causing the internal and external chain reversed in some scenarios.
It's actually inconsistent;
I can reproduce it in some "MultiPath descriptor", some descriptors work as intended, some result with the same behavior.
I used the latest release version v2.1.3.
So, you may have found an issue with Sparrow Wallet's implementation of BIP389.
It's worth reporting as a new issue if it's not posted already: github.com/sparrowwallet/sparrow/issues
I definitely will, but let's just be sure first. Because it's possible that I may have screwed up...
Let me give some additional context, because there must be an issue with my Core watch-only wallet (because of my mistake) and not with my Sparrow watch-only wallet.
So, I am on my watch-only wallet (on Core) and I am running > listdescriptors
It produces this:
It confuses me that:
(a) it says "active": false on the first descriptor
(b) I was expecting that the first descriptor (/0/*) should be saying "internal": false and the second one (/1/*) should be saying "internal": true
It looks like I may have messed up when creating the watch-only wallet...
Edit: The commands I 've written in my OP may be correct but when I actually submitted the commands and spotted the issue I may have made a mistake. This inconsistency from my part, could be happening because I didn't copy-paste the exact commands I used, but instead I re-wrote them (probably correctly the second time). So I may have written them wrong at first when I created the core watch-only wallet, but correctly the second time when I created the OP.
gr3g.0rbitHero Member
Posts: 1025 · Reputation: 2646
#7Jul 9, 2017, 02:40 PM
This happens if you've imported a same-script descriptor with the same "internal" flag that has its "active" flag set to true.
The older descriptor will then be marked false.
Can you try it again in another watch-only wallet?
Perhaps it's the case above where you forgot to include the "internal" flag.
Anyways, here's an example in Sparrow where it successfully imported a "MultiPath descriptor":
Receiving Addresses:
deriveaddresses "wpkh([17cedf16/84h/0h/0h]xpub6CpCrfxag5Dg1mnpf8eZrMgfY8igb9PZrPgEcAKqdAn486pbAYStBsYz3xgPDc35VJVG45Ntjwr jk3rj7deonTzq1broC77ipsVWKVhsCi5/0/*)#395jh6ks" "[0,4]"
Change Address Index 0:
".../1/*)#q33n20xg" "[0,0]"
Import to Sparrow:
You can see that the instructions you found on Google works.
Then, I've just tested the descriptor that you've provided in the OP and it seem to be working normally.
The instance where I reproduced the reversed internal flag in Sparrow may have been a misunderstanding on Bitcoin Core's getaddressinfo "ischange: true" flag of a non-active descriptor's receiving address.
Sparrow's BIP389 import seem to be working as intended.
Sorry for the small merit amount, I am out of sMerit. Your answer is very helpful.
Indeed, I tried it and it works perfectly. I have messed up with the descriptors. I have set the internal flag wrong. Now, I 've tried it in another wallet and it works like a charm.
I think it's time for me to lock the thread. Again, thank you!
?Reply
Sign in to reply to this topic