Your approach requires to have the wallet policy at hand, whereas mine can be used on any wallet-policy-compatible descriptor. I think it’s a nice property to have.
The _
placeholder would be a wallet policy feature, so expecting to have the wallet policy seems a natural assumption, and I don’t think the standard should be optimized for “not having it”.
Other orders push code complexity to the hardware signer, that will now have to add more code to parse the “descriptor template” just to find the right order of keys.
Finally, a wallet policy might have the same @i
multiple times (especially on taproot); in your version you’d either be concatenating the corresponding pubkey multiple times, or would need a stateful parser to skip the ones that have been seen already.
An issue with using left-to-right is that it makes sortedmulti_a
depend on the order of keys added now.
A sortedmulti_a(k,KEY_1,KEY_2,...,KEY_N)
descriptor is identical to sortedmulti_a(k,KEY_N,KEY_N-1,...,KEY_1)
, but this will create a different chaincode with this approach.
I agree with @andrewtoth that it would be most beneficial if the chain code would be derived from the XPUBs independently of their order. It would alleviate the issue of whether the wallet policy order or the descriptor order should be used, as well as the mentioned surprising behavior with sortedmulti_a
.
I see three possible approaches to achieve this:
- Sort the XPUBs, then hash the sorted and concatenated list.
- Hash each XPUB, then XOR the results. (Problem: repeated XPUBs would cancel out. I suppose that may happen in more complex descriptors/policies.)
- Hash each XPUB, then add the results mod 2^256. (Repeated XPUBs don’t cancel out.)
Instead of XPUBs it may be simpler to work with only a part of the XPUB, i.e. the compressed public key, as @AntoineP did, or with the chain code. In fact, I think the chain code could be used directly in options 2 or 3 without hashing it, i.e. just a XOR-sum of the chain codes or a mod 2^256 sum of the chain codes. That would make for a very simple implementation. A potential risk of not hashing is that a malicious participant could craft the chain code in their XPUB so that it cancels out with the other participants to force the result to a desired value. However, such a malicious participant could just as well publish the dummy XPUB to achieve the same goal, so I don’t see a problem with a simple sum of the chain codes.
To ensure smooth interoperability amongst different wallets, it would be very helpful if we could agree on standardizing unspend()
with deterministic HEXCHAINCODE
.
I think publishing the dummy XPUB out of band to interested parties is not exactly the same goal as making the dummy XPUB obvious to any observer of the transaction.