Skip to content

Commit 8cf8fa6

Browse files
committed
update page name, add info on custom note
1 parent 7947732 commit 8cf8fa6

File tree

9 files changed

+50
-35
lines changed

9 files changed

+50
-35
lines changed

docs/docs/aztec/concepts/accounts/keys.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ When it comes to storing the signing key in a private note, there are several de
106106

107107
#### Using Delayed Public Mutable state
108108

109-
By [Delayed Public Mutable](../../../developers/guides/smart_contracts/data_types.md#delayed-public-mutable) we mean privately readable publicly mutable state.
109+
By [Delayed Public Mutable](../../../developers/guides/smart_contracts/storage_types.md#delayed-public-mutable) we mean privately readable publicly mutable state.
110110

111111
To make public state accessible privately, there is a delay window in public state updates. One needs this window to be able to generate proofs client-side. This approach would not generate additional nullifiers and commitments for each transaction while allowing the user to rotate their key. However, this causes every transaction to now have a time-to-live determined by the frequency of the delayed mutable state, as well as imposing restrictions on how fast keys can be rotated due to minimum delays.
112112

docs/docs/aztec/concepts/call_types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ aztec = { git = "https://github.com/AztecProtocol/aztec-packages/", tag = "#incl
149149

150150
Even with the router contract achieving good privacy is hard.
151151
For example, if the value being checked against is unique and stored in the contract's public storage, it's then simple to find private transactions that are using that value in the enqueued public reads, and therefore link them to this contract.
152-
For this reason it is encouraged to try to avoid public function calls and instead privately read [Shared State](../../developers/guides/smart_contracts/data_types.md#delayed-public-mutable) when possible.
152+
For this reason it is encouraged to try to avoid public function calls and instead privately read [Shared State](../../developers/guides/smart_contracts/storage_types.md#delayed-public-mutable) when possible.
153153

154154
### Public Execution
155155

docs/docs/developers/guides/smart_contracts/common_patterns.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Note - you could also create a note and send it to the user. The problem is ther
3939

4040
### Reading public storage in private
4141

42-
You can read public storage in private domain by leveraging the private getters of `PublicImmutable` (for values that never change) and `DelayedPublicMutable` (for values that change infrequently, see [delayed public mutable state](./data_types.md#delayed-public-mutable) for details) state variables.
42+
You can read public storage in private domain by leveraging the private getters of `PublicImmutable` (for values that never change) and `DelayedPublicMutable` (for values that change infrequently, see [delayed public mutable state](./storage_types.md#delayed-public-mutable) for details) state variables.
4343
Values that change frequently (`PublicMutable`) cannot be read in private as for those we need access to the tip of the chain and only a sequencer has access to that (and sequencer executes only public functions).
4444

4545
E.g. when using `PublicImmutable`

docs/docs/developers/guides/smart_contracts/custom_types.md renamed to docs/docs/developers/guides/smart_contracts/note_types.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
2-
title: Custom Types
2+
title: Note Types
33
tags: [contracts, notes]
44
sidebar_position: 3
55
keywords: [implementing note, note]
6-
description: Learn how to implement custom note types in your Aztec smart contracts.
6+
description: Learn about note types and how to implement custom note types in your Aztec smart contracts.
77
---
88

99
Notes are the fundamental data structure in Aztec when working with private state. Using Aztec.nr, developers can define note types which allow flexibility in how notes are stored and nullified.
@@ -14,9 +14,7 @@ For example, if you are developing a card game, you may want to store multiple p
1414

1515
If you want to work with values, addresses or integers, you can check out [ValueNote](#valuenote), or [AddressNote](#addressnote).
1616

17-
## Define a note type
18-
19-
You will likely want to define your note in a new file and import it into your contract.
17+
## Standard Note Type
2018

2119
A note type can be defined with the macro `#[note]` used on a struct:
2220

@@ -38,6 +36,7 @@ This would work since the nullifier would be unique and only the note recipient
3836
However, if we did this, the sender could also derive the nullifier off-chain and monitor the nullifier tree for its inclusion, allowing them to determine when a note has been spent.
3937
This would leak privacy.
4038

39+
4140
## Examples
4241

4342
Address notes hold one main property of the type `AztecAddress`. It also holds `owner` and `randomness`, similar to other note types.
@@ -124,6 +123,14 @@ For example:
124123

125124
The `decrement` function works similarly except the `amount` is the number that the value will be decremented by, and it will fail if the sum of the selected notes is less than the amount.
126125

126+
### Custom Note Type
127+
128+
Using the `#[custom_note]` macro allows you to define your own note hash and nullifier schemes for your notes, rather than using the default poseidon2 hash of the note to generate the note hash or using the note owners nullifier key to generate a nullifier.
129+
130+
The TransparentNote in an example token contract demonstrates how you can generate a custom note hash and nullifiers.
131+
132+
#include_code transparent_note_impl noir-projects/noir-contracts/contracts/app/token_blacklist_contract/src/types/transparent_note.nr rust
133+
127134
## Further reading
128135

129136
- [What is `#[note]` actually doing? + functions such as serialize() and deserialize()](../../../aztec/smart_contracts/functions/attributes.md#implementing-notes)

docs/docs/developers/guides/smart_contracts/storage.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ The `Context` parameter is injected into storage and contract functions. It prov
2525

2626
:::
2727

28-
Read more about the data types available in the [Data Types](./data_types.md) page.
28+
Read more about the data types available in the [Data Types](./storage_types.md) page.

docs/docs/developers/guides/smart_contracts/data_types.md renamed to docs/docs/developers/guides/smart_contracts/storage_types.md

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
---
2-
title: Data Types
2+
title: Storage Types
33
sidebar_position: 2
44
tags: [data-types, smart-contracts]
5-
description: Learn about the data types available in Aztec.nr.
5+
description: Learn about how data is stored in Aztec contracts.
66
---
77

8+
Interacting with the protocol in a reliable, private manner is simplified by using the storage types described below, provided by the Aztec.nr library for writing contracts.
9+
810
## Map
911

1012
A `map` is a state variable that "maps" a key to a value. It can be used with private or public storage variables.
@@ -57,15 +59,15 @@ To simplify the experience of writing private state, Aztec.nr provides three dif
5759

5860
These three structs abstract-away many of Aztec's protocol complexities, by providing intuitive methods to modify notes in the utxo tree in a privacy-preserving way.
5961

60-
Unlike public state variables, which can be arbitrary types, private state variables operate on `NoteType`. See [custom types](./custom_types.md) for more information about how to define your own note types.
62+
Unlike public state variables, which can be arbitrary types, private state variables operate on `NoteType`. See [Note Types](./note_types.md) for more information about how to define your own note types.
6163

6264
Notes are the fundamental elements of private state.
6365

6466
### PrivateMutable
6567

6668
PrivateMutable is a private state variable that is unique in a way. When a PrivateMutable is initialized, a note is created to represent its value. And the way to update the value is to destroy the current note, and create a new one with the updated value.
6769

68-
Like for public state, we define the struct to have context and a storage slot. You can view the implementation [here (GitHub link)](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr).
70+
Like for public state, we define the struct to have context and a storage slot. You can view the implementation [here](https://github.com/AztecProtocol/aztec-packages/blob/master/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr).
6971

7072
An example of `PrivateMutable` usage in the account contracts is keeping track of public keys. The `PrivateMutable` is added to the `Storage` struct as follows:
7173

@@ -103,12 +105,18 @@ An unconstrained method to check whether the PrivateMutable has been initialized
103105

104106
#### `replace`
105107

106-
To update the value of a `PrivateMutable`, we can use the `replace` method. The method takes a new note as input, and replaces the current note with the new one. It emits a nullifier for the old value, and inserts the new note into the data tree.
108+
To update the value of a `PrivateMutable`, we can use the `replace` method. The method takes a new note as input and replaces the current note with the new one. It emits a nullifier for the old value, and inserts the new note into the data tree.
107109

108110
An example of this is seen in a example card game, where we create a new note (a `CardNote`) containing some new data, and replace the current note with it:
109111

110112
#include_code state_vars-PrivateMutableReplace /noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr rust
111113

114+
:::info
115+
116+
Calling `emit(encode_and_encrypt_note())` on the `replace` method will encrypt the new note and post it to the data availability layer so that the note information is retrievable by the recipient.
117+
118+
:::
119+
112120
If two people are trying to modify the PrivateMutable at the same time, only one will succeed as we don't allow duplicate nullifiers! Developers should put in place appropriate access controls to avoid race conditions (unless a race is intended!).
113121

114122
#### `get_note`
@@ -151,6 +159,12 @@ Set the value of an PrivateImmutable by calling the `initialize` method:
151159

152160
#include_code initialize-private-mutable /noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr rust
153161

162+
:::info
163+
164+
Calling `emit(encode_and_encrypt_note())` on `initialize` will encrypt the new note and post it to the data availability layer so that the note information is retrievable by the recipient.
165+
166+
:::
167+
154168
Once initialized, an PrivateImmutable's value remains unchangeable. This method can only be called once.
155169

156170
#### `is_initialized`
@@ -175,21 +189,11 @@ Functionally similar to `get_note`, but executed unconstrained and can be used b
175189

176190
### PrivateSet
177191

178-
`PrivateSet` is used for managing a collection of notes. All notes in a `PrivateSet` are of the same `NoteType`. But whether these notes all belong to one entity, or are accessible and editable by different entities, is up to the developer. The set is a collection of notes inserted into the data-tree, but notes are never removed from the tree itself, they are only nullified.
179-
180-
You can view the implementation [here (GitHub link)](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr).
181-
182-
And can be added to the `Storage` struct as follows. Here adding a set for a custom note.
192+
`PrivateSet` is used for managing a collection of notes. All notes in a `PrivateSet` are of the same `NoteType`. But whether these notes all belong to one entity, or are accessible and editable by different entities, is up to the developer.
183193

184-
#include_code storage-set-declaration /noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr rust
194+
For example, adding a mapping of private NFTs to storage, indexed by `AztecAddress`:
185195

186-
#### `new`
187-
188-
The `new` method tells the contract how to operate on the underlying storage.
189-
190-
We can initialize the set as follows:
191-
192-
#include_code storage-set-init /noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr rust
196+
#include_code private_map /noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr rust
193197

194198
#### `insert`
195199

@@ -199,6 +203,12 @@ A hash of the note will be generated, and inserted into the note hash tree, allo
199203

200204
#include_code insert /noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr rust
201205

206+
:::info
207+
208+
Calling `emit(encode_and_encrypt_note())` on `insert` will encrypt the new note and post it to the data availability layer so that the note information is retrievable by the recipient.
209+
210+
:::
211+
202212
#### `insert_from_public`
203213

204214
The `insert_from_public` allow public function to insert notes into private storage. This is very useful when we want to support private function calls that have been initiated in public.
@@ -243,20 +253,16 @@ This function requires a `NoteViewerOptions`. The `NoteViewerOptions` is essenti
243253

244254
### PublicMutable
245255

246-
The `PublicMutable` (formerly known as `PublicState`) struct is generic over the variable type `T`.
256+
The `PublicMutable` struct is generic over the variable type `T`.
247257

248258
The struct contains a `storage_slot` which, similar to Ethereum, is used to figure out _where_ in storage the variable is located.
249259

250260
For a version of `PublicMutable` that can also be read in private, head to [`DelayedPublicMutable`](#delayed-public-mutable).
251261

252262
:::info
253-
An example using a larger struct can be found in the [lending example (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/master/noir-projects/noir-contracts/contracts/app/lending_contract)'s use of an [`Asset` (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/noir-contracts/contracts/app/lending_contract/src/asset.nr).
263+
An example using a larger struct can be found in the [lending example](https://github.com/AztecProtocol/aztec-packages/tree/master/noir-projects/noir-contracts/contracts/app/lending_contract)'s use of an [`Asset`](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/noir-contracts/contracts/app/lending_contract/src/asset.nr).
254264
:::
255265

256-
#### `new`
257-
258-
When declaring the storage for `T` as a persistent public storage variable, we use the `PublicMutable::new()` constructor. As seen below, this takes the `storage_slot` and the `serialization_methods` as arguments along with the `Context`, which in this case is used to share interface with other structures. You can view the implementation [here (GitHub link)](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr).
259-
260266
##### Single value example
261267

262268
To add `admin` public state variable into our storage struct, we can define it as:

docs/docs/developers/reference/environment_reference/cli_wallet_reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ For development, it may be useful to deploy, transact, or create notes in a non-
1111
- Deploying contracts
1212
- Sending transactions
1313
- Bridging L1 "Fee Juice" into Aztec
14-
- Pushing arbitrary [notes](../../guides/smart_contracts/custom_types.md) to your PXE
14+
- Pushing arbitrary [notes](../../guides/smart_contracts/note_types.md) to your PXE
1515
- Creating [authwits](../../guides/smart_contracts/authwit.md)
1616
- Aliasing info and secrets for further usage
1717
- Proving your transactions and profile gate counts

docs/docs/developers/tutorials/contract_tutorials/nft_contract.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ Below the dependencies, paste the following Storage struct:
174174

175175
## Custom Notes
176176

177-
The contract storage uses a [custom note](../../../guides/smart_contracts/custom_types.md) implementation. Custom notes are useful for defining your own data types. You can think of a custom note as a "chunk" of private data, the entire thing is added, updated or nullified (deleted) together. This NFT note is very simple and stores only the owner and the `token_id` and uses `randomness` to hide its contents.
177+
The contract storage uses a [custom note](../../../guides/smart_contracts/note_types.md) implementation. Custom notes are useful for defining your own data types. You can think of a custom note as a "chunk" of private data, the entire thing is added, updated or nullified (deleted) together. This NFT note is very simple and stores only the owner and the `token_id` and uses `randomness` to hide its contents.
178178

179179
Randomness is required because notes are stored as commitments (hashes) in the note hash tree. Without randomness, the contents of a note may be derived through brute force (e.g. without randomness, if you know my Aztec address, you may be able to figure out which note hash in the tree is mine by hashing my address with many potential `token_id`s).
180180

noir-projects/noir-contracts/contracts/app/token_blacklist_contract/src/types/transparent_note.nr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub struct TransparentNote {
2121
secret_hash: Field,
2222
}
2323

24+
// docs:start:transparent_note_impl
2425
impl NoteHash for TransparentNote {
2526
fn compute_note_hash(self, storage_slot: Field) -> Field {
2627
let inputs = self.pack().concat([storage_slot]);
@@ -51,6 +52,7 @@ impl NoteHash for TransparentNote {
5152
self.compute_nullifier(zeroed(), note_hash_for_nullify)
5253
}
5354
}
55+
// docs:end:transparent_note_impl
5456

5557
impl TransparentNote {
5658
// CONSTRUCTORS

0 commit comments

Comments
 (0)