I have heard about output descriptors or wallet descriptors. It is not clear to me what they are. What do they allow me to do? How does that improve my experience using Bitcoin?
An output descriptor (note that output descriptor and wallet descriptor refer to the same thing) is a human readable string that represents an output script (a scriptPubKey) and everything needed in order to solve¹ for that script. Descriptors also have a bech32-like checksum which allows for the descriptor to be given to others with less risk of accidentally mistyping or losing some characters in the descriptor string.
Descriptors are unambiguous as to the public keys to use (derivation paths for extended keys are explicit) and the scripts to use. This makes them suitable for importing to other wallets without confusion. In contrast, traditional import mechanisms support only keys with special versioning to indicate the scripts to produce, and don't provide the derivation paths. This creates a situation where a user imports an extended key into a wallet but is unable to see their addresses because that wallet uses a different derivation path than the original wallet. Descriptors avoids this issue entirely by specifying the derivation paths (if any) and the scripts to produce.
A descriptor wallet is one which stores output descriptors and uses them to create addresses and sign transactions. By abstracting away address creation and transaction signing to a largely standalone module, such wallets can upgrade to using new address types much more easily.
For most users, the only visible effects will be in wallet import/export. Descriptors will only be shown during exporting, and descriptors should only be handled by the user when they want to import their wallet. Wallets that use descriptors internally shouldn't have any noticeable effect to the user.
¹: Solve - Solving a script means that one would be able to create a final scriptSig/witness with valid signatures if they had a private key. This means that all public keys and other scripts are available.
There are lots of address types (P2PKH, P2SH, P2WSH etc), some are multisigs, some are BIP32. Descriptors help the wallet software figure out what the address string actually is. If this is abstracted away from the user then the user doesn’t need to know but they are really useful for the wallet software. They let the wallet software figure out how to spend from it basically. You have some funds at an address, you import those keys to a new wallet, the descriptor helps the wallet figure out how it can spend from that address. If the existing wallet generated the address then the descriptor isn’t needed but if it didn’t it needs to know how to spend from it.
As a user, is there anything I need to do extra?
I don’t think so. Maybe the descriptor could be useful for the user to see in some cases if they want to know more about the funds in individual addresses or in individual UTXOs. But as I said if that is all abstracted away and the user just sees an overall balance they don’t need to do anything. Other than to upgrade to the new version of a wallet that uses descriptors
What data is needed to figure out the address type is stored in the seed? Or how is that managed?
The address type is not stored in the seed. That is private material that you’d need to know to spend from an address of any type. So the seed is generally referred to as the list of words you store that allow you to spend from any address in a HD wallet. A HD (hierarchical deterministic) wallet generates a tree of addresses that can all be spent from if you know that seed. However, you could have multiple HD wallets with different seeds and completely independent trees of addresses. Or you could have addresses that aren’t part of a HD tree and are just standalone addressses. So the descriptors help the wallet (or the technical user) keep track of what addresses are part of which HD trees, which addresses are standalone and not part of any HD tree, which are multisig etc etc. It can get very messy without descriptors.
I guess my question is how descriptors are stored?
You mean the location in the filesystem? Or the format in which it is stored? I’d need to check on these.
When a wallet looks at an address, how does it know which descriptor was used to generate it? Does it just go through all possible options and see if something matches, like what happens during during the initial discovery of used addresses?
If there is a descriptor e.g. wpkh this will tell the wallet what kind of address it is. If there isn’t a descriptor then sometimes the wallet will be able to recognize what kind of address it is and sometimes it won’t. If it is a pre-SegWit wallet then it won’t recognize bech32 addresses for example. With no descriptors and a HD tree of addresses then it will go through like 10 different addresses to assess if there are any funds before it gives up and assumes there are no more funds at any further addresses in the tree. If there is a descriptor you can literally tell the wallet don’t stop at 10 because I’ve got some funds sent to the 100th address in the tree.
What would be situations when there is a descriptor and when there isn’t one?
If the wallet that generated the addresses uses descriptors. If the wallet that generated the addresses doesn’t have descriptors implemented/doesn’t use descriptors then it doesn’t matter if new wallet you’re uploading keys to has implemented descriptors because it won’t receive any descriptors. For descriptors to be passed between two wallets the wallet that generated the addresses needs to use descriptors/have descriptors implemented and the wallet the addresses are being transferred to needs to recognize those descriptors.
So the wallet that generated the addresses needs to store them and users need to also back up the descriptors? Or at least have them available if they switch wallets?
Descriptors are like additional metadata to be stored with each address. If a wallet you are transferring to wants to take advantage of descriptors they need to receive the descriptor with the address. It is like handing over an address and a short description of that address rather than just the address and telling the new wallet to figure it out.
And if I don’t transfer the descriptors, I can still import the wallet and use it as normal? Or do I lose something?
Yeah you can throw away the descriptor at any point and not use it from that point forward. (Go back to a world before descriptors existed.) You only lose the benefits of descriptors that we’ve been discussing.
Anyone know of any wallets using descriptors as a default wallet creation option?
The Bitcoin Core wallet uses descriptors and I know others have it on their roadmap but not sure if any have implemented yet. It looks like River are using descriptors.
These questions were asked by members of the Bitcoin Design community.