Skip to content

Commit

Permalink
feat(docs): Note type IDs and compute_note_hash_and_nullifier page (#…
Browse files Browse the repository at this point in the history
…4636)

Closes
https://github.com/orgs/AztecProtocol/projects/11/views/23?pane=issue&itemId=52988548

---------

Co-authored-by: josh crites <critesjosh@gmail.com>
  • Loading branch information
catmcgee and critesjosh authored Mar 1, 2024
1 parent 0ab0a94 commit 032874a
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 458 deletions.
474 changes: 57 additions & 417 deletions docs/docs/developers/contracts/references/storage/main.md

Large diffs are not rendered by default.

22 changes: 0 additions & 22 deletions docs/docs/developers/contracts/references/storage/public_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,12 @@ Say that we wish to add `admin` public state variable into our storage struct. I

#include_code storage-leader-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust

And then when initializing it in the `Storage::init` function we can do:

#include_code storage-leader-init /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust

We have specified that we are storing a `Field` that should be placed in storage slot `1`. This is just a single value, and is similar to the following in solidity:

```solidity
address internal admin;
```

#### Mapping example

Say we want to have a group of `minters` that are able to mint assets in our contract, and we want them in public storage, because [access control in private is quite cumbersome](../../../../learn/concepts/communication/cross_chain_calls.md#a-note-on-l2-access-control). In the `Storage` struct we can add it as follows:

#include_code storage-minters-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust

And then when initializing it in the `Storage::init` function we can do it as follows:

#include_code storage-minters-init /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust

In this case, specifying that we are dealing with a map of Fields, and that it should be put at slot 2.

This would be similar to the following in solidity:

```solidity
mapping(address => bool) internal minters;
```

### `read`

On the `PublicMutable` structs we have a `read` method to read the value at the location in storage.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: How to define compute_note_hash_and_nullifier
---

Aztec will automatically compute and manage notes and nullifiers that are created in smart contracts. However, in some cases, it might make sense to write custom logic for how these are computed. This is achieved through the `compute_note_hash_and_nullifier()` function, which tells the [PXE](../../../../learn/concepts/pxe/main.md) how to handle notes in your smart contract.

## Params and returns

The function should take 5 parameters:

* Contract address
* Nonce
* Storage slot
* Note type ID
* Serialiazed note

It should return `pub [Field; 4]` which is an array of 4 elements that tells the PXE how to handle the notes and nullifiers:

#include_code compute_note_hash_and_nullifier_returns noir-projects/aztec-nr/aztec/src/note/utils.nr rust

## Placeholder

If you don't have any private state variables defined, you can use this placeholder function:

#include_code compute_note_hash_and_nullifier_placeholder /noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr rust

## When using notes

If you are using custom notes or note types that come with Aztec.nr, you can call the util function `compute_note_hash_and_nulilfier` from the `aztec::utils` library in Aztec.nr. This will return the array needed.

This function takes:

#include_code compute_note_hash_and_nullifier_args /noir-projects/aztec-nr/aztec/src/note/utils.nr rust

Here is an example from the [token contract](../../../tutorials/writing_token_contract.md):

#include_code compute_note_hash_and_nullifier /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust

Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,4 @@ struct Storage {
}
```

Since Aztec.nr is written in Noir, which is state-less, we need to specify how the storage struct should be initialized to read and write data correctly. This is done by specifying an `init` function that is run in functions that rely on reading or altering the state variables. This `init` function must declare the Storage struct with an instantiation defining how variables are accessed and manipulated. The function MUST be called `init` for the Aztec.nr library to properly handle it (this will be relaxed in the future).

```rust
impl Storage {
fn init(context: Context) -> Self {
Storage {
// (public state variables)::new()
// (private state variables)::new()
}
}
}
```

If you have defined a `Storage` struct following this naming scheme, then it will be made available to you through the reserved `storage` keyword within your contract functions.

:::warning Using slot `0` is not supported!
No storage values should be initialized at slot `0` - storage slots begin at `1`. This is a known issue that will be fixed in the future.
:::
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,10 @@ Beware that this hash computation is what the aztec.nr library is doing, and not
With this note structure, the contract can require that only notes sitting at specific storage slots can be used by specific operations, e.g., if transferring funds from `from` to `to`, the notes to destroy should be linked to `H(map_slot, from)` and the new notes (except the change-note) should be linked to `H(map_slot, to)`.

That way, we can have logical storage slots, without them really existing. This means that knowing the storage slot for a note is not enough to actually figure out what is in there (whereas it would be for looking up public state).

## Note type IDs

Note type IDs allow for multiple `Map`s in the same smart contract to hold a different underlying note type.

Each note type now has its own ID unique to its smart contract which tells the PXE how to handle it. If you are using your own custom `compute_note_hash_and_nullifier()` function, you must specify the note type ID. You can read more about that [here](../functions/compute_note_hash_and_nullifier.md).

1 change: 1 addition & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ const sidebars = {
"developers/contracts/writing_contracts/functions/visibility",
"developers/contracts/writing_contracts/functions/call_functions",
"developers/contracts/writing_contracts/functions/write_constructor",
"developers/contracts/writing_contracts/functions/compute_note_hash_and_nullifier",
"developers/contracts/writing_contracts/functions/inner_workings",
],
},
Expand Down
6 changes: 4 additions & 2 deletions noir-projects/aztec-nr/aztec/src/note/utils.nr
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,10 @@ pub fn compute_note_hash_for_consumption<Note, N>(note: Note) -> Field where Not
}

pub fn compute_note_hash_and_nullifier<T, N, S>(
// docs:start:compute_note_hash_and_nullifier_args
deserialize_content: fn([Field; N]) -> T,
note_header: NoteHeader,
serialized_note: [Field; S]
serialized_note: [Field; S] // docs:end:compute_note_hash_and_nullifier_args
) -> [Field; 4] where T: NoteInterface<N> {
let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0));
// TODO: change this to note.setHeader(header) once https://github.com/noir-lang/noir/issues/4095 is fixed
Expand All @@ -101,6 +102,7 @@ pub fn compute_note_hash_and_nullifier<T, N, S>(
let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);

let inner_nullifier = note.compute_nullifier_without_context();

// docs:start:compute_note_hash_and_nullifier_returns
[inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]
// docs:end:compute_note_hash_and_nullifier_returns
}

0 comments on commit 032874a

Please sign in to comment.