# Broadcasting notes in token contracts

**URL:** <https://forum.aztec.network/t/broadcasting-notes-in-token-contracts/2658>\
**Category:** Aztec\
**Created:** [December 18, 2023, 6:30pm UTC](https://forum.aztec.network/t/broadcasting-notes-in-token-contracts/2658 "2023-12-18T18:30:11Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![spalladino](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.aztec.network/spalladino/32/32_2.png) [@spalladino](https://forum.aztec.network/u/spalladino)\
**Post date:** [December 22, 2023, 8:15pm UTC](https://forum.aztec.network/t/broadcasting-notes-in-token-contracts/2658/4 "2023-12-22T20:15:27Z")

</div>

> [@Mike](#):
>
> Separately, it would be nice if we could distill all our imagined token scenarios into a very minimal comparison, to help us to see how to design a single token contract standard which can enable all scenarios without too much ugly conditional logic:
> 
> - Me spending my notes
> - A 3rd party (without my secrets) spending my notes
> - An escrow smart contract spending its notes
> - And all the variants, relating to how many people can initiate spending of escrowed notes; whether all possible “spenders” need to be known in advance; etc etc.

Last working day of the year, but I finally got to this! Much of the work has already been done by @LHerskind [here](https://hackmd.io/3-UbzocrRVOcqZIBiNubDQ?view), but let’s recap all scenarios and their requirements. For each of them, we need to identify who’s the “application owner” of the note, who’s the “protocol owner” (as in who can nullify), and who can “see” the note (as in who has the preimage of it).

All scenarios begin with Alice having a note `A` in the token contract that represents part of her balance.

### Alice sends a transfer to Bob

- Alice calls `token.transfer(Bob)`
- Token consumes note `A` such that Alice is both its app and protocol owner using her nullifier key
- Token creates note `B` such that Bob is both app and protocol owner
- Token broadcasts the note to Bob, and both Alice and Bob can “see” it

### Alice deposits into a public contract

- Alice calls `defi.deposit()`
- The defi contract calls `token.unshield_from(Alice, this)`
- Token contract calls into Alice’s contract to check for authorization
- Alice provides her authwit via an oracle call
- Token consumes note `A` such that Alice is both its app and protocol owner using her nullifier key
- The defi contract’s public balance is incremented

### Bob transfers Alice’s funds to Charlie

This scenario requires notes with shareable nullifiers, as opposed to using nullifier secret keys. The way it has been implemented so far is by using a randomized value as a nullifier (see [here](https://forum.aztec.network/t/how-to-handle-private-escrows-between-two-parties/2440/2)), which gets stored in the note, but **this requires a different note format**.

- Alice converts note `A` into `A'` **such that it uses a random value stored in the note as nullifier** via a `token.escrow()` call
- Alice signs an authwit to authorize the transfer and sends it to Bob off-chain along with note `A'`'s preimage which includes the randomized nullifier.
- Bob calls `token.transfer_from(Alice, Bob)`
- Token contract calls into Alice’s contract to check for authorization
- Bob provides Alice’s authwit via an oracle call
- Token consumes note `A'` using the random value stored in the note preimage
- Token creates a note `C` for Charlie, such that Charlie is both the app and protocol owner
- Token broadcasts note `C` to Charlie

Would it be possible, instead of using a random value as nullifier, to have Alice derive the specific nullifier for the note and share it with Bob, and for Bob to be able to verify it without knowing Alice’s secret nullifier key? For instance, instead of deriving the nullifier as `nullifier = hash(note_hash, nullifier_secret_key)`, could we derive the nullifier as `shareable_nullifier = sign(private_note_hash, nullifier_secret_key)`, such that we can then verify it against the `nullifier_public_key`? Note the usage of a `private_note_hash` here which should be different from the `note_hash` stored in the private data tree, otherwise anyone could link the note and its nullifier.

### Bob deposits Alice’s funds in a public contract

Equivalent to a mix of scenarios 2 and 3:

- Alice converts note `A` into `A'` **such that it uses a random value stored in the note as nullifier** via a `token.escrow()` call
- Alice signs an authwit to authorize the deposit and sends it to Bob off-chain along with note `A'`'s preimage
- Bob calls `defi.deposit()`
- The defi contract calls `token.unshield_from(Alice, this)`
- Token contract calls into Alice’s contract to check for authorization
- Bob provides Alice’s authwit via an oracle call
- Token consumes note `A'` using the randomized value stored in the note
- The defi contract’s public balance is incremented

### Alice deposits her funds into a contract 0xB which then transfers publicly into 0xC

This is Lasse’s [transient escrowing](https://hackmd.io/3-UbzocrRVOcqZIBiNubDQ?both#Transient-Escrowing) scenario, in which contract 0xB performs some accounting before forwarding the funds to 0xC. Requires adding a `protocol_owner` option to the transfer method, or using a random value as nullifier.

- Alice calls `0xA.deposit()`
- Contract `0xA` calls `token.transfer_from(Alice, this, protocol_owner: Alice)`
- Token contract calls into Alice’s contract to check for authorization
- Alice provides her authwit via an oracle call
- Token consumes note `A` (such that Alice is both its app and protocol owner) using Alice’s nullifier key
- Token creates note `B` such that 0xB is the app owner but she is the protocol owner
- Contract `0xA` calls `0xB.deposit()`
- Contract `0xB` calls `token.unshield_from(0xA, this)`
- Token contract calls into 0xA to check for authorization
- `0xA` approves via custom logic (not via authwit, since there is no key to sign it)
- Contract `0xB` consumes note `B` **using Alice’s provided nullifier**
- The public balance for `0xB` is increased

### Alice deposits her funds privately into a betting contract with Bob and Charlie

This is [Wonderland’s escrow scenario](https://forum.aztec.network/t/how-to-handle-private-escrows-between-two-parties/2440/3), where we have a handful of parties that will be working together privately through a contract, and eventually one of them will cash out. Here, Alice, Bob, and Charlie need to provably see all escrowed notes, and be able to nullify them.

- Alice calls `bet.deposit()`
- Betting contract calls `token.transfer_from(Alice, this, nullifier: random, broadcast_for: [Alice, Bob, Charlie])`
- Alice consumes note `A` (such that Alice is both its app and protocol owner) using her nullifier key
- Token creates note `B` such that the betting contract is the app owner and **the nullifier is a random value** stored in the note itself.
- Token **broadcasts note `B` to Alice, Bob, and Charlie**.

Eventually the bet is settled. Let’s assume Charlie wins:

- Charlie calls `bet.cashout()`
- Betting contract calls `token.transfer(Charlie)`
- Token consumes note `B` using the random value stored in the note
- Token creates note `C` where Charlie is the app and protocol owner

Note that, in the scenario that David wants to join in the bet contract after it started, we’d need someone to re-broadcast every note (or a single note created from merging all individual notes) to him. This means that we’d need a `token.broadcast_for` method, as Wonderland implemented [here](https://github.com/defi-wonderland/aztec-token/blob/12cd9853076f86e053d63ae44a6bd73fb67b176a/src/contracts/src/main.nr#L422-L454).

This scenario could also be implemented by creating a new contract specifically for Alice, Bob, and Charlie (assuming they are all known in advance), using a set of public encryption keys derived from a shared secret, so they just treat the bet contract as another “account contract” they own. The downside of this approach is note discovery: all parties need to start scanning notes for yet another address, and they all need to agree in a single note tagging and encryption method.

* * *

I may be missing other scenarios, please comment and I’ll edit the post!

---

_[View the full topic](https://forum.aztec.network/t/broadcasting-notes-in-token-contracts/2658)._
