You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
⚠️ this PR builds off of the changes in #16442, so merge that one first
This PR makes several edits to the docs. The main impetus behind the changes being made is to make a more linear learning journey for developers as they move down the sidebar.
- moves the guides section above the tutorials
- flattens the pages inside the "Developer smart contracts" section
- makes the "developing smart contracts" section a more linear flow for how a developer should be moving through this content
- moves some of the technical explanations to the concepts section
- adds a several pages to the Guides section including:
- project sturcturing
- data types
- custom types
- defining functions (initializer page moved into here)
- removes some explainers and reference about storage from the references section into the guides section
closes: AztecProtocol/dev-rel#598
Co-authored-by: Alex Gherghisan <[email protected]>
Co-authored-by: Charlie Lye <[email protected]>
Co-authored-by: Facundo <[email protected]>
Co-authored-by: IlyasRidhuan <[email protected]>
Co-authored-by: Jonathan Hao <[email protected]>
Co-authored-by: Josh Crites <[email protected]>
Co-authored-by: José Pedro Sousa <[email protected]>
Co-authored-by: LHerskind <[email protected]>
Co-authored-by: Lasse Herskind <[email protected]>
Co-authored-by: Raju Krishnamoorthy <[email protected]>
Co-authored-by: fcarreiro <[email protected]>
Co-authored-by: federicobarbacovi <[email protected]>
Co-authored-by: jeanmon <[email protected]>
Co-authored-by: maramihali <[email protected]>
Co-authored-by: sergei iakovenko <[email protected]>
Co-authored-by: sirasistant <[email protected]>
Co-authored-by: thunkar <[email protected]>
Copy file name to clipboardExpand all lines: docs/docs/aztec/concepts/accounts/keys.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -106,7 +106,7 @@ When it comes to storing the signing key in a private note, there are several de
106
106
107
107
#### Using Delayed Public Mutable state
108
108
109
-
By [Delayed Public Mutable](../../../developers/reference/smart_contract_reference/storage/delayed_public_mutable.md#delayedpublicmutable) 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.
110
110
111
111
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.
Copy file name to clipboardExpand all lines: docs/docs/aztec/concepts/advanced/authwit.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -141,4 +141,4 @@ We don't need to limit ourselves to the `transfer` function, we can use the same
141
141
142
142
### Next Steps
143
143
144
-
Check out the [developer documentation](../../../developers/guides/smart_contracts/writing_contracts/authwit.md) to see how to implement this in your own contracts.
144
+
Check out the [developer documentation](../../../developers/guides/smart_contracts/authwit.md) to see how to implement this in your own contracts.
Copy file name to clipboardExpand all lines: docs/docs/aztec/concepts/advanced/storage/storage_slots.md
+57-3Lines changed: 57 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,8 +5,6 @@ sidebar_position: 1
5
5
description: Understand how storage slots work in Aztec for both public and private state, including siloing mechanisms and note hash commitments.
6
6
---
7
7
8
-
# Storage Slots
9
-
10
8
## Public State Slots
11
9
12
10
As mentioned in [State Model](../../storage/state_model.md), Aztec public state behaves similarly to public state on Ethereum from the point of view of the developer. Behind the scenes however, the storage is managed differently. As mentioned, public state has just one large sparse tree in Aztec - so we silo slots of public data by hashing it together with its contract address.
@@ -58,4 +56,60 @@ By doing this address-siloing at the kernel circuit we _force_ the inserted comm
58
56
To ensure that nullifiers don't collide across contracts we also force this contract siloing at the kernel level.
59
57
:::
60
58
61
-
For an example of this see [developer documentation on storage](../../../../developers/reference/smart_contract_reference/storage/index.md).
59
+
## Example
60
+
61
+
In this section we will go into more detail and walk through an entire example of how storage slots are computed for private state to improve our storage slot intuition. Recall, that storage slots in the private domain is just a logical construct, and are not "actually" used for lookups, but rather just as a value to constrain against.
62
+
63
+
For the case of the example, we will look at what is inserted into the note hashes tree when adding a note in the Token contract. Specifically, we are looking at the last part of the `transfer` function:
This function is creating a new note and inserting it into the balance set of the recipient `to`. Recall that to ensure privacy, only the note hash is really inserted into the note hashes tree. To share the contents of the note with `to` the contract can emit an encrypted log (which this one does), or it can require an out-of-band data transfer sharing the information. Below, we will walk through the steps of how the note hash is computed and inserted into the tree. For this, we don't care about the encrypted log, so we are going to ignore that part of the function call for now.
68
+
69
+
Outlining it in more detail below as a sequence diagram, we can see how the calls make their way down the stack.
70
+
In the end a siloed note hash is computed in the kernel.
71
+
72
+
:::info
73
+
Some of the syntax below is a little butchered to make it easier to follow variables without the full code.
Notice the `siloed_note_hash` at the very end. It's a hash that will be inserted into the note hashes tree. To clarify what this really is, we "unroll" the values to their simplest components. This gives us a better idea around what is actually inserted into the tree.
MSM is a multi scalar multiplication on a grumpkin curve and G\_\* values are generators.
106
+
107
+
And `to` is the actor who receives the note, `amount` of the note and `randomness` is the randomness used to make the note hiding. Without the `randomness` the note could just as well be plaintext (computational cost of a preimage attack would be trivial in such a case).
108
+
109
+
:::info
110
+
Beware that this hash computation is what the aztec.nr library is doing, and not strictly required by the network (only the kernel computation is).
111
+
:::
112
+
113
+
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)`.
114
+
115
+
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).
Even with the router contract achieving good privacy is hard.
151
151
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/reference/smart_contract_reference/storage/delayed_public_mutable.md) 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.
Copy file name to clipboardExpand all lines: docs/docs/aztec/concepts/storage/notes.md
+142-1Lines changed: 142 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,4 +43,145 @@ When using the Aztec protocol, users may not be aware of the specific notes that
43
43
44
44
This is accomplished through the smart contract library, Aztec.nr, which abstracts notes by allowing developers to specify custom note types. This means they can specify how notes are interacted with, nullified, transferred, and displayed. Aztec.nr also helps users discover all of the notes that have been encrypted to their account and posted to the chain, known as [note discovery](../advanced/storage/note_discovery.md).
45
45
46
-
To understand note abstraction in Aztec.nr, you can read the [Build section](../../../developers/guides/smart_contracts/writing_contracts/notes/index.md).
46
+
## Technical details
47
+
48
+
### Some context
49
+
50
+
- Public functions and storage work much like other blockchains in terms of having dedicated storage slots and being publicly visible
51
+
- Private functions are executed locally with proofs generated for sound execution, and commitments to private variable updates are stored using append-only trees
52
+
- "Note" types are part of Aztec.nr, a framework that facilitates use of Aztec's different storage trees to achieve things such as private variables
53
+
54
+
This page will focus on how private variables are implemented with Notes and storage trees.
55
+
56
+
#### Side-note about execution
57
+
58
+
Under the hood, the Aztec protocol handles some important details around public and private function calls. Calls between them are asynchronous due to different execution contexts (local execution vs. node execution).
59
+
A detailed explanation of the transaction lifecycle can be found [here](../transactions.md#simple-example-of-the-private-transaction-lifecycle).
60
+
61
+
## Private state variables in Aztec
62
+
63
+
State variables in an Aztec contract are defined inside a struct specifically named `Storage`, and must satisfy the [Note Interface (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/aztec/src/note/note_interface.nr) and contain a [Note header (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/aztec/src/note/note_header.nr).
64
+
65
+
The Note header struct contains the contract address which the value is effectively siloed to, a nonce to ensure unique Note hashes, and a storage "slot" (or ID) to associate multiple notes.
66
+
67
+
A couple of things to unpack here:
68
+
69
+
#### Storage "slot"
70
+
71
+
Storage slots are more literal for public storage, a place where a value is stored. For private storage, a storage slot is logical (more [here](../advanced/storage/storage_slots.md)).
72
+
73
+
#### Silos
74
+
75
+
The address of the contract is included in a Note's data to ensure that different contracts don't arrive at the same hash with an identical variable. This is handled in the protocol's execution.
76
+
77
+
### Note types
78
+
79
+
There is more than one Note type, such as the `PrivateSet` type is used for private variables. There are also `PrivateMutable` and `PrivateImmutable` types.
80
+
81
+
Furthermore, notes can be completely custom types, storing any value or set of values that are desired by an application.
82
+
83
+
### Initialization
84
+
85
+
Private state variables are stored locally when the contract is created. Depending on the application, values may be privately shared by the creator with others via encrypted logs onchain.
86
+
A hash of a note is stored in the append-only note hash tree on the network so as to prove existence of the current state of the note in a privacy preserving way.
87
+
88
+
#### Note Hash Tree
89
+
90
+
By virtue of being append only, notes are not edited. If two transactions amend a private value, multiple notes will be inserted into the tree to the note hash tree and the nullifier tree. The header will contain the same logical storage slot.
91
+
92
+
### Reading Notes
93
+
94
+
:::info
95
+
96
+
Only those with appropriate keys/information will be able to successfully read private values that they have permission to. Notes can be read outside of a transaction or "off-chain" with no changes to data structures on-chain.
97
+
98
+
:::
99
+
100
+
When a note is read in a transaction, a subsequent read from another transaction of the same note would reveal a link between the two. So to preserve privacy, notes that are read in a transaction are said to be "consumed" (defined below), and new note(s) are then created with a unique hash.
101
+
102
+
With type `PrviateSet`, a private variable's value is interpreted as the sum of values of notes with the same logical storage slot.
103
+
104
+
Consuming, deleting, or otherwise "nullifying" a note is NOT done by deleting the Note hash; this would leak information. Rather a nullifier is created deterministically linked to the value. This nullifier is inserted into another the nullifier storage tree.
105
+
106
+
When reading a value, the local private execution checks that its notes (of the corresponding storage slot/ID) have not been nullified.
107
+
108
+
### Updating
109
+
110
+
:::note
111
+
Only those with appropriate keys/information will be able to successfully nullify a value that they have permission to.
112
+
:::
113
+
114
+
To update a value, its previous note hash(es) are nullified. The new note value is updated in the user's private execution environment (PXE), and the updated note hash inserted into the note hash tree.
115
+
116
+
## Supplementary components
117
+
118
+
Some optional background resources on notes can be found here:
119
+
120
+
-[High level network architecture](../../index.md), specifically the Private Execution Environment
Notes touch several core components of the protocol, but we will focus on a the essentials first.
125
+
126
+
### Some code context
127
+
128
+
The way Aztec benefits from the Noir language is via three important components:
129
+
130
+
-`Aztec.nr` - a Noir framework enabling contracts on Aztec, written in Noir. Includes useful Note implementations
131
+
-`noir contracts` - example Aztec contracts
132
+
-`noir-protocol-circuits` - a crate containing essential circuits for the protocol (public circuits and private wrappers)
133
+
134
+
A lot of what we will look at will be in [aztec-nr/aztec/src/note (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/aztec/src/note), specifically the lifecycle and note interface.
135
+
136
+
Looking at the noir circuits in these components, you will see references to the distinction between public/private execution and state.
137
+
138
+
### Lifecycle functions
139
+
140
+
Inside the [lifecycle (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr) circuits we see the functions to create and destroy a note, implemented as insertions of note hashes and nullifiers respectively. This is helpful for regular private variables.
141
+
142
+
We also see a function to create a note hash from the public context, a way of creating a private variable from a public call (run in the sequencer). This could be used in application contracts to give private digital assets to users.
143
+
144
+
### Note Interface functions
145
+
146
+
To see a [note_interface (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/aztec/src/note/note_interface.nr) implementation, we will look at a simple [ValueNote GitHub link](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/value-note/src/value_note.nr).
147
+
148
+
The interface is required to work within an Aztec contract's storage, and a ValueNote is a specific type of note to hold a number (as a `Field`).
149
+
150
+
#### Computing hashes and nullifiers
151
+
152
+
A few key functions in the note interface are around computing the note hash and nullifier, with logic to get/use secret keys from the private context.
153
+
154
+
In the ValueNote implementation you'll notice that it uses the `pedersen_hash` function. This is currently required by the protocol, but may be updated to another hashing function, like poseidon.
155
+
156
+
As a convenience, the outer [note/utils.nr (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/aztec/src/note/utils.nr) contains implementations of functions that may be needed in Aztec contracts, for example computing note hashes.
157
+
158
+
#### Serialization and deserialization
159
+
160
+
Serialization/deserialization of content is used to convert between the Note's variables and a generic array of Field elements. The Field type is understood and used by lower level crypographic libraries.
161
+
This is analogous to the encoding/decoding between variables and bytes in solidity.
162
+
163
+
For example in ValueNote, the `serialize_content` function simply returns: the value, nullifying public key hash (as a field) and the note randomness; as an array of Field elements.
164
+
165
+
### Value as a sum of Notes
166
+
167
+
We recall that multiple notes are associated with a "slot" (or ID), and so the value of a numerical note (like ValueNote) is the sum of each note's value.
168
+
The helper function in [balance_utils (GitHub link)](https://github.com/AztecProtocol/aztec-packages/blob/#include_/noir-projects/aztec-nr/value-note/src/balance_utils.nr) implements this logic taking a `PrivateSet` of `ValueNotes`.
169
+
170
+
A couple of things worth clarifying:
171
+
172
+
- A `PrivateSet` takes a Generic type, specified here as `ValueNote`, but can be any `Note` type (for all notes in the set)
173
+
- A `PrivateSet` of notes also specifies _the_ slot of all Notes that it holds
174
+
175
+
### Example - Notes in action
176
+
177
+
The Aztec.nr framework includes examples of high-level states [easy_private_uint (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr) for use in contracts.
178
+
179
+
The struct (`EasyPrivateUint`) contains a Context, Set of ValueNotes, and storage_slot (used when setting the Set).
180
+
181
+
Notice how the `add` function shows the simplicity of appending a new note to all existing ones. On the other hand, `sub` (subtraction), needs to first add up all existing values (consuming them in the process), and then insert a single new value of the difference between the sum and parameter.
182
+
183
+
---
184
+
185
+
### References
186
+
187
+
-["Stable" state variable (GitHub link)](https://github.com/AztecProtocol/aztec-packages/issues/4130)
Copy file name to clipboardExpand all lines: docs/docs/aztec/concepts/storage/state_model.md
-4Lines changed: 0 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,3 @@ Private state is represented in an append-only database since updating a record
22
22
The act of "deleting" a private state variable can be represented by adding an associated nullifier to a nullifier set. The nullifier is generated such that, without knowing the decryption key of the owner, an observer cannot link a state record with a nullifier.
23
23
24
24
Modification of state variables can be emulated by nullifying the state record and creating a new record to represent the variable. Private state has an intrinsic UTXO structure.
25
-
26
-
## Further reading
27
-
28
-
Read more about how to leverage the Aztec state model in Aztec contracts [here](../../../developers/reference/smart_contract_reference/storage/index.md).
Copy file name to clipboardExpand all lines: docs/docs/aztec/smart_contracts/contract_creation.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -61,7 +61,7 @@ Aztec makes an important distinction between initialization and public deploymen
61
61
62
62
### Initialization
63
63
64
-
Contract constructors are not enshrined in the protocol, but handled at the application circuit level. Constructors are methods used for initializing a contract, either private or public, and contract classes may declare more than a single constructor. They can be declared by the `#[initializer]` macro. You can read more about how to use them on the [Defining Initializer Functions](../../developers/guides/smart_contracts/writing_contracts/initializers.md) page.
64
+
Contract constructors are not enshrined in the protocol, but handled at the application circuit level. Constructors are methods used for initializing a contract, either private or public, and contract classes may declare more than a single constructor. They can be declared by the `#[initializer]` macro. You can read more about how to use them on the [Defining Initializer Functions](../../developers/guides/smart_contracts/define_functions.md#initializer-functions) page.
0 commit comments