zk proof of spend of an ‘unknow amount’ to an ‘unknown address’

Some applications which have marketplace functionality (tipping, purchasing user created content, etc…) and use monero for payments need a way to confirm that the purchaser did indeed pay the provider. There are two ways to do this that I am aware of:

1. **Temporary Custody**In this approach the purchaser (buyer) sends the funds to an integrated address which the backend server has associated with a certain purchase. The associated wallet is checked on the backend server for the matching transaction. Upon confirmation those funds are then dispersed to the seller.
2. **Seller Notification**This approach requires the seller to act in good faith. The buyer makes a payment to the sellers address, and then the seller is expected to notify the server that a specific purchase has been made.

The downside of (2) is quite clear – it requires the seller to be online and act in good faith. However, (1) introduces trust of the server, increased code complexity, entices hacking of the server to extract custodied XMR, creates redundant transactions, and an additional fee is payed reducing sellers profit. It also means that the server must maintain a record of the seller’s address.Imagine that the seller’s address and requested amount is encrypted, and then decrypted by the buyer using a shared key (shared offline or via a url such as `[`](`) (stored after the hash so it isn’t sent to the server). At this point the client needs to produce a proof of the following:

Given the encrypted address and amount, I can prove that I authored a transaction which was sent to an address which when encrypted using with a key Y (which is not revealed) equals the encrypted address given. The same occurs with an amount. (Or something similar, I just started pondering this today)

If we were able to construct a zk-SNARK (or similar) circuit which could establish the above in the browser a proof could be made using something like []( and then validated on the server. This allows the server to know that a payment was made to the ‘unknown address’ of the ‘unknown amount’ and thus allow the purchaser to access the content/ship the product/alert the seller/etc…

Basically the goal is for the server to only know that the buyer sent the amount of monero the seller expected to the address the seller expected, without knowing what either of those values are. The buyer is made aware of the seller’s expected address and amount via decrypting a value the server does know using a key communicated offline.

Is the construction of such a circuit possible? I’ve just started to learn about zero-knowledge proving systems and such so please let me know if I’ve really misunderstood them 🙂


There seems to be a bit of confusion about what I’m describing, so I drew a diagram:

In this case _Alice_ is the “witness” which can attest to the fact that the Tx with a TxId of $X$ was sent for the appropriate amount and to the correct address, where those address and amounts when encrypted using the key only the witness and seller know, match the encrypted address and amount from the server.

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings


  1. >Basically the goal is for the server to only know that the buyer sent the amount of monero the seller expected to the address the seller expected, without knowing what either of those values are.

    The only way to know if a payment has succeeded is to check the blockchain. The only way for the seller to take custody of the funds is if the seller holds the seed for a wallet, for which the seller will know all possible receiving addresses.

    I don’t understand how you are proposing that the buyer sends funds directly to the seller’s wallet without the seller being able to check on the blockchain that this has happened.

Coinbase horrible

🐕 BNBShiba ($BNBSHIBA) Holders rewarded Directly in BNB! Claim BNB rewards any time! | Anti Whale and Anti Dump mechanics | 🚨 LAUNCHING TODAY (15/07/2021) 🚨