How to handle private escrows between two parties..?

To elaborate on this approach, we’ll need to modify the token contract and introduce a new note type. This new note, let’s call it SharedValueNote for lack of a better name (please, dear reader, think of a better name!), should be similar to the ValueNote except for:

  • compute_nullifier should not use the owner’s nullifier but a random secret generated by the note creator and embedded into the note, so it’s accessible by all viewers.
  • broadcast should not use the owner pubkey, but receive a list of the addresses for which to emit the encrypted log. Note that, given that this diverges from the default NoteInterface, we may need to make the note’s broadcast a noop and handle it manually.

Note that we still want to keep the owner field since that’s the address that’s authorised for actually spending this note in the contract logic.

The token contract then needs logic for creating and consuming these notes. An easy solution is to have a dedicated method create_shared_note that consumes existing regular ValueNotes of equivalent value, and then a consume_shared_note which does the opposite, similar to shield/unshield operations. An open question is how the balance_of method would work, since it’d have to add balance across both flavors of notes.

Alternatively, it’d be interesting to see if we can merge both the SharedValueNote and the ValueNote into a single note type somehow, since the only practical difference is whether the nullifier is set as a random value by the sender or generated from the recipient’s secret. This would probably require having a special flavor of the transfer function that accepts a list of “viewers” for the note.