Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 26 additions & 12 deletions aztec-up/test/default_scaffold.sh
Original file line number Diff line number Diff line change
@@ -1,41 +1,48 @@
#!/usr/bin/env bash
set -euo pipefail

# Tests that the default scaffold generated by `aztec new` compiles and passes its tests without any modifications.
# Also tests that a second contract can be added to the workspace with `aztec new`.
# Tests that `aztec init` scaffolds a Counter contract that compiles and passes tests,
# and that `aztec new` can add a blank contract to the same workspace.

export LOG_LEVEL=silent

aztec new my_workspace
mkdir my_workspace && cd my_workspace
aztec init

# Verify workspace structure with named crate directories.
if [ ! -f my_workspace/Nargo.toml ]; then
if [ ! -f Nargo.toml ]; then
echo "Failed to create workspace Nargo.toml."
exit 1
fi
if [ ! -f my_workspace/my_workspace_contract/Nargo.toml ] || [ ! -f my_workspace/my_workspace_contract/src/main.nr ]; then
if [ ! -f my_workspace_contract/Nargo.toml ] || [ ! -f my_workspace_contract/src/main.nr ]; then
echo "Failed to create contract crate."
exit 1
fi
if [ ! -f my_workspace/my_workspace_test/Nargo.toml ] || [ ! -f my_workspace/my_workspace_test/src/lib.nr ]; then
if [ ! -f my_workspace_test/Nargo.toml ] || [ ! -f my_workspace_test/src/lib.nr ]; then
echo "Failed to create test crate."
exit 1
fi

cd my_workspace
# Verify the Counter template was used.
if ! grep -q 'pub contract Counter' my_workspace_contract/src/main.nr; then
echo "Expected Counter contract from aztec init."
exit 1
fi

# This is unfortunate as it makes the test worse but in CI setting the aztec version is 0.0.1 which doesn't exist as
# a remote git tag, so we need to rewrite dependencies to use local aztec-nr.
sed -i 's|aztec = .*git.*AztecProtocol/aztec-nr.*|aztec = { path="/home/ubuntu/aztec-packages/noir-projects/aztec-nr/aztec" }|' \
sed -i \
-e 's|aztec = .*git.*AztecProtocol/aztec-nr.*|aztec = { path="/home/ubuntu/aztec-packages/noir-projects/aztec-nr/aztec" }|' \
-e 's|balance_set = .*git.*AztecProtocol/aztec-nr.*|balance_set = { path="/home/ubuntu/aztec-packages/noir-projects/aztec-nr/balance-set" }|' \
my_workspace_contract/Nargo.toml my_workspace_test/Nargo.toml

# Compile the default scaffold contract.
# Compile the Counter contract.
aztec compile

# Run the default scaffold tests.
# Run the Counter tests.
aztec test

# --- Test adding a second contract to the workspace ---
# --- Test adding a blank contract to the workspace with `aztec new` ---
aztec new token

# Verify token crates were created.
Expand All @@ -57,8 +64,15 @@ if ! grep -q '"my_workspace_contract"' Nargo.toml || \
exit 1
fi

# Verify the blank template was used for the new contract.
if ! grep -q 'pub contract Main' token_contract/src/main.nr; then
echo "Expected blank contract from aztec new."
exit 1
fi

# Rewrite aztec deps for token crates too.
sed -i 's|aztec = .*git.*AztecProtocol/aztec-nr.*|aztec = { path="/home/ubuntu/aztec-packages/noir-projects/aztec-nr/aztec" }|' \
sed -i \
's|aztec = .*git.*AztecProtocol/aztec-nr.*|aztec = { path="/home/ubuntu/aztec-packages/noir-projects/aztec-nr/aztec" }|' \
token_contract/Nargo.toml token_test/Nargo.toml

# Compile and test the full workspace (both contracts).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Therefore it is recommended to read the `aztec-nr` [guide on authwitnesses](../a

The authwit system supports different intent types depending on your use case:

- **`CallIntent`**: Use when authorizing a specific contract function call. Contains `{ caller, action }` where `action` is a `ContractFunctionInteraction`.
- **`CallIntent`**: Use when authorizing a specific contract function call. Contains `{ caller, call }` where `call` is a `FunctionCall`, typically obtained with `await interaction.getFunctionCall()`.
- **`ContractFunctionInteractionCallIntent`**: Convenience form that takes the interaction directly. Contains `{ caller, action }` where `action` is a `ContractFunctionInteraction`; internally resolved to a `FunctionCall` before signing.
- **`IntentInnerHash`**: Use when authorizing arbitrary data. Contains `{ consumer, innerHash }` where `consumer` is the contract that will verify the authwit.

## Create private authwits
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Log values from your contract using `debug_log`:

```rust
// Import debug logging
use dep::aztec::oracle::debug_log::{ debug_log, debug_log_format };
use aztec::oracle::logging::{ debug_log, debug_log_format };

// Log simple messages
debug_log("checkpoint reached");
Expand Down Expand Up @@ -65,23 +65,20 @@ LOG_LEVEL="info;debug:simulator:client_execution_context;debug:simulator:client_
```

:::info Log filter format
`LOG_LEVEL` accepts a semicolon-delimited list of filters. Each filter can be:

- `level` - Sets default level for all modules
- `level:module` - Sets level for a specific module
- `level:module:submodule` - Sets level for a specific submodule
`LOG_LEVEL` is a semicolon-delimited list. The **first segment must be a bare log level** — it sets the default level for all modules. Subsequent segments are `level:module` (or `level:module:submodule`) overrides.

```bash
# Default level only
LOG_LEVEL="debug"

# Default level + specific module overrides
# Default level + module overrides
LOG_LEVEL="info;debug:simulator;debug:execution"

# Default level + specific submodule overrides
# Default level + submodule overrides
LOG_LEVEL="info;debug:simulator:client_execution_context;debug:simulator:client_view_context"
```

A bare `level:module` (e.g. `LOG_LEVEL="warn:simulator"`) is **not valid** — the parser reads the first segment as the default level and rejects it with `Invalid log level: warn:simulator`.
:::

## Debugging common errors
Expand Down Expand Up @@ -113,9 +110,12 @@ LOG_LEVEL="info;debug:simulator:client_execution_context;debug:simulator:client_
### Quick Fixes for Common Issues

```bash
# Archiver sync issues - force progress with dummy transactions
aztec-wallet send transfer --from test0 --to test0 --amount 0
aztec-wallet send transfer --from test0 --to test0 --amount 0
# Archiver sync issues - force progress with dummy transactions.
# Assumes you have imported the local network test accounts
# (aztec-wallet import-test-accounts) and have a deployed token
# aliased as `testtoken`.
aztec-wallet send transfer --from test0 --contract-address testtoken --args accounts:test0 0
aztec-wallet send transfer --from test0 --contract-address testtoken --args accounts:test0 0

# L1 to L2 message pending - wait for inclusion
# Messages need 2 blocks to be processed
Expand Down Expand Up @@ -207,7 +207,7 @@ LOG_LEVEL=verbose aztec start --local-network
### Common debug imports

```rust
use dep::aztec::oracle::debug_log::{ debug_log, debug_log_format };
use aztec::oracle::logging::{ debug_log, debug_log_format };
```

### Check contract registration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ High-level structure of how Aztec smart contracts including the different compon

## Directory structure

Here's a common layout for a basic Aztec.nr Contract project:
When you create a new project with `aztec new my_project`, it generates a single-crate Noir contract project:

```text title="layout of an aztec contract project"
─── my_aztec_contract_project
├── src
└── main.nr <-- your contract
└── Nargo.toml <-- package and dependency management
─── my_project
├── Nargo.toml <-- contract package and dependencies
└── src
└── main.nr <-- your contract
```

`Nargo.toml` declares the contract package (with `type = "contract"`) and its dependencies. Your contract code lives in `src/main.nr`. Noir tests using `#[test]` live alongside the contract in the same crate — see [Testing Contracts](../testing_contracts.md).

To add another contract as a sibling of an existing one, run `aztec new <name>` from the parent directory (each contract is its own crate). To initialize a contract project inside an existing empty directory instead, `cd` into it and run `aztec init` (it takes no positional argument; pass `--name <name>` if you want the package name to differ from the directory name).

See the vanilla Noir docs for [more info on packages](https://noir-lang.org/docs/noir/modules_packages_crates/crates_and_packages).

## Contract block
Expand All @@ -44,7 +48,7 @@ The `#[aztec]` macro performs a lot of the low-level operations required to take

## Imports

Aside from the [`#[aztec]`](pathname:///aztec-nr-api/testnet/noir_aztec/macros/aztec/fn.aztec) macro import, all other imports need to go _inside_ the `contract` block - this is because `contract` acts like `mod`, creating a new [module](https://noir-lang.org/docs/noir/modules_packages_crates/modules).
Aside from the [`#[aztec]`](pathname:///aztec-nr-api/mainnet/noir_aztec/macros/fn.aztec) macro import, all other imports need to go _inside_ the `contract` block - this is because `contract` acts like `mod`, creating a new [module](https://noir-lang.org/docs/noir/modules_packages_crates/modules).

```rust
use aztec::macros::aztec;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ Create constructor-like functions using the `#[initializer]` annotation:
#[initializer]
#[external("private")]
// We can name our initializer anything we want as long as it's marked as aztec(initializer)
fn initialize(headstart: u64, owner: AztecAddress) {
self.storage.counters.at(owner).add(headstart as u128).deliver(
fn initialize(headstart: u128, owner: AztecAddress) {
self.storage.counters.at(owner).add(headstart).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,15 @@ storage.votes.insert(new_vote).deliver(vote_counter); // the vote counter accoun

### Flow

1. Write your contract and specify your contract dependencies. Every contract written for Aztec will have
aztec-nr as a dependency. Add it to your `Nargo.toml` with
1. Write your contract and specify your contract dependencies. Create a new project with `aztec new my_project`, which creates a single-crate Noir contract project (`Nargo.toml` + `src/main.nr`) with the `aztec` dependency already configured. If you need additional dependencies, add them to `my_project/Nargo.toml`:

```toml
# Nargo.toml
# my_project/Nargo.toml
[dependencies]
aztec = { git="https://github.com/AztecProtocol/aztec-nr/", tag="v4.1.0-rc.2", directory="aztec" }
```

Update your `main.nr` contract file to use the Aztec.nr macros for writing contracts.
Update your `my_project/src/main.nr` contract file to use the Aztec.nr macros for writing contracts.

```rust title="setup" showLineNumbers
use aztec::macros::aztec;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,28 @@ Always use `aztec test` instead of `nargo test`. The `TestEnvironment` requires

## Basic test structure

Tests live in the same crate as your contract. `aztec new` creates a single-crate project, and the convention is to place `#[test]` functions in a `mod tests` block alongside the contract (or in submodules of the crate):

```rust
use crate::MyContract;
use aztec::{
protocol::address::AztecAddress,
test::helpers::test_environment::TestEnvironment,
};
use aztec::macros::aztec;

#[test]
unconstrained fn test_basic_flow() {
// 1. Create test environment
let mut env = TestEnvironment::new();
#[aztec]
pub contract MyContract {
// ...contract functions...
}

// 2. Create accounts
let owner = env.create_light_account();
mod tests {
use super::MyContract;
use aztec::test::helpers::test_environment::TestEnvironment;

#[test]
unconstrained fn test_basic_flow() {
// 1. Create test environment
let mut env = TestEnvironment::new();

// 2. Create accounts
let _owner = env.create_light_account();
}
}
```

Expand All @@ -72,13 +80,14 @@ unconstrained fn test_basic_flow() {
:::

:::tip Organizing test files
You can organize tests in separate files:
For larger test suites, split tests into submodules of your crate rather than keeping them all inside `main.nr`:

- Create `src/test.nr` with `mod utils;` to import helper functions
- Split tests into modules like `src/test/transfer_tests.nr`, `src/test/auth_tests.nr`
- Import the test module in `src/main.nr` with `mod test;`
- Share setup functions in `src/test/utils.nr`
:::
- Create modules like `src/transfer_tests.nr`, `src/auth_tests.nr`
- Declare them from `src/main.nr` with `mod transfer_tests;`, `mod auth_tests;`
- Share setup functions in `src/test_utils.nr`

See the [aztec-standards token contract](https://github.com/defi-wonderland/aztec-standards/tree/dev/src/token_contract) for a worked example of this layout.
:::

## Deploying contracts

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ Let’s create a constructor method to run on deployment that assigns an initial
#[initializer]
#[external("private")]
// We can name our initializer anything we want as long as it's marked as aztec(initializer)
fn initialize(headstart: u64, owner: AztecAddress) {
self.storage.counters.at(owner).add(headstart as u128).deliver(
fn initialize(headstart: u128, owner: AztecAddress) {
self.storage.counters.at(owner).add(headstart).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,9 @@ nargo test
Expected output:

```text
[hello_circuit] Running 1 test functions
[hello_circuit] Testing test_main... ok
[hello_circuit] All tests passed
[hello_circuit] Running 1 test function
[hello_circuit] Testing test_main ... ok
[hello_circuit] 1 test passed
```

**Tip**: Circuit tests run without generating proofs, making them fast for development. Use them to verify your circuit logic before the more expensive proof generation step.
Expand All @@ -228,9 +228,11 @@ The contract demonstrates several important patterns:
Use `aztec new` to generate the contract project structure:

```bash
aztec new contract --name ValueNotEqual
aztec new --name ValueNotEqual contract
```

The `aztec new` wrapper stops parsing arguments at the first positional, so `--name` must come **before** the `contract` path — otherwise the flag is silently dropped and the Nargo package ends up named `contract`. The Nargo package name (`--name`) is independent of the Noir contract name declared inside `main.nr`; the artifact filename downstream is driven by the contract name.

This creates:

```tree
Expand Down Expand Up @@ -701,7 +703,7 @@ Expected output:
Proof verification: SUCCESS
Using deflattenFields to convert proof...
VK size: 115
Proof size: 508
Proof size: 500
Public inputs: 1
Done
```
Expand Down
Loading
Loading