Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docs): document noir macros #2016

Merged
merged 36 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
53a38e1
feat: document macros
Maddiaa0 Sep 5, 2023
4e04bcb
checkpoint
Maddiaa0 Sep 5, 2023
c1965dc
feat: add context section to the docs
Maddiaa0 Sep 6, 2023
464b3ae
feat: clean up functions docs
Maddiaa0 Sep 6, 2023
2ab0f65
feat: update context docs
Maddiaa0 Sep 6, 2023
934604b
feat: document macros
Maddiaa0 Sep 5, 2023
a6851f7
checkpoint
Maddiaa0 Sep 5, 2023
5ea83e3
feat: add context section to the docs
Maddiaa0 Sep 6, 2023
6f324f6
feat: clean up functions docs
Maddiaa0 Sep 6, 2023
319aada
feat: update context docs
Maddiaa0 Sep 6, 2023
2db1fba
Merge branch 'md/document-macros' of github.com:AztecProtocol/aztec-p…
Maddiaa0 Sep 12, 2023
b68ba49
Merge branch 'master' into md/document-macros
Maddiaa0 Sep 12, 2023
9c20b42
fix: new aztec-noir path
Maddiaa0 Sep 12, 2023
3b571b7
compliation fix
Maddiaa0 Sep 13, 2023
65de5b3
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Maddiaa0 Sep 13, 2023
801a7b3
Merge branch 'master' into md/document-macros
Maddiaa0 Sep 13, 2023
b16f617
fix: restore
Maddiaa0 Sep 13, 2023
2aa2a91
Merge branch 'master' into md/document-macros
Maddiaa0 Sep 13, 2023
7399b00
Merge branch 'master' into md/document-macros
Maddiaa0 Sep 14, 2023
757634c
Merge branch 'master' into md/document-macros
Maddiaa0 Sep 18, 2023
381c590
fix: review notes
Maddiaa0 Sep 18, 2023
8e8b214
fix: remove this.png
Maddiaa0 Sep 18, 2023
1cde337
Merge branch 'master' into md/document-macros
Maddiaa0 Sep 18, 2023
398e70f
fix
Maddiaa0 Sep 18, 2023
171f3f6
Merge branch 'md/document-macros' of github.com:AztecProtocol/aztec-p…
Maddiaa0 Sep 18, 2023
3ec0b0f
fix: alter context to mdx for images
Maddiaa0 Sep 18, 2023
b2033dd
feat(docs): globals documentation (#2067)
Maddiaa0 Sep 18, 2023
1d6561a
fix: aztec-nr ref post merge
Maddiaa0 Sep 18, 2023
27dcb8b
fix: package.json
Maddiaa0 Sep 18, 2023
2b02a14
fix: update context.md refs to mdx
Maddiaa0 Sep 18, 2023
57f42b4
nits
Maddiaa0 Sep 19, 2023
c00bba6
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Maddiaa0 Sep 19, 2023
8e04c5b
fix: merge fix
Maddiaa0 Sep 19, 2023
e8a0e21
Merge branch 'md/document-macros' of github.com:AztecProtocol/aztec-p…
Maddiaa0 Sep 19, 2023
18b0094
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Maddiaa0 Sep 19, 2023
c76ab7e
skibbidy
Maddiaa0 Sep 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/docs/about_aztec/roadmap/cryptography_roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ title: Cryptography Roadmap

## Honk

- Honk is a sumcheck-based zk-SNARK protocol with blazing-fast zk proof construction. We need to Honk allow users to prove correct execution of complicated, multi-step computations using recursion in a resource constraint environment like a cell phone. This is necessary for our mission, because we need to make sure our users' sensitive information never leaves their devices!
- Honk is a sumcheck-based zk-SNARK protocol with blazing-fast zk proof construction. We need Honk to allow users to prove correct execution of complicated, multi-step computations using recursion in a resource constraint environment like a cell phone. This is necessary for our mission, because we need to make sure our users' sensitive information never leaves their devices!
- List of Honk projects
- Completed: basic Honk prover and verifier with respectable construction and verification speeds, but no optimization.
- Upcoming:
Expand Down
85 changes: 85 additions & 0 deletions docs/docs/dev_docs/contracts/context.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Overview of this page (change this title)

We want ot include some over arching details on what is included inside the context structure, and give an overview of what it actually is.

## What is the context.
The context is a variable that is made available within every function in `Aztec.nr`. As mentioned in the KERNEL CIRCUIT SECTION. The application context is a structure that contains all of the infromation a function needs from the kernel circuit, as well as all the information the kernel needs after a function execution completes.

Behind the scenes, Aztec noir will pass data the kernel needs to and from a circuit, this is completely abstracted away from the developer. In an application developer's eyes; the context is a useful structure that allows access to anything on the aztec blockchain outside of the current circuit (REWORD THIS SECTION).

## What is contained within the context.

The code snippet below shows what is currently contained within the private context.
#include_code functions-OpenFunction /yarn-project/noir-libs/noir-aztec/src/context.nr rust

### Private Context Broken Down
#### Inputs
The context inputs includes all of the information that is passed from the kernel circuit into the application circuit. It contains the following values.

#include_code private-context-inputs /yarn-project/noir-libs/noir-aztec/src/abi.nr rust

As shown in the snippet, the application context is made up of 4 main structures. The call context, the block data, the contract deployment data and the private global variables.

First of all, the call context.

#include_code call-context /yarn-project/noir-libs/noir-aztec/src/abi.nr rust

The call context contains information about the current call being made:.
1, Msg Sender
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved
- The message sender is the account (Aztec Contract) that sent the message to the current context. In the first call of the kernel circuit (often the account contract call), this value will be empty. For all subsequent calls the value will be the previous call.
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved

( TODO: INCLUDE A DIAGRAM HERE SHOWING HOW IT GETS UPDATED ON CONTRACT CALLS )
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved
2. Storage contract address
- This value is the address of the current context's contract address. This value will be the value of the current contract that is being executed except for when the current call is a delegate call (TODO: INCLUDE A LINK TO ITS DOCUMENTATION). In this case the value will be that of the sending contract.
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved

- This value is important as it is the value that is used when siloing the storage values of a contract. ( TODO: DOES THIS NEED TO BE DIVED INTO MORE OR IS IT SOMETHING THTAT THERE IS A LINK TO).
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved
3. Portal Contract Address
- This value stores the current contract's linked portal contract address. ( INCLUDE A LINK TO THE LITERATURE ). As a quick recap, this value is the value of the contracts related ethereum l1 contract address, and will be the recipient of any messages that are created by this contract.
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved
4. Flags
- Furthermore there are a series of flags that are stored within the application context:
- is_delegate_call: Denotes whether the current call is a delegate call. If true, then the storage contract address will NOT be the current contract address.
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved
- is_static_call: (TODO: REFER TO EVM CODES TO FILL IN THIS SECTION)
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved
- is_contract_deployment: This will be set if and only if the current call is the contract's constructor.

### Historic Block Data
Another structure that is contained within the context is the Historic Block Data object. This object is a special one as it contains all of the roots of Aztec's data trees.

#include_code historic-block-data /yarn-project/noir-libs/noir-aztec/src/abi.nr rust

## TODO: gloss this up
Having these tree's on hand allows for a host of interesting use cases. If you can create a merkle proof which matches the root of these trees. Then you can prove that a value exists in the current state of the system.

### Contract Deployment Data
Just like with the `is_contract_deployment` flag mentioned earlier. This flag will only be set to true when the current transaction is one in which a contract is being deployed.

#### TODO : WAT CONTAIN AND WAT DO


### Private Global Variables
TODO:
- include in this section how the global variabels can be accessed and what they contain




## Args Hash



<!-- args_hash : Field,
return_values : BoundedVec<Field, RETURN_VALUES_LENGTH>,

read_requests: BoundedVec<Field, MAX_READ_REQUESTS_PER_CALL>,

new_commitments: BoundedVec<Field, MAX_NEW_COMMITMENTS_PER_CALL>,
new_nullifiers: BoundedVec<Field, MAX_NEW_NULLIFIERS_PER_CALL>,
nullified_commitments: BoundedVec<Field, MAX_NEW_NULLIFIERS_PER_CALL>,

private_call_stack : BoundedVec<Field, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL>,
public_call_stack : BoundedVec<Field, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL>,
new_l2_to_l1_msgs : BoundedVec<Field, MAX_NEW_L2_TO_L1_MSGS_PER_CALL>, --> -->

## Public Context Inputs
In the current version of the system, the public context is almost a clone of the private execution context. It contains the same call context data, access to the same historic tree roots, however it does NOT have access to contract deployment data, this is due to traditional contract deployments only currently being possible from private transactions.

#include_code public-context-inputs /yarn-project/noir-libs/noir-aztec/src/abi.nr rust
85 changes: 85 additions & 0 deletions docs/docs/dev_docs/contracts/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@
## secret functions

> a.k.a. "private" functions
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved
To create a private function you can annotate it with the `#[aztec(private)]` attribute. This will make the private context (INCLUDE LINK TO COVERAGE OF PRIVATE CONTEXT) available within your current function's execution scope.

#include_code functions-SecretFunction /yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr rust

## `open` functions

> a.k.a. "public" functions
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved

To create a public function you can annotate it with the `#[aztec(public)]` attribute. This will make the public context available within your current function's execution scope. (TODO: INCLUDE LINK)

#include_code functions-OpenFunction /yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr rust

## `unconstrained` functions
Expand Down Expand Up @@ -50,9 +53,91 @@ E.g. `get()`
## Recursive function calls

## L1 --> L2
<!-- TODO: Make a note to refer to the communication docs section -->
The context available within functions includes the ability to send messages to l1.



<!-- TODO: Leave links to the whole flow of sending a message to l2, this section should just show
how the message can be consumed on l2 itself
-->

#include_code send_to_l2 /yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr rust

### What happens behind the scenes?
When a user sends a message from a portal contract (INCLUDE LINK HERE) to the rollup's inbox it gets processed and added to the `l1 to l2 messages tree` (INCLUDE LINK TO WHERE THIS IS DISCUSSED). The l1 to l2 messages tree contains all messages that have been sent from l1 to the l2. The good thing about this tree is that it does not reveal when it's messages have been spent, as consuming a message from the l1 to l2 messages tree is done by nullifing a message, rather than directly marking it as consumed.

When calling the `consume_l1_to_l2_message` function on a contract; a number of actions are performed.

<!-- TODO: buff out these bullet points -->
1. As the consume message function is passed a `msgKey` value, we can look up on l1 what the full contents of the message by making an oracle call to get the data.
2. We check that the message recipient is the contract of the current calling context.
3. We check that the message content matches the content reproduced earlier on.
4. We validate that we know the preimage to the message's `secretHash` field. (TODO: SEE MORE ON THIS FOLLOWING A LINK)
5. We compute the nullifier for the message.
#include_code l1_to_l2_message_compute_nullifier /yarn-project/noir-libs/noir-aztec/src/messaging/l1_to_l2_message.nr rust
6. Finally we push the nullifier to the context. Allowing it to be checked for validity by the kernel and rollup circuits.

#include_code consume_l1_to_l2_message /yarn-project/noir-libs/noir-aztec/src/context.nr rust

The emitted nullifier prevents our message from being consumed again. Users cannot re consume a message as the nullifier would already exist.

## L2 --> L1

## Delegatecall

Talk a about the dangers of delegatecall too!


## Deep dive
<!-- TODO: all of the below an be considered as rough notes, and needs to be proof read and proof read and updated! -->
### Function type attributes explained.
Aztec.nr uses an attribute system to annotate a function's type. Annotating a function with the `#[aztec(private)]` attribute tells the framework that this will be a private function that will be executed on a users device. Thus the compiler will create a circuit to define this function.

However; `#aztec(private)` is just syntactic sugar. At compile time, the framework inserts some code that initializes the application context.

To help illustrate how this interacts with the internals of Aztec and its kernel circuits, we can take an example private function, and explore what it looks like after Aztec.nr's macro expansion.

#### The before
#include_code simple_macro_example /yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr rust


#### The expanded
#include_code simple_macro_example_expanded /yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr rust

#### What does the expansion do?
Seeing an expanded noir contract reveals a lot about how noir contracts interact with the kernel. Let's run down the changes and dive into what each part does.

<!-- Comment on what each of the lines do -> make a nice way to the processor to copy sub snippets / ignore sub snippets -->
`inputs: PrivateContextInputs`
As discussed in (INSeRT SECTION HERE) private function calls are stitched together from within the kernel circuit. The kernel circuit forwards information to each app circuit. This information then becomes the private context.
For example, within each circuit we can access some global variables. To access them we can call `context.chain_id()`. The value of this chain ID comes from the values passed into the circuit from the kernel.

<!-- NOTE: THIS ALL NEEDS A BIT MORE WORK, maybe dog food it with some other devs -->
The kernel can then check that all of the values passed to each circuit in a function call are the same.

`-> distinct pub abi::PrivateCircuitPublicInputs`
Just as the kernel passes information into the the app circuits, the application must return information about the executed app back to the kernel. This is done through a rigid structure we call the `PrivateCircuitPublicInputs`.
<!-- TODO: maybe break down the naming convention of Private Circuit Public Inputs -->

This structure contains a host of information about the executed program. It will contain any newly created nullifiers, any messages to be sent to l2 and most importantly it will contain the actual return values of the function!

`hasher`
What is the hasher and why is it needed?

Inside the kernel circuits, the inputs to functions are reduced to a single value; the inputs hash. This prevents there needing to be multiple different kernel circuits which support differing numbers of inputs to each function. The is an abstraction that allows us to create an array of all of the inputs that we can then hash to a single point.

<!-- TODO: include links -->

`let mut context = PrivateContext::new(inputs, hasher.hash())`
Creating the function's context.
Within each Aztec function we have access to a context object that feels like a global object. This is in-fact NOT global but rather is initialized from the inputs provided by the kernel, and a hash of the function's inputs.

<!-- TODO: include a link here to where people can learn more about what the context is and what it contains -->

`context.return_values.push(result)`
As mentioned in the kernel circuit section *(INCLUDE LINK)* we use the kernel to pass information between circuits. This means that the return values of functions must also be passed to the kernel to pass the value on to another function call.
This is done by pushing our return values to the execution context, which can then in turn pass the values to the kernel.

`context.finish()`
This function takes the application context, and converts it into the `PrivateCircuitPublicInputs` structure. This structure is what is passed to the kernel circuit to enable cross communication between applications.
31 changes: 4 additions & 27 deletions docs/docs/dev_docs/contracts/portals/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,37 +110,14 @@ Access control on the L1 portal contract is essential to prevent consumption of

As earlier, we can use a token bridge as an example. In this case, we are burning tokens on L2 and sending a message to the portal to free them on L1.

```rust title="NonNativeTokenContract.nr"
// burns token and sends a message to the portal
fn withdraw(
amount: Field,
sender: Field,
recipient: Field,
callerOnL1: Field,
) -> distinct pub abi::PrivateCircuitPublicInputs {
...
let sender_balance = storage.balances.at(sender);
spend_notes(&mut context, sender_balance, amount, sender);

let content = get_withdraw_content_hash(amount, recipient, callerOnL1);
context.message_portal(content);
...
}
```
#include_code send_to_portal /yarn-project/noir-contracts/src/contracts/non_native_token_contract/src/main.nr rust
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be updated along with #2177. Adding a comment here for reference.


When the transaction is included in a rollup block the message will be inserted into the `Outbox`, where the recipient portal can consume it from. When consuming, the `msg.sender` must match the `recipient` meaning that only portal can actually consume the message.

```solidity title="IOutbox.sol"
struct L2ToL1Msg {
DataStructures.L2Actor sender;
DataStructures.L1Actor recipient;
bytes32 content;
}
<!-- TODO: the rest of these docs should have code snippets updates -->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an issue, or should it be fixed in this pr?

Copy link
Member Author

@Maddiaa0 Maddiaa0 Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did it in this pr, will revert in this one

#include_code l1_to_l2_message_struct /l1-contracts/src/core/libraries/DataStructures.sol solidity

function consume(DataStructures.L2ToL1Msg memory _message)
external
returns (bytes32 entryKey);
```
#include_code consume_interface /l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol solidity

As noted earlier, the portal contract should check that the sender is as expected. In the example below, we support only one sender contract (stored in `l2TokenAddress`) so we can just pass it as the sender, that way we will only be able to consume messages from that contract. If multiple senders are supported, you could use a have `mapping(address => bool) allowed` and check that `allowed[msg.sender]` is `true`.

Expand Down
15 changes: 13 additions & 2 deletions docs/docs/dev_docs/contracts/syntax.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 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.
[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 framework -- written in Noir -- whose types and methods provide rich smart contract semantics.

On top of [Noir's stdlib](https://noir-lang.org/standard_library/array_methods), we provide [Aztec.nr](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-libs) for writing contracts on Aztec.

Expand All @@ -16,4 +16,15 @@ Aztec.nr contains abstractions which remove the need to understand the low-level

To import Aztec.nr into your Aztec contract project, simply include it as a dependency.

#include_code importing-aztec /yarn-project/noir-contracts/src/contracts/private_token_contract/Nargo.toml toml
```toml
[package]
name = "my_noir_contract"
authors = [""]
compiler_version = "0.10.0"
type = "contract"

[dependencies]
aztec = { git="https://github.com/AztecProtocol/aztec-packages", tag="master", directory="yarn-project/noir-libs/noir-aztec" }
```

Note: currently the dependency name ***MUST*** be `aztec`. The framework expects this namespace to be available when compiling into contracts. This limitation may be removed in the future.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would probably be better to make this a larger note os one of the info boxes.

2 changes: 2 additions & 0 deletions l1-contracts/src/core/interfaces/messagebridge/IOutbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface IOutbox {
*/
function sendL1Messages(bytes32[] memory _entryKeys) external;

/// docs:start:consume_interface
/**
* @notice Consumes an entry from the Outbox
* @dev Only meaningfully callable by portals, otherwise should never hit an entry
Expand All @@ -38,6 +39,7 @@ interface IOutbox {
* @return entryKey - The key of the entry removed
*/
function consume(DataStructures.L2ToL1Msg memory _message) external returns (bytes32 entryKey);
/// docs:end:consume_interface

/**
* @notice Fetch an entry
Expand Down
2 changes: 2 additions & 0 deletions l1-contracts/src/core/libraries/DataStructures.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ library DataStructures {
uint256 version;
}

// docs:start:l1_to_l2_message_struct
/**
* @notice Struct containing a message from L1 to L2
* @param sender - The sender of the message
Expand All @@ -59,6 +60,7 @@ library DataStructures {
uint32 deadline;
uint64 fee;
}
// docs:end:l1_to_l2_message_struct

/**
* @notice Struct containing a message from L2 to L1
Expand Down
Loading