diff --git a/README.md b/README.md
index a229197bb96..24a9c135cce 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,20 @@
# Aztec Monorepo
-All the packages that make up [Aztec](https://docs.aztec.network/what-is-aztec).
+All the packages that make up [Aztec](https://docs.aztec.network).
- [**`circuits`**](/circuits): C++ code for circuits and cryptographic functions
- [**`l1-contracts`**](/l1-contracts): Solidity code for the Ethereum contracts that process rollups
- [**`yarn-project`**](/yarn-project): Typescript code for client and backend
+- [**`docs`**](/docs): Documentation source for the docs site
+
+## Popular packages
+
+- [Aztec.nr](./yarn-project/aztec-nr/): A [Noir](https://noir-lang.org) framework for smart contracts on Aztec.
+- [Aztec Sandbox](./yarn-project/aztec-sandbox/): A package for setting up a local dev net, including a local Ethereum network, deployed rollup contracts and Aztec execution environment.
+- [Aztec.js](./yarn-project/aztec.js/): A tool for interacting with the Aztec network. It communicates via the [Aztec RPC Server](./yarn-project/aztec-rpc/).
+- [Aztec Boxes](./yarn-project/boxes/): A minimal framework for building full stack applications for Aztec (using React).
+- [Example contracts](./yarn-project/noir-contracts/): Example contracts for the Aztec network, written in Noir.
+- [End to end tests](./yarn-project/end-to-end/): Integration tests writted in Typescript--a good reference for how to use the packages for specific tasks.
## Issues Board
diff --git a/docs/docs/about_aztec/how_to_contribute.md b/docs/docs/about_aztec/how_to_contribute.md
index 1b359c64454..06d7f331758 100644
--- a/docs/docs/about_aztec/how_to_contribute.md
+++ b/docs/docs/about_aztec/how_to_contribute.md
@@ -2,19 +2,19 @@
title: How to Participate?
---
-- Talk about how we want the Aztec network to be as decentralised as possible, hence we want to actively encourage participation.
+Decentralization is one of our core values, so we want to encourage participation as much as possible and in any way you can.
## Improve the protocol
-- Point to discourse forum.
+- Join us at our [Discourse forum](https://discourse.aztec.network/) or [Discord server](https://discord.gg/DgWG2DBMyB) to discuss all things related to Aztec and share your feedback
## Contribute code
-- Point to github
-- Point to 'good first issues'
-- Encourage people to open issues
+- Check out the monorepo on GitHub [here](https://github.com/AztecProtocol/aztec-packages)
+- We have some [good first issues](https://github.com/AztecProtocol/aztec-packages/labels/good%20first%20issue) for newcomers
+- Anyone can open an Issue, so please feel free to create one
## Grants
-- Discuss opportunities for grants
-
+- We often run grants programs to support awesome projects and teams, you can read some of our past grantees [here](https://aztecnetwork.notion.site/Aztec-Grants-Wave-3-RFPs-acba57016db048868e5ed07cbf549979?p=5b2bf249f8f44836a10e6210cbaf95c0&pm=s)
+- Keep checking back to see when we're opening up a new wave of grants
diff --git a/docs/docs/about_aztec/overview.mdx b/docs/docs/about_aztec/overview.mdx
index 674462b2291..8c291ba3747 100644
--- a/docs/docs/about_aztec/overview.mdx
+++ b/docs/docs/about_aztec/overview.mdx
@@ -60,8 +60,7 @@ To support Aztec's rollup, our cryptography team is building [Honk](https://gith
## Participate
-Keep up with the latest discussion and join the conversation in the [Aztec forum](https://discourse.aztec.network).
+Keep up with the latest discussion and join the conversation in the [Aztec forum](https://discourse.aztec.network) or [Discord server](https://discord.gg/DgWG2DBMyB).
-
-import Disclaimer from "../misc/common/\_disclaimer.mdx";
-
\ No newline at end of file
+import Disclaimer from "../misc/common/_disclaimer.mdx";
+;
diff --git a/docs/docs/about_aztec/roadmap/cryptography_roadmap.md b/docs/docs/about_aztec/roadmap/cryptography_roadmap.md
index 0d59a4d1503..4c8f8facf4a 100644
--- a/docs/docs/about_aztec/roadmap/cryptography_roadmap.md
+++ b/docs/docs/about_aztec/roadmap/cryptography_roadmap.md
@@ -2,7 +2,7 @@
title: Cryptography Roadmap
---
-[Barretenberg](https://github.com/AztecProtocol/barretenberg/)
+The cryptography team is currently working on [Barretenberg here](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg)
## R&D projects
diff --git a/docs/docs/about_aztec/roadmap/features_initial_ldt.md b/docs/docs/about_aztec/roadmap/features_initial_ldt.md
index 50cf79233f1..da2de5c23f2 100644
--- a/docs/docs/about_aztec/roadmap/features_initial_ldt.md
+++ b/docs/docs/about_aztec/roadmap/features_initial_ldt.md
@@ -2,9 +2,13 @@
title: Initial Sandbox Features
---
+import Disclaimer from "../../misc/common/\_disclaimer.mdx";
+
+
+
The Aztec Sandbox is intended to provide developers with a lightweight & fast node, with features similar to Ethereum's Ganache or Anvil 'local node' packages.
-Devs should be able to quickly spin up local, emulated instances of an Ethereum blockchain and an Aztec encrypted rollup, and start deploying private contracts and submitting private txs.
+Developers should be able to quickly spin up local, emulated instances of an Ethereum blockchain and an Aztec encrypted rollup, and start deploying private contracts and submitting private txs.
Here's a summary of the features we intend to support with the first release of the Aztec Sandbox.
@@ -42,7 +46,7 @@ Here's a summary of the features we intend to support with the first release of
## `aztec.js`
-A typescript wrapper for making RPC calls to an Aztec LDT node.
+A typescript wrapper for making RPC calls to an Aztec Sandbox node.
- Similar in purpose to `web3.js`/`ethers.js`/`viem`, but for interacting with Aztec Network nodes. The RPC interface for an Aztec node is necessarily different from that of an Ethereum node, because it deals with encrypted transactions and state variables.
- A library for public/private key management.
@@ -54,7 +58,7 @@ A typescript wrapper for making RPC calls to an Aztec LDT node.
- Send txs to the LDT node, to be sent to the LDT network.
- Call `unconstrained` functions of a Aztec.nr contract, to perform `pure` calculations or retrieve state.
-## Aztec Local Developer Testnet Node
+## Aztec Sandbox Node
A bundle of packages which emulate the actions of all eventual Aztec network participants. The goal is for developer experience to be akin to Ganache / Anvil.
@@ -83,7 +87,3 @@ A bundle of packages which emulate the actions of all eventual Aztec network par
## Participate
Keep up with the latest discussion and join the conversation in the [Aztec forum](https://discourse.aztec.network).
-
-
-import Disclaimer from "../../misc/common/\_disclaimer.mdx";
-
\ No newline at end of file
diff --git a/docs/docs/about_aztec/roadmap/main.md b/docs/docs/about_aztec/roadmap/main.md
index b54fb257263..5e8f320137b 100644
--- a/docs/docs/about_aztec/roadmap/main.md
+++ b/docs/docs/about_aztec/roadmap/main.md
@@ -1,5 +1,5 @@
-
\ No newline at end of file
+# Roadmap
+
+
diff --git a/docs/docs/concepts/advanced/circuits/kernels/main.md b/docs/docs/concepts/advanced/circuits/kernels/main.md
index e69de29bb2d..66491cc446c 100644
--- a/docs/docs/concepts/advanced/circuits/kernels/main.md
+++ b/docs/docs/concepts/advanced/circuits/kernels/main.md
@@ -0,0 +1,5 @@
+import DocCardList from '@theme/DocCardList';
+
+# Kernel Circuits
+
+
diff --git a/docs/docs/concepts/advanced/circuits/rollup_circuits/base_rollup.md b/docs/docs/concepts/advanced/circuits/rollup_circuits/base_rollup.md
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/docs/docs/concepts/advanced/circuits/rollup_circuits/merge_rollup.md b/docs/docs/concepts/advanced/circuits/rollup_circuits/merge_rollup.md
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/docs/docs/concepts/advanced/circuits/rollup_circuits/root_rollup.md b/docs/docs/concepts/advanced/circuits/rollup_circuits/root_rollup.md
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/docs/docs/concepts/advanced/data_structures/main.md b/docs/docs/concepts/advanced/data_structures/main.md
index e69de29bb2d..43c378b2ec7 100644
--- a/docs/docs/concepts/advanced/data_structures/main.md
+++ b/docs/docs/concepts/advanced/data_structures/main.md
@@ -0,0 +1,5 @@
+import DocCardList from '@theme/DocCardList';
+
+# Data Structures
+
+
diff --git a/docs/docs/concepts/advanced/main.md b/docs/docs/concepts/advanced/main.md
index e69de29bb2d..a1234235739 100644
--- a/docs/docs/concepts/advanced/main.md
+++ b/docs/docs/concepts/advanced/main.md
@@ -0,0 +1,5 @@
+import DocCardList from '@theme/DocCardList';
+
+# Advanced Concepts
+
+
diff --git a/docs/docs/concepts/advanced/rollup_contract.md b/docs/docs/concepts/advanced/rollup_contract.md
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/docs/docs/concepts/foundation/main.md b/docs/docs/concepts/foundation/main.md
index e69de29bb2d..2f3509e5e79 100644
--- a/docs/docs/concepts/foundation/main.md
+++ b/docs/docs/concepts/foundation/main.md
@@ -0,0 +1,5 @@
+import DocCardList from '@theme/DocCardList';
+
+# Foundational Concepts
+
+
diff --git a/docs/docs/concepts/foundation/nodes_clients/main.md b/docs/docs/concepts/foundation/nodes_clients/main.md
deleted file mode 100644
index ed570a8d6f1..00000000000
--- a/docs/docs/concepts/foundation/nodes_clients/main.md
+++ /dev/null
@@ -1,3 +0,0 @@
----
-title: Nodes and Client
----
\ No newline at end of file
diff --git a/docs/docs/concepts/foundation/state_model.md b/docs/docs/concepts/foundation/state_model.md
index 87db190203c..d5ce47dd59b 100644
--- a/docs/docs/concepts/foundation/state_model.md
+++ b/docs/docs/concepts/foundation/state_model.md
@@ -6,8 +6,6 @@ import Disclaimer from '../../misc/common/\_disclaimer.mdx';
-## Public State
-
## Private State
Private state must be treated differently from public state and this must be expressed in the semantics of Aztec.nr.
@@ -29,19 +27,13 @@ This is achieved with two main features:
1. Users sign over transactions, not over specific UTXO's
2. Aztec.nr contracts support developer defined `unconstrained` getter functions to help dApp's make sense of UTXO's. e.g `getBalance()`. These functions can be called outside of a transaction context to read private state.
+## Coming soon
-### The lifecycle of a note
-
-#### Custom notes
-
-#### Injection of data by the kernel
-
-Nonce & contract address
-
-#### Custom nullifiers
-
-#### Emission of custom note data to L1
-
-#### Decrypting and storing encrypted note data
-
-Decryption and storing data and validating Note exists and computing nullifier
+- Public State
+- The lifecycle of a note
+- Custom notes
+- Injection of data by the kernel
+- Nonce & contract address
+- Custom nullifiers
+- Emission of custom note data to L1
+- Decrypting and storing encrypted note data
diff --git a/docs/docs/concepts/foundation/transactions.md b/docs/docs/concepts/foundation/transactions.md
index 1eba93f6dc2..bd1e051f776 100644
--- a/docs/docs/concepts/foundation/transactions.md
+++ b/docs/docs/concepts/foundation/transactions.md
@@ -9,11 +9,3 @@ import Disclaimer from '../../misc/common/\_disclaimer.mdx';
See [here](https://miro.com/app/board/uXjVMQbDwNk=/?share_link_id=47681418582) for a gigantic diagram (readonly) showing the flow from user to L2, to L1, back to user.
> Note: the protocol and its implementation are rapidly evolving, so some info in this diagram will be out of date.
-
-## Lifecycle of a private tx
-
-- Describe, in bullet points, the lifecycle
-
-## Lifecycle of a public tx
-
-- Describe, in bullet points, the lifecycle
diff --git a/docs/docs/cryptography/main.md b/docs/docs/cryptography/main.md
deleted file mode 100644
index 789bbe27104..00000000000
--- a/docs/docs/cryptography/main.md
+++ /dev/null
@@ -1,3 +0,0 @@
----
-title: Cryptography
----
\ No newline at end of file
diff --git a/docs/docs/dev_docs/getting_started/cli.md b/docs/docs/dev_docs/cli/cli.md
similarity index 98%
rename from docs/docs/dev_docs/getting_started/cli.md
rename to docs/docs/dev_docs/cli/cli.md
index 810e992183c..4e238b9e1d3 100644
--- a/docs/docs/dev_docs/getting_started/cli.md
+++ b/docs/docs/dev_docs/cli/cli.md
@@ -1,12 +1,12 @@
---
-title: Aztec CLI
+title: CLI Tutorial
---
## Introduction
The Aztec CLI is a tool designed to enable a user to interact with the Aztec Network.
-This tutorial will use the Aztec Sandbox so you should first set it up by following [the Aztec Sandbox instructions](../sandbox/main.md).
+This tutorial will use the Aztec Sandbox so you should first set it up by following [the Aztec Sandbox instructions](../getting_started/quickstart.md).
## Requirements
diff --git a/docs/docs/dev_docs/cli/main.md b/docs/docs/dev_docs/cli/main.md
index da28804c083..1236ed75bf5 100644
--- a/docs/docs/dev_docs/cli/main.md
+++ b/docs/docs/dev_docs/cli/main.md
@@ -20,4 +20,4 @@ Once installed it is invoked via:
## Getting Started
-To get up and running with the Aztec CLI head over to the [getting start page](../getting_started/cli.md).
+To get up and running with the Aztec CLI head over to the [getting start page](./cli.md).
diff --git a/docs/docs/dev_docs/contracts/compiling.md b/docs/docs/dev_docs/contracts/compiling.md
index 43f7f6b6cdd..071a7b56bec 100644
--- a/docs/docs/dev_docs/contracts/compiling.md
+++ b/docs/docs/dev_docs/contracts/compiling.md
@@ -1,6 +1,6 @@
# Compiling contracts
-Once you have written a [contract](../contracts/main.md) in Aztec.nr, you will need to compile it into an [artifact](./abi.md) in order to use it.
+Once you have written a [contract](../contracts/main.md) in Aztec.nr, you will need to compile it into an [artifact](./artifacts.md) in order to use it.
In this guide we will cover how to do so, both using the CLI and programmatically.
@@ -28,7 +28,7 @@ Then run the `compile` command with the path to your [contract project folder](.
aztec-cli compile ./path/to/my_aztec_contract_project
```
-This will output a JSON [artifact](./artifacts.md) for each contract in the project to a `target` folder containing their [ABI](./abi.md), which you can use for deploying or interacting with your contracts.
+This will output a JSON [artifact](./artifacts.md) for each contract in the project to a `target` folder containing their ABI, which you can use for deploying or interacting with your contracts.
### Typescript Interfaces
@@ -71,11 +71,11 @@ export class PrivateTokenContract extends ContractBase {
}
```
-Read more about interacting with contracts using `aztec.js` [here](../dapps/main.md).
+Read more about interacting with contracts using `aztec.js` [here](../getting_started/sandbox.md).
### Aztec.nr interfaces
-An Aztec.nr contract can [call a function](./functions.md) in another contract via `context.call_private_function` or `context.call_public_function`. However, this requires manually assembling the function selector and manually serialising the arguments, which is not type-safe.
+An Aztec.nr contract can [call a function](./syntax/functions.md) in another contract via `context.call_private_function` or `context.call_public_function`. However, this requires manually assembling the function selector and manually serialising the arguments, which is not type-safe.
To make this easier, the compiler can generate contract interface structs that expose a convenience method for each function listed in a given contract ABI. These structs are intended to be used from another contract project that calls into the current one. For each contract, two interface structs are generated: one to be used from private functions with a `PrivateContext`, and one to be used from open functions with a `PublicContext`.
@@ -98,7 +98,7 @@ impl PrivateTokenPrivateContextInterface {
fn at(address: Field) -> Self {
Self { address }
}
-
+
fn mint(
self, context: &mut PrivateContext, amount: Field, owner: Field
) -> [Field; RETURN_VALUES_LENGTH] {
@@ -109,7 +109,7 @@ impl PrivateTokenPrivateContextInterface {
// 0x1dc9c3c0 is the function selector for `mint(field,field)`
context.call_private_function(self.address, 0x1dc9c3c0, serialised_args)
}
-
+
fn transfer(
self, context: &mut PrivateContext, amount: Field, sender: Field, recipient: Field
@@ -125,7 +125,7 @@ impl PrivateTokenPrivateContextInterface {
}
```
-Read more about how to use the Aztec.nr interfaces [here](./functions.md#contract-interface).
+Read more about how to use the Aztec.nr interfaces [here](./syntax/functions.md#contract-interface).
:::info
At the moment, the compiler generates these interfaces from already compiled ABIs, and not from source code. This means that you should not import a generated interface from within the same project as its source contract, or you risk circular references.
@@ -135,19 +135,17 @@ At the moment, the compiler generates these interfaces from already compiled ABI
You can also programmatically access the compiler via the `@aztec/noir-compiler` package. To do this, install the package into your nodejs project:
-`
-npm install @aztec/noir-compiler
-`
+`npm install @aztec/noir-compiler`
The compiler exposes the following functions:
+
- `compileUsingNargo`: Compiles an Aztec.nr project in the target folder using the `nargo` binary available on the shell `PATH` and returns the generated ABIs.
- `generateTypescriptContractInterface`: Generates a typescript class for the given contract ABI.
- `generateNoirContractInterface`: Generates a Aztec.nr interface struct for the given contract ABI.
## Next steps
-Once you have compiled your contracts, you can use the generated artifacts via the `Contract` class in the `aztec.js` package to deploy and interact with them, or rely on the type-safe typescript classes directly. Alternatively, use the CLI [to deploy](../../dev_docs/getting_started/cli.md#deploying-a-token-contract) and [interact](../../dev_docs/getting_started/cli.md#sending-a-transaction) with them.
-
+Once you have compiled your contracts, you can use the generated artifacts via the `Contract` class in the `aztec.js` package to deploy and interact with them, or rely on the type-safe typescript classes directly. Alternatively, use the CLI [to deploy](../../dev_docs/cli/cli.md#deploying-a-token-contract) and [interact](../../dev_docs/cli/cli.md#sending-a-transaction) with them.
import Disclaimer from "../../misc/common/\_disclaimer.mdx";
-
\ No newline at end of file
+
diff --git a/docs/docs/dev_docs/contracts/events.md b/docs/docs/dev_docs/contracts/events.md
index 88eaf3b2396..36a809fde36 100644
--- a/docs/docs/dev_docs/contracts/events.md
+++ b/docs/docs/dev_docs/contracts/events.md
@@ -1,12 +1,17 @@
-## Events
+---
+title: Events
+---
+
Events in Aztec work similarly to Ethereum events in the sense that they are a way for contracts to communicate with the outside world.
They are emitted by contracts and stored inside each instance of an AztecNode.
+
> Aztec events are currently represented as raw data and are not ABI encoded.
> ABI encoded events are a feature that will be added in the future.
Unlike on Ethereum, there are 2 types of events supported by Aztec: encrypted and unencrypted.
### Encrypted Events
+
Encrypted events can only be emitted by private functions and are encrypted using a public key of a recipient.
For this reason it is necessary to register a recipient in the Aztec RPC Server before encrypting the events for them.
Recipients can be registered using the Aztec CLI or Aztec.js:
@@ -25,11 +30,21 @@ aztec-cli register-recipient --address 0x147392a39e593189902458f4303bc6e0a39128c
```ts
-const aztecAddress = AztecAddress.fromString("0x147392a39e593189902458f4303bc6e0a39128c5a1c1612f76527a162d36d529");
-const publicKey = Point.fromString("0x26e193aef4f83c70651485b5526c6d01a36d763223ab24efd1f9ff91b394ac0c20ad99d0ef669dc0dde8d5f5996c63105de8e15c2c87d8260b9e6f02f72af622");
-const partialAddress = Fr.fromString("0x200e9a6c2d2e8352012e51c6637659713d336405c29386c7c4ac56779ab54fa7");
-
-const completeAddress = CompleteAddress.create(aztecAddress, publicKey, partialKey);
+const aztecAddress = AztecAddress.fromString(
+ "0x147392a39e593189902458f4303bc6e0a39128c5a1c1612f76527a162d36d529"
+);
+const publicKey = Point.fromString(
+ "0x26e193aef4f83c70651485b5526c6d01a36d763223ab24efd1f9ff91b394ac0c20ad99d0ef669dc0dde8d5f5996c63105de8e15c2c87d8260b9e6f02f72af622"
+);
+const partialAddress = Fr.fromString(
+ "0x200e9a6c2d2e8352012e51c6637659713d336405c29386c7c4ac56779ab54fa7"
+);
+
+const completeAddress = CompleteAddress.create(
+ aztecAddress,
+ publicKey,
+ partialKey
+);
await aztecRpc.registerRecipient(completeAddress);
```
@@ -50,8 +65,8 @@ Then you can call the function:
#include_code encrypted /yarn-project/aztec-nr/value-note/src/utils.nr rust
-
### Unencrypted Events
+
Unencrypted events are events which can be read by anyone.
They can be emitted by both public and private functions.
@@ -96,21 +111,24 @@ All event data is pushed to Ethereum as calldata by the sequencer and for this r
> There are plans to adopt EIP-4844 blobs to reduce the cost of data submission further.
## Processing events
+
Both the encrypted and unencrypted events are stored in AztecNode.
Unencrypted logs can be queried by anyone as we described above in the [Unencrypted Events](#unencrypted-events) section.
Encrypted logs need to first be decrypted:
### Decrypting
+
One function of Aztec RPC Server is constantly loading encrypted logs from AztecNode and trying to decrypt them.
When new encrypted logs are obtained, the Aztec RPC Server will try to decrypt them using the private encryption key of all the accounts registered inside Aztec RPC Server.
If the decryption is successful, the Aztec RPC Server will store the decrypted note inside a database.
If the decryption fails, the specific log will be discarded.
For the Aztec RPC Server to successfully process the decrypted note we need to compute the note's 'note hash' and 'nullifier'.
-Aztec.nr enables smart contract developers to design custom notes, meaning developers can also customise how a note's note hash and nullifier should be computed. Because of this customisability, and because there will be a potentially-unlimited number of smart contracts deployed to Aztec, an Aztec RPR Server needs to be 'taught' how to compute the custom note hashes and nullifiers for a particular contract. Therefore, developers will need to implement a `compute_note_hash_and_nullifier` function inside their contracts.
+Aztec.nr enables smart contract developers to design custom notes, meaning developers can also customise how a note's note hash and nullifier should be computed. Because of this customisability, and because there will be a potentially-unlimited number of smart contracts deployed to Aztec, an Aztec RPC Server needs to be 'taught' how to compute the custom note hashes and nullifiers for a particular contract. Therefore, developers will need to implement a `compute_note_hash_and_nullifier` function inside their contracts.
+
Every time a new note is successfully decrypted, the Aztec RPC Server will expect the existence of a `compute_note_hash_and_nullifier` function, which must teach it how to correctly process the new note.
This is an example implementation inside the `PrivateTokenContract`:
-#include_code compute_note_hash_and_nullifier /yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr rust
\ No newline at end of file
+#include_code compute_note_hash_and_nullifier /yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr rust
diff --git a/docs/docs/dev_docs/contracts/example-contract.md b/docs/docs/dev_docs/contracts/example-contract.md
new file mode 100644
index 00000000000..5b661cba970
--- /dev/null
+++ b/docs/docs/dev_docs/contracts/example-contract.md
@@ -0,0 +1,13 @@
+---
+title: Example Aztec.nr Contract
+---
+
+## Example Aztec.nr Contract
+
+In keeping with the origins of blockchain, here's an example of a simple private token contract. Everyone's balances are private.
+
+#include_code easy_private_token_contract /yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr rust
+
+:::info Disclaimer
+Please note that any example contract set out herein is provided solely for informational purposes only and does not constitute any inducement to use or deploy. Any implementation of any such contract with an interface or any other infrastructure should be used in accordance with applicable laws and regulations.
+:::
diff --git a/docs/docs/dev_docs/contracts/globals.md b/docs/docs/dev_docs/contracts/globals.md
deleted file mode 100644
index 91b8c72fb6a..00000000000
--- a/docs/docs/dev_docs/contracts/globals.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Globals
-
-- timestamp
-- block number
-- chain id
-- version
\ No newline at end of file
diff --git a/docs/docs/dev_docs/contracts/main.md b/docs/docs/dev_docs/contracts/main.md
index b5e5ecc1787..e994361a146 100644
--- a/docs/docs/dev_docs/contracts/main.md
+++ b/docs/docs/dev_docs/contracts/main.md
@@ -1,3 +1,5 @@
+import DocCardList from '@theme/DocCardList';
+
# Aztec.nr
## What is Aztec.nr?
@@ -24,19 +26,6 @@ To write an Aztec.nr contract, you need to write Noir, and to write Noir, you ne
There are a number of tools to make writing Aztec.nr contracts more pleasant. See [here](https://github.com/noir-lang/awesome-noir#get-coding).
-## Quick start
-
-:::danger TODO
-Starter kit
-:::
-
-
-## Example Aztec.nr Contract
-
-In keeping with the origins of blockchain, here's an example of a simple private token contract. Everyone's balances are private.
-
-#include_code easy_private_token_contract /yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr rust
+## Learn more
-:::info Disclaimer
-Please note that any example contract set out herein is provided solely for informational purposes only and does not constitute any inducement to use or deploy. Any implementation of any such contract with an interface or any other infrastructure should be used in accordance with applicable laws and regulations.
-:::
+
diff --git a/docs/docs/dev_docs/contracts/resources/common_patterns/access_control.md b/docs/docs/dev_docs/contracts/resources/common_patterns/access_control.md
deleted file mode 100644
index bc46d2532c8..00000000000
--- a/docs/docs/dev_docs/contracts/resources/common_patterns/access_control.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Access Control
-
-## msg_sender
-
-## slow updates tree (TBC!!!)
\ No newline at end of file
diff --git a/docs/docs/dev_docs/contracts/constrain.md b/docs/docs/dev_docs/contracts/syntax/constrain.md
similarity index 75%
rename from docs/docs/dev_docs/contracts/constrain.md
rename to docs/docs/dev_docs/contracts/syntax/constrain.md
index f32c4c11348..eb529c1e3b1 100644
--- a/docs/docs/dev_docs/contracts/constrain.md
+++ b/docs/docs/dev_docs/contracts/syntax/constrain.md
@@ -1,2 +1,2 @@
Not sure what this one's for?
-`assert`?
\ No newline at end of file
+`assert`?
diff --git a/docs/docs/dev_docs/contracts/contract.md b/docs/docs/dev_docs/contracts/syntax/contract.md
similarity index 53%
rename from docs/docs/dev_docs/contracts/contract.md
rename to docs/docs/dev_docs/contracts/syntax/contract.md
index 211491237ee..5e125b8a797 100644
--- a/docs/docs/dev_docs/contracts/contract.md
+++ b/docs/docs/dev_docs/contracts/syntax/contract.md
@@ -4,7 +4,7 @@ title: Contract
# Contract
-A contract is a collection of persistent [state variables](#state-variables), and [functions](#functions) which may modify these persistent states. Functions and states within a contract's scope are said to belong to that contract. A contract can only access and modify its own state. If a contract wishes to access or modify another contract's state, it must make a [call](#calling-functions) to an external function of that other contract. For anything to happen on the Aztec network, an external function of a contract needs to be called.
+A contract is a collection of persistent [state variables](./state_variables.md), and [functions](./functions) which may modify these persistent states. Functions and states within a contract's scope are said to belong to that contract. A contract can only access and modify its own state. If a contract wishes to access or modify another contract's state, it must make a call to an external function of that other contract. For anything to happen on the Aztec network, an external function of a contract needs to be called.
A contract may be declared and given a name using the `contract` keyword (see snippet below). By convention, contracts are named in `PascalCase`.
@@ -17,7 +17,6 @@ contract MyContract {
}
```
-
> A note for vanilla Noir devs: There is no [`main()`](https://noir-lang.org/getting_started/breakdown/#mainnr) function within a Noir `contract` scope. This is because more than one function of a contract may be called and proven as external (as opposed to inlined by the compiler).
## Structure of a contract
@@ -27,4 +26,6 @@ contract MyContract {
- Private functions
- Public functions
- Encrypted events
-- Unencrypted events
\ No newline at end of file
+- Unencrypted events
+
+You can review the structure of a complete contract in the token contract tutorial [here](../../getting_started/token_contract_tutorial.md).
diff --git a/docs/docs/dev_docs/contracts/control_structure.md b/docs/docs/dev_docs/contracts/syntax/control_structure.md
similarity index 80%
rename from docs/docs/dev_docs/contracts/control_structure.md
rename to docs/docs/dev_docs/contracts/syntax/control_structure.md
index d4ce598c4dc..d3d0e57a6cf 100644
--- a/docs/docs/dev_docs/contracts/control_structure.md
+++ b/docs/docs/dev_docs/contracts/syntax/control_structure.md
@@ -5,7 +5,7 @@ title: Control Structures
:::danger
Question: this feels like the wrong title for a section about how to call functions. 'Control structure' in my mind is "if/else", "for", "while".
-Can we not put "how to call functions" in the [functions](./functions.md) section?
+Can we not put "how to call functions" in the functions section?
:::
# Function Calls
@@ -17,4 +17,3 @@ Can we not put "how to call functions" in the [functions](./functions.md) sectio
## Private to Public Function Calls
## Public to Private Function Calls
-
diff --git a/docs/docs/dev_docs/contracts/functions.md b/docs/docs/dev_docs/contracts/syntax/functions.md
similarity index 62%
rename from docs/docs/dev_docs/contracts/functions.md
rename to docs/docs/dev_docs/contracts/syntax/functions.md
index ceddbeb1186..0277e315815 100644
--- a/docs/docs/dev_docs/contracts/functions.md
+++ b/docs/docs/dev_docs/contracts/syntax/functions.md
@@ -1,4 +1,6 @@
-# Functions
+---
+title: Functions
+---
## `constructor`
@@ -23,36 +25,16 @@
#include_code functions-UncontrainedFunction /yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr rust
-# Calling functions
+## Visibility
-## Inlining
+### `internal`
-## Importing Contracts
+Similar to Solidity, internal functions and vars can be accessed within the contract itself. While technically callable from other contracts, there is a dynamic check that validates the caller to ensure it's the same contract.
-### Contract Interface
+### `external`
-## Constrained --> Unconstrained
+External is not used explicitly as it is in Solidity, but things not marked as `internal` will be external.
-E.g. `get()`
+### `#[aztec(public)]` and `#[aztec(private)]`
-## Oracle calls
-
-## Private --> Private
-
-## Public --> Public
-
-## Private --> Public
-
-## `internal` keyword
-
-## Public --> Private
-
-## Recursive function calls
-
-## L1 --> L2
-
-## L2 --> L1
-
-## Delegatecall
-
-Talk a about the dangers of delegatecall too!
+These are used to annotate functions so that they are compliant with Aztec ABIs. They inject `PublicContext` and `PrivateContext` for use in contracts.
diff --git a/docs/docs/dev_docs/contracts/syntax/globals.md b/docs/docs/dev_docs/contracts/syntax/globals.md
new file mode 100644
index 00000000000..604883293b9
--- /dev/null
+++ b/docs/docs/dev_docs/contracts/syntax/globals.md
@@ -0,0 +1,10 @@
+---
+title: Globals
+---
+
+# Globals
+
+- `timestamp`
+- `block_number`
+- `chain_id`
+- `version`
diff --git a/docs/docs/dev_docs/contracts/syntax.md b/docs/docs/dev_docs/contracts/syntax/main.md
similarity index 53%
rename from docs/docs/dev_docs/contracts/syntax.md
rename to docs/docs/dev_docs/contracts/syntax/main.md
index 584bdeab7ae..6452298329a 100644
--- a/docs/docs/dev_docs/contracts/syntax.md
+++ b/docs/docs/dev_docs/contracts/syntax/main.md
@@ -1,3 +1,5 @@
+import DocCardList from '@theme/DocCardList';
+
# Aztec.nr Syntax
[Noir](https://noir-lang.org/) is a language which is agnostic to proof systems and use cases. Rather than baking Aztec-specific keywords and smart contract types directly into Noir (which would break this agnosticism), we have developed a library -- written in Noir -- whose types and methods provide rich smart contract semantics.
@@ -6,14 +8,27 @@ On top of [Noir's stdlib](https://noir-lang.org/standard_library/array_methods),
Aztec.nr contains abstractions which remove the need to understand the low-level Aztec protocol. Notably, it provides:
-- Public and private [state variable types](./types.md)
-- Some pre-designed notes.
-- Functions for [emitting](./events.md) encrypted and unencrypted logs
+- Public and private [state variable types](./state_variables.md)
+- Some pre-designed notes
+- Functions for [emitting](../events.md) encrypted and unencrypted logs
- [Oracle functions](./functions.md#oracle-calls) for accessing:
- private state
- secrets
- Functions for communicating with Ethereum L1
-To import Aztec.nr into your Aztec contract project, simply include it as a dependency.
+To import Aztec.nr into your Aztec contract project, simply include it as a dependency. For example:
+
+```toml
+[package]
+name = "token_contract"
+authors = [""]
+compiler_version = "0.1"
+type = "contract"
+
+[dependencies]
+aztec = { git="https://github.com/AztecProtocol/aztec-packages/", tag="master", directory="yarn-project/aztec-nr/aztec" }
+value_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="master", directory="yarn-project/aztec-nr/value-note"}
+safe_math = { git="https://github.com/AztecProtocol/aztec-packages/", tag="master", directory="yarn-project/aztec-nr/safe-math"}
+```
-#include_code importing-aztec /yarn-project/noir-contracts/src/contracts/private_token_contract/Nargo.toml toml
+
diff --git a/docs/docs/dev_docs/contracts/state_variables.md b/docs/docs/dev_docs/contracts/syntax/state_variables.md
similarity index 99%
rename from docs/docs/dev_docs/contracts/state_variables.md
rename to docs/docs/dev_docs/contracts/syntax/state_variables.md
index db6ac3f6289..3930820782f 100644
--- a/docs/docs/dev_docs/contracts/state_variables.md
+++ b/docs/docs/dev_docs/contracts/syntax/state_variables.md
@@ -1,4 +1,6 @@
-# State Variables
+---
+title: State Variables
+---
State variables come in two flavours: [**public** state](#publicstatet-t_serialised_len) and [**private** state](#private-state-variables).
@@ -122,7 +124,7 @@ A note should conform to the following interface:
The interplay between a private state variable and its notes can be confusing. Here's a summary to aid intuition:
-- A private state variable (of type `Singleton`, `ImmutableSingleton` or `Set`) may be declared in [Storage](./storage.md).
+- A private state variable (of type `Singleton`, `ImmutableSingleton` or `Set`) may be declared in [Storage](storage).
- Every note contains (as a 'header') the contract address and storage slot of the state variable to which it "belongs". A note is said to "belong" to a private state if the storage slot of the private state matches the storage slot contained in the note's header.
- Management of this 'header' is abstracted-away from developers who use the `ImmutableSingleton`, `Singleton` and `Set` types.
- A private state variable is colloquially said to "point" to one or many notes (depending on the type), if those note(s) all "belong" to that private state, and those note(s) haven't-yet been nullified.
diff --git a/docs/docs/dev_docs/contracts/storage.md b/docs/docs/dev_docs/contracts/syntax/storage.md
similarity index 88%
rename from docs/docs/dev_docs/contracts/storage.md
rename to docs/docs/dev_docs/contracts/syntax/storage.md
index 366839646df..2ef2b361037 100644
--- a/docs/docs/dev_docs/contracts/storage.md
+++ b/docs/docs/dev_docs/contracts/syntax/storage.md
@@ -1,6 +1,6 @@
# Storage
-State variables must be declared inside a struct. (This enables us to declare types composed of nested generics in Noir - see [types](./types.md)).
+State variables must be declared inside a struct. (This enables us to declare types composed of nested generics in Noir).
We could define any kinds of state variables in the Storage struct:
diff --git a/docs/docs/dev_docs/contracts/types.md b/docs/docs/dev_docs/contracts/types.md
deleted file mode 100644
index a7e81ff0027..00000000000
--- a/docs/docs/dev_docs/contracts/types.md
+++ /dev/null
@@ -1,2 +0,0 @@
-See Noir docs for Noir types.
-See [state_variables](./state_variables.md) for Aztec.nr state variable types.
\ No newline at end of file
diff --git a/docs/docs/dev_docs/contracts/visibility.md b/docs/docs/dev_docs/contracts/visibility.md
deleted file mode 100644
index deb31e42106..00000000000
--- a/docs/docs/dev_docs/contracts/visibility.md
+++ /dev/null
@@ -1,3 +0,0 @@
-- internal
-- external
-- ?
\ No newline at end of file
diff --git a/docs/docs/dev_docs/contracts/workflow.md b/docs/docs/dev_docs/contracts/workflow.md
index 9ebe0ac2431..eb4641cbc8d 100644
--- a/docs/docs/dev_docs/contracts/workflow.md
+++ b/docs/docs/dev_docs/contracts/workflow.md
@@ -1,21 +1,23 @@
-# Aztec.nr smart contract workflow
+---
+title: Contract Workflow
+---
- ## Write
+## Write
- [Write a contract](./syntax.md)
+[Write a contract](./syntax/main.md).
- ## Compile
+## Compile
- [Compile a contract](./compiling.md).
+[Compile a contract](./compiling.md).
- ## Test
+## Unit Tests
- [Test individual noir functions](https://noir-lang.org/nargo/testing).
+[Test individual noir functions](https://noir-lang.org/nargo/testing).
- ## Deploy
+## Deploy
- [Deploy a contract](./deploying.md).
+[Deploy a contract](./deploying.md).
- ## Test
+## Integration Tests
- [Test a deployed contract](../testing/main.md)
\ No newline at end of file
+[Test a deployed contract](../testing/main.md)
diff --git a/docs/docs/dev_docs/dapps/api/aztec_rpc.md b/docs/docs/dev_docs/dapps/api/aztec_rpc.md
deleted file mode 100644
index 9107f2545ff..00000000000
--- a/docs/docs/dev_docs/dapps/api/aztec_rpc.md
+++ /dev/null
@@ -1,3 +0,0 @@
----
-title: Wallets and AztecRPC
----
diff --git a/docs/docs/dev_docs/dapps/api/contract_interaction.md b/docs/docs/dev_docs/dapps/api/contract_interaction.md
deleted file mode 100644
index 9bb0d573edd..00000000000
--- a/docs/docs/dev_docs/dapps/api/contract_interaction.md
+++ /dev/null
@@ -1,3 +0,0 @@
----
-title: Contract Interaction
----
diff --git a/docs/docs/dev_docs/dapps/tutorials/contract_interaction.md b/docs/docs/dev_docs/dapps/tutorials/contract_interaction.md
index 949a61b36ba..3f4508a2f2f 100644
--- a/docs/docs/dev_docs/dapps/tutorials/contract_interaction.md
+++ b/docs/docs/dev_docs/dapps/tutorials/contract_interaction.md
@@ -4,7 +4,7 @@ In this section, we'll write the logic in our app that will interact with the co
## Showing user balance
-Let's start by showing our user balance for the private token across their accounts. To do this, we can leverage the `balance_of_private` [unconstrained](../../contracts/functions.md#unconstrained-functions) view function of the private token contract:
+Let's start by showing our user balance for the private token across their accounts. To do this, we can leverage the `balance_of_private` unconstrained view function of the private token contract:
#include_code balance_of_private yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust
@@ -16,10 +16,10 @@ To do this, let's first initialise a new `Contract` instance using `aztec.js` th
```js
// src/contracts.mjs
-import { Contract } from '@aztec/aztec.js';
-import { readFileSync } from 'fs';
-import PrivateTokenArtifact from '../contracts/private_token/target/PrivateToken.json' assert { type: 'json' };
-import PublicTokenArtifact from '../contracts/public_token/target/PublicToken.json' assert { type: 'json' };
+import { Contract } from "@aztec/aztec.js";
+import { readFileSync } from "fs";
+import PrivateTokenArtifact from "../contracts/private_token/target/PrivateToken.json" assert { type: "json" };
+import PublicTokenArtifact from "../contracts/public_token/target/PublicToken.json" assert { type: "json" };
```
And then add the following code for initialising the `Contract` instances:
@@ -49,8 +49,12 @@ Now that we can see the balance for each user, let's transfer tokens from one ac
We can initialise a wallet using one of the `getAccount` methods from `aztec.js``, along with the corresponding signing and encryption keys:
```js
-import { getSchnorrAccount } from '@aztec/aztec.js';
-const wallet = await getSchnorrAccount(client, ENCRYPTION_PRIVATE_KEY, SIGNING_PRIVATE_KEY).getWallet();
+import { getSchnorrAccount } from "@aztec/aztec.js";
+const wallet = await getSchnorrAccount(
+ client,
+ ENCRYPTION_PRIVATE_KEY,
+ SIGNING_PRIVATE_KEY
+).getWallet();
```
For ease of use, `aztec.js` also ships with a helper `getSandboxAccountsWallets` method that returns a wallet for each of the pre-initialised accounts in the Sandbox, so you can send transactions as any of them. We'll use one of these wallets to initialise the `Contract` instance that represents our private token contract, so every transaction sent through it will be sent through that wallet.
@@ -132,4 +136,4 @@ At the time of this writing, there is no event-based mechanism in the `aztec.js`
## Next steps
-In the next and final section, we'll [set up automated tests for our application](./testing.md).
\ No newline at end of file
+In the next and final section, we'll [set up automated tests for our application](./testing.md).
diff --git a/docs/docs/dev_docs/dapps/tutorials/main.md b/docs/docs/dev_docs/dapps/tutorials/main.md
index 1d576759992..0685ab032a3 100644
--- a/docs/docs/dev_docs/dapps/tutorials/main.md
+++ b/docs/docs/dev_docs/dapps/tutorials/main.md
@@ -13,7 +13,7 @@ The full code for this tutorial is [available on the `aztec-packages` repository
- Linux or OSX environment
- [NodeJS](https://nodejs.org/) 18 or higher
- [Aztec Sandbox](../../getting_started/sandbox.md)
-- [Aztec CLI](../../getting_started/cli.md)
+- [Aztec CLI](../../cli/cli.md)
- [Nargo](../../getting_started/noir_contracts.md) for building contracts
## Prerequisites
diff --git a/docs/docs/dev_docs/dapps/tutorials/rpc_server.md b/docs/docs/dev_docs/dapps/tutorials/rpc_server.md
index 0412ddf5fde..4df09e27b9e 100644
--- a/docs/docs/dev_docs/dapps/tutorials/rpc_server.md
+++ b/docs/docs/dev_docs/dapps/tutorials/rpc_server.md
@@ -1,6 +1,6 @@
# Connecting to the RPC Server
-As an app developer, the [Aztec RPC Server interface](../api/aztec_rpc.md) provides you with access to the user's accounts and their private state, as well as a connection to the network for accessing public global state.
+As an app developer, the [Aztec RPC Server](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec-rpc) interface provides you with access to the user's accounts and their private state, as well as a connection to the network for accessing public global state.
During the Sandbox phase, this role is fulfilled by the [Aztec Sandbox](../../sandbox/main.md), which runs a local RPC Server and an Aztec Node, both connected to a local Ethereum development node like Anvil. The Sandbox also includes a set of pre-initialised accounts that you can use from your app.
@@ -8,13 +8,14 @@ In this section, we'll connect to the Sandbox from our project.
## Create RPC client
-We'll use the `createAztecRpcClient` function from `aztec.js` to connect to the Sandbox, which by default runs on `localhost:8080`. To test the connection works, we'll request and print the node's chain id.
+We'll use the `createAztecRpcClient` function from `aztec.js` to connect to the Sandbox, which by default runs on `localhost:8080`. To test the connection works, we'll request and print the node's chain id.
Let's create our first file `src/index.mjs` with the following contents:
#include_code all yarn-project/end-to-end/src/sample-dapp/connect.mjs javascript
Run this example as `node src/index.mjs` and you should see the following output:
+
```
Connected to chain 31337
```
@@ -40,4 +41,4 @@ User accounts:
## Next steps
-With a working connection to the RPC Server, let's now setup our application by [compiling and deploying our contracts](./contract_deployment.md).
\ No newline at end of file
+With a working connection to the RPC Server, let's now setup our application by [compiling and deploying our contracts](./contract_deployment.md).
diff --git a/docs/docs/dev_docs/dapps/tutorials/testing.md b/docs/docs/dev_docs/dapps/tutorials/testing.md
index c364e27f93b..d75b984686a 100644
--- a/docs/docs/dev_docs/dapps/tutorials/testing.md
+++ b/docs/docs/dev_docs/dapps/tutorials/testing.md
@@ -1,8 +1,10 @@
-# Testing
+---
+title: Testing
+---
-To wrap up this tutorial, we'll set up a simple automated test for our dapp contracts. We will be using [jest](https://jestjs.io/), but any nodejs test runner works fine.
+To wrap up this tutorial, we'll set up a simple automated test for our dapp contracts. We will be using [jest](https://jestjs.io/), but any nodejs test runner works fine.
-Here we'll only test the happy path for a `transfer` on our private token contract, but in a real application you should be testing both happy and unhappy paths, as well as both your contracts and application logic. Refer to the full [testing guide](../testing.md) for more info on testing and assertions.
+Here we'll only test the happy path for a `transfer` on our private token contract, but in a real application you should be testing both happy and unhappy paths, as well as both your contracts and application logic. Refer to the full [testing guide](../../testing/testing.md) for more info on testing and assertions.
## Dependencies
@@ -23,16 +25,14 @@ yarn add -D @aztec/aztec-sandbox
Create a new file `src/index.test.mjs` with the imports we'll be using and an empty test suite to begin with:
```js
-import { createSandbox } from '@aztec/aztec-sandbox';
-import { Contract, createAccount } from '@aztec/aztec.js';
-import PrivateTokenArtifact from '../contracts/private_token/target/PrivateToken.json' assert { type: 'json' };
+import { createSandbox } from "@aztec/aztec-sandbox";
+import { Contract, createAccount } from "@aztec/aztec.js";
+import PrivateTokenArtifact from "../contracts/private_token/target/PrivateToken.json" assert { type: "json" };
-describe('private token', () => {
-
-});
+describe("private token", () => {});
```
-Let's set up our test suite. We'll start [a new Sandbox instance within the test](../testing.md#running-sandbox-in-the-nodejs-process), create two fresh accounts to test with, and deploy an instance of our contract. The `aztec-sandbox` and `aztec.js` provide the helper functions we need to do this:
+Let's set up our test suite. We'll start [a new Sandbox instance within the test](../../testing/testing.md#running-sandbox-in-the-nodejs-process), create two fresh accounts to test with, and deploy an instance of our contract. The `aztec-sandbox` and `aztec.js` provide the helper functions we need to do this:
#include_code setup yarn-project/end-to-end/src/sample-dapp/index.test.mjs javascript
@@ -44,7 +44,7 @@ Now that we have a working test environment, we can write our first test for exe
#include_code test yarn-project/end-to-end/src/sample-dapp/index.test.mjs javascript
-In this example, we assert that the `recipient`'s balance is increased by the amount transferred. We could also test that the `owner`'s funds are decremented by the same amount, or that a transaction that attempts to send more funds than those available would fail. Check out the [testing guide](../testing.md) for more ideas.
+In this example, we assert that the `recipient`'s balance is increased by the amount transferred. We could also test that the `owner`'s funds are decremented by the same amount, or that a transaction that attempts to send more funds than those available would fail. Check out the [testing guide](../../testing/testing.md) for more ideas.
## Running our tests
@@ -56,4 +56,4 @@ yarn node --experimental-vm-modules $(yarn bin jest) --testRegex '.*\.test\.mjs$
## Next steps
-Now that you have finished the tutorial, you can dig deeper on the [APIs for dapp development](../api/main.md), learn more about [writing contracts with Noir](../../contracts/main.md), check out the [Sandbox's architecture](../../sandbox/main.md), or read about the [fundamental concepts behind Aztec Network](../../../concepts/foundation/main.md).
\ No newline at end of file
+Now that you have finished the tutorial, you can learn more about [writing contracts with Noir](../../contracts/main.md), check out the [Sandbox's architecture](../../sandbox/main.md), or read about the [fundamental concepts behind Aztec Network](../../../concepts/foundation/main.md).
diff --git a/docs/docs/dev_docs/getting_started/main.md b/docs/docs/dev_docs/getting_started/main.md
index e69de29bb2d..20ef05de9d5 100644
--- a/docs/docs/dev_docs/getting_started/main.md
+++ b/docs/docs/dev_docs/getting_started/main.md
@@ -0,0 +1,7 @@
+---
+title: Getting Started
+---
+
+import DocCardList from '@theme/DocCardList';
+
+
diff --git a/docs/docs/dev_docs/getting_started/noir_contracts.md b/docs/docs/dev_docs/getting_started/noir_contracts.md
index 683bf5e99b7..9d60ddab6b9 100644
--- a/docs/docs/dev_docs/getting_started/noir_contracts.md
+++ b/docs/docs/dev_docs/getting_started/noir_contracts.md
@@ -11,18 +11,23 @@ If you haven't read [Aztec Sandbox](./sandbox.md), we recommend going there firs
:::
### Dependencies
+
#### `nargo`
-Nargo is Noir's build tool. On your terminal, run:
+
+Nargo is Noir's build tool. On your terminal, run:
#### Aztec Sandbox
-You need to setup the [aztec sandbox](./sandbox.md)
+
+You need to setup the [Aztec sandbox](./sandbox.md).
## Set up for aztec.nr contracts
-1. Inside the yarn project you created from the [Sandbox](./sandbox.md) page, create a sub-folder where the contracts will reside.
+
+1. Inside the yarn project you created from the [Aztec.js](./sandbox.md) page, create a sub-folder where the contracts will reside.
+
```bash
mkdir contracts
```
@@ -30,14 +35,16 @@ mkdir contracts
All contract projects will reside within this folder. Note that contracts don't actually have to live here and this is just a style choice.
2. Next, create a noir project using nargo by running the following in the terminal from the `contracts` folder
+
```bash
cd contracts
nargo new example_contract
```
-This creates a noir project with a Nargo.toml (which is the manifest file of the project). This file is found at `example_contract/src/main.nr`, where we will write our contract.
+This creates a noir project with a Nargo.toml (which is the manifest file of the project). This file is found at `example_contract/src/main.nr`, where we will write our contract.
Your folder should look like:
+
```
.
|-contracts
@@ -51,6 +58,7 @@ Your folder should look like:
Before writing the contracts, we must add the aztec.nr library. This adds smart contract utility functions for interacting with the Aztec network.
3. Add aztec.nr library as a dependency to your noir project. Open Nargo.toml that is in the `contracts/example_contract` folder, and add the dependency section as follows:
+
```
[package]
name = "example_contract"
@@ -62,16 +70,15 @@ type = "contract"
aztec = { git="https://github.com/AztecProtocol/aztec-packages", tag="master", directory="yarn-project/aztec-nr/aztec" }
```
-You are now ready to write your own contracts!
+You are now ready to write your own contracts!
You can replace the content of the generated file `example_contract/src/main.nr` with your contract code.
## Next Steps
-You can learn more about writing contracts from the [Contracts section](../contracts/main.md).
-For now you can use the [PrivateToken contract example here](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr).
-
-After writing the contract, you have to compile it. Details can be found [here](../contracts/compiling.md).
-
-After compiling, you can deploy your contract to the Aztec network. Relevant instructions and explainations can be found [here](../contracts/deploying.md).
-Thereafter, you can interact with the contracts similar to how it was shown in the the [Creating and submitting transactions section on the Sandbox page](./sandbox.md#creating-and-submitting-transactions).
+- You can learn more about writing contracts from the [Contracts section](../contracts/main.md).
+- You can find more example Aztec contracts [here](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-contracts/src/contracts).
+- Consider going through the [token contract tutorial](./token_contract_tutorial.md) for a deep dive on writing more advanced Aztec contracts and an introduction to some of the concepts that underpin the Aztec network architecture.
+- After writing the contract, you have to compile it. Details can be found [here](../contracts/compiling.md).
+- After compiling, you can deploy your contract to the Aztec network. Relevant instructions and explanations can be found [here](../contracts/deploying.md).
+- Thereafter, you can interact with the contracts similar to how it was shown in the the [Creating and submitting transactions section on the Sandbox page](./sandbox.md#creating-and-submitting-transactions).
diff --git a/docs/docs/dev_docs/getting_started/quickstart.md b/docs/docs/dev_docs/getting_started/quickstart.md
new file mode 100644
index 00000000000..664924af16f
--- /dev/null
+++ b/docs/docs/dev_docs/getting_started/quickstart.md
@@ -0,0 +1,116 @@
+---
+title: Quickstart
+---
+
+Get started with the Aztec Sandbox
+
+## Introduction
+
+The Aztec Sandbox is an environment for local development on the Aztec Network. It's easy to get setup with just a single, simple command, and contains all the components needed to develop and test Aztec contracts and applications.
+
+### Background
+
+Aztec's Layer 2 network is a fully programmable combined private/public ZK rollup. To achieve this, the network contains the following primary components:
+
+- Aztec Node - Aggregates all of the 'backend' services necessary for the building and publishing of rollups. This packages is currently in development and much of the functionality is mocked.
+- [Aztec RPC Server](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec-rpc) - Normally residing with the end client, this decrypts and stores a client's private state, executes simulations and submits transactions to the Aztec Node.
+- [Aztec.js](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec.js) - Aztec's client library for interacting with the Aztec RPC Server (think Ethers.js). See the getting started guide [here](./sandbox.md).
+
+All of this is included in the Sandbox, with the exception of Aztec.js which you can use to interact with it.
+
+With the help of Aztec.js you will be able to:
+
+- Create an account
+- Deploy a contract
+- Call view methods on contracts
+- Simulate the calling of contract functions
+- Send transactions to the network
+- Be notified when transactions settle
+- Query chain state such as chain id, block number etc.
+
+This quickstart walks you through installing the Sandbox, deploying your first Noir contract, and verifying its execution!
+
+## Installation
+
+You can run the Sandbox using either Docker or npm.
+
+### With Docker
+
+To install and start the Sandbox paste the line below in a macOS Terminal or Linux shell prompt. You will need to have Docker installed and running on your machine.
+
+```bash
+/bin/bash -c "$(curl -fsSL 'https://sandbox.aztec.network')"
+```
+
+This will attempt to run the Sandbox on localhost:8080, so you will have to make sure nothing else is running on that port or change the port defined in `./.aztec/docker-compose.yml`. Running the command again will overwrite any changes made to the docker-compose.yml.
+
+To install a specific version of the sandbox, you can set the environment variable `SANDBOX_VERSION`
+
+```bash
+SANDBOX_VERSION= /bin/bash -c "$(curl -fsSL 'https://sandbox.aztec.network')"
+```
+
+NOTE: If `SANDBOX_VERSION` is not defined, the script will pull the latest release of the sandbox.
+
+### With npm
+
+You can download and run the Sandbox package directly if you have nodejs 18 or higher installed.
+
+You will also need an Ethereum node like Anvil or Hardhat running locally on port 8545.
+
+```bash
+npx @aztec/aztec-sandbox
+```
+
+### CLI
+
+To interact with the sandbox now that it's running locally, install the Aztec CLI:
+
+```bash
+npm install -g @aztec/cli
+```
+
+## Deploying a contract
+
+The sandbox is preloaded with two accounts. Let's assign them to shell variables. Run the following in your terminal, so we can refer to the accounts as $ALICE and $BOB from now on:
+
+:::note
+The default accounts that come with sandbox will likely change over time. Save two of the "Initial accounts" that are printed in the terminal when you started the sandbox.
+:::
+
+#include_code declare-accounts yarn-project/end-to-end/src/guides/up_quick_start.sh bash
+
+Start by deploying a token contract. After it is deployed, we check that the deployment succeeded, export the deployment address to use in future commands and then call the `_initialize` function. For more detail on how the token contract works, see the [token contract tutorial](./token_contract_tutorial).
+
+#include_code deploy yarn-project/end-to-end/src/guides/up_quick_start.sh bash
+
+The contract address of the newly-deployed contract should be printed to the console. Store this contract address for future commands:
+
+```bash
+CONTRACT="Paste the contract address here"
+```
+
+## Calling a contract
+
+Alice is set up as the contract admin and token minter in the `_initialize` function. Let's get Alice some private tokens.
+
+We need to export the `SECRET` and `SECRET_HASH` values in order to privately mint tokens. Private tokens are claimable by anyone with the pre-image to a provided hash, see more about how the token contract works in the [token contract tutorial](./token_contract_tutorial.md). Once the tokens have been minted, Alice can claim them with the `redeem_shield` function. After this, Alice should have 1000 tokens in their private balance.
+
+#include_code mint-private yarn-project/end-to-end/src/guides/up_quick_start.sh bash
+
+We can have Alice privately transfer tokens to Bob. Only Alice and Bob will know what's happened. Here, we use Alice's private key to send a transaction to transfer tokens to Bob. Once they are transferred, we can verify that it worked as expected by checking Alice's and Bob's balances:
+
+#include_code transfer yarn-project/end-to-end/src/guides/up_quick_start.sh bash
+
+Alice and Bob should have 500 tokens.
+
+Congratulations! You are all set up with the Aztec sandbox!
+
+## Great, but what can I do with it?
+
+Aztec's Layer 2 network is a fully programmable combined private/public ZK rollup. To achieve this, the network contains the following primary components:
+
+- Aztec Node - Aggregates all of the 'backend' services necessary for the building and publishing of rollups.
+- Aztec RPC Server - Normally residing with the end client, this decrypts and stores a client's private state, executes simulations and submits transactions to the Aztec Node.
+- [Aztec.js](./sandbox) - Aztec's client library for interacting with the Aztec RPC Server (think Ethers.js).
+- [Write your own contracts](./noir_contracts.md)
diff --git a/docs/docs/dev_docs/getting_started/sandbox.md b/docs/docs/dev_docs/getting_started/sandbox.md
index acc80c8abbe..621a9e68c0d 100644
--- a/docs/docs/dev_docs/getting_started/sandbox.md
+++ b/docs/docs/dev_docs/getting_started/sandbox.md
@@ -8,7 +8,7 @@ import Image from "@theme/IdealImage";
The Aztec Sandbox aims to provide a local development system against which you can build and test Aztec.nr contracts in a fast, safe, and free environment.
-Here we will walkthrough the process of retrieving the Sandbox, installing the client libraries and using it to deploy and use a fully private token contract on the Aztec network.
+Here we will walkthrough the process of retrieving the Sandbox, installing the client libraries and using it to deploy and use a fully private token contract on the Aztec network using Aztec.js.
## What do you need?
@@ -58,9 +58,9 @@ With the help of Aztec.js you will be able to:
- Be notified when transactions settle
- Query chain state such as chain id, block number etc.
-## I have the Sandbox running, show me how to use it!
+## I have the Sandbox running, show me how to use it
-We will deploy a token contract, and send tokens privately, using the Sandbox.
+We will deploy a token contract, and send tokens privately, using the Sandbox. You can see the final result of the [tutorial code here](https://github.com/AztecProtocol/dev-rel/tree/main/tutorials/sandbox-tutorial/token), if you don't want to follow along, copy and pasting the example code.
Writing the contract itself is out of scope for this tutorial, so we will use a Token Contract which has been pre-supplied as an example. See [here](../contracts/main.md) for more information on how to write contracts for Aztec.
@@ -84,23 +84,7 @@ cd token
yarn init
```
-This should ask a series of questions that you can fill like so:
-
-```
-yarn init v1.22.19
-question name (token):
-question version (1.0.0):
-question description: My first token contract
-question entry point (index.js):
-question repository url:
-question author: Phil
-question license (MIT):
-question private:
-success Saved package.json
-Done in 23.60s.
-```
-
-3. Create a `src` folder inside your new `token` directory:
+1. Create a `src` folder inside your new `token` directory:
```sh
mkdir src
@@ -174,7 +158,15 @@ yarn add @aztec/aztec.js @aztec/noir-contracts
#include_code imports /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript
-and the following setup code:
+Below the imports, set up a function in which we'll add the logic to interact with the Sandbox.
+
+```ts
+async function main() {}
+
+main();
+```
+
+and the following setup code goes in the `main` function:
#include_code setup /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript
@@ -198,7 +190,7 @@ A successful run should show:
}
```
-Great!. The Sandbox is running and we are able to interact with it.
+Great! The Sandbox is running and we are able to interact with it.
## Account Creation/Deployment
@@ -234,14 +226,14 @@ That might seem like a lot to digest but it can be broken down into the followin
2. We wait for the deployment of the 2 account contracts to complete.
3. We retrieve the expected account addresses from the `Account` objects and ensure that they are present in the set of account addresses registered on the Sandbox.
-Note, we use the `getRegisteredAccounts` api to verify that the addresses computed as part of the
+Note, we use the `getRegisteredAccounts` API to verify that the addresses computed as part of the
account contract deployment have been successfully added to the Sandbox.
-If you were looking at your terminal that is running the Sandbox you should hopefully have seen a lot of activity. This is because the Sandbox will have simulated the deployment of both contracts, executed the private kernel circuit for each before submitted 2 transactions to the pool. The sequencer will have picked them up and inserted them into a rollup and executed the recursive rollup circuits before publishing the rollup to Anvil. Once this has completed, the rollup is retrieved and pulled down to the internal RPC Server so that any new account state can be decrypted.
+If you were looking at your terminal that is running the Sandbox you should have seen a lot of activity. This is because the Sandbox will have simulated the deployment of both contracts, executed the private kernel circuit for each before submitted 2 transactions to the pool. The sequencer will have picked them up and inserted them into a rollup and executed the recursive rollup circuits before publishing the rollup to Anvil. Once this has completed, the rollup is retrieved and pulled down to the internal RPC Server so that any new account state can be decrypted.
## Token Contract Deployment
-Now that we have our accounts setup, let's move on to deploy our private token contract. Add this to `index.ts`:
+Now that we have our accounts setup, let's move on to deploy our private token contract. Add this to `index.ts` below the code you added earlier:
#include_code Deployment /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript
@@ -272,7 +264,7 @@ We can break this down as follows:
4. We connect to the contract with Alice
5. Alice initialize the contract with herself as the admin and a minter.
6. Alice adds Bob as minter.
-7. Alice mints 1000000 tokens to be claimed by herself in private.
+7. Alice mints 1,000,000 tokens to be claimed by herself in private.
8. Alice claims the tokens privately.
## Viewing the balance of an account
@@ -281,7 +273,7 @@ A token contract wouldn't be very useful if you aren't able to query the balance
#include_code balance_of_private /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust
-Call this function using the following code:
+Call the `balance_of_private` function using the following code:
#include_code Balance /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript
@@ -306,7 +298,7 @@ Running now should yield output:
token Bob's balance 0 +33ms
```
-In this section, we first created 2 instances of the `PrivateTokenContract` contract abstraction. One for each of our deployed accounts. This contract abstraction offers a Typescript interface reflecting the abi of the contract. We then call `getBalance()` as a `view` method. View methods can be thought as read-only. No transaction is submitted as a result but a user's state can be queried.
+In this section, we created 2 instances of the `TokenContract` contract abstraction, one for each of our deployed accounts. This contract abstraction offers a Typescript interface reflecting the abi of the contract. We then call `getBalance()` as a `view` method. View methods can be thought as read-only. No transaction is submitted as a result but a user's state can be queried.
We can see that each account has the expected balance of tokens.
@@ -319,8 +311,12 @@ Now lets transfer some funds from Alice to Bob by calling the `transfer` functio
3. The quantity of tokens to be transferred.
4. The nonce for the [authentication witness](../../concepts//foundation/accounts/main.md#authorizing-actions), or 0 if msg.sender equal sender.
+Here is the Noir code for the `transfer` function:
+
#include_code transfer /yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr rust
+Here is the Typescript code to call the `transfer` function, add this to your `index.ts` at the bottom of the `main` function:
+
#include_code Transfer /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript
Our output should now look like this:
@@ -354,9 +350,11 @@ Finally, the contract has a `mint` function that can be used to generate new tok
1. The quantity of tokens to be minted.
2. The recipient of the new tokens.
+Here is the Noir code:
+
#include_code mint /yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr rust
-Let's mint some tokens to Bob's account:
+Let's mint some tokens to Bob's account using Typescript, add this to `index.ts`:
#include_code Mint /yarn-project/end-to-end/src/e2e_sandbox_example.test.ts typescript
@@ -389,7 +387,10 @@ Our complete output should now be:
That's it! We have successfully deployed a private token contract to an instance of the Aztec network and mined private state-transitioning transactions. We have also queried the resulting state all via the interfaces provided by the contract.
+You can find the [complete tutorial code here](https://github.com/AztecProtocol/dev-rel/tree/main/tutorials/sandbox-tutorial/token).
+
## Next Steps
-Here we showed how to interact with the sandbox, but didn't go into details on how to write your own contract or any relevant setup needed for it.
-You can find details on setting up [here](./noir_contracts.md) and refer to the [Contracts section](../contracts/main.md) on syntax, compiling, deploying and interacting with how to start writing contracts.
\ No newline at end of file
+Here we showed how to interact with the sandbox, but didn't go into details on how to write your own contract or any relevant setup needed for it.
+
+You can find more information about writing Aztec contracts [here](./noir_contracts.md) and refer to the [Contracts section](../contracts/main.md) on syntax, compiling, deploying and interacting with how to start writing contracts.
diff --git a/docs/docs/dev_docs/getting_started/token_contract_tutorial.md b/docs/docs/dev_docs/getting_started/token_contract_tutorial.md
new file mode 100644
index 00000000000..a0683a8b019
--- /dev/null
+++ b/docs/docs/dev_docs/getting_started/token_contract_tutorial.md
@@ -0,0 +1,909 @@
+# Token Contract Tutorial
+
+In this tutorial we will go through writing a standard L2 native token contract
+for the Aztec Network, using the Aztec.nr contract libraries. It is recommended that you go through the [the introduction to contracts](./noir_contracts) section before this tutorial to gain some familiarity with writing Aztec smart contracts.
+
+This tutorial is intended to help you get familiar with the Aztec.nr library, Aztec contract syntax and some of the underlying structure of the Aztec network.
+
+In this tutorial you will learn how to:
+
+- Write public functions that update public state
+- Write private functions that update private state
+- Implement access control on public and private functions
+- Handle math operations safely
+- Handle different private note types
+- Pass data between private and public state
+
+We are going to start with a blank project and fill in the code defined [here](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr), and explain what is being added as we go.
+
+## Requirements
+
+You will need to install nargo, the Noir build too. if you are familiar with Rust, this is similar to cargo.
+
+
+
+If you've already installed the `aztec-cli`, as described in the quickstart [here](./quickstart#cli), you can check which version of Noir is compatible with your version of the CLI and sandbox by running:
+
+```bash
+aztec-cli get-node-info
+```
+
+It should print something similar to:
+
+```bash
+➜ ~ aztec-cli get-node-info
+
+Node Info:
+
+Version: 1
+Chain Id: 31337
+Rollup Address: 0xcf7ed3acca5a467e9e704c703e8d87f634fb0fc9
+Client: aztec-rpc@0.7.5
+Compatible Nargo Version: 0.11.1-aztec.0
+```
+
+When you are running the Sandbox, `aztec-cli`, and compiling contracts with Noir, make sure you are using matching versions--we will be shipping breaking changes so mis-matched versions may not work.
+
+You should also install the [Noir Language Support extension](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir) for VS Code.
+
+Check the [Dev Tools section](https://github.com/noir-lang/awesome-noir#dev-tools) of the awesome-noir repo for language support for additional editors (Vim, emacs, tree-sitter, etc).
+
+## Project setup
+
+Create a new directory called `token_contract_tutorial`
+
+```bash
+mkdir token_contract_tutorial
+```
+
+inside that directory, create a `contracts` folder for the Aztec contracts.
+
+```bash
+cd token_contract_tutorial && mkdir contracts && cd contracts
+```
+
+Create a new Noir project using nargo.
+
+```bash
+nargo init --name token_contract
+```
+
+Your project should look like this:
+
+```tree
+.
+└── contracts
+ ├── Nargo.toml
+ └── src
+ └── main.nr
+```
+
+Add the following dependencies to your Nargo.toml file, below the package information:
+
+```toml
+[package]
+name = "token_contract"
+authors = [""]
+compiler_version = "0.1"
+type = "contract"
+
+[dependencies]
+aztec = { git="https://github.com/AztecProtocol/aztec-packages/", tag="master", directory="yarn-project/aztec-nr/aztec" }
+value_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="master", directory="yarn-project/aztec-nr/value-note"}
+safe_math = { git="https://github.com/AztecProtocol/aztec-packages/", tag="master", directory="yarn-project/aztec-nr/safe-math"}
+```
+
+## Contract Interface
+
+```rust
+contract Token {
+ #[aztec(private)]
+ fn constructor() {}
+
+ #[aztec(public)]
+ fn set_admin(new_admin: AztecAddress) {}
+
+ #[aztec(public)]
+ fn set_minter(minter: AztecAddress, approve: bool) {}
+
+ #[aztec(public)]
+ fn mint_public(to: AztecAddress, amount: Field) -> Field {}
+
+ #[aztec(public)]
+ fn mint_private(amount: Field, secret_hash: Field) -> Field {}
+
+ #[aztec(public)]
+ fn shield(from: AztecAddress, amount: Field, secret_hash: Field, nonce: Field) -> Field {}
+
+ #[aztec(public)]
+ fn transfer_public(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) -> Field {}
+
+ #[aztec(public)]
+ fn burn_public(from: AztecAddress, amount: Field, nonce: Field) -> Field {}
+
+ // Private functions
+
+ #[aztec(private)]
+ fn redeem_shield(to: AztecAddress, amount: Field, secret: Field) -> Field {}
+
+ #[aztec(private)]
+ fn unshield(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) -> Field {}
+
+ #[aztec(private)]
+ fn transfer(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) -> Field {}
+
+ #[aztec(private)]
+ fn burn(from: AztecAddress, amount: Field, nonce: Field) -> Field {}
+
+ // Internal functions below
+
+ // Will be internal in the future
+ #[aztec(public)]
+ fn _initialize(new_admin: AztecAddress) {}
+
+ #[aztec(public)]
+ internal fn _increase_public_balance(to: AztecAddress, amount: Field) {}
+
+ #[aztec(public)]
+ internal fn _reduce_total_supply(amount: Field) {}
+
+ // Unconstrained functions (read only)
+
+ unconstrained fn admin() -> Field {}
+
+ unconstrained fn is_minter(minter: AztecAddress) -> bool {}
+
+ unconstrained fn total_supply() -> Field {}
+
+ unconstrained fn balance_of_private(owner: AztecAddress) -> Field {}
+
+ unconstrained fn balance_of_public(owner: AztecAddress) -> Field {}
+
+ unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; VALUE_NOTE_LEN]) -> [Field; 4] {}
+}
+```
+
+This specifies the interface of the `Token` contract. Go ahead and copy and paste this interface into your `main.nr` file.
+
+Before we through the interface and implement each function, let's review the functions to get a sense of what the contract does.
+
+### Constructor interface
+
+There is a `constructor` function that will be executed once, when the contract is deployed, similar to the constructor function in Solidity. This is marked private, so the function logic will not be transparent. To execute public function logic in the constructor, this function will call `_initialize` (marked internal, more detail below).
+
+### Public functions
+
+These are functions that have transparent logic, will execute in a publicly verifiable context and can update public storage.
+
+- `set_admin` enables the admin to be updated
+- `set_minter` enables accounts to be added / removed from the approved minter list
+- `mint_public` enables tokens to be minted to the public balance of an account
+- `mint_private` enables tokens to be minted to the private balance of an account (with some caveats we will dig into)
+- `shield` enables tokens to be moved from a public balance to a private balance, not necessarily the same account (step 1 of a 2 step process)
+- `transfer_public` enables users to transfer tokens from one account's public balance to another account's public balance
+- `burn_public` enables users to burn tokens
+
+### Private functions
+
+These are functions that have private logic and will be executed on user devices to maintain privacy. The only data that is submitted to the network is a proof of correct execution, new data [commitments](https://en.wikipedia.org/wiki/Commitment_scheme) and [nullifiers](../../concepts/advanced/data_structures/trees#nullifier-tree), so users will not reveal which contract they are interacting with or which function they are executing. The only information that will be revealed publicly is that someone executed a private transaction on Aztec.
+
+- `redeem_shield` enables accounts to claim tokens that have been made private via `mint_private` or `shield` by providing the secret
+- `unshield` enables an account to send tokens from their private balance to any other account's public balance
+- `transfer` enables an account to send tokens from their private balance to another account's private balance
+- `burn` enables tokens to be burned privately
+
+### Internal functions
+
+Internal functions are functions that can only be called by the contract itself. These can be used when the contract needs to call one of it's public functions from one of it's private functions.
+
+- `_initialize` is a way to call a public function from the `constructor` (which is a private function)
+- `_increase_public_balance` increases the public balance of an account when `unshield` is called
+- `_reduce_total_supply` reduces the total supply of tokens when a token is privately burned
+
+To clarify, let's review some details of the Aztec transaction lifecycle, particularly how a transaction "moves through" these contexts.
+
+#### Execution contexts
+
+Transactions are initiated in the private context, then move to the L2 public context, then to the Ethereum L1 context.
+
+Step 1. Private Execution
+
+Users provide inputs and execute locally on a their device for privacy reasons. Outputs of the private execution are commitment and nullifier updates, a proof of correct execution and any return data to pass to the public execution context.
+
+Step 2. Public Execution
+
+This happens remotely by the sequencer, which takes inputs from the private execution and runs the public code in the network virtual machine, similar to any other public blockchain.
+
+Step 3. Ethereum execution
+
+Aztec transactions can pass data to Ethereum contracts through the rollup via the outbox. The data can consumed by Ethereum contracts at a later time, but this is not part of the transaction flow for an Aztec transaction. The technical details of this are beyond the scope of this tutorial, but we will cover them in an upcoming piece.
+
+### Unconstrained functions
+
+Unconstrained functions can be thought of as view functions from Solidity--they only return information from the contract storage or compute and return data without modifying contract storage.
+
+The `compute_note_hash_and_nullifier` function allows contract devs to specify how to compute notes and nullifiers. This must be included in every contract because it depends on the storage slots, which are defined when we set up storage.
+
+## Contract dependencies
+
+Before we can implement the functions, we need set up the contract storage, and before we do that we need to import the appropriate dependencies.
+
+Just below the contract definition, add the following imports:
+
+```rust
+mod types;
+mod util;
+
+contract Token {
+ use dep::std::option::Option;
+
+ use dep::safe_math::SafeU120;
+
+ use dep::value_note::{
+ balance_utils,
+ utils::{increment, decrement},
+ value_note::{VALUE_NOTE_LEN, ValueNoteMethods, ValueNote},
+ };
+
+ use dep::aztec::{
+ note::{
+ note_header::NoteHeader,
+ utils as note_utils,
+ },
+ context::{PrivateContext, PublicContext, Context},
+ state_vars::{map::Map, public_state::PublicState, set::Set},
+ types::type_serialisation::field_serialisation::{
+ FieldSerialisationMethods, FIELD_SERIALISED_LEN,
+ },
+ oracle::compute_selector::compute_selector,
+ auth::{assert_valid_message_for, assert_valid_public_message_for}
+ };
+
+ use crate::types::{AztecAddress, TransparentNote, TransparentNoteMethods, TRANSPARENT_NOTE_LEN};
+ use crate::account_interface::AccountContract;
+ use crate::util::{compute_message_hash};
+```
+
+We are importing the Option type, items from the `value_note` library to help manage private value storage, note utilities, context (for managing private and public execution contexts), `state_vars` for helping manage state, `types` for data manipulation and `oracle` for help passing data from the private to public execution context. We also import the `auth` [library](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/auth.nr) to handle token authorizations from [Account Contracts](../../concepts/foundation/accounts/main). Check out the Account Contract with AuthWitness [here](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/schnorr_auth_witness_account_contract/src/main.nr).
+
+[SafeU120](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/safe-math/src/safe_u120.nr) is a library to do safe math operations on unsigned integers that protects against overflows and underflows.
+
+For more detail on execution contexts, see [Contract Communitaction](../../concepts/foundation/communication/main).
+
+We are also importing types from a `types.nr` file. Copy [this file](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_contract/src/types.nr) into your `token_contract_tutorial/contracts/src` directory next to main.nr. The main thing to note from this types file is the `TransparentNote` definition. This defines how the contract moves value from the public domain into the private domain. It is similar to the `value_note` that we imported, but with some modifications namely, instead of a defined `owner`, it allows anyone that can produce the pre-image to the stored `secret_hash` to spend the note.
+
+### Note on private state
+
+Private state in Aztec is all [UTXOs](https://en.wikipedia.org/wiki/Unspent_transaction_output) under the hood. Handling UTXOs is largely abstracted away from developers, but there are some unique things for developers to be aware of when creating and managing private state in an Aztec contract. See [State Variables](../contracts/syntax/state_variables) to learn more about public and private state in Aztec.
+
+Copy [`util.nr`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_contract/src/util.nr) into `token_contract_tutorial/contracts/src` as well. The function defined in `util.nr` will be helpful for generating message hashes that are used when communicating between contracts.
+
+## Contract Storage
+
+Now that we have dependencies imported into our contract we can define the storage for the contract.
+
+Below the dependencies, paste the following Storage struct:
+
+```rust
+ struct Storage {
+ admin: PublicState,
+ minters: Map>,
+ balances: Map>,
+ total_supply: PublicState,
+ pending_shields: Set,
+ public_balances: Map>,
+ }
+```
+
+Reading through the storage variables:
+
+- `admin` a single Field value stored in public state. `FIELD_SERIALISED_LEN` indicates the length of the variable, which is 1 in this case because it's a single Field element. A `Field` is basically an unsigned integer with a maximum value determined by the underlying cryptographic curve.
+- `minters` is a mapping of Fields in public state. This will store whether an account is an approved minter on the contract.
+- `balances` is a mapping of private balances. Private balances are stored in a `Set` of `ValueNote`s. The balance is the sum of all of an account's `ValueNote`s.
+- `total_supply` is a Field value stored in public state and represents the total number of tokens minted.
+- `pending_shields` is a `Set` of `TransparentNote`s stored in private state. What is stored publicly is a set of commitments to `TransparentNote`s.
+- `public_balances` is a mapping field elements in public state and represents the publicly viewable balances of accounts.
+
+You can read more about it [here](../contracts/syntax/storage.md).
+
+### Initializing Storage
+
+Once we have Storage defined, we need to specify how to initialize it. The `init` method creates and initializes an instance of `Storage`. We define an initialization method for each of the storage variables defined above. Storage initialization is generic and can largely be reused for similar types, across different contracts, but it is important to note that each storage variable specifies it's storage slot, starting at 1.
+
+Also, the public storage variables define the type that they store by passing the methods by which they are serialized. Because all `PublicState` in this contract is storing Field elements, each storage variable takes `FieldSerialisationMethods`.
+
+```rust
+ impl Storage {
+ fn init(context: Context) -> pub Self {
+ Storage {
+ // storage slot 1
+ admin: PublicState::new(
+ context,
+ 1,
+ FieldSerialisationMethods,
+ ),
+ // storage slot 2
+ minters: Map::new(
+ context,
+ 2,
+ |context, slot| {
+ PublicState::new(
+ context,
+ slot,
+ FieldSerialisationMethods,
+ )
+ },
+ ),
+ // storage slot 3
+ balances: Map::new(
+ context,
+ 3,
+ |context, slot| {
+ Set::new(context, slot, ValueNoteMethods)
+ },
+ ),
+ // storage slot 4
+ total_supply: PublicState::new(
+ context,
+ 4,
+ FieldSerialisationMethods,
+ ),
+ // storage slot 5
+ pending_shields: Set::new(context, 5, TransparentNoteMethods),
+ // storage slot 6
+ public_balances: Map::new(
+ context,
+ 6,
+ |context, slot| {
+ PublicState::new(
+ context,
+ slot,
+ FieldSerialisationMethods,
+ )
+ },
+ ),
+ }
+ }
+ }
+```
+
+## Functions
+
+Copy and paste the body of each function into the appropriate place in your project if you are following along.
+
+### Constructor
+
+In the source code, the constructor logic is commented out. I uncommented it here for legibility, but you should comment out the body of the function in your example, otherwise the contract may not compile.
+
+```rust
+ #[aztec(private)]
+ fn constructor() {
+ // Currently not possible to execute public calls from constructor as code not yet available to sequencer.
+ let selector = compute_selector("_initialize((Field))");
+ let _callStackItem = context.call_public_function(context.this_address(), selector, [context.msg_sender()]);
+ }
+```
+
+The constructor is a private function. There isn't any private state to set up in this function, but there is public state to set up. The `context` is a global variable that is available to private and public functions, but the available methods differ based on the context. You can see the implementation details [here](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/context.nr). The `context.call_public_function` allows a private function to call a public function on any contract. In this case, the constructor is passing the `msg_sender` as the argument to the `_initialize` function, which is also defined in this contract.
+
+### Public function implementations
+
+Public functions are declared with the `#[aztec(public)]` macro above the function name like so:
+
+```rust
+ #[aztec(public)]
+ fn set_admin(
+ new_admin: AztecAddress,
+```
+
+As described in the [execution contexts section above](#execution-contexts), public function logic and transaction information is transparent to the world. Public functions update public state, but can be used to prepare data to be used in a private context, as we will go over below (e.g. see the [shield](#shield) function).
+
+Every public function initializes storage using the public context like so:
+
+```rust
+let storage = Storage::init(Context::public(&mut context));
+```
+
+After this, storage is referenced as `storage.variable`. We won't go over this step in any of the following function descriptions.
+
+#### `set_admin`
+
+After storage is initialized, the contract checks that the `msg_sender` is the `admin`. If not, the transaction will fail. If it is, the `new_admin` is saved as the `admin`.
+
+```rust
+ #[aztec(public)]
+ fn set_admin(
+ new_admin: AztecAddress,
+ ) {
+ let storage = Storage::init(Context::public(&mut context));
+ assert(storage.admin.read() == context.msg_sender(), "caller is not admin");
+ storage.admin.write(new_admin.address);
+ }
+```
+
+#### `set_minter`
+
+This function allows the `admin` to add or a remove a `minter` from the public `minters` mapping. It checks that `msg_sender` is the `admin` and finally adds the `minter` to the `minters` mapping.
+
+```rust
+ #[aztec(public)]
+ fn set_minter(
+ minter: AztecAddress,
+ approve: bool,
+ ) {
+ let storage = Storage::init(Context::public(&mut context));
+ assert(storage.admin.read() == context.msg_sender(), "caller is not admin");
+ storage.minters.at(minter.address).write(approve as Field);
+ }
+```
+
+#### `mint_public`
+
+This function allows an account approved in the public `minters` mapping to create new public tokens owned by the provided `to` address.
+
+First, storage is initialized. Then the function checks that the `msg_sender` is approved to mint in the `minters` mapping. If it is, a new `SafeU120` value is created of the `amount` provided. The function reads the recipients public balance and then adds the amount to mint, saving the output as `new_balance`, then reads to total supply and adds the amount to mint, saving the output as `supply`. `new_balance` and `supply` are then written to storage.
+
+The function returns 1 to indicate successful execution.
+
+```rust
+ #[aztec(public)]
+ fn mint_public(
+ to: AztecAddress,
+ amount: Field,
+ ) -> Field {
+ let storage = Storage::init(Context::public(&mut context));
+ assert(storage.minters.at(context.msg_sender()).read() == 1, "caller is not minter");
+ let amount = SafeU120::new(amount);
+ let new_balance = SafeU120::new(storage.public_balances.at(to.address).read()).add(amount);
+ let supply = SafeU120::new(storage.total_supply.read()).add(amount);
+
+ storage.public_balances.at(to.address).write(new_balance.value as Field);
+ storage.total_supply.write(supply.value as Field);
+ 1
+ }
+```
+
+#### `mint_private`
+
+This public function allows an account approved in the public `minters` mapping to create new private tokens that can be claimed by anyone that has the pre-image to the `secret_hash`.
+
+First, public storage is initialized. Then it checks that the `msg_sender` is an approved minter. Then a new `TransparentNote` is created with the specified `amount` and `secret_hash`. You can read the details of the `TransparentNote` in the `types.nr` file [here](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_contract/src/types.nr#L61). The `amount` is added to the existing public `total_supply` and the storage value is updated. Then the new `TransparentNote` is added to the `pending_shields` using the `insert_from_public` function, which is accessible on the `Set` type. Then it's ready to be claimed by anyone with the `secret_hash` pre-image using the `redeem_shield` function. It returns `1` to indicate successful execution.
+
+```rust
+ #[aztec(public)]
+ fn mint_private(
+ amount: Field,
+ secret_hash: Field,
+ ) -> Field {
+ let storage = Storage::init(Context::public(&mut context));
+ assert(storage.minters.at(context.msg_sender()).read() == 1, "caller is not minter");
+ let pending_shields = storage.pending_shields;
+ let mut note = TransparentNote::new(amount, secret_hash);
+ let supply = SafeU120::new(storage.total_supply.read()).add(SafeU120::new(amount));
+
+ storage.total_supply.write(supply.value as Field);
+ pending_shields.insert_from_public(&mut note);
+ 1
+ }
+```
+
+#### `shield`
+
+This public function enables an account to stage tokens from it's `public_balance` to be claimed as a private `TransparentNote` by any account that has the pre-image to the `secret_hash`.
+
+First, storage is initialized. Then it checks whether the calling contract (`context.msg_sender`) matches the account that the funds will be debited from.
+
+##### Authorizing token spends
+
+If the `msg_sender` is **NOT** the same as the account to debit from, the function checks that the account has authorized the `msg_sender` contract to debit tokens on its behalf. This check is done by computing the function selector that needs to be authorized (in this case, the `shield` function), computing the hash of the message that the account contract has approved. This is a hash of the contract that is approved to spend (`context.msg_sender`), the token contract that can be spent from (`context.this_address()`), the `selector`, the account to spend from (`from.address`), the `amount`, the `secret_hash` and a `nonce` to prevent multiple spends. This hash is passed to `assert_valid_public_message_for` to ensure that the Account Contract has approved tokens to be spent on it's behalf.
+
+If the `msg_sender` is the same as the account to debit tokens from, the authorization check is bypassed and the function proceeds to update the account's `public_balance` and adds a new `TransparentNote` to the `pending_shields`.
+
+It returns `1` to indicate successful execution.
+
+```rust
+ #[aztec(public)]
+ fn shield(
+ from: AztecAddress,
+ amount: Field,
+ secret_hash: Field,
+ nonce: Field,
+ ) -> Field {
+ let storage = Storage::init(Context::public(&mut context));
+
+ if (from.address != context.msg_sender()) {
+ // The redeem is only spendable once, so we need to ensure that you cannot insert multiple shields from the same message.
+ let selector = compute_selector("shield((Field),Field,Field,Field)");
+ let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, amount, secret_hash, nonce]);
+ assert_valid_public_message_for(&mut context, from.address, message_field);
+ } else {
+ assert(nonce == 0, "invalid nonce");
+ }
+
+ let amount = SafeU120::new(amount);
+ let from_balance = SafeU120::new(storage.public_balances.at(from.address).read()).sub(amount);
+
+ let pending_shields = storage.pending_shields;
+ let mut note = TransparentNote::new(amount.value as Field, secret_hash);
+
+ storage.public_balances.at(from.address).write(from_balance.value as Field);
+ pending_shields.insert_from_public(&mut note);
+ 1
+ }
+```
+
+#### `transfer_public`
+
+This public function enables public transfers between Aztec accounts. The sender's public balance will be debited the specified `amount` and the recipient's public balances will be credited with that amount.
+
+After storage is initialized, the [authorization flow specified above](#authorizing-token-spends) is checked. Then the sender and recipient's balances are updated and saved to storage using the `SafeU120` library.
+
+```rust
+ #[aztec(public)]
+ fn transfer_public(
+ from: AztecAddress,
+ to: AztecAddress,
+ amount: Field,
+ nonce: Field,
+ ) -> Field {
+ let storage = Storage::init(Context::public(&mut context));
+
+ if (from.address != context.msg_sender()) {
+ let selector = compute_selector("transfer_public((Field),(Field),Field,Field)");
+ let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, to.address, amount, nonce]);
+ assert_valid_public_message_for(&mut context, from.address, message_field);
+ } else {
+ assert(nonce == 0, "invalid nonce");
+ }
+
+ let amount = SafeU120::new(amount);
+ let from_balance = SafeU120::new(storage.public_balances.at(from.address).read()).sub(amount);
+ storage.public_balances.at(from.address).write(from_balance.value as Field);
+
+ let to_balance = SafeU120::new(storage.public_balances.at(to.address).read()).add(amount);
+ storage.public_balances.at(to.address).write(to_balance.value as Field);
+
+ 1
+ }
+```
+
+#### `burn_public`
+
+This public function enables public burning (destroying) of tokens from the sender's public balance.
+
+After storage is initialized, the [authorization flow specified above](#authorizing-token-spends) is checked. Then the sender's public balance and the `total_supply` are updated and saved to storage using the `SafeU120` library.
+
+```rust
+ #[aztec(public)]
+ fn burn_public(
+ from: AztecAddress,
+ amount: Field,
+ nonce: Field,
+ ) -> Field {
+ let storage = Storage::init(Context::public(&mut context));
+
+ if (from.address != context.msg_sender()) {
+ let selector = compute_selector("burn_public((Field),Field,Field)");
+ let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, amount, nonce]);
+ assert_valid_public_message_for(&mut context, from.address, message_field);
+ } else {
+ assert(nonce == 0, "invalid nonce");
+ }
+
+ let amount = SafeU120::new(amount);
+ let from_balance = SafeU120::new(storage.public_balances.at(from.address).read()).sub(amount);
+ storage.public_balances.at(from.address).write(from_balance.value as Field);
+
+ let new_supply = SafeU120::new(storage.total_supply.read()).sub(amount);
+ storage.total_supply.write(new_supply.value as Field);
+
+ 1
+ }
+```
+
+### Private function implementations
+
+Private functions are declared with the `#[aztec(private)]` macro above the function name like so:
+
+```rust
+ #[aztec(private)]
+ fn redeem_shield(
+```
+
+As described in the [execution contexts section above](#execution-contexts), private function logic and transaction information is hidden from the world and is executed on user devices. Private functions update private state, but can pass data to the public execution context (e.g. see the [`unshield`](#unshield) function).
+
+Every private function initializes storage using the private context like so:
+
+```rust
+let storage = Storage::init(Context::private(&mut context));
+```
+
+After this, storage is referenced as `storage.variable`. We won't go over this step in any of the following function descriptions.
+
+#### `redeem_shield`
+
+This private function enables an account to move tokens from a `TransparentNote` in the `pending_shields` mapping to any Aztec account as a `ValueNote` in private `balances`.
+
+Going through the function logic, first storage is initialized. Then it gets the private balance for the recipient. A `TransparentNote` is created from the `amount` and `secret` and verified to exist storage in `pending_shields` with the `assert_contains_and_remove_publicly_created` method. If that is verified, the recipient's private balance is incremented using the `increment` helper function from the `value_note` [library](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/value-note/src/utils.nr).
+
+The function returns `1` to indicate successful execution.
+
+```rust
+ #[aztec(private)]
+ fn redeem_shield(
+ to: AztecAddress,
+ amount: Field,
+ secret: Field,
+ ) -> Field {
+ let storage = Storage::init(Context::private(&mut context));
+ let pending_shields = storage.pending_shields;
+ let balance = storage.balances.at(to.address);
+ let mut public_note = TransparentNote::new_from_secret(amount, secret);
+
+ pending_shields.assert_contains_and_remove_publicly_created(&mut public_note);
+ increment(balance, amount, to.address);
+
+ 1
+ }
+```
+
+#### `unshield`
+
+This private function enables un-shielding of private `ValueNote`s stored in `balances` to any Aztec account's `public_balance`.
+
+After initializing storage, the function checks that the `msg_sender` is authorized to spend tokens. See [the Authorizing token spends section](#authorizing-token-spends) above for more detail--the only difference being that `assert_valid_message_for` is modified to work specifically in the private context. After the authorization check, the sender's private balance is decreased using the `decrement` helper function for the `value_note` library. Then it stages a public function call on this contract ([`_increase_public_balance`](#_increase_public_balance)) to be executed in the [public execution phase](#execution-contexts) of transaction execution. `_increase_public_balance` is marked as an `internal` function, so can only be called by this token contract.
+
+The function returns `1` to indicate successful execution.
+
+```rust
+ #[aztec(private)]
+ fn unshield(
+ from: AztecAddress,
+ to: AztecAddress,
+ amount: Field,
+ nonce: Field,
+ ) -> Field {
+ let storage = Storage::init(Context::private(&mut context));
+
+ if (from.address != context.msg_sender()) {
+ let selector = compute_selector("unshield((Field),(Field),Field,Field)");
+ let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, to.address, amount, nonce]);
+ assert_valid_message_for(&mut context, from.address, message_field);
+ } else {
+ assert(nonce == 0, "invalid nonce");
+ }
+
+ let from_balance = storage.balances.at(from.address);
+ decrement(from_balance, amount, from.address);
+
+ let selector = compute_selector("_increase_public_balance((Field),Field)");
+ let _void = context.call_public_function(context.this_address(), selector, [to.address, amount]);
+
+ 1
+ }
+```
+
+#### `transfer`
+
+This private function enables private token transfers between Aztec accounts.
+
+After initializing storage, the function checks that the `msg_sender` is authorized to spend tokens. See [the Authorizing token spends section](#authorizing-token-spends) above for more detail--the only difference being that `assert_valid_message_for` is modified to work specifically in the private context. After authorization, the function gets the current balances for the sender and recipient and decrements and increments them, respectively, using the `value_note` helper functions.
+
+```rust
+ #[aztec(private)]
+ fn transfer(
+ from: AztecAddress,
+ to: AztecAddress,
+ amount: Field,
+ nonce: Field,
+ ) -> Field {
+ let storage = Storage::init(Context::private(&mut context));
+
+ if (from.address != context.msg_sender()) {
+ let selector = compute_selector("transfer((Field),(Field),Field,Field)");
+ let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, to.address, amount, nonce]);
+ assert_valid_message_for(&mut context, from.address, message_field);
+ } else {
+ assert(nonce == 0, "invalid nonce");
+ }
+
+ let from_balance = storage.balances.at(from.address);
+ let to_balance = storage.balances.at(to.address);
+
+ decrement(from_balance, amount, from.address);
+ increment(to_balance, amount, to.address);
+
+ 1
+ }
+```
+
+#### `burn`
+
+This private function enables accounts to privately burn (destroy) tokens.
+
+After initializing storage, the function checks that the `msg_sender` is authorized to spend tokens. Then it gets the sender's current balance and decrements it. Finally it stages a public function call to [`_reduce_total_supply`](#_reduce_total_supply).
+
+```rust
+ #[aztec(private)]
+ fn burn(
+ from: AztecAddress,
+ amount: Field,
+ nonce: Field,
+ ) -> Field {
+ let storage = Storage::init(Context::private(&mut context));
+
+ if (from.address != context.msg_sender()) {
+ let selector = compute_selector("burn((Field),Field,Field)");
+ let message_field = compute_message_hash([context.msg_sender(), context.this_address(), selector, from.address, amount, nonce]);
+ assert_valid_message_for(&mut context, from.address, message_field);
+ } else {
+ assert(nonce == 0, "invalid nonce");
+ }
+
+ let from_balance = storage.balances.at(from.address);
+
+ decrement(from_balance, amount, from.address);
+
+ let selector = compute_selector("_reduce_total_supply(Field)");
+ let _void = context.call_public_function(context.this_address(), selector, [amount]);
+
+ 1
+ }
+```
+
+### Internal function implementations
+
+Internal functions are functions that can only be called by this contract. The following 3 functions are public functions that are called from the [private execution context](#execution-contexts). Marking these as `internal` ensures that only the desired private functions in this contract are able to call them. Private functions defer execution to public functions because private functions cannot update public state directly.
+
+#### `_initialize`
+
+This function is called via the [constructor](#constructor). Note that it is not actually marked `internal` right now--this is because this functionality is still being worked on.
+
+This function sets the creator of the contract (passed as `msg_sender` from the constructor) as the admin and makes them a minter.
+
+```rust
+ // We cannot do this from the constructor currently
+ // Since this should be internal, for now, we ignore the safety checks of it, as they are
+ // enforced by it being internal and only called from the constructor.
+ #[aztec(public)]
+ fn _initialize(
+ new_admin: AztecAddress,
+ ) {
+ let storage = Storage::init(Context::public(&mut context));
+ storage.admin.write(new_admin.address);
+ storage.minters.at(new_admin.address).write(1);
+ }
+```
+
+#### `_increase_public_balance`
+
+This function is called from [`unshield`](#unshield). The account's private balance is decremented in `shield` and the public balance is increased in this function.
+
+```rust
+ #[aztec(public)]
+ internal fn _increase_public_balance(
+ to: AztecAddress,
+ amount: Field,
+ ) {
+ let storage = Storage::init(Context::public(&mut context));
+ let new_balance = SafeU120::new(storage.public_balances.at(to.address).read()).add(SafeU120::new(amount));
+ storage.public_balances.at(to.address).write(new_balance.value as Field);
+ }
+```
+
+#### `_reduce_total_supply`
+
+This function is called from [`burn`](#burn). The account's private balance is decremened in `burn` and the public `total_supply` is reduced in this function.
+
+```rust
+ #[aztec(public)]
+ internal fn _reduce_total_supply(
+ amount: Field,
+ ) {
+ // Only to be called from burn.
+ let storage = Storage::init(Context::public(&mut context));
+ let new_supply = SafeU120::new(storage.total_supply.read()).sub(SafeU120::new(amount));
+ storage.total_supply.write(new_supply.value as Field);
+ }
+```
+
+### Unconstrained function implementations
+
+Unconstrained functions are similar to `view` functions in Solidity in that they only return information from the contract storage or compute and return data without modifying contract storage.
+
+#### `admin`
+
+A getter function for reading the public `admin` value.
+
+```rust
+ unconstrained fn admin() -> Field {
+ let storage = Storage::init(Context::none());
+ storage.admin.read()
+ }
+```
+
+#### `is_minter`
+
+A getter function for checking the value of associated with a `minter` in the public `minters` mapping.
+
+```rust
+ unconstrained fn is_minter(
+ minter: AztecAddress,
+ ) -> bool {
+ let storage = Storage::init(Context::none());
+ storage.minters.at(minter.address).read() as bool
+ }
+```
+
+#### `total_supply`
+
+A getter function for checking the token `total_supply`.
+
+```rust
+ unconstrained fn total_supply() -> Field {
+ let storage = Storage::init(Context::none());
+ storage.total_supply.read()
+ }
+```
+
+#### `balance_of_private`
+
+A getter function for checking the private balance of the provided Aztec account. Note that the [Aztec RPC Server](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec-rpc) must have access to the `owner`s decryption keys in order to decrypt their notes.
+
+```rust
+ unconstrained fn balance_of_private(
+ owner: AztecAddress,
+ ) -> Field {
+ let storage = Storage::init(Context::none());
+ let owner_balance = storage.balances.at(owner.address);
+
+ balance_utils::get_balance(owner_balance)
+ }
+```
+
+#### `balance_of_public`
+
+A getter function for checking the public balance of the provided Aztec account.
+
+```rust
+ unconstrained fn balance_of_public(
+ owner: AztecAddress,
+ ) -> Field {
+ let storage = Storage::init(Context::none());
+ storage.public_balances.at(owner.address).read()
+ }
+```
+
+#### `compute_note_hash_and_nullifier`
+
+A getter function to compute the note hash and nullifier for notes in the contract's storage.
+
+This must be included in every contract because it depends on the storage slots, which are defined when we set up storage.
+
+```rust
+ // Computes note hash and nullifier.
+ // Note 1: Needs to be defined by every contract producing logs.
+ // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes.
+ unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; VALUE_NOTE_LEN]) -> [Field; 4] {
+ let note_header = NoteHeader { contract_address, nonce, storage_slot };
+ if (storage_slot == 5) {
+ note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, preimage)
+ } else {
+ note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, preimage)
+ }
+ }
+```
+
+## Compiling
+
+Now that the contract is complete, you should be able to compile it with the `aztec-cli`. See the [CLI page](../cli/cli.md) for instructions on setting it up.
+
+```bash
+aztec-cli compile /path/to/token_contracts_folder
+```
+
+## Testing
+
+End to end tests for reference:
+
+https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/end-to-end/src/e2e_token_contract.test.ts
diff --git a/docs/docs/dev_docs/limitations/main.md b/docs/docs/dev_docs/limitations/main.md
index ee620445d9b..7790b895cff 100644
--- a/docs/docs/dev_docs/limitations/main.md
+++ b/docs/docs/dev_docs/limitations/main.md
@@ -1,8 +1,9 @@
-# Limitations
+---
+title: Limitations
+---
The Aztec Sandbox and the Aztec Smart Contract Library are **prototypes**, and should be treated as such. They've been released early, to gather feedback on the capabilities of the protocol and user experiences.
-
## What to expect?
- Regular Breaking Changes;
@@ -11,17 +12,16 @@ The Aztec Sandbox and the Aztec Smart Contract Library are **prototypes**, and s
- An 'unpolished' UX;
- Missing information.
-
## Why isn't it working perfectly yet?
These things take time :)
-
## Why participate?
Front-run the future!
Help shape and define:
+
- Previously-impossible smart contracts and applications
- Network tooling;
- Network standards;
@@ -29,19 +29,15 @@ Help shape and define:
- Educational content;
- Core protocol improvements;
-
-
## Limitations
There are plans to resolve all of the below. See also the [engineering roadmap](../../about_aztec/roadmap/engineering_roadmap.md).
-
-### It is not audited.
+### It is not audited
None of the Sandbox code is audited. It's being iterated-on every day. It will not be audited for quite some time.
-
-### No Proofs!
+### No Proofs
That's right, the Sandbox doesn't actually generate or verify any zk-SNARKs yet!
@@ -55,7 +51,6 @@ By the time mainnet comes around, zk-SNARKs will be needed in order to validate
But proofs are really only needed as a protection against malicious behaviour. The Sandbox is an emulated ecosystem; entirely contained within your laptop, and it follows the network's rules out of the box. So as long as its inner workings aren't tampered-with, it will act 'honestly'. Since you'll be the only person interacting with the Sandbox on your own laptop, and with a healthy assumption that you should be honest with yourself, you won't need proofs when testing.
-
### No Circuits!
This is kind-of a repetition of ['No Proofs!'](#no-proofs) above, but for the sake of clarity, there aren't yet any arithmetic circuits in the Sandbox. We might refer to certain components of the core protocol as being 'circuits', and we might refer to user-defined smart contract functions as being compiled to 'circuits', but the Sandbox doesn't actually contain any circuits yet. Instead, there is code which emulates the logic of a circuit. This is intentional, to make execution of the Sandbox as fast as possible.
@@ -64,10 +59,9 @@ Obviously, as development continues, the so-called 'circuits' will actually beco
#### What are the consequences?
-The Sandbox will execute more quickly. The logic of all 'circuits' is still in place*. Smart contract logic will be executed, and core protocol logic will be executed*. So invalid transactions will be caught* and rejected.
-
-*Note: some core protocol circuit assertions and constraints still need to be written (see [GitHub](https://github.com/AztecProtocol/aztec-packages/issues)). This would be bad in an adversarial environment, but the Sandbox is not that. Naturally, proper circuits will need to be written - see the [engineering roadmap](../../about_aztec/roadmap/engineering_roadmap.md).
+The Sandbox will execute more quickly. The logic of all 'circuits' is still in place*. Smart contract logic will be executed, and core protocol logic will be executed*. So invalid transactions will be caught\* and rejected.
+\*Note: some core protocol circuit assertions and constraints still need to be written (see [GitHub](https://github.com/AztecProtocol/aztec-packages/issues)). This would be bad in an adversarial environment, but the Sandbox is not that. Naturally, proper circuits will need to be written - see the [engineering roadmap](../../about_aztec/roadmap/engineering_roadmap.md).
### No Fees!
@@ -81,7 +75,6 @@ The Sandbox can currently be thought of as a bare-minimum execution layer. We'll
Apps won't yet be able to allow for any L2 fee logic. Once fees are introduced, this will cause breaking changes to in-progress apps, which will need to be updated to accommodate the notion of paying network fees for transactions. Clear documentation will be provided.
-
### Basic Keys and Addresses!
The way in which keypairs and addresses are currently derived and implemented (inside the Sandbox) is greatly over-simplified, relative to future plans.
@@ -105,13 +98,11 @@ This will impact the kinds of apps that you can build with the Sandbox, as it is
Please open new discussions on [discourse](http://discourse.aztec.network) or open issues on [github](http://github.com/AztecProtocol/aztec-packages), if you have requirements that aren't-yet being met by the Sandbox's current key derivation scheme.
-
### It's not-yet decentralised
It's an emulated blockchain entirely contained within your own laptop! It's centralised by design!
As for deploying this all to mainnet, a decentralised sequencer selection and prover selection protocols are still [being discussed](https://discourse.aztec.network/t/request-for-proposals-decentralized-sequencer-selection/350). There are plans for decentralised testnets in 2024.
-
### You can't read mutable public state from a private function
Private smart contract functions won't be able to read mutable public state yet. We have some [ideas](https://discourse.aztec.network/t/accessing-historic-public-state-from-private-functions/241/7?u=mike) for how to solve this, and will look to implement something very soon.
@@ -120,7 +111,6 @@ Private smart contract functions won't be able to read mutable public state yet.
Reading public state from a private contract will be a common pattern. For example, it's needed if you want to maintain a public whitelist/blacklist, but prove you are/aren't on that blacklist privately. This will be a high priority, coming soon.
-
### No delegatecalls
A contract can't perform a delegatecall yet (if ever). Delegatecalls are quite a controversial feature of the EVM.
@@ -131,7 +121,6 @@ Ethereum has a notion of a 'full node' which keeps-up with the blockchain and st
This pattern is likely to develop in Aztec as well, except there's a problem: privacy. If a privacy-seeking user makes a query to a 3rd-party 'full node', that user might leak data about who they are, or about their historic network activity, or about their future intentions. One solution to this problem is "always run a full node", but pragmatically, not everyone will. To protect less-advanced users' privacy, [research is underway](../../about_aztec/roadmap/engineering_roadmap.md) to explore how a privacy-seeking user may request and receive data from a 3rd-party node without revealing what that data is, nor who is making the request.
-
### No private data authentication
Private data should not be returned to an app, unless the user authorizes such access to the app. An authorization layer is not-yet in place.
@@ -142,7 +131,6 @@ Any app can request and receive any private user data relating to any other priv
An auth layer will be added in due course.
-
### No bytecode validation
Bytecode should not be executed, unless the Sandbox has validated that the user's intentions (the function signature and contract address) match the bytecode.
@@ -153,7 +141,6 @@ Without such 'bytecode validation', if the incorrect bytecode is executed, and t
There are plans to add bytecode validation soon.
-
### Insecure hashes
Currently, Pedersen hashes are being used pretty-much everywhere. To any cryptographers reading this, don't panic. A thorough review of which hashes to use in which part of the protocol will be conducted soon.
@@ -162,8 +149,7 @@ Additionally, domain separation of hashes needs some review.
#### What are the consequences?
-Collisions and other hash-related attacks might be possible in the Sandbox. Obviously that would be bad in production. But it's unlikely to cause problems at this early stage of testing.
-
+Collisions and other hash-related attacks might be possible in the Sandbox. Obviously that would be bad in production. But it's unlikely to cause problems at this early stage of testing.
### `msg_sender` is leaked when making a private -> public call
@@ -174,7 +160,6 @@ There are [ongoing discussions](https://discourse.aztec.network/t/who-is-msg-sen
When a private function makes a call to a public function, the `msg_sender` of the calling function will be given to the public world. Most critically, this includes if the `msg_sender` is an account contract.
This will be patched in the near future, but unfortunately, app developers might need to 'overlook' this privacy leakage until then, with the assumption that it will be fixed. But note, one possible 'patch' might be to set `msg_sender` to `0` for all private -> public calls. This might cause breaking changes to your public functions, if they rely on reading `msg_sender`. There are patterns to work around this, but they wouldn't be pretty, and we won't go into details until a solution is chosen. Sorry about this, and thanks for your patience whilst we work this out :)
-
### New Privacy Standards are required
There are many [patterns](../privacy/main.md) which can leak privacy, even on Aztec. Standards haven't been developed yet, to encourage best practices when designing private smart contracts.
@@ -183,12 +168,11 @@ There are many [patterns](../privacy/main.md) which can leak privacy, even on Az
For example, until community standards are developed to reduce the uniqueness of ['Tx Fingerprints'](../privacy/main.md#function-fingerprints-and-tx-fingerprints) app developers might accidentally forfeit some function privacy.
-
## Circuit limitations
### Upper limits on function outputs and tx outputs
-Due to the rigidity of zk-SNARK circuits, there are upper bounds on the amount of computation a circuit can perform, and on the amount of data that can be passed into and out of a function. See [Aztec function ABIs](../contracts/abi.md) for more information.
+Due to the rigidity of zk-SNARK circuits, there are upper bounds on the amount of computation a circuit can perform, and on the amount of data that can be passed into and out of a function.
> Blockchain developers are no stranger to restrictive computational environments. Ethereum has gas limits, local variable stack limits, call stack limits, contract deployment size limits, log size limits, etc.
@@ -198,7 +182,8 @@ Here are the current constants:
#### What are the consequences?
-When you write an [Aztec.nr](../contracts/main.md) [function](../contracts/functions.md), there will be upper bounds on the following:
+When you write an [Aztec.nr](../contracts/main.md) [function](../contracts/syntax/functions.md), there will be upper bounds on the following:
+
- The number of public state reads and writes;
- The number of note reads and nullifications;
- The number of new notes that may be created;
@@ -224,24 +209,29 @@ Each function call is represented by a circuit with a dedicated zero-knowledge p
Note that there is no plan to change this in the future.
### Example
+
Let us assume that the main function named $f_1$ is calling in order $f_2$, $f_3$ (which calls $f_5$ folllowed by $f_6$), and $f_4$.
Call Dependency:
+
> $f_1 \longrightarrow f_2$, $f_3$, $f_4$
> $f_3 \longrightarrow f_5$, $f_6$
Execution Order:
-> $f_1$, $f_2$, $f_3$, $f_5$, $f_6$, $f_4$
+> $f_1$, $f_2$, $f_3$, $f_5$, $f_6$, $f_4$
Private Kernel Processing Order:
+
> $f_1$, $f_4$, $f_3$, $f_6$, $f_5$, $f_2$
#### What are the consequences?
+
Transaction output elements such as notes in encrypted logs, note hashes (commitments), nullifiers might be ordered differently than the one exepected by the execution.
### Chopped Transient Notes are still Emitted in Logs
+
A note which is created and nullified during the very same transaction is called transient. Such a note is chopped by the [private kernel circuit](../../concepts/advanced/circuits/kernels/private_kernel.md) and is never stored in any persistent data tree.
For the time being, such chopped notes are still emitted through encrypted logs (which is the communication channel to transmit notes). When a log containing a chopped note is processed, a warning will be logged about a decrypted note which does not exist in data tree. We [improved](https://github.com/AztecProtocol/aztec-packages/issues/1603) error logging to help identify such an occurence. However, this might be a source of confusion.
@@ -249,8 +239,8 @@ This issue is tracked in ticket [#1641](https://github.com/AztecProtocol/aztec-p
### Note Terminology: Note Commitments and Note Hashes
-The notes or UTXOs in Aztec need to be compressed before they are added to the trees. To do so, we need to hash all the data inside a note using a collision-resistant hash function. Currently, we use Pedersen hash (using lookup tables) to compress note data. The compressed note data is referred to as "note commitments" in our architecture. However, note commitments are referred to as "note hashes" in aztec-noir code. Be mindful of that fact that note commitments and note hashes mean the same thing. Note that we only mean to talk about terminology here and in no way one should infer security/cryptographic properties (e.g., hiding, binding) based on the name. Namely, notes come with different flavours of security properties depending on the use case.
+The notes or UTXOs in Aztec need to be compressed before they are added to the trees. To do so, we need to hash all the data inside a note using a collision-resistant hash function. Currently, we use Pedersen hash (using lookup tables) to compress note data. The compressed note data is referred to as "note commitments" in our architecture. However, note commitments are referred to as "note hashes" in aztec-noir code. Be mindful of that fact that note commitments and note hashes mean the same thing. Note that we only mean to talk about terminology here and in no way one should infer security/cryptographic properties (e.g., hiding, binding) based on the name. Namely, notes come with different flavours of security properties depending on the use case.
## There's more
-See the [GitHub issues](https://github.com/AztecProtocol/aztec-packages/issues) for all known bugs fixes and features currently being worked on.
\ No newline at end of file
+See the [GitHub issues](https://github.com/AztecProtocol/aztec-packages/issues) for all known bugs fixes and features currently being worked on.
diff --git a/docs/docs/dev_docs/sandbox/main.md b/docs/docs/dev_docs/sandbox/main.md
index 2f33ffa684a..66d4e60c755 100644
--- a/docs/docs/dev_docs/sandbox/main.md
+++ b/docs/docs/dev_docs/sandbox/main.md
@@ -1,17 +1,9 @@
-# Aztec Sandbox
+---
+title: Aztec Sandbox
+---
## What is the Aztec Sandbox?
The Aztec Sandbox is local development system against which you can build and test Aztec.nr contracts in a fast, safe, and free environment.
-To learn more and to download to for yourself you can visit the [website](https://sandbox.aztec.network).
-
-## Requirements
-
-The Sandbox runs on Docker, so any x86 Docker environment should be able to host it.
-
-The following command will download and execute a script that uses docker compose to launch an instance of Anvil and the Sandbox side by side. This will get you up and running in just a few seconds.
-
-`/bin/bash -c "$(curl -fsSL 'https://sandbox.aztec.network')"`
-
-For a complete walk-through deploying and using a private contract, see our [getting started guide](../getting_started/sandbox.md).
+For a complete walk-through deploying and using a private contract with the Sandbox and CLI, see our [quickstart](../getting_started/quickstart).
diff --git a/docs/docs/dev_docs/testing/cheat_codes.md b/docs/docs/dev_docs/testing/cheat_codes.md
index 458b5f406db..4e2ca1ac099 100644
--- a/docs/docs/dev_docs/testing/cheat_codes.md
+++ b/docs/docs/dev_docs/testing/cheat_codes.md
@@ -6,7 +6,7 @@ title: Cheat Codes
To help with testing, the sandbox is shipped with a set of cheatcodes.
-Cheatcodes allow you to change the time of the Aztec block, load certain state or more easily manipulate Ethereum instead of having to write dedicated RPC calls to anvil or hardhat.
+Cheatcodes allow you to change the time of the Aztec block, load certain state or more easily manipulate Ethereum instead of having to write dedicated RPC calls to anvil or hardhat.
:::info Prerequisites
If you aren't familiar with [Anvil](https://book.getfoundry.sh/anvil/), we recommend reading up on that since Aztec Sandbox uses Anvil as the local Ethereum instance.
@@ -15,18 +15,21 @@ If you aren't familiar with [Anvil](https://book.getfoundry.sh/anvil/), we recom
### Aims
The guide will cover how to manipulate the state of the:
+
- Ethereum blockchain;
- Aztec network.
### Dependencies
For this guide, the following Aztec packages are used:
+
- @aztec/aztec.js
### Initialisation
+
```ts
-import { createAztecRpcClient, CheatCodes } from '@aztec/aztec.js';
-const aztecRpcUrl = 'http://localhost:8080';
+import { createAztecRpcClient, CheatCodes } from "@aztec/aztec.js";
+const aztecRpcUrl = "http://localhost:8080";
const aztecRpcClient = createAztecRpcClient(aztecRpcUrl);
const cc = await CheatCodes.create(aztecRpcUrl, aztecRpcClient);
```
@@ -34,178 +37,204 @@ const cc = await CheatCodes.create(aztecRpcUrl, aztecRpcClient);
There are two properties of the CheatCodes class - `eth` and `aztec` for cheatcodes relating to the Ethereum blockchain (L1) and the Aztec network (L2) respectively.
## Ethereum related cheatcodes
+
These are cheatcodes exposed from anvil/hardhat conveniently wrapped for ease of use in the Sandbox.
### Interface
+
```ts
// Fetch current block number of Ethereum
-public async blockNumber(): Promise
+public async blockNumber(): Promise
// Fetch chain ID of the local Ethereum instance
-public async chainId(): Promise
+public async chainId(): Promise
// Fetch current timestamp on Ethereum
-public async timestamp(): Promise
+public async timestamp(): Promise
// Mine a given number of blocks on Ethereum. Mines 1 block by default
-public async mine(numberOfBlocks = 1): Promise
+public async mine(numberOfBlocks = 1): Promise
-// Set the timestamp for the next block on Ethereum.
-public async setNextBlockTimestamp(timestamp: number): Promise
+// Set the timestamp for the next block on Ethereum.
+public async setNextBlockTimestamp(timestamp: number): Promise
-// Dumps the current Ethereum chain state to a given file.
-public async dumpChainState(fileName: string): Promise
+// Dumps the current Ethereum chain state to a given file.
+public async dumpChainState(fileName: string): Promise
-// Loads the Ethereum chain state from a file. You may use `dumpChainState()` to save the state of the Ethereum chain to a file and later load it.
-public async loadChainState(fileName: string): Promise
+// Loads the Ethereum chain state from a file. You may use `dumpChainState()` to save the state of the Ethereum chain to a file and later load it.
+public async loadChainState(fileName: string): Promise
// Load the value at a storage slot of a contract address on Ethereum
-public async load(contract: EthAddress, slot: bigint): Promise
+public async load(contract: EthAddress, slot: bigint): Promise
-// Set the value at a storage slot of a contract address on Ethereum (e.g. modify a storage variable on your portal contract or even the rollup contract).
-public async store(contract: EthAddress, slot: bigint, value: bigint): Promise
+// Set the value at a storage slot of a contract address on Ethereum (e.g. modify a storage variable on your portal contract or even the rollup contract).
+public async store(contract: EthAddress, slot: bigint, value: bigint): Promise
// Computes the slot value for a given map and key on Ethereum. A convenient wrapper to find the appropriate storage slot to load or overwrite the state.
public keccak256(baseSlot: bigint, key: bigint): bigint
// Let you send transactions on Ethereum impersonating an externally owned or contract, without knowing the private key.
-public async startImpersonating(who: EthAddress): Promise
+public async startImpersonating(who: EthAddress): Promise
// Stop impersonating an account on Ethereum that you are currently impersonating.
-public async stopImpersonating(who: EthAddress): Promise
+public async stopImpersonating(who: EthAddress): Promise
// Set the bytecode for a Ethereum contract
-public async etch(contract: EthAddress, bytecode: `0x${string}`): Promise
+public async etch(contract: EthAddress, bytecode: `0x${string}`): Promise
// Get the bytecode for a Ethereum contract
-public async getBytecode(contract: EthAddress): Promise<`0x${string}`>
+public async getBytecode(contract: EthAddress): Promise<`0x${string}`>
```
### blockNumber
-#### Function Signature
+#### Function Signature
+
```ts
public async blockNumber(): Promise
```
#### Description
+
Fetches the current Ethereum block number.
#### Example
+
```ts
-const blockNumber = await cc.eth.blockNumber()
+const blockNumber = await cc.eth.blockNumber();
```
### chainId
-#### Function Signature
+#### Function Signature
+
```ts
-public async chainId(): Promise
+public async chainId(): Promise
```
#### Description
+
Fetches the Ethereum chain ID
-#### Example
+#### Example
+
```ts
-const chainId = await cc.eth.chainId()
+const chainId = await cc.eth.chainId();
```
### timestamp
#### Function Signature
+
```ts
-public async timestamp(): Promise
+public async timestamp(): Promise
```
-#### Description
+#### Description
+
Fetches the current Ethereum timestamp.
#### Example
-```ts
-const timestamp = await cc.eth.timestamp()
+
+```ts
+const timestamp = await cc.eth.timestamp();
```
### mine
#### Function Signature
+
```ts
-public async mine(numberOfBlocks = 1): Promise
+public async mine(numberOfBlocks = 1): Promise
```
#### Description
+
Mines the specified number of blocks on Ethereum (default 1).
#### Example
+
```ts
const blockNum = await cc.eth.blockNumber();
-await cc.eth.mine(10) // mines 10 blocks
+await cc.eth.mine(10); // mines 10 blocks
const newBlockNum = await cc.eth.blockNumber(); // = blockNum + 10.
```
### setNextBlockTimestamp
-#### Function Signature
+#### Function Signature
+
```ts
public async setNextBlockTimestamp(timestamp: number): Promise
```
#### Description
-Sets the timestamp (unix format in seconds) for the next mined block on Ethereum.
+
+Sets the timestamp (unix format in seconds) for the next mined block on Ethereum.
Time can only be set in the future.
If you set the timestamp to a time in the past, this method will throw an error.
#### Example
+
```ts
// // Set next block timestamp to 16 Aug 2023 10:54:30 GMT
-await cc.eth.setNextBlockTimestamp(1692183270)
+await cc.eth.setNextBlockTimestamp(1692183270);
// next transaction you will do will have the timestamp as 1692183270
```
### dumpChainState
#### Function Signature
+
```ts
-public async dumpChainState(fileName: string): Promise
+public async dumpChainState(fileName: string): Promise
```
#### Description
+
Dumps the current Ethereum chain state to a file.
Stores a hex string representing the complete state of the chain in a file with the provided path. Can be re-imported into a fresh/restarted instance of Anvil to reattain the same state.
When combined with `loadChainState()` cheatcode, it can be let you easily import the current state of mainnet into the Anvil instance of the sandbox.
#### Example
+
```ts
-await cc.eth.dumpChainState('chain-state.json')
+await cc.eth.dumpChainState("chain-state.json");
```
### loadChainState
-#### Function Signature
+#### Function Signature
+
```ts
public async loadChainState(fileName: string): Promise
```
#### Description
-Loads the Ethereum chain state from a file which contains a hex string representing an Ethereum state.
+
+Loads the Ethereum chain state from a file which contains a hex string representing an Ethereum state.
When given a file previously written to by `cc.eth.dumpChainState()`, it merges the contents into the current chain state. Will overwrite any colliding accounts/storage slots.
-#### Example
+#### Example
+
```ts
-await cc.eth.loadChainState('chain-state.json')
+await cc.eth.loadChainState("chain-state.json");
```
-### load
+### load
#### Function Signature
+
```ts
public async load(contract: EthAddress, slot: bigint): Promise
```
-#### Description
+#### Description
+
Loads the value at a storage slot of a Ethereum contract.
#### Example
+
```solidity
contract LeetContract {
uint256 private leet = 1337; // slot 0
@@ -213,7 +242,7 @@ contract LeetContract {
```
```ts
-const leetContractAddress = EthAddress.fromString('0x1234...');
+const leetContractAddress = EthAddress.fromString("0x1234...");
const value = await cc.eth.load(leetContractAddress, BigInt(0));
console.log(value); // 1337
```
@@ -221,14 +250,17 @@ console.log(value); // 1337
### store
#### Function Signature
+
```ts
-public async store(contract: EthAddress, slot: bigint, value: bigint): Promise
+public async store(contract: EthAddress, slot: bigint, value: bigint): Promise
```
#### Description
+
Stores the value in storage slot on a Ethereum contract.
#### Example
+
```solidity
contract LeetContract {
uint256 private leet = 1337; // slot 0
@@ -236,7 +268,7 @@ contract LeetContract {
```
```ts
-const leetContractAddress = EthAddress.fromString('0x1234...');
+const leetContractAddress = EthAddress.fromString("0x1234...");
await cc.eth.store(leetContractAddress, BigInt(0), BigInt(1000));
const value = await cc.eth.load(leetContractAddress, BigInt(0));
console.log(value); // 1000
@@ -244,15 +276,18 @@ console.log(value); // 1000
### keccak256
-#### Function Signature
+#### Function Signature
+
```ts
public keccak256(baseSlot: bigint, key: bigint): bigint
```
-#### Description
+#### Description
+
Computes the storage slot for a map key.
#### Example
+
```solidity
contract LeetContract {
uint256 private leet = 1337; // slot 0
@@ -262,7 +297,7 @@ contract LeetContract {
```ts
// find the storage slot for key `0xdead` in the balance map.
-const address = BigInt('0x000000000000000000000000000000000000dead');
+const address = BigInt("0x000000000000000000000000000000000000dead");
const slot = cc.eth.keccak256(1n, address);
// store balance of 0xdead as 100
await cc.eth.store(contractAddress, slot, 100n);
@@ -271,15 +306,18 @@ await cc.eth.store(contractAddress, slot, 100n);
### startImpersonating
#### Function Signature
-```ts
+
+```ts
public async startImpersonating(who: EthAddress): Promise
```
-#### Description
+#### Description
+
Start impersonating an Ethereum account.
This allows you to use this address as a sender.
#### Example
+
```ts
await cc.eth.startImpersonating(EthAddress.fromString(address));
```
@@ -287,55 +325,66 @@ await cc.eth.startImpersonating(EthAddress.fromString(address));
### stopImpersonating
#### Function Signature
+
```ts
public async stopImpersonating(who: EthAddress): Promise
```
#### Description
+
Stop impersonating an Ethereum account.
Stops an active impersonation started by startImpersonating.
#### Example
-```ts
-await cc.eth.stopImpersonating(EthAddress.fromString(address))
+
+```ts
+await cc.eth.stopImpersonating(EthAddress.fromString(address));
```
### getBytecode
#### Function Signature
+
```ts
public async getBytecode(contract: EthAddress): Promise<`0x${string}`>
```
-#### Description
+#### Description
+
Get the bytecode for an Ethereum contract.
#### Example
+
```ts
-const bytecode = await cc.eth.getBytecode(contract) // 0x6080604052348015610010...
+const bytecode = await cc.eth.getBytecode(contract); // 0x6080604052348015610010...
```
### etch
-#### Function Signature
+#### Function Signature
+
```ts
-public async etch(contract: EthAddress, bytecode: `0x${string}`): Promise
+public async etch(contract: EthAddress, bytecode: `0x${string}`): Promise
```
#### Description
+
Set the bytecode for an Ethereum contract.
-#### Example
+#### Example
+
```ts
-const bytecode = `0x6080604052348015610010...`
-await cc.eth.etch(contract, bytecode)
-console.log(await cc.eth.getBytecode(contract)) // 0x6080604052348015610010...
+const bytecode = `0x6080604052348015610010...`;
+await cc.eth.etch(contract, bytecode);
+console.log(await cc.eth.getBytecode(contract)); // 0x6080604052348015610010...
```
## Aztec related cheatcodes
+
These are cheatcodes specific to manipulating the state of Aztec rollup.
### Interface
+
```ts
// Get the current aztec block number
public async blockNumber(): Promise
@@ -353,51 +402,60 @@ public computeSlotInMap(baseSlot: Fr | bigint, key: Fr | bigint): Fr
### blockNumber
#### Function Signature
+
```ts
public async blockNumber(): Promise
```
-#### Description
+#### Description
+
Get the current aztec block number.
#### Example
+
```ts
-const blockNumber = await cc.aztec.blockNumber()
+const blockNumber = await cc.aztec.blockNumber();
```
-### warp
+### warp
#### Function Signature
+
```ts
public async warp(to: number): Promise
```
#### Description
+
Sets the time on Ethereum and the time of the next block on Aztec.
Like with the corresponding Ethereum cheatcode, time can only be set in the future, not the past.
Otherwise, it will throw an error.
#### Example
+
```ts
const timestamp = await cc.eth.timestamp();
const newTimestamp = timestamp + 100_000_000;
await cc.aztec.warp(newTimestamp);
-// any Aztec.nr contract calls that make use of current timestamp
+// any Aztec.nr contract calls that make use of current timestamp
// and is executed in the next rollup block will now read `newTimestamp`
```
### computeSlotInMap
#### Function Signature
+
```ts
public computeSlotInMap(baseSlot: Fr | bigint, key: Fr | bigint): Fr
```
#### Description
+
Compute storage slot for a map key.
-The baseSlot is specified in the Aztec.nr contract.
+The baseSlot is specified in the Aztec.nr contract.
+
+#### Example
-#### Example
```rust
struct Storage {
balances: Map>,
@@ -417,22 +475,25 @@ contract Token {
```
```ts
-const slot = cc.aztec.computeSlotInMap(1n, key)
+const slot = cc.aztec.computeSlotInMap(1n, key);
```
### loadPublic
#### Function Signature
+
```ts
-public async loadPublic(who: AztecAddress, slot: Fr | bigint): Promise
+public async loadPublic(who: AztecAddress, slot: Fr | bigint): Promise
```
#### Description
-Loads the value stored at the given slot in the public storage of the given contract.
+
+Loads the value stored at the given slot in the public storage of the given contract.
Note: One Field element occupies a storage slot. Hence, structs with multiple field elements will be spread over multiple sequential slots. Using loadPublic will only load a single field of the struct (depending on the size of the attributes within it).
#### Example
+
```rust
struct Storage {
balances: Map>,
@@ -452,10 +513,11 @@ contract Token {
```
```ts
-const address = AztecAddress.fromString("0x123...")
-const slot = cc.aztec.computeSlotInMap(1n, key)
+const address = AztecAddress.fromString("0x123...");
+const slot = cc.aztec.computeSlotInMap(1n, key);
const value = await cc.aztec.loadPublic(address, slot);
```
+
## Participate
Keep up with the latest discussion and join the conversation in the [Aztec forum](https://discourse.aztec.network).
@@ -463,4 +525,4 @@ Keep up with the latest discussion and join the conversation in the [Aztec forum
You can also use the above link to request more cheatcodes.
import Disclaimer from "../../misc/common/\_disclaimer.mdx";
-
\ No newline at end of file
+
diff --git a/docs/docs/dev_docs/testing/main.md b/docs/docs/dev_docs/testing/main.md
index a6adae5114b..5413e63cd3d 100644
--- a/docs/docs/dev_docs/testing/main.md
+++ b/docs/docs/dev_docs/testing/main.md
@@ -1,9 +1,5 @@
-# Testing contracts
+import DocCardList from '@theme/DocCardList';
-Please use the [TUTORIAL-TEMPLATE](../../TUTORIAL_TEMPLATE.md) for standalone guides / tutorials.
+# Testing
-## Testing in Aztec.nr
-
-Individual functions can be tested much like [how 'regular Noir' functions can be tested](https://noir-lang.org/nargo/testing).
-
-But an Aztec.nr contract typically tracks state variables, so you'll likely need to write more complex tests in TypeScript, using Aztec.js
\ No newline at end of file
+
diff --git a/docs/docs/dev_docs/dapps/testing.md b/docs/docs/dev_docs/testing/testing.md
similarity index 97%
rename from docs/docs/dev_docs/dapps/testing.md
rename to docs/docs/dev_docs/testing/testing.md
index 3551a435e69..ef2ce16123a 100644
--- a/docs/docs/dev_docs/dapps/testing.md
+++ b/docs/docs/dev_docs/testing/testing.md
@@ -1,6 +1,8 @@
-# Testing
+---
+title: Testing with Typescript
+---
-Testing is an integral part of any piece of software, and especially important for any blockchain application. In this page we will cover how to interact with your Noir contracts in a testing environment to write automated tests for your apps.
+Testing is an integral part of any piece of software, and especially important for any blockchain application. In this page we will cover how to interact with your Noir contracts in a testing environment to write automated tests for your apps.
We will be using typescript to write our tests, and rely on the [`aztec.js`](https://www.npmjs.com/package/@aztec/aztec.js) client library to interact with a local Aztec network. We will use [`jest`](https://jestjs.io/) as a testing library, though feel free to use whatever you work with. Configuring the nodejs testing framework is out of scope for this guide.
@@ -125,7 +127,7 @@ In the near future, transactions where a public function call fails will get min
We can check private or public state directly rather than going through view-only methods, as we did in the initial example by calling `token.methods.balance().view()`. Bear in mind that directly accessing contract storage will break any kind of encapsulation.
-To query storage directly, you'll need to know the slot you want to access. This can be checked in the [contract's `Storage` definition](../contracts/storage.md) directly for most data types. However, when it comes to mapping types, as in most EVM languages, we'll need to calculate the slot for a given key. To do this, we'll use the `CheatCodes` utility class:
+To query storage directly, you'll need to know the slot you want to access. This can be checked in the [contract's `Storage` definition](../contracts/syntax/storage.md) directly for most data types. However, when it comes to mapping types, as in most EVM languages, we'll need to calculate the slot for a given key. To do this, we'll use the `CheatCodes` utility class:
#include_code calc-slot /yarn-project/end-to-end/src/guides/dapp_testing.test.ts typescript
diff --git a/docs/docs/dev_docs/testing/writing_a_test.md b/docs/docs/dev_docs/testing/writing_a_test.md
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/docs/docs/dev_docs/wallets/writing_an_account_contract.md b/docs/docs/dev_docs/wallets/writing_an_account_contract.md
index 78f0a9d1f90..9916cf790cb 100644
--- a/docs/docs/dev_docs/wallets/writing_an_account_contract.md
+++ b/docs/docs/dev_docs/wallets/writing_an_account_contract.md
@@ -20,6 +20,7 @@ Let's start with the account contract itself in Aztec.nr. Create [a new Aztec.nr
:::info
You can use [the Aztec CLI](../cli/main.md) to generate a new keypair if you want to use a different one:
+
```bash
$ aztec-cli generate-private-key
```
@@ -28,6 +29,7 @@ $ aztec-cli generate-private-key
Private Key: 0xc06461a031058f116f087bc0161b11c039648eb47e03bad3eab089709bf9b8ae
Public Key: 0x0ede151adaef1cfcc1b3e152ea39f00c5cda3f3857cef00decb049d283672dc713c0e184340407e796411f74b7383252f1406272b58fccad6fee203f8a6db474
```
+
:::
The important part of this contract is the `entrypoint` function, which will be the first function executed in any transaction originated from this account. This function has two main responsibilities: authenticating the transaction and executing calls. It receives a `payload` with the list of function calls to execute, and requests a corresponding auth witness from an oracle to validate it. You will find this logic implemented in the `AccountActions` module, which uses the `EntrypointPayload` struct:
@@ -44,6 +46,7 @@ The `AccountActions` module provides default implementations for most of the acc
#include_code is-valid yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr rust
+
For our account contract, we will take the hash of the action to authorize, request the corresponding auth witness from the oracle, and validate it against our hardcoded public key. If the signature is correct, we authorize the action.
## The typescript side of things
@@ -56,6 +59,7 @@ However, if you are using the default `AccountActions` module, then you can leve
#include_code account-contract yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts typescript
As you can see in the snippet above, to fill in this base class, we need to define three things:
+
- The build artifact for the corresponding account contract.
- The deployment arguments.
- How to create an auth witness.
@@ -70,7 +74,6 @@ More signing schemes are available in case you want to experiment with other typ
Let's try creating a new account backed by our account contract, and interact with a simple token contract to test it works.
-
To create and deploy the account, we will use the `AccountManager` class, which takes an instance of an Aztec RPC server, a [privacy private key](../../concepts/foundation/accounts/keys.md#privacy-keys), and an instance of our `AccountContract` class:
#include_code account-contract-deploy yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts typescript
@@ -85,4 +88,4 @@ To make sure that we are actually validating the provided signature in our accou
#include_code account-contract-fails yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts typescript
-Lo and behold, we get `Error: Assertion failed: 'verification == true'` when running the snippet above, pointing to the line in our account contract where we verify the Schnorr signature.
\ No newline at end of file
+Lo and behold, we get `Error: Assertion failed: 'verification == true'` when running the snippet above, pointing to the line in our account contract where we verify the Schnorr signature.
diff --git a/docs/docs/external/up-quick-start.md b/docs/docs/external/up-quick-start.md
deleted file mode 100644
index b62d371cd88..00000000000
--- a/docs/docs/external/up-quick-start.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# Quick start
-
-:::info
-This guide is meant to be included in the sandbox.aztec.network site and not in the main documentation.
-:::
-
-To interact with the sandbox, install the [Aztec CLI](../dev_docs/cli/main.md):
-
-`npm install -g @aztec/cli`
-
-The sandbox is preloaded with two [accounts](../concepts/foundation/accounts/main.md), let's assign them as Alice and Bob:
-
-#include_code declare-accounts yarn-project/end-to-end/src/guides/up_quick_start.sh bash noTitle,noLineNumbers,noSourceLink
-
-Start by deploying a token [contract](../concepts/foundation/contracts.md), initializing it and minting tokens to Alice:
-
-#include_code deploy yarn-project/end-to-end/src/guides/up_quick_start.sh bash noTitle,noLineNumbers,noSourceLink
-
-We can check Alice's private token balance by querying the contract:
-
-#include_code get-balance yarn-project/end-to-end/src/guides/up_quick_start.sh bash noTitle,noLineNumbers,noSourceLink
-
-We can have Alice privately transfer tokens to Bob. Only Alice and Bob will know what's happened. Here, we use Alice's private key to [send a transaction](../concepts/foundation/transactions.md) to transfer tokens to Bob, and check the result:
-
-#include_code transfer yarn-project/end-to-end/src/guides/up_quick_start.sh bash noTitle,noLineNumbers,noSourceLink
-
-To learn more, check out an extended version of this quick start [on our docs](../dev_docs/getting_started/cli.md).
diff --git a/docs/docs/intro.md b/docs/docs/intro.md
index 111bf2af038..0b0328452c8 100644
--- a/docs/docs/intro.md
+++ b/docs/docs/intro.md
@@ -11,12 +11,12 @@ On Ethereum today, everything is publicly visible, by everyone.
In the real world, people enjoy privacy.
Aztec brings privacy to Ethereum.
-
+
---
-# Build with confidence.
+## Build with confidence.
-Design, build, and deploy private smart contracts.
+Design, build, and deploy private smart contracts with the following features:
- Private functions
- Private arguments
@@ -30,24 +30,23 @@ Design, build, and deploy private smart contracts.
- Encrypted logs
Plus:
+
- Composability with Ethereum L1
- Access to Ethereum's L1 liquidity
- Cheap, public logic, if you need it
- Cheap, public persistent state, if you need it
+---
----
-
-# Play!
+## Play
-[Write a private smart contract today](./dev_docs/getting_started/main.md).
+[Write a private smart contract today](./dev_docs/getting_started/quickstart).
-[Deploy to the Aztec Sandbox today](./dev_docs/sandbox/main.md)
+[Deploy to the Aztec Sandbox today](./dev_docs/getting_started/sandbox)
---
-
-# But what _is_ Aztec?
+## But what _is_ Aztec?
Aztec encrypts Ethereum.
diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js
index 8244b892329..ab4487d3d6c 100644
--- a/docs/docusaurus.config.js
+++ b/docs/docusaurus.config.js
@@ -164,6 +164,10 @@ const config = {
label: "Introduction",
to: "/",
},
+ {
+ label: "Developer Quickstart",
+ to: "/dev_docs/getting_started/quickstart",
+ },
],
},
{
@@ -173,6 +177,10 @@ const config = {
label: "Discourse",
href: "https://discourse.aztec.network",
},
+ {
+ label: "Discord",
+ href: "https://discord.gg/DgWG2DBMyB",
+ },
{
label: "Twitter",
href: "https://twitter.com/aztecnetwork",
diff --git a/docs/docs/TUTORIAL_TEMPLATE.md b/docs/internal_notes/TUTORIAL_TEMPLATE.md
similarity index 100%
rename from docs/docs/TUTORIAL_TEMPLATE.md
rename to docs/internal_notes/TUTORIAL_TEMPLATE.md
diff --git a/docs/docs/dev_docs/dapps/api/main.md b/docs/internal_notes/api.md
similarity index 100%
rename from docs/docs/dev_docs/dapps/api/main.md
rename to docs/internal_notes/api.md
diff --git a/docs/docs/dev_docs/dapps/main.md b/docs/internal_notes/building_dapps.md
similarity index 89%
rename from docs/docs/dev_docs/dapps/main.md
rename to docs/internal_notes/building_dapps.md
index d267ad9a162..fc807def92b 100644
--- a/docs/docs/dev_docs/dapps/main.md
+++ b/docs/internal_notes/building_dapps.md
@@ -1,6 +1,6 @@
# Building dapps
-Please use the [TUTORIAL-TEMPLATE](../../TUTORIAL_TEMPLATE.md) for standalone guides / tutorials.
+Please use the [TUTORIAL-TEMPLATE](./TUTORIAL_TEMPLATE.md) for standalone guides / tutorials.
Explain how to write a dapp using [`aztec.js`](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec.js). Maybe that readme is enough?
@@ -36,7 +36,7 @@ FOR INSTRUCTIONS FOR BUILDING A WALLET, WE SHOULD WRITE DOCS HERE
ERRORS:
-- Add any error explanations to [errors.md](../contracts/common_errors.md) (and break that file into multiple files if it's too unwieldy).
+- Add any error explanations to [errors.md](../docs/dev_docs/contracts/common_errors.md) (and break that file into multiple files if it's too unwieldy).
## Testing a dapp
diff --git a/docs/docs/dev_docs/sandbox/components.md b/docs/internal_notes/dev_docs/sandbox/components.md
similarity index 100%
rename from docs/docs/dev_docs/sandbox/components.md
rename to docs/internal_notes/dev_docs/sandbox/components.md
diff --git a/docs/netlify.toml b/docs/netlify.toml
index bd95e06d321..396e43fd59e 100644
--- a/docs/netlify.toml
+++ b/docs/netlify.toml
@@ -19,5 +19,43 @@
to = "/"
[[redirects]]
- from = "/aztec3/*"
- to = "/aztec/overview"
+ from = "/dev_docs/aztec3/*"
+ to = "/dev_docs/aztec/overview"
+
+[[redirects]]
+ from = "/dev_docs/contracts/types"
+ to = "/dev_docs/contracts/syntax/types"
+
+[[redirects]]
+ from = "/dev_docs/contracts/storage"
+ to = "/dev_docs/contracts/syntax/storage"
+
+[[redirects]]
+ from = "/dev_docs/contracts/state_variables"
+ to = "/dev_docs/contracts/syntax/state_variables"
+
+[[redirects]]
+ from = "/dev_docs/contracts/functions"
+ to = "/dev_docs/contracts/syntax/functions"
+
+[[redirects]]
+ from = "/dev_docs/contracts/visibility"
+ to = "/dev_docs/contracts/syntax/visibility"
+
+[[redirects]]
+ from = "/dev_docs/contracts/globals"
+ to = "/dev_docs/contracts/syntax/globals"
+
+[[redirects]]
+ from = "/dev_docs/contracts/syntax"
+ to = "/dev_docs/contracts/syntax/main"
+
+[[redirects]]
+ from = "/dev_docs/contracts/contract"
+ to = "/dev_docs/contracts/syntax/contract"
+
+[[redirects]]
+ from = "/dev_docs/getting_started/cli"
+ to = "/dev_docs/cli"
+
+
\ No newline at end of file
diff --git a/docs/sidebars.js b/docs/sidebars.js
index 9ff2f5e8f32..ae69f0ada65 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -75,14 +75,15 @@ const sidebars = {
id: "dev_docs/getting_started/main",
},
items: [
+ "dev_docs/getting_started/quickstart",
"dev_docs/getting_started/sandbox",
"dev_docs/getting_started/noir_contracts",
- "dev_docs/getting_started/cli",
+ "dev_docs/getting_started/token_contract_tutorial",
],
},
{
- label: "Contracts",
+ label: "Aztec.nr Contracts",
type: "category",
link: {
type: "doc",
@@ -90,22 +91,26 @@ const sidebars = {
},
items: [
"dev_docs/contracts/workflow",
- "dev_docs/contracts/syntax",
- "dev_docs/contracts/contract",
"dev_docs/contracts/layout",
- "dev_docs/contracts/types",
- "dev_docs/contracts/storage",
- "dev_docs/contracts/state_variables",
- "dev_docs/contracts/functions",
- "dev_docs/contracts/control_structure",
- "dev_docs/contracts/visibility",
- "dev_docs/contracts/globals",
"dev_docs/contracts/events",
- "dev_docs/contracts/constrain",
"dev_docs/contracts/compiling",
"dev_docs/contracts/deploying",
"dev_docs/contracts/artifacts",
- "dev_docs/contracts/abi",
+ {
+ label: "Syntax",
+ type: "category",
+ link: {
+ type: "doc",
+ id: "dev_docs/contracts/syntax/main",
+ },
+ items: [
+ "dev_docs/contracts/syntax/contract",
+ "dev_docs/contracts/syntax/functions",
+ "dev_docs/contracts/syntax/storage",
+ "dev_docs/contracts/syntax/state_variables",
+ "dev_docs/contracts/syntax/globals",
+ ],
+ },
{
label: "Portals",
type: "category",
@@ -120,64 +125,80 @@ const sidebars = {
"dev_docs/contracts/portals/outbox",
],
},
- {
- label: "Resources",
- type: "category",
- items: [
- "dev_docs/contracts/resources/style_guide",
- {
- label: "Common Patterns",
- type: "category",
- link: {
- type: "doc",
- id: "dev_docs/contracts/resources/common_patterns/main",
- },
- items: [
- "dev_docs/contracts/resources/common_patterns/sending_tokens_to_user",
- "dev_docs/contracts/resources/common_patterns/sending_tokens_to_contract",
- "dev_docs/contracts/resources/common_patterns/access_control",
- "dev_docs/contracts/resources/common_patterns/interacting_with_l1",
- ],
- },
- ],
- },
- {
- label: "Security Considerations",
- type: "category",
- items: [
- {
- label: "Breaking changes",
- type: "category",
- link: {
- type: "doc",
- id: "dev_docs/contracts/security/breaking_changes/main",
- },
- items: ["dev_docs/contracts/security/breaking_changes/v0"],
- },
- ],
- },
+ // {
+ // label: "Resources",
+ // type: "category",
+ // items: [
+ // "dev_docs/contracts/resources/style_guide",
+ // {
+ // label: "Common Patterns",
+ // type: "category",
+ // link: {
+ // type: "doc",
+ // id: "dev_docs/contracts/resources/common_patterns/main",
+ // },
+ // items: [
+ // "dev_docs/contracts/resources/common_patterns/sending_tokens_to_user",
+ // "dev_docs/contracts/resources/common_patterns/sending_tokens_to_contract",
+ // "dev_docs/contracts/resources/common_patterns/access_control",
+ // "dev_docs/contracts/resources/common_patterns/interacting_with_l1",
+ // ],
+ // },
+ // ],
+ // },
+ // {
+ // label: "Security Considerations",
+ // type: "category",
+ // items: [
+ // {
+ // label: "Breaking changes",
+ // type: "category",
+ // link: {
+ // type: "doc",
+ // id: "dev_docs/contracts/security/breaking_changes/main",
+ // },
+ // items: ["dev_docs/contracts/security/breaking_changes/v0"],
+ // },
+ // ],
+ // },
],
},
+
{
- label: "DApp Development",
+ label: "Sandbox",
type: "category",
link: {
type: "doc",
- id: "dev_docs/dapps/main",
+ id: "dev_docs/sandbox/main",
},
+ items: ["dev_docs/sandbox/common_errors"],
+ },
+
+ {
+ label: "CLI",
+ type: "category",
+ link: {
+ type: "doc",
+ id: "dev_docs/cli/main",
+ },
+ items: ["dev_docs/cli/cli"],
+ },
+ {
+ label: "DApp Development",
+ type: "category",
items: [
- {
- label: "API",
- type: "category",
- link: {
- type: "doc",
- id: "dev_docs/dapps/api/main",
- },
- items: [
- "dev_docs/dapps/api/aztec_rpc",
- "dev_docs/dapps/api/contract_interaction",
- ],
- },
+ // {
+ // label: "API",
+ // type: "category",
+ // link: {
+ // type: "doc",
+ // id: "dev_docs/dapps/api/main",
+ // },
+ // items: [
+ // "dev_docs/dapps/api/aztec_rpc",
+ // "dev_docs/dapps/api/contract_interaction",
+ // ],
+ // },
{
label: "Tutorials",
type: "category",
@@ -196,26 +217,6 @@ const sidebars = {
],
},
- {
- label: "Sandbox",
- type: "category",
- link: {
- type: "doc",
- id: "dev_docs/sandbox/main",
- },
- items: ["dev_docs/sandbox/components", "dev_docs/sandbox/common_errors"],
- },
-
- {
- label: "CLI",
- type: "category",
- link: {
- type: "doc",
- id: "dev_docs/cli/main",
- },
- items: [],
- },
-
{
label: "Testing",
type: "category",
@@ -223,10 +224,7 @@ const sidebars = {
type: "doc",
id: "dev_docs/testing/main",
},
- items: [
- "dev_docs/testing/writing_a_test",
- "dev_docs/testing/cheat_codes",
- ],
+ items: ["dev_docs/testing/testing", "dev_docs/testing/cheat_codes"],
},
{
@@ -242,8 +240,11 @@ const sidebars = {
],
},
- "dev_docs/limitations/main",
- "dev_docs/privacy/main",
+ {
+ label: "Security Considerations",
+ type: "category",
+ items: ["dev_docs/limitations/main", "dev_docs/privacy/main"],
+ },
{
type: "html",
@@ -276,8 +277,8 @@ const sidebars = {
},
"concepts/foundation/contracts",
"concepts/foundation/transactions",
- "concepts/foundation/blocks",
- "concepts/foundation/globals",
+ // "concepts/foundation/blocks",
+ // "concepts/foundation/globals",
{
label: "Communication",
type: "category",
@@ -290,21 +291,21 @@ const sidebars = {
"concepts/foundation/communication/cross_chain_calls",
],
},
- {
- label: "Nodes and Clients",
- type: "category",
- link: {
- type: "doc",
- id: "concepts/foundation/nodes_clients/main",
- },
- items: [
- "concepts/foundation/nodes_clients/execution_client",
- "concepts/foundation/nodes_clients/prover_client",
- "concepts/foundation/nodes_clients/sequencer_client",
- ],
- },
- "concepts/foundation/block_production",
- "concepts/foundation/upgrade_mechanism",
+ // {
+ // label: "Nodes and Clients",
+ // type: "category",
+ // link: {
+ // type: "doc",
+ // id: "concepts/foundation/nodes_clients/main",
+ // },
+ // items: [
+ // "concepts/foundation/nodes_clients/execution_client",
+ // "concepts/foundation/nodes_clients/prover_client",
+ // "concepts/foundation/nodes_clients/sequencer_client",
+ // ],
+ // },
+ // "concepts/foundation/block_production",
+ // "concepts/foundation/upgrade_mechanism",
],
},
@@ -355,19 +356,12 @@ const sidebars = {
type: "doc",
id: "concepts/advanced/circuits/rollup_circuits/main",
},
- items: [
- "concepts/advanced/circuits/rollup_circuits/base_rollup",
- "concepts/advanced/circuits/rollup_circuits/merge_rollup",
- "concepts/advanced/circuits/rollup_circuits/root_rollup",
- ],
+ items: [],
},
],
},
-
"concepts/advanced/public_vm",
-
"concepts/advanced/contract_creation",
- "concepts/advanced/rollup_contract",
],
},
diff --git a/yarn-project/boxes/private-token/README.md b/yarn-project/boxes/private-token/README.md
index 272fc2cdfbc..063750cafdf 100644
--- a/yarn-project/boxes/private-token/README.md
+++ b/yarn-project/boxes/private-token/README.md
@@ -1,3 +1,5 @@
+# Aztec Boxes
+
This is a minimal [Aztec](https://aztec.network/) Noir smart contract and frontend bootstrapped with [`aztec-cli unbox`](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/cli). It is recommended you use the `aztec-cli unbox PrivateToken` command so that the repository is copied with needed modifications from the monorepo subpackage.
Some contract specific settings for `PrivateToken` are in a [config](src/config.ts) will require manual updates depending on your changes to the source code. `aztec-cli` can be installed with `npm i -g @aztec/cli`, if you don't have it already.
diff --git a/yarn-project/end-to-end/src/guides/up_quick_start.sh b/yarn-project/end-to-end/src/guides/up_quick_start.sh
index 7b25a747dd6..a882e80035d 100755
--- a/yarn-project/end-to-end/src/guides/up_quick_start.sh
+++ b/yarn-project/end-to-end/src/guides/up_quick_start.sh
@@ -16,10 +16,12 @@ aztec-cli deploy \
aztec-cli check-deploy --contract-address 0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c
+CONTRACT="0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c"
+
aztec-cli send _initialize \
--args $ALICE \
--contract-abi TokenContractAbi \
- --contract-address 0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c \
+ --contract-address $CONTRACT \
--private-key $ALICE_PRIVATE_KEY
# docs:end:deploy
@@ -30,13 +32,13 @@ SECRET_HASH="0x0a42b1fe22b652cc8610e33bb1128040ce2d2862e7041ff235aa871739822b74"
aztec-cli send mint_private \
--args 1000 $SECRET_HASH \
--contract-abi TokenContractAbi \
- --contract-address 0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c \
+ --contract-address $CONTRACT \
--private-key $ALICE_PRIVATE_KEY
aztec-cli send redeem_shield \
--args $ALICE 1000 $SECRET \
--contract-abi TokenContractAbi \
- --contract-address 0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c \
+ --contract-address $CONTRACT \
--private-key $ALICE_PRIVATE_KEY
# docs:end:mint-private
@@ -44,32 +46,32 @@ aztec-cli send redeem_shield \
aztec-cli call balance_of_private \
--args $ALICE \
--contract-abi TokenContractAbi \
- --contract-address 0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c
+ --contract-address $CONTRACT
# docs:end:get-balance
# docs:start:transfer
aztec-cli send transfer \
--args $ALICE $BOB 500 0 \
--contract-abi TokenContractAbi \
- --contract-address 0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c \
+ --contract-address $CONTRACT \
--private-key $ALICE_PRIVATE_KEY
aztec-cli call balance_of_private \
--args $ALICE \
--contract-abi TokenContractAbi \
- --contract-address 0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c
+ --contract-address $CONTRACT
aztec-cli call balance_of_private \
--args $BOB \
--contract-abi TokenContractAbi \
- --contract-address 0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c
+ --contract-address $CONTRACT
# docs:end:transfer
aztec-cli get-logs
# Test end result
-BOB_BALANCE=$(aztec-cli call balance_of_private --args $BOB --contract-abi TokenContractAbi --contract-address 0x2d23acefa3ce07b3c308caf78d86c064cdf8957bcea48b38753cf58441796c8c)
+BOB_BALANCE=$(aztec-cli call balance_of_private --args $BOB --contract-abi TokenContractAbi --contract-address $CONTRACT)
if ! echo $BOB_BALANCE | grep -q 500; then
echo "Incorrect Bob balance after transaction (expected 500 but got $BOB_BALANCE)"
exit 1
-fi
+fi
\ No newline at end of file