[RFC] Explicit UTXO Selection in z_sendmany for Greater Control

Hi everyone,

I wrote a patch that adds an optional parameter to the z_sendmany RPC call for zcasd full node, allowing users to specify a list of unspent notes (UTXOs) that should be spent. I’d like to get your feedback on both the approach and its implications.

With the patch, the z_sendmany command accepts an additional (6th) parameter: an array of JSON objects. Each object specifies a txid and an outindex, uniquely identifying a UTXO or note to spend.

By letting users pick which UTXOs to spend, we give them finer control over their wallet’s behavior. This can be especially useful for managing coin consolidation or when dealing with coins that have particular histories.

As a practical example, consider an escrow service that receives payments from users. With explicit UTXO selection, the escrow can keep each payment separate. When conditions for the escrow are met, the service can then spend a particular UTXO or note without mixing it with others. This level of granularity can simplify bookkeeping and ensure that funds are handled precisely according to the escrow agreement.

The patch is available here:

Before I propose this patch to zcash developers, I’d love to hear your thoughts on this change. Are there any potential pitfalls or edge cases that I might have missed? Does the additional flexibility introduce any concerns regarding wallet usability or privacy that we should address?

Looking forward to your feedback.

Best regards,
Tomas Matejicek

4 Likes

@str4d and/or @nuttycom will probably have feedback

Note that zcashd is being deprecated in favor of zebrad and the wallet component will now be separate (zallet). However the RPC interface should be kept mostly unchanged.

2 Likes

I think that this kind of API is a good idea, but shoe-horning explicit UTXO selection into z_sendmany is probably not the right way to approach this. The provided outputs-to-spend-from would need to be consistent with all of fromaddress, minconf, fee, and privacyPolicy; expecting the caller to get all of this right makes for a complex API.

The proposed patch avoids these complexities by not actually implementing explicit UTXO selection. Instead, the new argument is a filter that limits the outputs z_sendmany can select from; z_sendmany is the final arbiter on which outputs are selected. The user can set the filter to precisely which outputs they want selected with no excess, but that would re-encounter the complexity mentioned above.

Now, if what is actually wanted here is just a filter, then this seems like a potentially reasonable change. However, the changes would actually need to be implemented in Zallet, which is replacing the zcashd wallet (and currently does not even have z_sendmany implemented).

But for explicit UTXO selection, I think a more forward-compatible approach here would be to lean into transaction proposals and PCZTs, for several reasons:

  • Selecting outputs to add as spends for a PCZT is precisely what the Constructor role in a PCZT workflow does. A JSON-RPC equivalent to that role makes perfect sense.
  • There’s no conflict with fromaddress or minconf fields because you would have two separate steps: one API to get the UTXOs corresponding to a fromaddress and matching a desired minconf, and then a separate API taking the explicitly-chosen UTXOs without either of the fields.
  • There’s no conflict with a fee field because fee-handling would be reversed. Instead of setting an explicit fee, the APIs would return an error if there were insufficient inputs to construct the desired transaction with a ZIP 317 fee, and then you’d explicitly select more UTXOs to make up the difference.
    • Having to iterate multiple times on this is part of why explicit UTXO selection can be very complex, and may be one reason to actually prefer a filter API depending on whether that actually serves the desired use case.
  • There’s no conflict with a privacyPolicy field because this is also inverted. Per my other comment, with a proposal / PCZT workflow you instead have the wallet propose a transaction, that the caller can inspect to determine its privacy properties and whether they are desirable.
2 Likes

Yeah, you understood the code right, it acts as a filter for now, since I am no professional C coder and I do not know much about zcashd internals, this was the only doable approach I could think of.

Is there an ETA for Zallet? When is it planned to replace zcashd? Is it any time soon? The RPC method planned for Zallet will be the same like zcashd supports now or is it going to be completely rewritten?

2 Likes

The deprecating zcashd thread is a good place to get some updates but the short answer to eta is asap. https://forum.zcashcommunity.com/t/zcashd-deprecation-updates

1 Like