Skip to content

Commit f741d51

Browse files
committed
fix link
1 parent aa7e3cd commit f741d51

File tree

1 file changed

+15
-12
lines changed

1 file changed

+15
-12
lines changed

docs/docs/aztec/writing_efficient_contracts.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Since proof generation is a significant local burden, being mindful of the gate-
3737
An explanation of efficient use of Noir for circuits should be considered for each subsection under [writing efficient Noir](https://noir-lang.org/docs/explainers/explainer-writing-noir#writing-efficient-noir-for-performant-products) to avoid hitting local limits. The general theme is to use language features that favour the underlying primitives and representation of a circuit from code.
3838

3939
A couple of examples:
40+
4041
- Since the underlying cryptography uses an equation made of additions and multiplications, these are more efficient (wrt gate count) in Noir than say bit-shifting.
4142
- Unconstrained functions by definition do not constrain their operations/output, so do not contribute to gate count. Using them carefully can bring in some savings, but the results must then be constrained so that proofs are meaningful for your application.
4243

@@ -50,7 +51,7 @@ When private functions are called, the overhead of a "kernel circuit" is added e
5051

5152
#### Profiling using FlameGraph
5253

53-
Measuring the gate count across a private function can be seen at the end of the counter tutorial [here](../developers/tutorials/contract_tutorials/counter_contract#investigate-the-increment-function). Full profiling and flamegraph commands explained [here](../developers/guides/smart_contracts/profiling_transactions).
54+
Measuring the gate count across a private function can be seen at the end of the counter tutorial [here](../developers/tutorials/contract_tutorials/counter_contract#investigate-the-increment-function). Full profiling and flamegraph commands explained [here](../developers/guides/smart_contracts/advanced/profiling_transactions).
5455

5556
### L2 Data costs
5657

@@ -63,7 +64,6 @@ That is, what is stored in an L1 contract is simply a hash.
6364

6465
For data availability, blobs are utilized since data storage is often cheaper here than in contracts. Like other L2s such costs are factored into the L2 fee mechanisms. These limits can be seen and iterated on when a transaction is simulated/estimated.
6566

66-
6767
## Examples for private functions (reducing gate count)
6868

6969
After the first section about generating a flamegraph for an Aztec function, each section shows an example of different optimisation techniques.
@@ -78,14 +78,14 @@ For example, the resulting flamegraph (as an .svg file) of a counter's increment
7878

7979
To get a sense of things, here is a table of gate counts for common operations:
8080

81-
Gates | Operation
82-
----- | ----------
83-
~75 | Hashing 3 fields with Poseidon2
84-
3500 | Reading a value from a tree (public data tree, note hash tree, nullifier tree)
85-
4000 | Reading a delayed public mutable read
86-
X000 | Calculating sha256
87-
X000 | Constrained encryption of a log of Y fields
88-
X000 | Constrained encryption and tag a log of Y fields
81+
| Gates | Operation |
82+
| ----- | ------------------------------------------------------------------------------ |
83+
| ~75 | Hashing 3 fields with Poseidon2 |
84+
| 3500 | Reading a value from a tree (public data tree, note hash tree, nullifier tree) |
85+
| 4000 | Reading a delayed public mutable read |
86+
| X000 | Calculating sha256 |
87+
| X000 | Constrained encryption of a log of Y fields |
88+
| X000 | Constrained encryption and tag a log of Y fields |
8989

9090
### Optimization: use arithmetic instead of non-arithmetic operations
9191

@@ -115,7 +115,6 @@ In the same vein bitwise `AND`/`OR`, and inequality relational operators (`>`, `
115115

116116
For example, use boolean equality effectively instead of `>=`:
117117

118-
119118
```rust
120119
{
121120
#[private]
@@ -147,6 +146,7 @@ For example, use boolean equality effectively instead of `>=`:
147146
```
148147

149148
So for a loop of 1000 iterations, 751 gates were saved by:
149+
150150
- Adding an equivalence check and a boolean assignment
151151
- Replacing `>=` with a boolean equivalence check
152152

@@ -161,9 +161,11 @@ Since private functions are circuits, their size must be known at compile time,
161161
See [this example](https://github.com/noir-lang/noir-examples/blob/master/noir_by_example/loops/noir/src/main.nr#L11) for how to use loops when dynamic execution lengths (ie variable number of loops) is not possible.
162162

163163
### Optimization: considered use of `unconstrained` functions
164+
164165
#### Example - calculating square root
165166

166167
Consider the following example of an implementation of the `sqrt` function:
168+
167169
```rust
168170
use dep::aztec::macros::aztec;
169171

@@ -226,6 +228,7 @@ The two implementations after the contract differ in one being constrained vs un
226228
Measuring the two, we find the `sqrt_inefficient` to require around 1500 extra gates compared to `sqrt_efficient`.
227229

228230
To see each flamegraph:
231+
229232
- `SERVE=1 aztec flamegraph target/optimisation_example-OptimisationExample.json sqrt_inefficient`
230233
- `SERVE=1 aztec flamegraph target/optimisation_example-OptimisationExample.json sqrt_efficient`
231234
- (if you make changes to the code, you will need to compile and regenerate the flamegraph, then refresh in your browser to use the latest svg file)
@@ -355,5 +358,5 @@ unconstrained fn refactor_array(array: [u32; ARRAY_SIZE]) -> [u32; ARRAY_SIZE] {
355358
If a struct has many fields to be read, we can design an extra variable maintained as the hash of all values within it (like a checksum). When it comes to reading, we can now do an unconstrained read (incurring no read requests), and then check the hash of the result against that stored for the struct. This final check is thus only one read request rather than one per variable.
356359

357360
:::note Leverage unconstrained functions
358-
When needing to make use of large private operations (eg private execution or many read requests), use of [unconstrained functions](https://noir-lang.org/docs/explainers/explainer-writing-noir#leverage-unconstrained-execution) wisely to reduce the gate count of private functions.
361+
When needing to make use of large private operations (eg private execution or many read requests), use of [unconstrained functions](https://noir-lang.org/docs/explainers/explainer-writing-noir#leverage-unconstrained-execution) wisely to reduce the gate count of private functions.
359362
:::

0 commit comments

Comments
 (0)