diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/compiling_contracts.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/compiling_contracts.md index a7d63c90f4a5..b0e5bc269a4a 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/compiling_contracts.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/compiling_contracts.md @@ -33,7 +33,7 @@ Use generated interfaces instead of manual function calls: ```rust contract MyContract { - use dep::token::Token; + use token::Token; #[external("private")] fn transfer_tokens(token_address: AztecAddress, recipient: AztecAddress, amount: u128) { diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/debugging.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/debugging.md index de9112d27395..7807187e4ffe 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/debugging.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/debugging.md @@ -5,8 +5,6 @@ tags: [debugging, errors, logging, local_network, aztec.nr] description: This guide shows you how to debug issues in your Aztec contracts. --- - - This guide shows you how to debug issues in your Aztec development environment. ## Prerequisites @@ -33,7 +31,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"); @@ -49,7 +47,7 @@ debug_log_format("values: {0}, {1}, {2}", [val1, val2, val3]); ``` :::note -Debug logs appear only during local execution. Private functions always execute locally, but public functions must be simulated to show logs. Use `.simulate()` or `.prove()` in TypeScript, or `env.simulate_public_function()` in TXE tests. +Debug logs appear only during local execution. Private functions always execute locally, but public functions must be simulated to show logs. Use `.simulate()` or `.prove()` in TypeScript, or `env.call_public()` in TXE tests. ::: To see debug logs from your tests, set `LOG_LEVEL` when running: @@ -160,7 +158,7 @@ link.click(); ## Interpret error messages -### Kernel circuit errors (2xxx) +### Circuit and protocol errors - **Private kernel errors (2xxx)**: Issues with private function execution - **Public kernel errors (3xxx)**: Issues with public function execution @@ -207,7 +205,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 @@ -218,7 +216,7 @@ await wallet.getContractMetadata(myContractInstance.address); ### Decode L1 errors -Check hex errors against [Errors.sol](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/libraries/Errors.sol) +Check hex errors against [Errors.sol](https://github.com/AztecProtocol/aztec-packages/blob/v4.2.0-aztecnr-rc.2/l1-contracts/src/core/libraries/Errors.sol) ## Tips diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/how_to_use_capsules.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/how_to_use_capsules.md index b0e6fa953a22..95048fca06dd 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/how_to_use_capsules.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/how_to_use_capsules.md @@ -12,22 +12,26 @@ Capsules provide per-contract non-volatile storage in the PXE. Data is stored lo ```rust use aztec::oracle::capsules; -// Inside a contract function, use self.address for contract_address -let contract_address: AztecAddress = self.address; +// Capsule operations are unconstrained, so these values are typically +// passed in as parameters from the calling context. +let contract_address: AztecAddress = /* self.address */; let slot: Field = 1; +// scope is an AztecAddress used for capsule isolation, allowing multiple +// independent namespaces within the same contract. +let scope: AztecAddress = /* e.g. the account address */; // Store data at a slot (overwrites existing data) -capsules::store(contract_address, slot, value); +capsules::store(contract_address, slot, value, scope); // Load data (returns Option) -let result: Option = capsules::load(contract_address, slot); +let result: Option = capsules::load(contract_address, slot, scope); // Delete data at a slot -capsules::delete(contract_address, slot); +capsules::delete(contract_address, slot, scope); // Copy contiguous slots (supports overlapping regions) -// copy(contract_address, src_slot, dst_slot, num_entries: u32) -capsules::copy(contract_address, src_slot, dst_slot, 3); +// copy(contract_address, src_slot, dst_slot, num_entries: u32, scope) +capsules::copy(contract_address, src_slot, dst_slot, 3, scope); ``` Types must implement `Serialize` and `Deserialize` traits. @@ -42,12 +46,12 @@ All capsule operations are `unconstrained`. Data loaded from capsules should be ```rust use aztec::capsules::CapsuleArray; -use protocol::hash::sha256_to_field; +use aztec::protocol::hash::sha256_to_field; // Use a hash for base_slot to avoid collisions with other storage global BASE_SLOT: Field = sha256_to_field("MY_CONTRACT::MY_ARRAY".as_bytes()); -let array: CapsuleArray = CapsuleArray::at(contract_address, BASE_SLOT); +let array: CapsuleArray = CapsuleArray::at(contract_address, BASE_SLOT, scope); array.push(value); // Append to end let value = array.get(index); // Read at index (throws if out of bounds) diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/partial_notes.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/partial_notes.md index 9c6e6045eef9..e34b334a33e8 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/partial_notes.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/partial_notes.md @@ -27,7 +27,7 @@ pub struct UintNote { The `UintNote` struct itself only contains the `value` field. Additional fields including `owner`, `randomness`, and `storage_slot` are passed as parameters during note hash computation. -When creating the note locally during private execution, the `owner` and `storage_slot` are known, but the `value` potentially is not (e.g., it depends on some onchain dynamic variable). First, a **partial note** can be created during private execution that commits to the `owner`, `randomness`, and `storage_slot`, and then the note is *"completed"* to create a full note by later adding the `value` field, usually during public execution. +When creating the note locally during private execution, the `owner` and `storage_slot` are known, but the `value` potentially is not (e.g., it depends on some onchain dynamic variable). First, a **partial note** can be created during private execution that commits to the `owner` and `randomness`, and then the note is *"completed"* to create a full note by later adding the `storage_slot` and `value` fields, usually during public execution. @@ -62,7 +62,7 @@ pub struct UintNote { **Phase 1: Partial Commitment (Private Execution)** -The private fields (`owner`, `randomness`, and `storage_slot`) are committed during local, private execution: +The private fields (`owner` and `randomness`) are committed during local, private execution: ```rust title="compute_partial_commitment" showLineNumbers fn compute_partial_commitment(owner: AztecAddress, randomness: Field) -> Field { @@ -75,7 +75,7 @@ fn compute_partial_commitment(owner: AztecAddress, randomness: Field) -> Field { This creates a partial note commitment: ``` -partial_commitment = H(owner, storage_slot, randomness) +partial_commitment = H(owner, randomness) ``` **Phase 2: Note Completion (Public Execution)** @@ -99,8 +99,8 @@ fn compute_complete_note_hash(self, storage_slot: Field, value: u128) -> Field { The resulting structure is a nested commitment: ``` -note_hash = H(H(owner, storage_slot, randomness), value) - = H(partial_commitment, value) +note_hash = H(H(owner, randomness), storage_slot, value) + = H(partial_commitment, storage_slot, value) ``` ## Universal Note Format @@ -109,8 +109,8 @@ All notes in Aztec use the partial note format internally, even when all data is When a note is created with all fields known (including `owner`, `storage_slot`, `randomness`, and `value`): -1. A partial commitment is computed from the private fields (`owner`, `storage_slot`, `randomness`) -2. The partial commitment is immediately completed with the `value` field +1. A partial commitment is computed from the private fields (`owner`, `randomness`) +2. The partial commitment is immediately completed with the `storage_slot` and `value` fields ```rust title="compute_note_hash" showLineNumbers fn compute_note_hash(self, owner: AztecAddress, storage_slot: Field, randomness: Field) -> Field { @@ -135,7 +135,6 @@ fn compute_note_hash(self, owner: AztecAddress, storage_slot: Field, randomness: This two-step process ensures that notes with identical field values produce identical note hashes, regardless of whether they were created as partial notes or complete notes. - ## Partial Notes in Practice diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/writing_efficient_contracts.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/writing_efficient_contracts.md index e3407e0adb3a..71977ac0aeb9 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/writing_efficient_contracts.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/advanced/writing_efficient_contracts.md @@ -95,9 +95,9 @@ To get a sense of things, here is a table of gate counts for common operations: | ~75 | Hashing 3 fields with Poseidon2 | | 3500 | Reading a value from a tree (public data tree, note hash tree, nullifier tree) | | 4000 | Reading a delayed public mutable read | -| X000 | Calculating sha256 | -| X000 | Constrained encryption of a log of Y fields | -| X000 | Constrained encryption and tag a log of Y fields | +| ~5,000 | Calculating sha256 (varies by input size) | +| Varies | Constrained encryption of a private log (depends on field count) | +| Varies | Constrained encryption and tagging of a private log (depends on field count) | ### Optimization: use arithmetic instead of non-arithmetic operations @@ -106,7 +106,7 @@ Because the underlying equation in the proving backend makes use of multiplicati For example: ```rust -comptime global TWO_POW_32: Field = 2.pow_32(16); +comptime global TWO_POW_16: Field = 2.pow_32(16); // ... { #[external("private")] @@ -116,7 +116,7 @@ comptime global TWO_POW_32: Field = 2.pow_32(16); #[external("private")] fn mul_efficient(number: Field) -> u128 { - (number * TWO_POW_32) as u128 + (number * TWO_POW_16) as u128 } // 5184 gates (60 gates less) } ``` @@ -153,7 +153,7 @@ For example, use boolean equality effectively instead of `>=`: } } sum - } // 45068 gates (751 gates less) + } // 45068 gates (751 gates more due to the boolean operations, but the pattern demonstrates how to avoid range checks) } ``` @@ -279,9 +279,12 @@ Like with sqrt, we have the inefficient function that does the sort with constra // Safety: calculate in unconstrained function, then constrain the result let sorted_array = unsafe { super::sort_array(array) }; // constrain that sorted_array elements are sorted - for i in 0..super::ARRAY_SIZE as u32 { + for i in 0..super::ARRAY_SIZE as u32 - 1 { assert(sorted_array[i] <= sorted_array[i + 1], "array should be sorted"); } + // Note: A production implementation should also verify that sorted_array is a + // permutation of the input array to prevent a malicious prover from returning + // arbitrary sorted values. sorted_array } // 5870 gates (953 gates less) for 10 elements, 12582 gates for 100 elements (115198 gates less) } @@ -309,7 +312,7 @@ Note: The stdlib provides a highly optimized version of sort on arrays, `array.s ```rust #[external("private")] fn sort_stdlib(array: [u32; super::ARRAY_SIZE]) -> [u32; super::ARRAY_SIZE] { - array.sort(); + array.sort() } // 5943 gates (880 gates less) for 10 elements, 13308 gates for 100 elements (114472 gates less) ``` diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/contract_structure.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/contract_structure.md index fde1038197cc..8fae3c8ac828 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/contract_structure.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/contract_structure.md @@ -98,15 +98,16 @@ use aztec::macros::aztec; pub contract MyContract { use aztec::{ macros::storage, - state_vars::{PrivateMutable, PublicMutable} + state_vars::{Owned, PrivateMutable, PublicMutable} }; + use uint_note::UintNote; // The storage struct can have any name, but is typically called `Storage`. It must have the `#[storage]` macro applied to it. // This struct must also have a generic type called C or Context. #[storage] struct Storage { // A private numeric value which can change over time. This value will be hidden, and only those with the secret can know its current value. - my_private_state_variable: Owned>, + my_private_state_variable: Owned, Context>, // A public numeric value which can change over time. This value will be known to everyone and is equivalent to the Solidity example above. my_public_state_variable: PublicMutable, } @@ -142,6 +143,7 @@ use aztec::macros::aztec; #[aztec] contract MyContract { use aztec::macros::functions::external; + use aztec::protocol::address::AztecAddress; #[external("private")] fn my_private_function(parameter_a: u128, parameter_b: AztecAddress) { @@ -154,7 +156,7 @@ contract MyContract { } #[external("utility")] - fn my_utility_function(parameter_a: u128, parameter_b: AztecAddress) { + unconstrained fn my_utility_function(parameter_a: u128, parameter_b: AztecAddress) { // ... } } diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/contract_upgrades.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/contract_upgrades.md index 8260a2da2fe6..a581e9fbefbf 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/contract_upgrades.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/contract_upgrades.md @@ -41,6 +41,13 @@ fn update_to(new_class_id: ContractClassId) { } ``` +:::info +To use the `ContractInstanceRegistry`, add this dependency to your `Nargo.toml`: +```toml +contract_instance_registry = { git="https://github.com/AztecProtocol/aztec-packages/", tag="v4.2.0-aztecnr-rc.2", directory="noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface" } +``` +::: + The `update` function in the registry is a public function, so you can enqueue it from a private function (as shown above) or call it directly from a public function. :::warning[Access Control] diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/custom_notes.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/custom_notes.md index 5254de40560f..fde198e877bd 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/custom_notes.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/custom_notes.md @@ -29,21 +29,21 @@ Aztec.nr provides pre-built note types for common use cases: ```toml # In Nargo.toml -uint_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="v4.2.0-aztecnr-rc.2", directory="noir-projects/aztec-nr/uint-note" } +uint_note = { git="https://github.com/AztecProtocol/aztec-nr", tag="v4.2.0-aztecnr-rc.2", directory="uint-note" } ``` **FieldNote** - For storing single Field values: ```toml # In Nargo.toml -field_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="v4.2.0-aztecnr-rc.2", directory="noir-projects/aztec-nr/field-note" } +field_note = { git="https://github.com/AztecProtocol/aztec-nr", tag="v4.2.0-aztecnr-rc.2", directory="field-note" } ``` **AddressNote** - For storing Aztec addresses: ```toml # In Nargo.toml -address_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="v4.2.0-aztecnr-rc.2", directory="noir-projects/aztec-nr/address-note" } +address_note = { git="https://github.com/AztecProtocol/aztec-nr", tag="v4.2.0-aztecnr-rc.2", directory="address-note" } ``` ::: diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/dependencies.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/dependencies.md index 6f3e8a48f0b8..4632eaf8e4b9 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/dependencies.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/dependencies.md @@ -18,25 +18,17 @@ aztec = { git="https://github.com/AztecProtocol/aztec-nr/", tag="v4.2.0-aztecnr- ### Aztec (required) ```toml -aztec = { git="https://github.com/AztecProtocol/aztec-packages/", tag="v4.2.0-aztecnr-rc.2", directory="noir-projects/aztec-nr/aztec" } +aztec = { git="https://github.com/AztecProtocol/aztec-nr/", tag="v4.2.0-aztecnr-rc.2", directory="aztec" } ``` The core Aztec library required for every Aztec.nr smart contract. -### Protocol Types - -```toml -protocol = { git="https://github.com/AztecProtocol/aztec-packages/", tag="v4.2.0-aztecnr-rc.2", directory="noir-projects/noir-protocol-circuits/crates/types"} -``` - -Contains types used in the Aztec protocol (addresses, constants, hashes, etc.). - ## Note Types ### Address Note ```toml -address_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="v4.2.0-aztecnr-rc.2", directory="noir-projects/aztec-nr/address-note" } +address_note = { git="https://github.com/AztecProtocol/aztec-nr/", tag="v4.2.0-aztecnr-rc.2", directory="address-note" } ``` Provides `AddressNote`, a note type for storing `AztecAddress` values. @@ -76,3 +68,22 @@ compressed_string = { git="https://github.com/AztecProtocol/aztec-nr/", tag="v4. ``` Provides `CompressedString` and `FieldCompressedString` utilities for working with compressed string data. + +## Updating your aztec dependencies + +When `aztec compile` warns that your aztec dependency tag does not match the CLI version, update the `tag` field in every Aztec.nr entry in your `Nargo.toml` to match the CLI version you are running. + +For example, if your CLI is `v4.2.0-aztecnr-rc.2`, change: + +```toml +aztec = { git="https://github.com/AztecProtocol/aztec-nr/", tag="v", directory="aztec" } +``` + +to: + +```toml +aztec = { git="https://github.com/AztecProtocol/aztec-nr/", tag="v4.2.0-aztecnr-rc.2", directory="aztec" } +``` + +Repeat for every other Aztec.nr dependency in your `Nargo.toml` (e.g. `address_note`, +`balance_set`, etc.). You can check your current CLI version with `aztec --version`. diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/ethereum_aztec_messaging.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/ethereum_aztec_messaging.md index 92c9a1c8ae4d..47a7dac127ad 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/ethereum_aztec_messaging.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/ethereum_aztec_messaging.md @@ -126,8 +126,8 @@ L2 to L1 messages are only available after the epoch proof is submitted to L1. S * @param _amount - The amount to withdraw * @param _withCaller - Flag to use `msg.sender` as caller, otherwise address(0) * @param _epoch - The epoch the message is in - * @param _leafIndex - The amount to withdraw - * @param _path - Flag to use `msg.sender` as caller, otherwise address(0) + * @param _leafIndex - The index of the message leaf in the tree + * @param _path - The Merkle proof path for the message leaf * Must match the caller of the message (specified from L2) to consume it. */ function withdraw( diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/events_and_logs.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/events_and_logs.md index 7d3ec45e2be1..0fbe002e1fa9 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/events_and_logs.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/events_and_logs.md @@ -34,7 +34,7 @@ use aztec::messages::message_delivery::MessageDelivery; #[external("private")] fn transfer(to: AztecAddress, amount: u128) { - let from = self.msg_sender().unwrap(); + let from = self.msg_sender(); // ... transfer logic ... diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/attributes.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/attributes.md index c58e203a3d89..a5f3892ea4b4 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/attributes.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/attributes.md @@ -141,7 +141,7 @@ It is also useful in private functions when dealing with tasks of an unknown siz This macro inserts a check at the beginning of the function to ensure that the caller is the contract itself. This is done by adding the following assertion: ```rust -assert(self.msg_sender().unwrap() == self.address, "Function can only be called internally"); +assert(self.msg_sender() == self.address, "Function can only be called internally"); ``` ## #[allow_phase_change] diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/context.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/context.md index 473842f73d08..db9c31bcb17e 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/context.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/context.md @@ -81,7 +81,7 @@ pub struct PrivateContextInputs { > Source code: noir-projects/aztec-nr/aztec/src/context/inputs/private_context_inputs.nr#L7-L15 -As shown in the snippet, the application context is made up of 4 main structures. The call context, the block header, and the private global variables. +As shown in the snippet, the application context is made up of 3 main structures. The call context, the block header, and the private global variables. First of all, the call context. @@ -110,13 +110,12 @@ The call context contains information about the current call being made: -2. Storage contract address +2. 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 (Warning: This is yet to be implemented). In this case the value will be that of the sending contract. + - 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. 3. 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 be the address of the sender. - is_static_call: This will be set if and only if the current call is a static call. In a static call, state changing altering operations are not allowed. ### Block Header @@ -166,14 +165,14 @@ pub struct TxContext { To allow for flexibility in the number of arguments supported by Aztec functions, all function inputs are reduced to a singular value which can be proven from within the application. -The `args_hash` is the result of pedersen hashing all of a function's inputs. +The `args_hash` is the result of poseidon2 hashing all of a function's inputs. ### Return Values The return values are a set of values that are returned from an applications execution to be passed to other functions through the kernel. Developers do not need to worry about passing their function return values to the `context` directly as `Aztec.nr` takes care of it for you. See the documentation surrounding `Aztec.nr` [macro expansion](./function_transforms.md#function-transformation) for more details. ```rust -return_values : BoundedVec\, +return_hash: Field, ``` ## Expiration Timestamp diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/function_transforms.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/function_transforms.md index eef169108cb4..e819a3db5f95 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/function_transforms.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/functions/function_transforms.md @@ -11,7 +11,7 @@ This page explains what happens under the hood when you create a function in an Private functions in Aztec compile to standalone circuits that must conform to the protocol's kernel circuit interface. Public functions compile to AVM bytecode. The transformations described below bridge the gap between developer-friendly Aztec.nr syntax and these underlying requirements. -Utility functions (marked with `#[utility]`) do not undergo these transformations—they remain as regular Noir functions. +Utility functions (marked with `#[external("utility")]`) do not undergo these transformations—they remain as regular Noir functions. ## Function transformation diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/macros.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/macros.md index 7ad827af268b..1bcf09bd5e40 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/macros.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/macros.md @@ -22,8 +22,8 @@ Aztec.nr provides macros (attributes) that transform your code during compilatio | `#[external("private")]` | Client-side private execution with proofs | | `#[external("public")]` | Sequencer-side public execution | | `#[external("utility")]` | Unconstrained queries, not included in transactions | -| `#[internal("private")]` | Private helper, inlined at call sites | -| `#[internal("public")]` | Public helper, inlined at call sites | +| `#[internal("private")]` | Private helper, only callable within the same contract | +| `#[internal("public")]` | Public helper, only callable within the same contract | | `#[view]` | Prevents state modification | | `#[initializer]` | Contract constructor | | `#[noinitcheck]` | Callable before contract initialization | diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/state_variables.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/state_variables.md index 2a098e702aaa..8564d9d286e2 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/state_variables.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/framework-description/state_variables.md @@ -72,7 +72,7 @@ Consider, for example, a `PublicMutable` state variable, which is a value that i ```rust #[storage] struct Storage { - my_public_variable: PublicMutable, + my_public_variable: PublicMutable, } #[external("public")] @@ -301,7 +301,7 @@ They also have some metadata, including a storage slot to avoid collisions with The note content plus the metadata are all hashed together, and it is this hash that gets stored onchain in the note hash tree. This hash is called a commitment. The underlying note content (the note hash preimage) is not stored anywhere onchain, so third parties cannot access it and it remains private. The note hash tree is append-only - if it wasn't, when a note was spent, external observers would notice that the tree leaf inserted in some transaction was modified in a second transaction, linking them together and leaking privacy. For example, when a user made a payment to a third party, the recipient would be able to know when they spent the received funds. Nullifiers exist to solve this issue. -Note: Aztec.nr comes with some prebuilt note types, including [`UintNote`](https://github.com/AztecProtocol/aztec-packages/tree/08935f75dbc3052ce984add225fc7a0dac863050/noir-projects/aztec-nr/uint-note) and [`AddressNote`](https://github.com/AztecProtocol/aztec-packages/tree/08935f75dbc3052ce984add225fc7a0dac863050/noir-projects/aztec-nr/address-note), but users are also free to create their own with the `#[note]` macro. +Note: Aztec.nr comes with some prebuilt note types, including [`UintNote`](https://github.com/AztecProtocol/aztec-packages/tree/v4.2.0-aztecnr-rc.2/noir-projects/aztec-nr/uint-note) and [`AddressNote`](https://github.com/AztecProtocol/aztec-packages/tree/v4.2.0-aztecnr-rc.2/noir-projects/aztec-nr/address-note), but users are also free to create their own with the `#[note]` macro. ##### Note Lifecycle @@ -345,7 +345,7 @@ When working with private state variables, many operations return a `NoteMessage #### Delivery Methods Private notes need to be communicated to their recipients so they know the note exists and can use it. The [`NoteMessage`](pathname:///aztec-nr-api/mainnet/noir_aztec/note/struct.NoteMessage) wrapper forces you to make an explicit choice about how this happens: - - [`MessageDelivery.ONCHAIN_CONSTRAINED`](pathname:///aztec-nr-api/mainnet/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.ONCHAIN_UNCONSTRAINED): Verified in the circuit (most secure, but highest cost) - Use when the sender cannot be trusted to deliver correctly (e.g., protocol fees, multisig config updates). **Warning:** Currently [not fully constrained](https://github.com/AztecProtocol/aztec-packages/issues/14565) - the log's tag is unconstrained. + - [`MessageDelivery.ONCHAIN_CONSTRAINED`](pathname:///aztec-nr-api/mainnet/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.ONCHAIN_CONSTRAINED): Verified in the circuit (most secure, but highest cost) - Use when the sender cannot be trusted to deliver correctly (e.g., protocol fees, multisig config updates). **Warning:** Currently [not fully constrained](https://github.com/AztecProtocol/aztec-packages/issues/14565) - the log's tag is unconstrained. - [`MessageDelivery.ONCHAIN_UNCONSTRAINED`](pathname:///aztec-nr-api/mainnet/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.ONCHAIN_UNCONSTRAINED): Message stored onchain but no guarantees on content - Use when the sender is incentivized to deliver correctly but may not have an offchain channel to the recipient. - [`MessageDelivery.OFFCHAIN`](pathname:///aztec-nr-api/mainnet/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.OFFCHAIN): Lowest cost, no onchain data - Use when the sender and recipient can communicate and the sender is incentivized to deliver correctly. @@ -419,7 +419,7 @@ fn perform_admin_action() { // value of the counter and can update it again in the future. self.storage.admin_call_count .replace(|current| UintNote{ value: current.value + 1 }) // wouldn't it be great if we didn't have to deal with this wrapping and unwrapping? - .deliver(admin); + .deliver(MessageDelivery.ONCHAIN_CONSTRAINED); // ... } @@ -497,7 +497,7 @@ This function allows us to get the note of a `PrivateMutable`, essentially readi ```rust #[external("private")] fn read_settings() { - let owner = self.msg_sender().unwrap(); + let owner = self.msg_sender(); self.storage.user_settings.at(owner).get_note().deliver(MessageDelivery.ONCHAIN_CONSTRAINED); } ``` @@ -720,7 +720,7 @@ fn transfer(from: AztecAddress, to: AztecAddress, amount: u128) { let notes = self.storage.balances.at(from).pop_notes(options); // Access the balance for the 'to' address - let new_note = UintNote::new(amount, to); + let new_note = UintNote { value: amount }; self.storage.balances.at(to).insert(new_note).deliver(MessageDelivery.ONCHAIN_UNCONSTRAINED); } ``` @@ -736,7 +736,7 @@ Both `PublicMutable` and `PublicImmutable` are generic over any serializable typ To use a custom struct in public storage, it must implement the `Packable` trait: ```rust -use dep::aztec::protocol_types::{ +use aztec::protocol::{ address::AztecAddress, traits::{Deserialize, Packable, Serialize} }; diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/index.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/index.md index 505e766963ee..82bcf6c24fea 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/index.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/index.md @@ -29,8 +29,8 @@ It allows safe and easy implementation of well understood design patterns, such A good example of this is writing to private state variables. These functions return a `NoteMessage` struct, which results in a compiler error unless used. This is because writing to private state also requires sending an encrypted message with the new state to the people that need to access it - otherwise, because it is private, they will not even know the state changed. ```rust -storage.votes.insert(new_vote); // compiler error - unused NoteMessagePendingDelivery return value -storage.votes.insert(new_vote).deliver(vote_counter); // the vote counter account will now be notified of the new vote +storage.votes.insert(new_vote); // compiler error - unused NoteMessage return value +storage.votes.insert(new_vote).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); // deliver the note message onchain ``` ## Contract Development diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/standards/aip-4626.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/standards/aip-4626.md index 559c12fc94d9..7db638cf2836 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/standards/aip-4626.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/standards/aip-4626.md @@ -4,7 +4,7 @@ sidebar_position: 3 description: Yield-bearing vault standard with share conversion across private and public contexts. --- -[Source](https://github.com/defi-wonderland/aztec-standards/tree/dev/src/token_contract) (extends the AIP-20 token contract) +[Source](https://github.com/defi-wonderland/aztec-standards/tree/dev/src/vault_contract) (extends the AIP-20 token contract) AIP-4626 extends [AIP-20](./aip-20.md) to describe a tokenized vault: a contract that holds an underlying asset and issues shares representing a proportional claim on that asset. It mirrors the design of ERC-4626 but adapts the share conversion arithmetic for Aztec's `u128` integer type. diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/standards/aip-721.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/standards/aip-721.md index 6ac5970f1b6e..7d307265a034 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/standards/aip-721.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/standards/aip-721.md @@ -30,6 +30,7 @@ struct Storage { Each private NFT is represented as an `NFTNote` containing only the `token_id`: ```rust +#[derive(Eq, Serialize, Packable)] #[custom_note] pub struct NFTNote { pub token_id: Field, @@ -68,4 +69,4 @@ fn initialize_transfer_commitment(to: AztecAddress, completer: AztecAddress) -> } ``` -This function returns `commitment.commitment()` (the raw commitment field), whereas the AIP-20 equivalent returns `commitment.to_field()`. The difference reflects the distinct internal types — `PartialNFTNote` vs `PartialUintNote` — but both return an opaque `Field` to the caller. +This function returns `commitment.commitment()` — an opaque `Field` representing the commitment. The AIP-20 equivalent returns `commitment.to_field()` for `PartialUintNote`. diff --git a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/testing_contracts.md b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/testing_contracts.md index 22855c9b3cf7..cefb9fe20762 100644 --- a/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/testing_contracts.md +++ b/docs/developer_versioned_docs/version-v4.2.0-aztecnr-rc.2/docs/aztec-nr/testing_contracts.md @@ -169,7 +169,7 @@ let balance = env.view_public(Token::at(token_address).balance_of_public(owner)) ```rust // Simulate utility/view functions (unconstrained) -let total = env.simulate_utility(Token::at(token_address).balance_of_private(owner)); +let total = env.execute_utility(Token::at(token_address).balance_of_private(owner)); ``` :::tip Helper function pattern @@ -183,7 +183,7 @@ pub unconstrained fn check_balance( expected: u128, ) { assert_eq( - env.simulate_utility(Token::at(token_address).balance_of_private(owner)), + env.execute_utility(Token::at(token_address).balance_of_private(owner)), expected ); } @@ -282,7 +282,7 @@ unconstrained fn test_public_authwit() { let (env, token_address, owner, spender) = setup(true); // Create public action that needs authorization - let transfer_call = Token::at(token_address).transfer_public(owner, recipient, 100, nonce); + let transfer_call = Token::at(token_address).transfer_in_public(owner, recipient, 100, nonce); // Grant public authorization add_public_authwit_from_call(env, owner, spender, transfer_call); @@ -294,7 +294,7 @@ unconstrained fn test_public_authwit() { ## Time traveling -Contract calls do not advance the timestamp by default, despite each of them resulting in a block with a single transaction. Block timestamp can instead by manually manipulated by any of the following methods: +Contract calls do not advance the timestamp by default, despite each of them resulting in a block with a single transaction. Block timestamp can instead be manually manipulated by any of the following methods: ```rust // Sets the timestamp of the next block to be mined, i.e. of the next public execution. Does not affect private execution. @@ -305,7 +305,7 @@ env.advance_next_block_timestamp_by(duration); // Mines an empty block at a given timestamp, causing the next public execution to occur at this time (like `set_next_block_timestamp`), but also allowing for private execution to happen using this empty block as the anchor block. env.mine_block_at(block_timestamp); -```` +``` ## Testing failure cases diff --git a/docs/docs-developers/docs/aztec-nr/compiling_contracts.md b/docs/docs-developers/docs/aztec-nr/compiling_contracts.md index a7d63c90f4a5..b0e5bc269a4a 100644 --- a/docs/docs-developers/docs/aztec-nr/compiling_contracts.md +++ b/docs/docs-developers/docs/aztec-nr/compiling_contracts.md @@ -33,7 +33,7 @@ Use generated interfaces instead of manual function calls: ```rust contract MyContract { - use dep::token::Token; + use token::Token; #[external("private")] fn transfer_tokens(token_address: AztecAddress, recipient: AztecAddress, amount: u128) { diff --git a/docs/docs-developers/docs/aztec-nr/debugging.md b/docs/docs-developers/docs/aztec-nr/debugging.md index cd1d9ede405c..18c470c50480 100644 --- a/docs/docs-developers/docs/aztec-nr/debugging.md +++ b/docs/docs-developers/docs/aztec-nr/debugging.md @@ -5,8 +5,6 @@ tags: [debugging, errors, logging, local_network, aztec.nr] description: This guide shows you how to debug issues in your Aztec contracts. --- - - This guide shows you how to debug issues in your Aztec development environment. ## Prerequisites @@ -33,7 +31,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"); @@ -49,7 +47,7 @@ debug_log_format("values: {0}, {1}, {2}", [val1, val2, val3]); ``` :::note -Debug logs appear only during local execution. Private functions always execute locally, but public functions must be simulated to show logs. Use `.simulate()` or `.prove()` in TypeScript, or `env.simulate_public_function()` in TXE tests. +Debug logs appear only during local execution. Private functions always execute locally, but public functions must be simulated to show logs. Use `.simulate()` or `.prove()` in TypeScript, or `env.call_public()` in TXE tests. ::: To see debug logs from your tests, set `LOG_LEVEL` when running: @@ -160,7 +158,7 @@ link.click(); ## Interpret error messages -### Kernel circuit errors (2xxx) +### Circuit and protocol errors - **Private kernel errors (2xxx)**: Issues with private function execution - **Public kernel errors (3xxx)**: Issues with public function execution @@ -207,7 +205,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 @@ -218,7 +216,7 @@ await wallet.getContractMetadata(myContractInstance.address); ### Decode L1 errors -Check hex errors against [Errors.sol](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/libraries/Errors.sol) +Check hex errors against [Errors.sol](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/l1-contracts/src/core/libraries/Errors.sol) ## Tips diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/advanced/how_to_use_capsules.md b/docs/docs-developers/docs/aztec-nr/framework-description/advanced/how_to_use_capsules.md index b0e6fa953a22..95048fca06dd 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/advanced/how_to_use_capsules.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/advanced/how_to_use_capsules.md @@ -12,22 +12,26 @@ Capsules provide per-contract non-volatile storage in the PXE. Data is stored lo ```rust use aztec::oracle::capsules; -// Inside a contract function, use self.address for contract_address -let contract_address: AztecAddress = self.address; +// Capsule operations are unconstrained, so these values are typically +// passed in as parameters from the calling context. +let contract_address: AztecAddress = /* self.address */; let slot: Field = 1; +// scope is an AztecAddress used for capsule isolation, allowing multiple +// independent namespaces within the same contract. +let scope: AztecAddress = /* e.g. the account address */; // Store data at a slot (overwrites existing data) -capsules::store(contract_address, slot, value); +capsules::store(contract_address, slot, value, scope); // Load data (returns Option) -let result: Option = capsules::load(contract_address, slot); +let result: Option = capsules::load(contract_address, slot, scope); // Delete data at a slot -capsules::delete(contract_address, slot); +capsules::delete(contract_address, slot, scope); // Copy contiguous slots (supports overlapping regions) -// copy(contract_address, src_slot, dst_slot, num_entries: u32) -capsules::copy(contract_address, src_slot, dst_slot, 3); +// copy(contract_address, src_slot, dst_slot, num_entries: u32, scope) +capsules::copy(contract_address, src_slot, dst_slot, 3, scope); ``` Types must implement `Serialize` and `Deserialize` traits. @@ -42,12 +46,12 @@ All capsule operations are `unconstrained`. Data loaded from capsules should be ```rust use aztec::capsules::CapsuleArray; -use protocol::hash::sha256_to_field; +use aztec::protocol::hash::sha256_to_field; // Use a hash for base_slot to avoid collisions with other storage global BASE_SLOT: Field = sha256_to_field("MY_CONTRACT::MY_ARRAY".as_bytes()); -let array: CapsuleArray = CapsuleArray::at(contract_address, BASE_SLOT); +let array: CapsuleArray = CapsuleArray::at(contract_address, BASE_SLOT, scope); array.push(value); // Append to end let value = array.get(index); // Read at index (throws if out of bounds) diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/advanced/partial_notes.md b/docs/docs-developers/docs/aztec-nr/framework-description/advanced/partial_notes.md index 72e41d56b9c8..d1651256723e 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/advanced/partial_notes.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/advanced/partial_notes.md @@ -18,7 +18,7 @@ Let's say, for example, we have a `UintNote`: The `UintNote` struct itself only contains the `value` field. Additional fields including `owner`, `randomness`, and `storage_slot` are passed as parameters during note hash computation. -When creating the note locally during private execution, the `owner` and `storage_slot` are known, but the `value` potentially is not (e.g., it depends on some onchain dynamic variable). First, a **partial note** can be created during private execution that commits to the `owner`, `randomness`, and `storage_slot`, and then the note is *"completed"* to create a full note by later adding the `value` field, usually during public execution. +When creating the note locally during private execution, the `owner` and `storage_slot` are known, but the `value` potentially is not (e.g., it depends on some onchain dynamic variable). First, a **partial note** can be created during private execution that commits to the `owner` and `randomness`, and then the note is *"completed"* to create a full note by later adding the `storage_slot` and `value` fields, usually during public execution. @@ -44,14 +44,14 @@ The `UintNote` struct contains only the `value` field: **Phase 1: Partial Commitment (Private Execution)** -The private fields (`owner`, `randomness`, and `storage_slot`) are committed during local, private execution: +The private fields (`owner` and `randomness`) are committed during local, private execution: #include_code compute_partial_commitment /noir-projects/aztec-nr/uint-note/src/uint_note.nr rust This creates a partial note commitment: ``` -partial_commitment = H(owner, storage_slot, randomness) +partial_commitment = H(owner, randomness) ``` **Phase 2: Note Completion (Public Execution)** @@ -63,8 +63,8 @@ The note is completed by hashing the partial commitment with the public value: The resulting structure is a nested commitment: ``` -note_hash = H(H(owner, storage_slot, randomness), value) - = H(partial_commitment, value) +note_hash = H(H(owner, randomness), storage_slot, value) + = H(partial_commitment, storage_slot, value) ``` ## Universal Note Format @@ -73,14 +73,13 @@ All notes in Aztec use the partial note format internally, even when all data is When a note is created with all fields known (including `owner`, `storage_slot`, `randomness`, and `value`): -1. A partial commitment is computed from the private fields (`owner`, `storage_slot`, `randomness`) -2. The partial commitment is immediately completed with the `value` field +1. A partial commitment is computed from the private fields (`owner`, `randomness`) +2. The partial commitment is immediately completed with the `storage_slot` and `value` fields #include_code compute_note_hash /noir-projects/aztec-nr/uint-note/src/uint_note.nr rust This two-step process ensures that notes with identical field values produce identical note hashes, regardless of whether they were created as partial notes or complete notes. - ## Partial Notes in Practice diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/advanced/writing_efficient_contracts.md b/docs/docs-developers/docs/aztec-nr/framework-description/advanced/writing_efficient_contracts.md index e3407e0adb3a..71977ac0aeb9 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/advanced/writing_efficient_contracts.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/advanced/writing_efficient_contracts.md @@ -95,9 +95,9 @@ To get a sense of things, here is a table of gate counts for common operations: | ~75 | Hashing 3 fields with Poseidon2 | | 3500 | Reading a value from a tree (public data tree, note hash tree, nullifier tree) | | 4000 | Reading a delayed public mutable read | -| X000 | Calculating sha256 | -| X000 | Constrained encryption of a log of Y fields | -| X000 | Constrained encryption and tag a log of Y fields | +| ~5,000 | Calculating sha256 (varies by input size) | +| Varies | Constrained encryption of a private log (depends on field count) | +| Varies | Constrained encryption and tagging of a private log (depends on field count) | ### Optimization: use arithmetic instead of non-arithmetic operations @@ -106,7 +106,7 @@ Because the underlying equation in the proving backend makes use of multiplicati For example: ```rust -comptime global TWO_POW_32: Field = 2.pow_32(16); +comptime global TWO_POW_16: Field = 2.pow_32(16); // ... { #[external("private")] @@ -116,7 +116,7 @@ comptime global TWO_POW_32: Field = 2.pow_32(16); #[external("private")] fn mul_efficient(number: Field) -> u128 { - (number * TWO_POW_32) as u128 + (number * TWO_POW_16) as u128 } // 5184 gates (60 gates less) } ``` @@ -153,7 +153,7 @@ For example, use boolean equality effectively instead of `>=`: } } sum - } // 45068 gates (751 gates less) + } // 45068 gates (751 gates more due to the boolean operations, but the pattern demonstrates how to avoid range checks) } ``` @@ -279,9 +279,12 @@ Like with sqrt, we have the inefficient function that does the sort with constra // Safety: calculate in unconstrained function, then constrain the result let sorted_array = unsafe { super::sort_array(array) }; // constrain that sorted_array elements are sorted - for i in 0..super::ARRAY_SIZE as u32 { + for i in 0..super::ARRAY_SIZE as u32 - 1 { assert(sorted_array[i] <= sorted_array[i + 1], "array should be sorted"); } + // Note: A production implementation should also verify that sorted_array is a + // permutation of the input array to prevent a malicious prover from returning + // arbitrary sorted values. sorted_array } // 5870 gates (953 gates less) for 10 elements, 12582 gates for 100 elements (115198 gates less) } @@ -309,7 +312,7 @@ Note: The stdlib provides a highly optimized version of sort on arrays, `array.s ```rust #[external("private")] fn sort_stdlib(array: [u32; super::ARRAY_SIZE]) -> [u32; super::ARRAY_SIZE] { - array.sort(); + array.sort() } // 5943 gates (880 gates less) for 10 elements, 13308 gates for 100 elements (114472 gates less) ``` diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/contract_structure.md b/docs/docs-developers/docs/aztec-nr/framework-description/contract_structure.md index 87c051771ca0..c699bc41486d 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/contract_structure.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/contract_structure.md @@ -98,15 +98,16 @@ use aztec::macros::aztec; pub contract MyContract { use aztec::{ macros::storage, - state_vars::{PrivateMutable, PublicMutable} + state_vars::{Owned, PrivateMutable, PublicMutable} }; + use uint_note::UintNote; // The storage struct can have any name, but is typically called `Storage`. It must have the `#[storage]` macro applied to it. // This struct must also have a generic type called C or Context. #[storage] struct Storage { // A private numeric value which can change over time. This value will be hidden, and only those with the secret can know its current value. - my_private_state_variable: Owned>, + my_private_state_variable: Owned, Context>, // A public numeric value which can change over time. This value will be known to everyone and is equivalent to the Solidity example above. my_public_state_variable: PublicMutable, } @@ -142,6 +143,7 @@ use aztec::macros::aztec; #[aztec] contract MyContract { use aztec::macros::functions::external; + use aztec::protocol::address::AztecAddress; #[external("private")] fn my_private_function(parameter_a: u128, parameter_b: AztecAddress) { @@ -154,7 +156,7 @@ contract MyContract { } #[external("utility")] - fn my_utility_function(parameter_a: u128, parameter_b: AztecAddress) { + unconstrained fn my_utility_function(parameter_a: u128, parameter_b: AztecAddress) { // ... } } diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/contract_upgrades.md b/docs/docs-developers/docs/aztec-nr/framework-description/contract_upgrades.md index 8260a2da2fe6..9dd1db5c37fd 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/contract_upgrades.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/contract_upgrades.md @@ -41,6 +41,13 @@ fn update_to(new_class_id: ContractClassId) { } ``` +:::info +To use the `ContractInstanceRegistry`, add this dependency to your `Nargo.toml`: +```toml +contract_instance_registry = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="noir-projects/noir-contracts/contracts/protocol_interface/contract_instance_registry_interface" } +``` +::: + The `update` function in the registry is a public function, so you can enqueue it from a private function (as shown above) or call it directly from a public function. :::warning[Access Control] diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md b/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md index bbab767650f2..cab9797873c7 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/custom_notes.md @@ -29,21 +29,21 @@ Aztec.nr provides pre-built note types for common use cases: ```toml # In Nargo.toml -uint_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="noir-projects/aztec-nr/uint-note" } +uint_note = { git="https://github.com/AztecProtocol/aztec-nr", tag="#include_aztec_version", directory="uint-note" } ``` **FieldNote** - For storing single Field values: ```toml # In Nargo.toml -field_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="noir-projects/aztec-nr/field-note" } +field_note = { git="https://github.com/AztecProtocol/aztec-nr", tag="#include_aztec_version", directory="field-note" } ``` **AddressNote** - For storing Aztec addresses: ```toml # In Nargo.toml -address_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="noir-projects/aztec-nr/address-note" } +address_note = { git="https://github.com/AztecProtocol/aztec-nr", tag="#include_aztec_version", directory="address-note" } ``` ::: diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/events_and_logs.md b/docs/docs-developers/docs/aztec-nr/framework-description/events_and_logs.md index 7d3ec45e2be1..0fbe002e1fa9 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/events_and_logs.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/events_and_logs.md @@ -34,7 +34,7 @@ use aztec::messages::message_delivery::MessageDelivery; #[external("private")] fn transfer(to: AztecAddress, amount: u128) { - let from = self.msg_sender().unwrap(); + let from = self.msg_sender(); // ... transfer logic ... diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/functions/attributes.md b/docs/docs-developers/docs/aztec-nr/framework-description/functions/attributes.md index 41519939f218..8e96cbc6f9e3 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/functions/attributes.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/functions/attributes.md @@ -126,7 +126,7 @@ It is also useful in private functions when dealing with tasks of an unknown siz This macro inserts a check at the beginning of the function to ensure that the caller is the contract itself. This is done by adding the following assertion: ```rust -assert(self.msg_sender().unwrap() == self.address, "Function can only be called internally"); +assert(self.msg_sender() == self.address, "Function can only be called internally"); ``` ## #[allow_phase_change] diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/functions/context.md b/docs/docs-developers/docs/aztec-nr/framework-description/functions/context.md index 34b9be29a626..3a8352d74b87 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/functions/context.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/functions/context.md @@ -46,7 +46,7 @@ The context inputs includes all of the information that is passed from the kerne #include_code private-context-inputs /noir-projects/aztec-nr/aztec/src/context/inputs/private_context_inputs.nr rust -As shown in the snippet, the application context is made up of 4 main structures. The call context, the block header, and the private global variables. +As shown in the snippet, the application context is made up of 3 main structures. The call context, the block header, and the private global variables. First of all, the call context. @@ -61,13 +61,12 @@ The call context contains information about the current call being made: -2. Storage contract address +2. 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 (Warning: This is yet to be implemented). In this case the value will be that of the sending contract. + - 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. 3. 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 be the address of the sender. - is_static_call: This will be set if and only if the current call is a static call. In a static call, state changing altering operations are not allowed. ### Block Header @@ -86,14 +85,14 @@ The private context provides access to the transaction context as well, which ar To allow for flexibility in the number of arguments supported by Aztec functions, all function inputs are reduced to a singular value which can be proven from within the application. -The `args_hash` is the result of pedersen hashing all of a function's inputs. +The `args_hash` is the result of poseidon2 hashing all of a function's inputs. ### Return Values The return values are a set of values that are returned from an applications execution to be passed to other functions through the kernel. Developers do not need to worry about passing their function return values to the `context` directly as `Aztec.nr` takes care of it for you. See the documentation surrounding `Aztec.nr` [macro expansion](./attributes.md#private-functions-externalprivate) for more details. ```rust -return_values : BoundedVec\, +return_hash: Field, ``` ## Expiration Timestamp diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/functions/function_transforms.md b/docs/docs-developers/docs/aztec-nr/framework-description/functions/function_transforms.md index 64b74fa94e97..647382f70e18 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/functions/function_transforms.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/functions/function_transforms.md @@ -11,7 +11,7 @@ This page explains what happens under the hood when you create a function in an Private functions in Aztec compile to standalone circuits that must conform to the protocol's kernel circuit interface. Public functions compile to AVM bytecode. The transformations described below bridge the gap between developer-friendly Aztec.nr syntax and these underlying requirements. -Utility functions (marked with `#[utility]`) do not undergo these transformations—they remain as regular Noir functions. +Utility functions (marked with `#[external("utility")]`) do not undergo these transformations—they remain as regular Noir functions. ## Function transformation diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/macros.md b/docs/docs-developers/docs/aztec-nr/framework-description/macros.md index 7ad827af268b..1bcf09bd5e40 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/macros.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/macros.md @@ -22,8 +22,8 @@ Aztec.nr provides macros (attributes) that transform your code during compilatio | `#[external("private")]` | Client-side private execution with proofs | | `#[external("public")]` | Sequencer-side public execution | | `#[external("utility")]` | Unconstrained queries, not included in transactions | -| `#[internal("private")]` | Private helper, inlined at call sites | -| `#[internal("public")]` | Public helper, inlined at call sites | +| `#[internal("private")]` | Private helper, only callable within the same contract | +| `#[internal("public")]` | Public helper, only callable within the same contract | | `#[view]` | Prevents state modification | | `#[initializer]` | Contract constructor | | `#[noinitcheck]` | Callable before contract initialization | diff --git a/docs/docs-developers/docs/aztec-nr/framework-description/state_variables.md b/docs/docs-developers/docs/aztec-nr/framework-description/state_variables.md index 2a30b43ab134..424e2b1fac72 100644 --- a/docs/docs-developers/docs/aztec-nr/framework-description/state_variables.md +++ b/docs/docs-developers/docs/aztec-nr/framework-description/state_variables.md @@ -72,7 +72,7 @@ Consider, for example, a `PublicMutable` state variable, which is a value that i ```rust #[storage] struct Storage { - my_public_variable: PublicMutable, + my_public_variable: PublicMutable, } #[external("public")] @@ -229,7 +229,7 @@ They also have some metadata, including a storage slot to avoid collisions with The note content plus the metadata are all hashed together, and it is this hash that gets stored onchain in the note hash tree. This hash is called a commitment. The underlying note content (the note hash preimage) is not stored anywhere onchain, so third parties cannot access it and it remains private. The note hash tree is append-only - if it wasn't, when a note was spent, external observers would notice that the tree leaf inserted in some transaction was modified in a second transaction, linking them together and leaking privacy. For example, when a user made a payment to a third party, the recipient would be able to know when they spent the received funds. Nullifiers exist to solve this issue. -Note: Aztec.nr comes with some prebuilt note types, including [`UintNote`](https://github.com/AztecProtocol/aztec-packages/tree/08935f75dbc3052ce984add225fc7a0dac863050/noir-projects/aztec-nr/uint-note) and [`AddressNote`](https://github.com/AztecProtocol/aztec-packages/tree/08935f75dbc3052ce984add225fc7a0dac863050/noir-projects/aztec-nr/address-note), but users are also free to create their own with the `#[note]` macro. +Note: Aztec.nr comes with some prebuilt note types, including [`UintNote`](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/uint-note) and [`AddressNote`](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/noir-projects/aztec-nr/address-note), but users are also free to create their own with the `#[note]` macro. ##### Note Lifecycle @@ -273,7 +273,7 @@ When working with private state variables, many operations return a `NoteMessage #### Delivery Methods Private notes need to be communicated to their recipients so they know the note exists and can use it. The [`NoteMessage`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/note/struct.NoteMessage) wrapper forces you to make an explicit choice about how this happens: - - [`MessageDelivery.ONCHAIN_CONSTRAINED`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.ONCHAIN_UNCONSTRAINED): Verified in the circuit (most secure, but highest cost) - Use when the sender cannot be trusted to deliver correctly (e.g., protocol fees, multisig config updates). **Warning:** Currently [not fully constrained](https://github.com/AztecProtocol/aztec-packages/issues/14565) - the log's tag is unconstrained. + - [`MessageDelivery.ONCHAIN_CONSTRAINED`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.ONCHAIN_CONSTRAINED): Verified in the circuit (most secure, but highest cost) - Use when the sender cannot be trusted to deliver correctly (e.g., protocol fees, multisig config updates). **Warning:** Currently [not fully constrained](https://github.com/AztecProtocol/aztec-packages/issues/14565) - the log's tag is unconstrained. - [`MessageDelivery.ONCHAIN_UNCONSTRAINED`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.ONCHAIN_UNCONSTRAINED): Message stored onchain but no guarantees on content - Use when the sender is incentivized to deliver correctly but may not have an offchain channel to the recipient. - [`MessageDelivery.OFFCHAIN`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.OFFCHAIN): Lowest cost, no onchain data - Use when the sender and recipient can communicate and the sender is incentivized to deliver correctly. @@ -324,7 +324,7 @@ fn perform_admin_action() { // value of the counter and can update it again in the future. self.storage.admin_call_count .replace(|current| UintNote{ value: current.value + 1 }) // wouldn't it be great if we didn't have to deal with this wrapping and unwrapping? - .deliver(admin); + .deliver(MessageDelivery.ONCHAIN_CONSTRAINED); // ... } @@ -380,7 +380,7 @@ This function allows us to get the note of a `PrivateMutable`, essentially readi ```rust #[external("private")] fn read_settings() { - let owner = self.msg_sender().unwrap(); + let owner = self.msg_sender(); self.storage.user_settings.at(owner).get_note().deliver(MessageDelivery.ONCHAIN_CONSTRAINED); } ``` @@ -557,7 +557,7 @@ fn transfer(from: AztecAddress, to: AztecAddress, amount: u128) { let notes = self.storage.balances.at(from).pop_notes(options); // Access the balance for the 'to' address - let new_note = UintNote::new(amount, to); + let new_note = UintNote { value: amount }; self.storage.balances.at(to).insert(new_note).deliver(MessageDelivery.ONCHAIN_UNCONSTRAINED); } ``` @@ -573,7 +573,7 @@ Both `PublicMutable` and `PublicImmutable` are generic over any serializable typ To use a custom struct in public storage, it must implement the `Packable` trait: ```rust -use dep::aztec::protocol_types::{ +use aztec::protocol::{ address::AztecAddress, traits::{Deserialize, Packable, Serialize} }; diff --git a/docs/docs-developers/docs/aztec-nr/index.md b/docs/docs-developers/docs/aztec-nr/index.md index 2292165c6757..646d94a67ba1 100644 --- a/docs/docs-developers/docs/aztec-nr/index.md +++ b/docs/docs-developers/docs/aztec-nr/index.md @@ -29,8 +29,8 @@ It allows safe and easy implementation of well understood design patterns, such A good example of this is writing to private state variables. These functions return a `NoteMessage` struct, which results in a compiler error unless used. This is because writing to private state also requires sending an encrypted message with the new state to the people that need to access it - otherwise, because it is private, they will not even know the state changed. ```rust -storage.votes.insert(new_vote); // compiler error - unused NoteMessagePendingDelivery return value -storage.votes.insert(new_vote).deliver(vote_counter); // the vote counter account will now be notified of the new vote +storage.votes.insert(new_vote); // compiler error - unused NoteMessage return value +storage.votes.insert(new_vote).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); // deliver the note message onchain ``` ## Contract Development diff --git a/docs/docs-developers/docs/aztec-nr/standards/aip-4626.md b/docs/docs-developers/docs/aztec-nr/standards/aip-4626.md index 559c12fc94d9..7db638cf2836 100644 --- a/docs/docs-developers/docs/aztec-nr/standards/aip-4626.md +++ b/docs/docs-developers/docs/aztec-nr/standards/aip-4626.md @@ -4,7 +4,7 @@ sidebar_position: 3 description: Yield-bearing vault standard with share conversion across private and public contexts. --- -[Source](https://github.com/defi-wonderland/aztec-standards/tree/dev/src/token_contract) (extends the AIP-20 token contract) +[Source](https://github.com/defi-wonderland/aztec-standards/tree/dev/src/vault_contract) (extends the AIP-20 token contract) AIP-4626 extends [AIP-20](./aip-20.md) to describe a tokenized vault: a contract that holds an underlying asset and issues shares representing a proportional claim on that asset. It mirrors the design of ERC-4626 but adapts the share conversion arithmetic for Aztec's `u128` integer type. diff --git a/docs/docs-developers/docs/aztec-nr/standards/aip-721.md b/docs/docs-developers/docs/aztec-nr/standards/aip-721.md index 6ac5970f1b6e..7d307265a034 100644 --- a/docs/docs-developers/docs/aztec-nr/standards/aip-721.md +++ b/docs/docs-developers/docs/aztec-nr/standards/aip-721.md @@ -30,6 +30,7 @@ struct Storage { Each private NFT is represented as an `NFTNote` containing only the `token_id`: ```rust +#[derive(Eq, Serialize, Packable)] #[custom_note] pub struct NFTNote { pub token_id: Field, @@ -68,4 +69,4 @@ fn initialize_transfer_commitment(to: AztecAddress, completer: AztecAddress) -> } ``` -This function returns `commitment.commitment()` (the raw commitment field), whereas the AIP-20 equivalent returns `commitment.to_field()`. The difference reflects the distinct internal types — `PartialNFTNote` vs `PartialUintNote` — but both return an opaque `Field` to the caller. +This function returns `commitment.commitment()` — an opaque `Field` representing the commitment. The AIP-20 equivalent returns `commitment.to_field()` for `PartialUintNote`. diff --git a/docs/docs-developers/docs/aztec-nr/testing_contracts.md b/docs/docs-developers/docs/aztec-nr/testing_contracts.md index 03d19207600d..801b180fe240 100644 --- a/docs/docs-developers/docs/aztec-nr/testing_contracts.md +++ b/docs/docs-developers/docs/aztec-nr/testing_contracts.md @@ -169,7 +169,7 @@ let balance = env.view_public(Token::at(token_address).balance_of_public(owner)) ```rust // Simulate utility/view functions (unconstrained) -let total = env.simulate_utility(Token::at(token_address).balance_of_private(owner)); +let total = env.execute_utility(Token::at(token_address).balance_of_private(owner)); ``` :::tip Helper function pattern @@ -183,7 +183,7 @@ pub unconstrained fn check_balance( expected: u128, ) { assert_eq( - env.simulate_utility(Token::at(token_address).balance_of_private(owner)), + env.execute_utility(Token::at(token_address).balance_of_private(owner)), expected ); } @@ -282,7 +282,7 @@ unconstrained fn test_public_authwit() { let (env, token_address, owner, spender) = setup(true); // Create public action that needs authorization - let transfer_call = Token::at(token_address).transfer_public(owner, recipient, 100, nonce); + let transfer_call = Token::at(token_address).transfer_in_public(owner, recipient, 100, nonce); // Grant public authorization add_public_authwit_from_call(env, owner, spender, transfer_call); @@ -294,7 +294,7 @@ unconstrained fn test_public_authwit() { ## Time traveling -Contract calls do not advance the timestamp by default, despite each of them resulting in a block with a single transaction. Block timestamp can instead by manually manipulated by any of the following methods: +Contract calls do not advance the timestamp by default, despite each of them resulting in a block with a single transaction. Block timestamp can instead be manually manipulated by any of the following methods: ```rust // Sets the timestamp of the next block to be mined, i.e. of the next public execution. Does not affect private execution. @@ -305,7 +305,7 @@ env.advance_next_block_timestamp_by(duration); // Mines an empty block at a given timestamp, causing the next public execution to occur at this time (like `set_next_block_timestamp`), but also allowing for private execution to happen using this empty block as the anchor block. env.mine_block_at(block_timestamp); -```` +``` ## Testing failure cases