diff --git a/docs/docs-words.txt b/docs/docs-words.txt index ade99affdd56..c053e6653f20 100644 --- a/docs/docs-words.txt +++ b/docs/docs-words.txt @@ -21,7 +21,9 @@ autonumber Azguard AZIP AZTC +aztecexplorer aztecjs +aztecscan barebones Becuase becuse diff --git a/docs/docs/developers/guides/getting_started_on_testnet.md b/docs/docs/developers/guides/getting_started_on_testnet.md index 05a88ad5f7d7..275c29ac2a30 100644 --- a/docs/docs/developers/guides/getting_started_on_testnet.md +++ b/docs/docs/developers/guides/getting_started_on_testnet.md @@ -115,11 +115,13 @@ aztec-wallet deploy \ --payment method=fpc-sponsored,fpc=contracts:sponsoredfpc \ --alias token \ TokenContract \ - --args accounts:my-wallet Token TOK 18 + --args accounts:my-wallet Token TOK 18 --no-wait ``` You should see confirmation that the token contract is stored in the database. +Wait for the transaction to be mined on testnet. You can check the transaction status with the transaction hash on [aztecscan](https://aztecscan.xyz) or [aztecexplorer](https://aztecexplorer.xyz). + 2. Mint 10 private tokens to yourself: ```bash @@ -127,7 +129,7 @@ aztec-wallet send mint_to_private \ --node-url $NODE_URL \ --from accounts:my-wallet \ --payment method=fpc-sponsored,fpc=contracts:sponsoredfpc \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet accounts:my-wallet 10 ``` @@ -140,7 +142,7 @@ aztec-wallet send transfer_to_public \ --node-url $NODE_URL \ --from accounts:my-wallet \ --payment method=fpc-sponsored,fpc=contracts:sponsoredfpc \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet accounts:my-wallet 2 0 ``` @@ -154,7 +156,7 @@ Private balance: aztec-wallet simulate balance_of_private \ --node-url $NODE_URL \ --from my-wallet \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet ``` @@ -166,7 +168,7 @@ Public balance: aztec-wallet simulate balance_of_public \ --node-url $NODE_URL \ --from my-wallet \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet ``` diff --git a/docs/docs/developers/tutorials/codealong/contract_tutorials/counter_contract.md b/docs/docs/developers/tutorials/codealong/contract_tutorials/counter_contract.md index 08db7860765a..f6cf25db7426 100644 --- a/docs/docs/developers/tutorials/codealong/contract_tutorials/counter_contract.md +++ b/docs/docs/developers/tutorials/codealong/contract_tutorials/counter_contract.md @@ -7,7 +7,7 @@ import Image from "@theme/IdealImage"; In this guide, we will create our first Aztec.nr smart contract. We will build a simple private counter, where you can keep your own private counter - so no one knows what ID you are at or when you increment! This contract will get you started with the basic setup and syntax of Aztec.nr, but doesn't showcase all of the awesome stuff Aztec is capable of. -This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up #include_aztec_version`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up -v #include_version_without_prefix`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Prerequisites @@ -69,19 +69,19 @@ pub contract Counter { #include_code imports /noir-projects/noir-contracts/contracts/test/counter_contract/src/main.nr rust -- `use aztec::macros::{functions::{initializer, private, utility}, storage::storage};` +- `use aztec::macros::{functions::{initializer, private, utility}, storage::storage};` Imports the macros needed to define function types (`initializer`, `private`, and `utility`) and the `storage` macro for declaring contract storage structures. -- `use aztec::prelude::{AztecAddress, Map};` +- `use aztec::prelude::{AztecAddress, Map};` Brings in `AztecAddress` (used to identify accounts/contracts) and `Map` (used for creating state mappings, like our counters). -- `use aztec::protocol_types::traits::{FromField, ToField};` +- `use aztec::protocol_types::traits::{FromField, ToField};` Provides traits for converting values to and from field elements, necessary for serialization and formatting inside Aztec. -- `use easy_private_state::EasyPrivateUint;` +- `use easy_private_state::EasyPrivateUint;` Imports a wrapper to manage private integer-like state variables (ie our counter), abstracting away notes. -- `use value_note::{balance_utils, value_note::ValueNote};` +- `use value_note::{balance_utils, value_note::ValueNote};` Brings in `ValueNote`, which represents a private value stored as a note, and `balance_utils`, which makes working with notes feel like working with simple balances. ## Declare storage diff --git a/docs/docs/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md b/docs/docs/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md index bb3120c28543..0798da691fa2 100644 --- a/docs/docs/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md +++ b/docs/docs/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md @@ -22,7 +22,7 @@ Along the way you will: - Wrap an address with its interface (token) - Create custom private value notes -This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up #include_aztec_version`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up -v #include_version_without_prefix`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Setup diff --git a/docs/docs/developers/tutorials/codealong/contract_tutorials/nft_contract.md b/docs/docs/developers/tutorials/codealong/contract_tutorials/nft_contract.md index c7030ad243bd..423d368e66d8 100644 --- a/docs/docs/developers/tutorials/codealong/contract_tutorials/nft_contract.md +++ b/docs/docs/developers/tutorials/codealong/contract_tutorials/nft_contract.md @@ -17,7 +17,7 @@ In this tutorial you will learn how to: - Handle different private note types - Pass data between private and public state -This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up #include_aztec_version`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up -v #include_version_without_prefix`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. We are going to start with a blank project and fill in the token contract source code defined [here (GitHub Link)](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr), and explain what is being added as we go. diff --git a/docs/docs/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md b/docs/docs/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md index aadb78565c1f..28126c9a2fd8 100644 --- a/docs/docs/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md +++ b/docs/docs/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md @@ -9,7 +9,7 @@ import Image from '@theme/IdealImage'; In this tutorial we will go through writing a very simple private voting smart contract in Aztec.nr. You will learn about private functions, public functions, composability between them, state management and creatively using nullifiers to prevent people from voting twice! -This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up #include_aztec_version`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up -v #include_version_without_prefix`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. We will build this: @@ -70,23 +70,23 @@ Inside this, paste these imports: We are using various utils within the Aztec `prelude` library: -- `use dep::aztec::keys::getters::get_public_keys;` +- `use dep::aztec::keys::getters::get_public_keys;` Imports a helper to retrieve public keys associated with the caller, used for computing a secure nullifier during voting. -- `use dep::aztec::macros::{functions::{initializer, internal, private, public, utility}, storage::storage};` +- `use dep::aztec::macros::{functions::{initializer, internal, private, public, utility}, storage::storage};` Brings in macros for defining different function types (`initializer`, `internal`, `private`, `public`, `utility`) and for declaring contract storage via `storage`. -- `use dep::aztec::prelude::{AztecAddress, Map, PublicImmutable, PublicMutable};` +- `use dep::aztec::prelude::{AztecAddress, Map, PublicImmutable, PublicMutable};` Imports: + - `AztecAddress`: a type for account/contract addresses, - `Map`: a key-value storage structure, - `PublicMutable`: public state that can be updated, - `PublicImmutable`: public state that is read-only after being set once. -- `use dep::aztec::protocol_types::traits::{Hash, ToField};` +- `use dep::aztec::protocol_types::traits::{Hash, ToField};` Provides the `Hash` and `ToField` traits, used for hashing values and converting them to a Field, used for nullifier creation and other computations. - ## Set up storage Under these imports, we need to set up our contract storage. diff --git a/docs/docs/developers/tutorials/codealong/contract_tutorials/token_contract.md b/docs/docs/developers/tutorials/codealong/contract_tutorials/token_contract.md index f2495efe644f..a90888c69a43 100644 --- a/docs/docs/developers/tutorials/codealong/contract_tutorials/token_contract.md +++ b/docs/docs/developers/tutorials/codealong/contract_tutorials/token_contract.md @@ -19,7 +19,7 @@ In this tutorial you will learn how to: We are going to start with a blank project and fill in the token contract source code defined [here (GitHub Link)](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr), and explain what is being added as we go. -This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up #include_aztec_version`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up #include_version_without_prefix`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Requirements diff --git a/docs/docs/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md b/docs/docs/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md index 35b3ae818101..efeaed6850f3 100644 --- a/docs/docs/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md +++ b/docs/docs/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md @@ -15,7 +15,7 @@ You will learn: - Typescript glue code to format and authenticate transactions - Deploying and testing the account contract -This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up #include_aztec_version`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up -v #include_version_without_prefix`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. Writing your own account contract allows you to define the rules by which user transactions are authorized and paid for, as well as how user keys are managed (including key rotation and recovery). In other words, writing an account contract lets you make the most out of account abstraction in the Aztec network. diff --git a/docs/docs/developers/tutorials/codealong/js_tutorials/token_bridge.md b/docs/docs/developers/tutorials/codealong/js_tutorials/token_bridge.md index 4eda49fe9d9d..83719a985a3c 100644 --- a/docs/docs/developers/tutorials/codealong/js_tutorials/token_bridge.md +++ b/docs/docs/developers/tutorials/codealong/js_tutorials/token_bridge.md @@ -20,7 +20,7 @@ The first half of this page reviews the process and contracts for bridging token - sending tokens from L2 back to L1 - withdrawing tokens from the L1 portal -This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up #include_aztec_version`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `#include_aztec_version`. Install the correct version with `aztec-up -v #include_version_without_prefix`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Components diff --git a/docs/versioned_docs/version-alpha-testnet/developers/guides/getting_started_on_testnet.md b/docs/versioned_docs/version-alpha-testnet/developers/guides/getting_started_on_testnet.md index 05a88ad5f7d7..275c29ac2a30 100644 --- a/docs/versioned_docs/version-alpha-testnet/developers/guides/getting_started_on_testnet.md +++ b/docs/versioned_docs/version-alpha-testnet/developers/guides/getting_started_on_testnet.md @@ -115,11 +115,13 @@ aztec-wallet deploy \ --payment method=fpc-sponsored,fpc=contracts:sponsoredfpc \ --alias token \ TokenContract \ - --args accounts:my-wallet Token TOK 18 + --args accounts:my-wallet Token TOK 18 --no-wait ``` You should see confirmation that the token contract is stored in the database. +Wait for the transaction to be mined on testnet. You can check the transaction status with the transaction hash on [aztecscan](https://aztecscan.xyz) or [aztecexplorer](https://aztecexplorer.xyz). + 2. Mint 10 private tokens to yourself: ```bash @@ -127,7 +129,7 @@ aztec-wallet send mint_to_private \ --node-url $NODE_URL \ --from accounts:my-wallet \ --payment method=fpc-sponsored,fpc=contracts:sponsoredfpc \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet accounts:my-wallet 10 ``` @@ -140,7 +142,7 @@ aztec-wallet send transfer_to_public \ --node-url $NODE_URL \ --from accounts:my-wallet \ --payment method=fpc-sponsored,fpc=contracts:sponsoredfpc \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet accounts:my-wallet 2 0 ``` @@ -154,7 +156,7 @@ Private balance: aztec-wallet simulate balance_of_private \ --node-url $NODE_URL \ --from my-wallet \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet ``` @@ -166,7 +168,7 @@ Public balance: aztec-wallet simulate balance_of_public \ --node-url $NODE_URL \ --from my-wallet \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet ``` diff --git a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/counter_contract.md b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/counter_contract.md index bf8c82049eb0..9e71dd7ca6b0 100644 --- a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/counter_contract.md +++ b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/counter_contract.md @@ -7,7 +7,7 @@ import Image from "@theme/IdealImage"; In this guide, we will create our first Aztec.nr smart contract. We will build a simple private counter, where you can keep your own private counter - so no one knows what ID you are at or when you increment! This contract will get you started with the basic setup and syntax of Aztec.nr, but doesn't showcase all of the awesome stuff Aztec is capable of. -This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up v0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up 0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Prerequisites @@ -70,7 +70,7 @@ pub contract Counter { } ``` -```rust title="imports" showLineNumbers +```rust title="imports" showLineNumbers use aztec::macros::{functions::{initializer, private, public, utility}, storage::storage}; use aztec::prelude::{AztecAddress, Map}; use aztec::protocol_types::{ @@ -83,26 +83,26 @@ use value_note::{balance_utils, value_note::ValueNote}; > Source code: noir-projects/noir-contracts/contracts/test/counter_contract/src/main.nr#L8-L17 -- `use aztec::macros::{functions::{initializer, private, utility}, storage::storage};` +- `use aztec::macros::{functions::{initializer, private, utility}, storage::storage};` Imports the macros needed to define function types (`initializer`, `private`, and `utility`) and the `storage` macro for declaring contract storage structures. -- `use aztec::prelude::{AztecAddress, Map};` +- `use aztec::prelude::{AztecAddress, Map};` Brings in `AztecAddress` (used to identify accounts/contracts) and `Map` (used for creating state mappings, like our counters). -- `use aztec::protocol_types::traits::{FromField, ToField};` +- `use aztec::protocol_types::traits::{FromField, ToField};` Provides traits for converting values to and from field elements, necessary for serialization and formatting inside Aztec. -- `use easy_private_state::EasyPrivateUint;` +- `use easy_private_state::EasyPrivateUint;` Imports a wrapper to manage private integer-like state variables (ie our counter), abstracting away notes. -- `use value_note::{balance_utils, value_note::ValueNote};` +- `use value_note::{balance_utils, value_note::ValueNote};` Brings in `ValueNote`, which represents a private value stored as a note, and `balance_utils`, which makes working with notes feel like working with simple balances. ## Declare storage Add this below the imports. It declares the storage variables for our contract. We are going to store a mapping of values for each `AztecAddress`. -```rust title="storage_struct" showLineNumbers +```rust title="storage_struct" showLineNumbers #[storage] struct Storage { counters: Map, Context>, @@ -117,7 +117,7 @@ Now we’ve got a mechanism for storing our private state, we can start using it Let’s create a constructor method to run on deployment that assigns an initial count to a specified owner. This function is called `initialize`, but behaves like a constructor. It is the `#[initializer]` decorator that specifies that this function behaves like a constructor. Write this: -```rust title="constructor" showLineNumbers +```rust title="constructor" showLineNumbers #[initializer] #[private] // We can name our initializer anything we want as long as it's marked as aztec(initializer) @@ -137,7 +137,7 @@ We have annotated this and other functions with `#[private]` which are ABI macro Now let’s implement the `increment` function we defined in the first step. -```rust title="increment" showLineNumbers +```rust title="increment" showLineNumbers #[private] fn increment(owner: AztecAddress, sender: AztecAddress) { unsafe { @@ -166,7 +166,7 @@ Because our counters are private, the network can't directly verify if a note wa The last thing we need to implement is the function in order to retrieve a counter. In the `getCounter` we defined in the first step, write this: -```rust title="get_counter" showLineNumbers +```rust title="get_counter" showLineNumbers #[utility] unconstrained fn get_counter(owner: AztecAddress) -> Field { let counters = storage.counters; diff --git a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md index 061a6f9eb503..88bf71a5d4a2 100644 --- a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md +++ b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md @@ -22,7 +22,7 @@ Along the way you will: - Wrap an address with its interface (token) - Create custom private value notes -This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up v0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up 0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Setup @@ -124,7 +124,7 @@ The `aztec::protocol_types` can be browsed [here (GitHub link)](https://github.c This contract uses another file called `config.nr`. Create this in the same directory as `main.nr` and paste this in: -```rust title="config.nr" showLineNumbers +```rust title="config.nr" showLineNumbers use dep::aztec::protocol_types::{address::AztecAddress, traits::Packable}; use std::meta::derive; @@ -144,7 +144,7 @@ pub struct Config { To retain the initializer parameters in the contract's Storage, we'll need to declare them in a preceding `Storage` struct in our `main.nr`: -```rust title="storage" showLineNumbers +```rust title="storage" showLineNumbers #[storage] struct Storage { config: PublicImmutable, @@ -157,7 +157,7 @@ struct Storage { Now complete the initializer by setting the storage variables with the parameters: -```rust title="init" showLineNumbers +```rust title="init" showLineNumbers #[public] #[initializer] fn init(donation_token: AztecAddress, operator: AztecAddress, deadline: u64) { @@ -175,7 +175,7 @@ To check that the donation occurs before the campaign deadline, we must access t We read the deadline from public storage in private and use the router contract to assert that the current `timestamp` is before the deadline. -```rust title="call-check-deadline" showLineNumbers +```rust title="call-check-deadline" showLineNumbers privately_check_timestamp(Comparator.LT, config.deadline, &mut context); ``` > Source code: noir-projects/noir-contracts/contracts/app/crowdfunding_contract/src/main.nr#L68-L70 @@ -187,7 +187,7 @@ If it's unique to this contract, then there'll be a privacy leak regardless, as Now conclude adding all dependencies to the `Crowdfunding` contract: -```rust title="all-deps" showLineNumbers +```rust title="all-deps" showLineNumbers use crate::config::Config; use dep::aztec::{ event::event_interface::EventInterface, @@ -228,7 +228,7 @@ With the dependency already `use`d at the start of the contract, the token contr The last thing to do is create a new value note and add it to the `donation_receipts`. So the full donation function is now -```rust title="donate" showLineNumbers +```rust title="donate" showLineNumbers #[private] fn donate(amount: u128) { let config = storage.config.read(); @@ -269,7 +269,7 @@ The last point is achieved by emitting an unencrypted event log. Copy the last function into your Crowdfunding contract: -```rust title="operator-withdrawals" showLineNumbers +```rust title="operator-withdrawals" showLineNumbers // Withdraws balance to the operator. Requires that msg_sender() is the operator. #[private] fn withdraw(amount: u128) { @@ -298,7 +298,7 @@ fn _publish_donation_receipts(amount: u128, to: AztecAddress) { This is emitting an event, which we will need to create. Paste this earlier in our contract after our `Storage` declaration: -```rust title="withdrawal-processed-event" showLineNumbers +```rust title="withdrawal-processed-event" showLineNumbers #[derive(Serialize)] #[event] struct WithdrawalProcessed { diff --git a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/nft_contract.md b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/nft_contract.md index b1b88f9e8968..d22d351bbcae 100644 --- a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/nft_contract.md +++ b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/nft_contract.md @@ -17,7 +17,7 @@ In this tutorial you will learn how to: - Handle different private note types - Pass data between private and public state -This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up v0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up 0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. We are going to start with a blank project and fill in the token contract source code defined [here (GitHub Link)](https://github.com/AztecProtocol/aztec-packages/blob/v0.87.2/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr), and explain what is being added as we go. @@ -201,7 +201,7 @@ Now that we have dependencies imported into our contract we can define the stora Below the dependencies, paste the following Storage struct: -```rust title="storage_struct" showLineNumbers +```rust title="storage_struct" showLineNumbers #[storage] struct Storage { // The symbol of the NFT @@ -229,7 +229,7 @@ The contract storage uses a [custom note](../../../guides/smart_contracts/writin Randomness is required because notes are stored as commitments (hashes) in the note hash tree. Without randomness, the contents of a note may be derived through brute force (e.g. without randomness, if you know my Aztec address, you may be able to figure out which note hash in the tree is mine by hashing my address with many potential `token_id`s). -```rust title="nft_note" showLineNumbers +```rust title="nft_note" showLineNumbers /// A private note representing a token id associated to an account. #[custom_note] #[derive(Eq, Serialize)] @@ -258,7 +258,7 @@ Copy and paste the body of each function into the appropriate place in your proj This function sets the admin and makes them a minter, and sets the name and symbol. -```rust title="constructor" showLineNumbers +```rust title="constructor" showLineNumbers #[public] #[initializer] fn constructor(admin: AztecAddress, name: str<31>, symbol: str<31>) { @@ -284,7 +284,7 @@ Storage is referenced as `storage.variable`. The function checks that the `msg_sender` is the `admin`. If not, the transaction will fail. If it is, the `new_admin` is saved as the `admin`. -```rust title="set_admin" showLineNumbers +```rust title="set_admin" showLineNumbers #[public] fn set_admin(new_admin: AztecAddress) { assert(storage.admin.read().eq(context.msg_sender()), "caller is not an admin"); @@ -298,7 +298,7 @@ fn set_admin(new_admin: AztecAddress) { This function allows the `admin` to add or a remove a `minter` from the public `minters` mapping. It checks that `msg_sender` is the `admin` and finally adds the `minter` to the `minters` mapping. -```rust title="set_minter" showLineNumbers +```rust title="set_minter" showLineNumbers #[public] fn set_minter(minter: AztecAddress, approve: bool) { assert(storage.admin.read().eq(context.msg_sender()), "caller is not an admin"); @@ -312,7 +312,7 @@ fn set_minter(minter: AztecAddress, approve: bool) { This public function checks that the `token_id` is not 0 and does not already exist and the `msg_sender` is authorized to mint. Then it indicates that the `token_id` exists, which is useful for verifying its existence if it gets transferred to private, and updates the owner in the `public_owners` mapping. -```rust title="mint" showLineNumbers +```rust title="mint" showLineNumbers #[public] fn mint(to: AztecAddress, token_id: Field) { assert(token_id != 0, "zero token ID not supported"); @@ -329,7 +329,7 @@ fn mint(to: AztecAddress, token_id: Field) { #### `transfer_in_public` -```rust title="transfer_in_public" showLineNumbers +```rust title="transfer_in_public" showLineNumbers #[public] fn transfer_in_public(from: AztecAddress, to: AztecAddress, token_id: Field, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -357,7 +357,7 @@ If the `msg_sender` is the same as the account to debit from, the authorization This public function finalizes a transfer that has been set up by a call to [`prepare_private_balance_increase`](#prepare_private_balance_increase) by reducing the public balance of the associated account and emitting the note for the intended recipient. -```rust title="finalize_transfer_to_private" showLineNumbers +```rust title="finalize_transfer_to_private" showLineNumbers #[public] fn finalize_transfer_to_private(token_id: Field, partial_note: PartialNFTNote) { let from = context.msg_sender(); @@ -384,7 +384,7 @@ Storage is referenced as `storage.variable`. Transfers token with `token_id` from public balance of the sender to a private balance of `to`. Calls [`_prepare_private_balance_increase`](#prepare_private_balance_increase) to get the hiding point slot (a transient storage slot where we can keep the partial note) and then calls [`_finalize_transfer_to_private_unsafe`](#_finalize_transfer_to_private_unsafe) to finalize the transfer in the public context. -```rust title="transfer_to_private" showLineNumbers +```rust title="transfer_to_private" showLineNumbers #[private] fn transfer_to_private(to: AztecAddress, token_id: Field) { let from = context.msg_sender(); @@ -414,7 +414,7 @@ This function calls `_prepare_private_balance_increase` which is marked as `#[co It also calls [`_store_payload_in_transient_storage_unsafe`](#_store_payload_in_transient_storage_unsafe) to store the partial note in "transient storage" (more below) -```rust title="prepare_private_balance_increase" showLineNumbers +```rust title="prepare_private_balance_increase" showLineNumbers #[private] fn prepare_private_balance_increase(to: AztecAddress) -> PartialNFTNote { _prepare_private_balance_increase(to, &mut context, storage) @@ -452,7 +452,7 @@ fn _prepare_private_balance_increase( Cancels a private authwit by emitting the corresponding nullifier. -```rust title="cancel_authwit" showLineNumbers +```rust title="cancel_authwit" showLineNumbers #[private] fn cancel_authwit(inner_hash: Field) { let on_behalf_of = context.msg_sender(); @@ -467,7 +467,7 @@ fn cancel_authwit(inner_hash: Field) { Transfers an NFT between two addresses in the private context. Uses [authwits](../../../../aztec/concepts/advanced/authwit.md) to allow contracts to transfer NFTs on behalf of other accounts. -```rust title="transfer_in_private" showLineNumbers +```rust title="transfer_in_private" showLineNumbers #[private] fn transfer_in_private(from: AztecAddress, to: AztecAddress, token_id: Field, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -495,7 +495,7 @@ fn transfer_in_private(from: AztecAddress, to: AztecAddress, token_id: Field, no Transfers and NFT from private storage to public storage. The private call enqueues a call to [`_finish_transfer_to_public`](#_finish_transfer_to_public) which updates the public owner of the `token_id`. -```rust title="transfer_to_public" showLineNumbers +```rust title="transfer_to_public" showLineNumbers #[private] fn transfer_to_public(from: AztecAddress, to: AztecAddress, token_id: Field, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -527,7 +527,7 @@ It is labeled unsafe because the public function does not check the value of the This is transient storage since the storage is not permanent, but is scoped to the current transaction only, after which it will be reset. The partial note is stored the "hiding point slot" value (computed in `_prepare_private_balance_increase()`) in public storage. However subsequent enqueued call to `_finalize_transfer_to_private_unsafe()` will read the partial note in this slot, complete it and emit it. Since the note is completed, there is no use of storing the hiding point slot anymore so we will reset to empty. This saves a write to public storage too. -```rust title="store_payload_in_transient_storage_unsafe" showLineNumbers +```rust title="store_payload_in_transient_storage_unsafe" showLineNumbers #[public] #[internal] fn _store_nft_set_partial_note(partial_note: PartialNFTNote) { @@ -545,7 +545,7 @@ fn _store_nft_set_partial_note(partial_note: PartialNFTNote) { This function is labeled as unsafe because the sender is not enforced in this function, but it is safe because the sender is enforced in the execution of the private function that calls this function. -```rust title="finalize_transfer_to_private_unsafe" showLineNumbers +```rust title="finalize_transfer_to_private_unsafe" showLineNumbers #[public] #[internal] fn _finalize_transfer_to_private_unsafe( @@ -563,7 +563,7 @@ fn _finalize_transfer_to_private_unsafe( Updates the public owner of the `token_id` to the `to` address. -```rust title="finish_transfer_to_public" showLineNumbers +```rust title="finish_transfer_to_public" showLineNumbers #[public] #[internal] fn _finish_transfer_to_public(to: AztecAddress, token_id: Field) { @@ -581,7 +581,7 @@ NFT implements the following `view` functions: A getter function for reading the public `admin` value. -```rust title="admin" showLineNumbers +```rust title="admin" showLineNumbers #[public] #[view] fn get_admin() -> Field { @@ -595,7 +595,7 @@ fn get_admin() -> Field { A getter function for checking the value of associated with a `minter` in the public `minters` mapping. -```rust title="is_minter" showLineNumbers +```rust title="is_minter" showLineNumbers #[public] #[view] fn is_minter(minter: AztecAddress) -> bool { @@ -633,7 +633,7 @@ The NFT implements the following [utility](../../../../aztec/concepts/call_types A getter function for checking the private balance of the provided Aztec account. Returns an array of token IDs owned by `owner` in private and a flag indicating whether a page limit was reached. -```rust title="get_private_nfts" showLineNumbers +```rust title="get_private_nfts" showLineNumbers #[utility] unconstrained fn get_private_nfts( owner: AztecAddress, diff --git a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md index c27d76d95c29..b21600e8c711 100644 --- a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md +++ b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md @@ -9,7 +9,7 @@ import Image from '@theme/IdealImage'; In this tutorial we will go through writing a very simple private voting smart contract in Aztec.nr. You will learn about private functions, public functions, composability between them, state management and creatively using nullifiers to prevent people from voting twice! -This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up v0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up 0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. We will build this: @@ -69,7 +69,7 @@ This defines a contract called `Voter`. Everything will sit inside this block. Inside this, paste these imports: -```rust title="imports" showLineNumbers +```rust title="imports" showLineNumbers use dep::aztec::{ keys::getters::get_public_keys, macros::{functions::{initializer, internal, private, public, utility}, storage::storage}, @@ -82,20 +82,20 @@ use dep::aztec::protocol_types::traits::{Hash, ToField}; We are using various utils within the Aztec `prelude` library: -- `use dep::aztec::keys::getters::get_public_keys;` +- `use dep::aztec::keys::getters::get_public_keys;` Imports a helper to retrieve public keys associated with the caller, used for computing a secure nullifier during voting. -- `use dep::aztec::macros::{functions::{initializer, internal, private, public, utility}, storage::storage};` +- `use dep::aztec::macros::{functions::{initializer, internal, private, public, utility}, storage::storage};` Brings in macros for defining different function types (`initializer`, `internal`, `private`, `public`, `utility`) and for declaring contract storage via `storage`. -- `use dep::aztec::prelude::{AztecAddress, Map, PublicImmutable, PublicMutable};` +- `use dep::aztec::prelude::{AztecAddress, Map, PublicImmutable, PublicMutable};` Imports: - `AztecAddress`: a type for account/contract addresses, - `Map`: a key-value storage structure, - `PublicMutable`: public state that can be updated, - `PublicImmutable`: public state that is read-only after being set once. -- `use dep::aztec::protocol_types::traits::{Hash, ToField};` +- `use dep::aztec::protocol_types::traits::{Hash, ToField};` Provides the `Hash` and `ToField` traits, used for hashing values and converting them to a Field, used for nullifier creation and other computations. @@ -104,7 +104,7 @@ We are using various utils within the Aztec `prelude` library: Under these imports, we need to set up our contract storage. Define the storage struct like so: -```rust title="storage_struct" showLineNumbers +```rust title="storage_struct" showLineNumbers #[storage] struct Storage { admin: PublicMutable, // admin can end vote @@ -127,7 +127,7 @@ In this contract, we will store three vars: The next step is to initialize the contract with a constructor. The constructor will take an address as a parameter and set the admin. -```rust title="constructor" showLineNumbers +```rust title="constructor" showLineNumbers #[public] #[initializer] // annotation to mark function as a constructor @@ -154,7 +154,7 @@ To ensure someone only votes once, we will create a nullifier as part of the fun Create a private function called `cast_vote`: -```rust title="cast_vote" showLineNumbers +```rust title="cast_vote" showLineNumbers #[private] // annotation to mark function as private and expose private context fn cast_vote(candidate: Field) { @@ -179,7 +179,7 @@ After pushing the nullifier, we update the `tally` to reflect this vote. As we k Create this new public function like this: -```rust title="add_to_tally_public" showLineNumbers +```rust title="add_to_tally_public" showLineNumbers #[public] #[internal] fn add_to_tally_public(candidate: Field) { @@ -201,7 +201,7 @@ The code after the assertion will only run if the assertion is true. In this sni We will create a function that anyone can call that will return the number of votes at a given vote Id. Paste this in your contract: -```rust title="get_vote" showLineNumbers +```rust title="get_vote" showLineNumbers #[utility] unconstrained fn get_vote(candidate: Field) -> Field { storage.tally.at(candidate).read() @@ -218,7 +218,7 @@ To ensure that only an `admin` can end a voting period, we can use another `asse Paste this function in your contract: -```rust title="end_vote" showLineNumbers +```rust title="end_vote" showLineNumbers #[public] fn end_vote() { assert(storage.admin.read().eq(context.msg_sender()), "Only admin can end votes"); // assert that caller is admin diff --git a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/token_contract.md b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/token_contract.md index 095245861714..0e2d2603d567 100644 --- a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/token_contract.md +++ b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/token_contract.md @@ -19,7 +19,7 @@ In this tutorial you will learn how to: We are going to start with a blank project and fill in the token contract source code defined [here (GitHub Link)](https://github.com/AztecProtocol/aztec-packages/blob/v0.87.2/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr), and explain what is being added as we go. -This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up v0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up 0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Requirements @@ -206,7 +206,7 @@ Now that we have dependencies imported into our contract we can define the stora Below the dependencies, paste the following Storage struct: -```rust title="storage_struct" showLineNumbers +```rust title="storage_struct" showLineNumbers #[storage] struct Storage { admin: PublicMutable, @@ -239,7 +239,7 @@ Copy and paste the body of each function into the appropriate place in your proj This function sets the creator of the contract (passed as `msg_sender` from the constructor) as the admin and makes them a minter, and sets name, symbol, and decimals. -```rust title="constructor" showLineNumbers +```rust title="constructor" showLineNumbers #[public] #[initializer] fn constructor(admin: AztecAddress, name: str<31>, symbol: str<31>, decimals: u8) { @@ -266,7 +266,7 @@ Storage is referenced as `storage.variable`. After storage is initialized, the contract checks that the `msg_sender` is the `admin`. If not, the transaction will fail. If it is, the `new_admin` is saved as the `admin`. -```rust title="set_admin" showLineNumbers +```rust title="set_admin" showLineNumbers #[public] fn set_admin(new_admin: AztecAddress) { assert(storage.admin.read().eq(context.msg_sender()), "caller is not admin"); @@ -280,7 +280,7 @@ fn set_admin(new_admin: AztecAddress) { This function allows the `admin` to add or a remove a `minter` from the public `minters` mapping. It checks that `msg_sender` is the `admin` and finally adds the `minter` to the `minters` mapping. -```rust title="set_minter" showLineNumbers +```rust title="set_minter" showLineNumbers #[public] fn set_minter(minter: AztecAddress, approve: bool) { assert(storage.admin.read().eq(context.msg_sender()), "caller is not admin"); @@ -296,7 +296,7 @@ This function allows an account approved in the public `minters` mapping to crea First, storage is initialized. Then the function checks that the `msg_sender` is approved to mint in the `minters` mapping. If it is, a new `U128` value is created of the `amount` provided. The function reads the recipients public balance and then adds the amount to mint, saving the output as `new_balance`, then reads to total supply and adds the amount to mint, saving the output as `supply`. `new_balance` and `supply` are then written to storage. -```rust title="mint_to_public" showLineNumbers +```rust title="mint_to_public" showLineNumbers #[public] fn mint_to_public(to: AztecAddress, amount: u128) { assert(storage.minters.at(context.msg_sender()).read(), "caller is not minter"); @@ -319,7 +319,7 @@ If the `msg_sender` is **NOT** the same as the account to debit from, the functi If the `msg_sender` is the same as the account to debit tokens from, the authorization check is bypassed and the function proceeds to update the account's `public_balance`. -```rust title="transfer_in_public" showLineNumbers +```rust title="transfer_in_public" showLineNumbers #[public] fn transfer_in_public(from: AztecAddress, to: AztecAddress, amount: u128, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -342,7 +342,7 @@ This public function enables public burning (destroying) of tokens from the send After storage is initialized, the [authorization flow specified above](#authorizing-token-spends) is checked. Then the sender's public balance and the `total_supply` are updated and saved to storage. -```rust title="burn_public" showLineNumbers +```rust title="burn_public" showLineNumbers #[public] fn burn_public(from: AztecAddress, amount: u128, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -363,7 +363,7 @@ fn burn_public(from: AztecAddress, amount: u128, nonce: Field) { This public function finalizes a transfer that has been set up by a call to `prepare_private_balance_increase` by reducing the public balance of the associated account and emitting the note for the intended recipient. -```rust title="finalize_mint_to_private" showLineNumbers +```rust title="finalize_mint_to_private" showLineNumbers /// Finalizes a mint of token `amount` to a private balance of `to`. The mint must be prepared by calling /// `prepare_private_balance_increase` first and the resulting /// `partial_note` must be passed as an argument to this function. @@ -385,7 +385,7 @@ fn finalize_mint_to_private(amount: u128, partial_note: PartialUintNote) { Similar to `finalize_mint_to_private`, this public function finalizes a transfer that has been set up by a call to `prepare_private_balance_increase` by reducing the public balance of the associated account and emitting the note for the intended recipient. -```rust title="finalize_transfer_to_private" showLineNumbers +```rust title="finalize_transfer_to_private" showLineNumbers /// Finalizes a transfer of token `amount` from public balance of `from` to a private balance of `to`. /// The transfer must be prepared by calling `prepare_private_balance_increase` first and the resulting /// `partial_note` must be passed as an argument to this function. @@ -419,7 +419,7 @@ After initializing storage, the function checks that the `msg_sender` is authori The function returns `1` to indicate successful execution. -```rust title="transfer_to_public" showLineNumbers +```rust title="transfer_to_public" showLineNumbers #[private] fn transfer_to_public(from: AztecAddress, to: AztecAddress, amount: u128, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -445,7 +445,7 @@ This private function enables private token transfers between Aztec accounts. After initializing storage, the function checks that the `msg_sender` is authorized to spend tokens. See [the Authorizing token spends section](#authorizing-token-spends) above for more detail--the only difference being that `assert_valid_message_for` is modified to work specifically in the private context. After authorization, the function gets the current balances for the sender and recipient and decrements and increments them, respectively, using the `value_note` helper functions. -```rust title="transfer" showLineNumbers +```rust title="transfer" showLineNumbers #[private] fn transfer(to: AztecAddress, amount: u128) { let from = context.msg_sender(); @@ -492,7 +492,7 @@ fn transfer(to: AztecAddress, amount: u128) { This private function enables an account to transfer tokens on behalf of another account. The account that tokens are being debited from must have authorized the `msg_sender` to spend tokens on its behalf. -```rust title="transfer_in_private" showLineNumbers +```rust title="transfer_in_private" showLineNumbers #[private] fn transfer_in_private(from: AztecAddress, to: AztecAddress, amount: u128, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -518,7 +518,7 @@ This function execution flow starts in the private context and is completed with First a partial note is prepared then a call to the public, internal `_finalize_transfer_to_private_unsafe` is enqueued. The enqueued public call subtracts the `amount` from public balance of `msg_sender` and finalizes the partial note with the `amount`. -```rust title="transfer_to_private" showLineNumbers +```rust title="transfer_to_private" showLineNumbers // Transfers token `amount` from public balance of message sender to a private balance of `to`. #[private] fn transfer_to_private(to: AztecAddress, amount: u128) { @@ -541,7 +541,7 @@ fn transfer_to_private(to: AztecAddress, amount: u128) { This private function prepares a partial `UintNote` at the recipients storage slot in the contract and enqueues a public call to `_finalize_mint_to_private_unsafe`, which asserts that the `msg_sender` is an authorized minter and finalized the mint by incrementing the total supply and emitting the complete, encrypted `UintNote` to the intended recipient. Note that the `amount` and the minter (`from`) are public, but the recipient is private. -```rust title="mint_to_private" showLineNumbers +```rust title="mint_to_private" showLineNumbers /// Mints token `amount` to a private balance of `to`. Message sender has to have minter permissions (checked /// in the enqueued call). #[private] @@ -570,7 +570,7 @@ fn mint_to_private( This private function allows a user to cancel an authwit that was previously granted. This is achieved by emitting the corresponding nullifier before it is used. -```rust title="cancel_authwit" showLineNumbers +```rust title="cancel_authwit" showLineNumbers #[private] fn cancel_authwit(inner_hash: Field) { let on_behalf_of = context.msg_sender(); @@ -587,7 +587,7 @@ This private function enables accounts to privately burn (destroy) tokens. After initializing storage, the function checks that the `msg_sender` is authorized to spend tokens. Then it gets the sender's current balance and decrements it. Finally it stages a public function call to [`_reduce_total_supply`](#_reduce_total_supply). -```rust title="burn_private" showLineNumbers +```rust title="burn_private" showLineNumbers #[private] fn burn_private(from: AztecAddress, amount: u128, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -612,7 +612,7 @@ TODO: update from `prepare_transfer_to_private` This private function prepares to transfer from a public balance to a private balance by setting up a partial note for the recipient. The function returns the `hiding_point_slot`. After this, the public [`finalize_transfer_to_private`](#finalize_transfer_to_private) must be called, passing the amount and the hiding point slot. -```rust title="prepare_private_balance_increase" showLineNumbers +```rust title="prepare_private_balance_increase" showLineNumbers /// Prepares an increase of private balance of `to` (partial note). The increase needs to be finalized by calling /// some of the finalization functions (`finalize_transfer_to_private`, `finalize_mint_to_private`) with the /// returned partial note. @@ -633,7 +633,7 @@ Internal functions are functions that can only be called by this contract. The f This function is called from [`transfer_to_public`](#transfer_to_public). The account's private balance is decremented in `transfer_to_public` and the public balance is increased in this function. -```rust title="increase_public_balance" showLineNumbers +```rust title="increase_public_balance" showLineNumbers /// TODO(#9180): Consider adding macro support for functions callable both as an entrypoint and as an internal /// function. #[public] @@ -649,7 +649,7 @@ fn _increase_public_balance(to: AztecAddress, amount: u128) { This function is called from [`burn`](#burn). The account's private balance is decremented in `burn` and the public `total_supply` is reduced in this function. -```rust title="reduce_total_supply" showLineNumbers +```rust title="reduce_total_supply" showLineNumbers #[public] #[internal] fn _reduce_total_supply(amount: u128) { @@ -667,7 +667,7 @@ This public internal function decrements the public balance of the `from` accoun This function is called by the private function [`transfer_to_private`](#transfer_to_private) to finalize the transfer. The `transfer_to_private` enforces the `from` argument, which is why using it `unsafe` is okay. -```rust title="finalize_transfer_to_private_unsafe" showLineNumbers +```rust title="finalize_transfer_to_private_unsafe" showLineNumbers /// This is a wrapper around `_finalize_transfer_to_private` placed here so that a call /// to `_finalize_transfer_to_private` can be enqueued. Called unsafe as it does not check `from` (this has to be /// done in the calling function). @@ -688,7 +688,7 @@ fn _finalize_transfer_to_private_unsafe( Similar to `_finalize_transfer_to_private_unsafe`, this public internal function increments the private balance of the recipient by finalizing the partial note and emitting the encrypted note. It also increments the public total supply and ensures that the sender of the transaction is authorized to mint tokens on the contract. -```rust title="finalize_mint_to_private_unsafe" showLineNumbers +```rust title="finalize_mint_to_private_unsafe" showLineNumbers #[public] #[internal] fn _finalize_mint_to_private_unsafe( @@ -714,7 +714,7 @@ Public view calls that are part of a transaction will be executed by the sequenc A getter function for reading the public `admin` value. -```rust title="admin" showLineNumbers +```rust title="admin" showLineNumbers #[public] #[view] fn get_admin() -> Field { @@ -728,7 +728,7 @@ fn get_admin() -> Field { A getter function for checking the value of associated with a `minter` in the public `minters` mapping. -```rust title="is_minter" showLineNumbers +```rust title="is_minter" showLineNumbers #[public] #[view] fn is_minter(minter: AztecAddress) -> bool { @@ -742,7 +742,7 @@ fn is_minter(minter: AztecAddress) -> bool { A getter function for checking the token `total_supply`. -```rust title="total_supply" showLineNumbers +```rust title="total_supply" showLineNumbers #[public] #[view] fn total_supply() -> u128 { @@ -756,7 +756,7 @@ fn total_supply() -> u128 { A getter function for checking the public balance of the provided Aztec account. -```rust title="balance_of_public" showLineNumbers +```rust title="balance_of_public" showLineNumbers #[public] #[view] fn balance_of_public(owner: AztecAddress) -> u128 { @@ -774,7 +774,7 @@ fn balance_of_public(owner: AztecAddress) -> u128 { A getter function for checking the private balance of the provided Aztec account. Note that the [Private Execution Environment (PXE) (GitHub link)](https://github.com/AztecProtocol/aztec-packages/tree/v0.87.2/yarn-project/pxe) must have `ivsk` ([incoming viewing secret key](../../../../aztec/concepts/accounts/keys.md#incoming-viewing-keys)) in order to decrypt the notes. -```rust title="balance_of_private" showLineNumbers +```rust title="balance_of_private" showLineNumbers #[utility] pub(crate) unconstrained fn balance_of_private(owner: AztecAddress) -> u128 { storage.balances.at(owner).balance_of() diff --git a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md index 482370b07381..814c9d3a0b5b 100644 --- a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md +++ b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md @@ -15,7 +15,7 @@ You will learn: - Typescript glue code to format and authenticate transactions - Deploying and testing the account contract -This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up v0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up 0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. Writing your own account contract allows you to define the rules by which user transactions are authorized and paid for, as well as how user keys are managed (including key rotation and recovery). In other words, writing an account contract lets you make the most out of account abstraction in the Aztec network. @@ -31,7 +31,7 @@ For the sake of simplicity, we will hardcode the signing public key into the con Let's start with the account contract itself in Aztec.nr. Create a new Aztec.nr contract project that will contain a file with the code for the account contract, with a hardcoded public key: -```rust title="contract" showLineNumbers +```rust title="contract" showLineNumbers // Account contract that uses Schnorr signatures for authentication using a hardcoded public key. use dep::aztec::macros::aztec; @@ -98,7 +98,7 @@ schnorr = { git = "https://github.com/noir-lang/schnorr", tag = "v0.1.1" } The important part of this contract is the `entrypoint` function, which will be the first function executed in any transaction originated from this account. This function has two main responsibilities: authenticating the transaction and executing calls. It receives a `payload` with the list of function calls to execute, and requests a corresponding authentication witness from an oracle to validate it. Authentication witnesses are used for authorizing actions for an account, whether it is just checking a signature, like in this case, or granting authorization for another account to act on an accounts behalf (e.g. token approvals). You will find this logic implemented in the `AccountActions` module, which use the `AppPayload` and `FeePayload` structs: -```rust title="entrypoint" showLineNumbers +```rust title="entrypoint" showLineNumbers pub fn entrypoint(self, app_payload: AppPayload, fee_payload: FeePayload, cancellable: bool) { let valid_fn = self.is_valid_impl; @@ -121,7 +121,7 @@ pub fn entrypoint(self, app_payload: AppPayload, fee_payload: FeePayload, cancel > Source code: noir-projects/aztec-nr/authwit/src/account.nr#L40-L59 -```rust title="app-payload-struct" showLineNumbers +```rust title="app-payload-struct" showLineNumbers #[derive(Serialize)] pub struct AppPayload { function_calls: [FunctionCall; ACCOUNT_MAX_CALLS], @@ -131,7 +131,7 @@ pub struct AppPayload { > Source code: noir-projects/aztec-nr/authwit/src/entrypoint/app.nr#L19-L25 -```rust title="fee-payload-struct" showLineNumbers +```rust title="fee-payload-struct" showLineNumbers #[derive(Serialize)] pub struct FeePayload { function_calls: [FunctionCall; MAX_FEE_FUNCTION_CALLS], @@ -148,7 +148,7 @@ Using the `AccountActions` module and the payload structs is not mandatory. You The `AccountActions` module provides default implementations for most of the account contract methods needed, but it requires a function for validating an auth witness. In this function you will customize how your account validates an action: whether it is using a specific signature scheme, a multi-party approval, a password, etc. -```rust title="is-valid" showLineNumbers +```rust title="is-valid" showLineNumbers #[contract_library_method] fn is_valid_impl(_context: &mut PrivateContext, outer_hash: Field) -> bool { // Load auth witness and format as an u8 array @@ -190,7 +190,7 @@ A side-effect of not having nonces at the protocol level is that it is not possi Now that we have a valid account contract, we need to write the typescript glue code that will take care of formatting and authenticating transactions so they can be processed by our contract, as well as deploying the contract during account setup. This takes the form of implementing the `AccountContract` interface from `@aztec/aztec.js`: -```typescript title="account-contract-interface" showLineNumbers +```typescript title="account-contract-interface" showLineNumbers /** * An account contract instance. Knows its artifact, deployment arguments, how to create * transaction execution requests out of function calls, and how to authorize actions. @@ -236,7 +236,7 @@ export interface AccountContract { However, if you are using the default `AccountActions` module, then you can leverage the `DefaultAccountContract` class from `@aztec/accounts` and just implement the logic for generating an auth witness that matches the one you wrote in Noir: -```typescript title="account-contract" showLineNumbers +```typescript title="account-contract" showLineNumbers const PRIVATE_KEY = GrumpkinScalar.fromHexString('0xd35d743ac0dfe3d6dbe6be8c877cb524a00ab1e3d52d7bada095dfc8894ccfa'); /** Account contract implementation that authenticates txs using Schnorr signatures. */ @@ -287,7 +287,7 @@ Let's try creating a new account backed by our account contract, and interact wi To create and deploy the account, we will use the `AccountManager` class, which takes an instance of an Private Execution Environment (PXE), a [privacy private key](../../../../aztec/concepts/accounts/keys.md#incoming-viewing-keys), and an instance of our `AccountContract` class: -```typescript title="account-contract-deploy" showLineNumbers +```typescript title="account-contract-deploy" showLineNumbers const secretKey = Fr.random(); const account = await AccountManager.create(pxe, secretKey, new SchnorrHardcodedKeyAccountContract()); @@ -308,7 +308,7 @@ const address = wallet.getAddress(); Note that we used a funded wallet to deploy the account contract and pay for the transaction fee. The new account doesn't have any funds yet. We will continue using the funded wallet to deploy the token contract: -```typescript title="token-contract-deploy" showLineNumbers +```typescript title="token-contract-deploy" showLineNumbers const token = await TokenContract.deploy(fundedWallet, fundedWallet.getAddress(), 'TokenName', 'TokenSymbol', 18) .send() .deployed(); @@ -328,7 +328,7 @@ If we run this, we get `Balance of wallet is now 150`, which shows that the `min To make sure that we are actually validating the provided signature in our account contract, we can try signing with a different key. To do this, we will set up a new `Account` instance pointing to the contract we already deployed but using a wrong signing key: -```typescript title="account-contract-fails" showLineNumbers +```typescript title="account-contract-fails" showLineNumbers const wrongKey = GrumpkinScalar.random(); const wrongAccountContract = new SchnorrHardcodedKeyAccountContract(wrongKey); const wrongAccount = await AccountManager.create(pxe, secretKey, wrongAccountContract, account.salt); diff --git a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/js_tutorials/token_bridge.md b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/js_tutorials/token_bridge.md index d65f24e91ca3..e7d7d8d11348 100644 --- a/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/js_tutorials/token_bridge.md +++ b/docs/versioned_docs/version-alpha-testnet/developers/tutorials/codealong/js_tutorials/token_bridge.md @@ -20,7 +20,7 @@ The first half of this page reviews the process and contracts for bridging token - sending tokens from L2 back to L1 - withdrawing tokens from the L1 portal -This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up v0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.2`. Install the correct version with `aztec-up 0.87.2`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Components @@ -75,7 +75,7 @@ Note that because L1 is public, everyone can inspect and figure out the contentH #### `depositToAztecPublic` (TokenPortal.sol) -```solidity title="deposit_public" showLineNumbers +```solidity title="deposit_public" showLineNumbers /** * @notice Deposit funds into the portal and adds an L2 message which can only be consumed publicly on Aztec * @param _to - The aztec address of the recipient @@ -92,7 +92,7 @@ function depositToAztecPublic(bytes32 _to, uint256 _amount, bytes32 _secretHash) #### `depositToAztecPrivate` (TokenPortal.sol) -```solidity title="deposit_private" showLineNumbers +```solidity title="deposit_private" showLineNumbers /** * @notice Deposit funds into the portal and adds an L2 message which can only be consumed privately on Aztec * @param _amount - The amount to deposit @@ -116,7 +116,7 @@ The previous code snippets moved funds to the bridge and created a L1->L2 messag This happens inside the `TokenBridge` contract on Aztec. -```rust title="claim_public" showLineNumbers +```rust title="claim_public" showLineNumbers // Consumes a L1->L2 message and calls the token contract to mint the appropriate amount publicly #[public] fn claim_public(to: AztecAddress, amount: u128, secret: Field, message_leaf_index: Field) { @@ -154,7 +154,7 @@ For both the public and private flow, we use the same mechanism to determine the #### `exit_to_L1_public` (TokenBridge.nr) -```rust title="exit_to_l1_public" showLineNumbers +```rust title="exit_to_l1_public" showLineNumbers // Burns the appropriate amount of tokens and creates a L2 to L1 withdraw message publicly // Requires `msg.sender` to give approval to the bridge to burn tokens on their behalf using witness signatures #[public] @@ -181,7 +181,7 @@ fn exit_to_l1_public( This function works very similarly to the public version, except here we burn user’s private notes. -```rust title="exit_to_l1_private" showLineNumbers +```rust title="exit_to_l1_private" showLineNumbers // Burns the appropriate amount of tokens and creates a L2 to L1 withdraw message privately // Requires `msg.sender` (caller of the method) to give approval to the bridge to burn tokens on their behalf using witness signatures #[private] @@ -218,7 +218,7 @@ A user must sign an approval message to let the contract burn tokens on their be After the transaction is completed on L2, the portal must call the outbox to successfully transfer funds to the user on L1. Like with deposits, things can be complex here. For example, what happens if the transaction was done on L2 to burn tokens but can’t be withdrawn to L1? Then the funds are lost forever! How do we prevent this? -```solidity title="token_portal_withdraw" showLineNumbers +```solidity title="token_portal_withdraw" showLineNumbers /** * @notice Withdraw funds from the portal * @dev Second part of withdraw, must be initiated from L2 first as it will consume a message from outbox @@ -336,7 +336,7 @@ You can run the script we will build in `index.ts` at any point with `yarn start Add the following imports to your `index.ts`: -```typescript title="imports" showLineNumbers +```typescript title="imports" showLineNumbers import { getInitialTestAccountsWallets } from '@aztec/accounts/testing'; import { EthAddress, @@ -368,7 +368,7 @@ import { getContract } from 'viem'; Add the following utility functions to your `index.ts` below the imports: -```typescript title="utils" showLineNumbers +```typescript title="utils" showLineNumbers const MNEMONIC = 'test test test test test test test test test test test junk'; const { ETHEREUM_HOSTS = 'http://localhost:8545' } = process.env; @@ -452,7 +452,7 @@ Run the script with `yarn start` and you should see the L1 contract addresses pr Add the following code to `index.ts` to deploy the L2 token contract: -```typescript title="deploy-l2-token" showLineNumbers +```typescript title="deploy-l2-token" showLineNumbers const l2TokenContract = await TokenContract.deploy(ownerWallet, ownerAztecAddress, 'L2 Token', 'L2', 18) .send() .deployed(); @@ -463,7 +463,7 @@ logger.info(`L2 token contract deployed at ${l2TokenContract.address}`); Add the following code to `index.ts` to deploy the L1 token contract and set up the `L1TokenManager` (a utility class to interact with the L1 token contract): -```typescript title="deploy-l1-token" showLineNumbers +```typescript title="deploy-l1-token" showLineNumbers const l1TokenContract = await deployTestERC20(); logger.info('erc20 contract deployed'); @@ -477,7 +477,7 @@ const l1TokenManager = new L1TokenManager(l1TokenContract, feeAssetHandler, l1Cl Add the following code to `index.ts` to deploy the L1 portal contract: -```typescript title="deploy-portal" showLineNumbers +```typescript title="deploy-portal" showLineNumbers const l1PortalContractAddress = await deployTokenPortal(); logger.info('L1 portal contract deployed'); @@ -492,7 +492,7 @@ const l1Portal = getContract({ Add the following code to `index.ts` to deploy the L2 bridge contract: -```typescript title="deploy-l2-bridge" showLineNumbers +```typescript title="deploy-l2-bridge" showLineNumbers const l2BridgeContract = await TokenBridgeContract.deploy( ownerWallet, l2TokenContract.address, @@ -511,7 +511,7 @@ Run `yarn start` to confirm that all of the contracts are deployed. Add the following code to `index.ts` to authorize the L2 bridge contract to mint tokens on the L2 token contract: -```typescript title="authorize-l2-bridge" showLineNumbers +```typescript title="authorize-l2-bridge" showLineNumbers await l2TokenContract.methods.set_minter(l2BridgeContract.address, true).send().wait(); ``` > Source code: yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts#L133-L135 @@ -519,7 +519,7 @@ await l2TokenContract.methods.set_minter(l2BridgeContract.address, true).send(). Add the following code to `index.ts` to set up the L1 portal contract and `L1TokenPortalManager` (a utility class to interact with the L1 portal contract): -```typescript title="setup-portal" showLineNumbers +```typescript title="setup-portal" showLineNumbers await l1Portal.write.initialize( [l1ContractAddresses.registryAddress.toString(), l1TokenContract.toString(), l2BridgeContract.address.toString()], {}, @@ -542,7 +542,7 @@ const l1PortalManager = new L1TokenPortalManager( Add the following code to `index.ts` to bridge tokens from L1 to L2: -```typescript title="l1-bridge-public" showLineNumbers +```typescript title="l1-bridge-public" showLineNumbers const claim = await l1PortalManager.bridgeTokensPublic(ownerAztecAddress, MINT_AMOUNT, true); // Do 2 unrleated actions because @@ -559,7 +559,7 @@ We have to send two additional transactions because the network must process 2 b Add the following code to `index.ts` to claim the tokens publicly on Aztec: -```typescript title="claim" showLineNumbers +```typescript title="claim" showLineNumbers await l2BridgeContract.methods .claim_public(ownerAztecAddress, MINT_AMOUNT, claim.claimSecret, claim.messageLeafIndex) .send() @@ -576,7 +576,7 @@ Run `yarn start` to confirm that tokens are claimed on Aztec. Add the following code to `index.ts` to start the withdraw the tokens to L1: -```typescript title="setup-withdrawal" showLineNumbers +```typescript title="setup-withdrawal" showLineNumbers const withdrawAmount = 9n; const nonce = Fr.random(); @@ -597,7 +597,7 @@ We have to send a public authwit to allow the bridge contract to burn tokens on Add the following code to `index.ts` to start the withdraw process on Aztec: -```typescript title="l2-withdraw" showLineNumbers +```typescript title="l2-withdraw" showLineNumbers const l2ToL1Message = await l1PortalManager.getL2ToL1MessageLeaf( withdrawAmount, EthAddress.fromString(ownerEthAddress), @@ -617,7 +617,7 @@ logger.info(`New L2 balance of ${ownerAztecAddress} is ${newL2Balance}`); Add the following code to `index.ts` to complete the withdraw process on L1: -```typescript title="l1-withdraw" showLineNumbers +```typescript title="l1-withdraw" showLineNumbers const [l2ToL1MessageIndex, siblingPath] = await pxe.getL2ToL1MembershipWitness( await pxe.getBlockNumber(), l2ToL1Message, diff --git a/docs/versioned_docs/version-v0.87.0/developers/guides/getting_started_on_testnet.md b/docs/versioned_docs/version-v0.87.0/developers/guides/getting_started_on_testnet.md index 05a88ad5f7d7..275c29ac2a30 100644 --- a/docs/versioned_docs/version-v0.87.0/developers/guides/getting_started_on_testnet.md +++ b/docs/versioned_docs/version-v0.87.0/developers/guides/getting_started_on_testnet.md @@ -115,11 +115,13 @@ aztec-wallet deploy \ --payment method=fpc-sponsored,fpc=contracts:sponsoredfpc \ --alias token \ TokenContract \ - --args accounts:my-wallet Token TOK 18 + --args accounts:my-wallet Token TOK 18 --no-wait ``` You should see confirmation that the token contract is stored in the database. +Wait for the transaction to be mined on testnet. You can check the transaction status with the transaction hash on [aztecscan](https://aztecscan.xyz) or [aztecexplorer](https://aztecexplorer.xyz). + 2. Mint 10 private tokens to yourself: ```bash @@ -127,7 +129,7 @@ aztec-wallet send mint_to_private \ --node-url $NODE_URL \ --from accounts:my-wallet \ --payment method=fpc-sponsored,fpc=contracts:sponsoredfpc \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet accounts:my-wallet 10 ``` @@ -140,7 +142,7 @@ aztec-wallet send transfer_to_public \ --node-url $NODE_URL \ --from accounts:my-wallet \ --payment method=fpc-sponsored,fpc=contracts:sponsoredfpc \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet accounts:my-wallet 2 0 ``` @@ -154,7 +156,7 @@ Private balance: aztec-wallet simulate balance_of_private \ --node-url $NODE_URL \ --from my-wallet \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet ``` @@ -166,7 +168,7 @@ Public balance: aztec-wallet simulate balance_of_public \ --node-url $NODE_URL \ --from my-wallet \ - --contract-address last \ + --contract-address token \ --args accounts:my-wallet ``` diff --git a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/counter_contract.md b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/counter_contract.md index 83aad06c5205..db83af4f3d6e 100644 --- a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/counter_contract.md +++ b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/counter_contract.md @@ -7,7 +7,7 @@ import Image from "@theme/IdealImage"; In this guide, we will create our first Aztec.nr smart contract. We will build a simple private counter, where you can keep your own private counter - so no one knows what ID you are at or when you increment! This contract will get you started with the basic setup and syntax of Aztec.nr, but doesn't showcase all of the awesome stuff Aztec is capable of. -This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up v0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up 0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Prerequisites @@ -70,7 +70,7 @@ pub contract Counter { } ``` -```rust title="imports" showLineNumbers +```rust title="imports" showLineNumbers use aztec::macros::{functions::{initializer, private, public, utility}, storage::storage}; use aztec::prelude::{AztecAddress, Map}; use aztec::protocol_types::{ @@ -83,26 +83,26 @@ use value_note::{balance_utils, value_note::ValueNote}; > Source code: noir-projects/noir-contracts/contracts/test/counter_contract/src/main.nr#L8-L17 -- `use aztec::macros::{functions::{initializer, private, utility}, storage::storage};` +- `use aztec::macros::{functions::{initializer, private, utility}, storage::storage};` Imports the macros needed to define function types (`initializer`, `private`, and `utility`) and the `storage` macro for declaring contract storage structures. -- `use aztec::prelude::{AztecAddress, Map};` +- `use aztec::prelude::{AztecAddress, Map};` Brings in `AztecAddress` (used to identify accounts/contracts) and `Map` (used for creating state mappings, like our counters). -- `use aztec::protocol_types::traits::{FromField, ToField};` +- `use aztec::protocol_types::traits::{FromField, ToField};` Provides traits for converting values to and from field elements, necessary for serialization and formatting inside Aztec. -- `use easy_private_state::EasyPrivateUint;` +- `use easy_private_state::EasyPrivateUint;` Imports a wrapper to manage private integer-like state variables (ie our counter), abstracting away notes. -- `use value_note::{balance_utils, value_note::ValueNote};` +- `use value_note::{balance_utils, value_note::ValueNote};` Brings in `ValueNote`, which represents a private value stored as a note, and `balance_utils`, which makes working with notes feel like working with simple balances. ## Declare storage Add this below the imports. It declares the storage variables for our contract. We are going to store a mapping of values for each `AztecAddress`. -```rust title="storage_struct" showLineNumbers +```rust title="storage_struct" showLineNumbers #[storage] struct Storage { counters: Map, Context>, @@ -117,7 +117,7 @@ Now we’ve got a mechanism for storing our private state, we can start using it Let’s create a constructor method to run on deployment that assigns an initial count to a specified owner. This function is called `initialize`, but behaves like a constructor. It is the `#[initializer]` decorator that specifies that this function behaves like a constructor. Write this: -```rust title="constructor" showLineNumbers +```rust title="constructor" showLineNumbers #[initializer] #[private] // We can name our initializer anything we want as long as it's marked as aztec(initializer) @@ -137,7 +137,7 @@ We have annotated this and other functions with `#[private]` which are ABI macro Now let’s implement the `increment` function we defined in the first step. -```rust title="increment" showLineNumbers +```rust title="increment" showLineNumbers #[private] fn increment(owner: AztecAddress, sender: AztecAddress) { unsafe { @@ -166,7 +166,7 @@ Because our counters are private, the network can't directly verify if a note wa The last thing we need to implement is the function in order to retrieve a counter. In the `getCounter` we defined in the first step, write this: -```rust title="get_counter" showLineNumbers +```rust title="get_counter" showLineNumbers #[utility] unconstrained fn get_counter(owner: AztecAddress) -> Field { let counters = storage.counters; diff --git a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md index ac3c821becfd..ded91a65e93a 100644 --- a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md +++ b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/crowdfunding_contract.md @@ -22,7 +22,7 @@ Along the way you will: - Wrap an address with its interface (token) - Create custom private value notes -This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up v0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up 0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Setup @@ -124,7 +124,7 @@ The `aztec::protocol_types` can be browsed [here (GitHub link)](https://github.c This contract uses another file called `config.nr`. Create this in the same directory as `main.nr` and paste this in: -```rust title="config.nr" showLineNumbers +```rust title="config.nr" showLineNumbers use dep::aztec::protocol_types::{address::AztecAddress, traits::Packable}; use std::meta::derive; @@ -144,7 +144,7 @@ pub struct Config { To retain the initializer parameters in the contract's Storage, we'll need to declare them in a preceding `Storage` struct in our `main.nr`: -```rust title="storage" showLineNumbers +```rust title="storage" showLineNumbers #[storage] struct Storage { config: PublicImmutable, @@ -157,7 +157,7 @@ struct Storage { Now complete the initializer by setting the storage variables with the parameters: -```rust title="init" showLineNumbers +```rust title="init" showLineNumbers #[public] #[initializer] fn init(donation_token: AztecAddress, operator: AztecAddress, deadline: u64) { @@ -175,7 +175,7 @@ To check that the donation occurs before the campaign deadline, we must access t We read the deadline from public storage in private and use the router contract to assert that the current `timestamp` is before the deadline. -```rust title="call-check-deadline" showLineNumbers +```rust title="call-check-deadline" showLineNumbers privately_check_timestamp(Comparator.LT, config.deadline, &mut context); ``` > Source code: noir-projects/noir-contracts/contracts/app/crowdfunding_contract/src/main.nr#L68-L70 @@ -187,7 +187,7 @@ If it's unique to this contract, then there'll be a privacy leak regardless, as Now conclude adding all dependencies to the `Crowdfunding` contract: -```rust title="all-deps" showLineNumbers +```rust title="all-deps" showLineNumbers use crate::config::Config; use dep::aztec::{ event::event_interface::EventInterface, @@ -228,7 +228,7 @@ With the dependency already `use`d at the start of the contract, the token contr The last thing to do is create a new value note and add it to the `donation_receipts`. So the full donation function is now -```rust title="donate" showLineNumbers +```rust title="donate" showLineNumbers #[private] fn donate(amount: u128) { let config = storage.config.read(); @@ -269,7 +269,7 @@ The last point is achieved by emitting an unencrypted event log. Copy the last function into your Crowdfunding contract: -```rust title="operator-withdrawals" showLineNumbers +```rust title="operator-withdrawals" showLineNumbers // Withdraws balance to the operator. Requires that msg_sender() is the operator. #[private] fn withdraw(amount: u128) { @@ -298,7 +298,7 @@ fn _publish_donation_receipts(amount: u128, to: AztecAddress) { This is emitting an event, which we will need to create. Paste this earlier in our contract after our `Storage` declaration: -```rust title="withdrawal-processed-event" showLineNumbers +```rust title="withdrawal-processed-event" showLineNumbers #[derive(Serialize)] #[event] struct WithdrawalProcessed { diff --git a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/nft_contract.md b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/nft_contract.md index ce4b42c095c8..976ff4ed7dd4 100644 --- a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/nft_contract.md +++ b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/nft_contract.md @@ -17,7 +17,7 @@ In this tutorial you will learn how to: - Handle different private note types - Pass data between private and public state -This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up v0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up 0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. We are going to start with a blank project and fill in the token contract source code defined [here (GitHub Link)](https://github.com/AztecProtocol/aztec-packages/blob/v0.87.0/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr), and explain what is being added as we go. @@ -201,7 +201,7 @@ Now that we have dependencies imported into our contract we can define the stora Below the dependencies, paste the following Storage struct: -```rust title="storage_struct" showLineNumbers +```rust title="storage_struct" showLineNumbers #[storage] struct Storage { // The symbol of the NFT @@ -229,7 +229,7 @@ The contract storage uses a [custom note](../../../guides/smart_contracts/writin Randomness is required because notes are stored as commitments (hashes) in the note hash tree. Without randomness, the contents of a note may be derived through brute force (e.g. without randomness, if you know my Aztec address, you may be able to figure out which note hash in the tree is mine by hashing my address with many potential `token_id`s). -```rust title="nft_note" showLineNumbers +```rust title="nft_note" showLineNumbers /// A private note representing a token id associated to an account. #[custom_note] #[derive(Eq, Serialize)] @@ -258,7 +258,7 @@ Copy and paste the body of each function into the appropriate place in your proj This function sets the admin and makes them a minter, and sets the name and symbol. -```rust title="constructor" showLineNumbers +```rust title="constructor" showLineNumbers #[public] #[initializer] fn constructor(admin: AztecAddress, name: str<31>, symbol: str<31>) { @@ -284,7 +284,7 @@ Storage is referenced as `storage.variable`. The function checks that the `msg_sender` is the `admin`. If not, the transaction will fail. If it is, the `new_admin` is saved as the `admin`. -```rust title="set_admin" showLineNumbers +```rust title="set_admin" showLineNumbers #[public] fn set_admin(new_admin: AztecAddress) { assert(storage.admin.read().eq(context.msg_sender()), "caller is not an admin"); @@ -298,7 +298,7 @@ fn set_admin(new_admin: AztecAddress) { This function allows the `admin` to add or a remove a `minter` from the public `minters` mapping. It checks that `msg_sender` is the `admin` and finally adds the `minter` to the `minters` mapping. -```rust title="set_minter" showLineNumbers +```rust title="set_minter" showLineNumbers #[public] fn set_minter(minter: AztecAddress, approve: bool) { assert(storage.admin.read().eq(context.msg_sender()), "caller is not an admin"); @@ -312,7 +312,7 @@ fn set_minter(minter: AztecAddress, approve: bool) { This public function checks that the `token_id` is not 0 and does not already exist and the `msg_sender` is authorized to mint. Then it indicates that the `token_id` exists, which is useful for verifying its existence if it gets transferred to private, and updates the owner in the `public_owners` mapping. -```rust title="mint" showLineNumbers +```rust title="mint" showLineNumbers #[public] fn mint(to: AztecAddress, token_id: Field) { assert(token_id != 0, "zero token ID not supported"); @@ -329,7 +329,7 @@ fn mint(to: AztecAddress, token_id: Field) { #### `transfer_in_public` -```rust title="transfer_in_public" showLineNumbers +```rust title="transfer_in_public" showLineNumbers #[public] fn transfer_in_public(from: AztecAddress, to: AztecAddress, token_id: Field, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -357,7 +357,7 @@ If the `msg_sender` is the same as the account to debit from, the authorization This public function finalizes a transfer that has been set up by a call to [`prepare_private_balance_increase`](#prepare_private_balance_increase) by reducing the public balance of the associated account and emitting the note for the intended recipient. -```rust title="finalize_transfer_to_private" showLineNumbers +```rust title="finalize_transfer_to_private" showLineNumbers #[public] fn finalize_transfer_to_private(token_id: Field, partial_note: PartialNFTNote) { let from = context.msg_sender(); @@ -384,7 +384,7 @@ Storage is referenced as `storage.variable`. Transfers token with `token_id` from public balance of the sender to a private balance of `to`. Calls [`_prepare_private_balance_increase`](#prepare_private_balance_increase) to get the hiding point slot (a transient storage slot where we can keep the partial note) and then calls [`_finalize_transfer_to_private_unsafe`](#_finalize_transfer_to_private_unsafe) to finalize the transfer in the public context. -```rust title="transfer_to_private" showLineNumbers +```rust title="transfer_to_private" showLineNumbers #[private] fn transfer_to_private(to: AztecAddress, token_id: Field) { let from = context.msg_sender(); @@ -414,7 +414,7 @@ This function calls `_prepare_private_balance_increase` which is marked as `#[co It also calls [`_store_payload_in_transient_storage_unsafe`](#_store_payload_in_transient_storage_unsafe) to store the partial note in "transient storage" (more below) -```rust title="prepare_private_balance_increase" showLineNumbers +```rust title="prepare_private_balance_increase" showLineNumbers #[private] fn prepare_private_balance_increase(to: AztecAddress) -> PartialNFTNote { _prepare_private_balance_increase(to, &mut context, storage) @@ -452,7 +452,7 @@ fn _prepare_private_balance_increase( Cancels a private authwit by emitting the corresponding nullifier. -```rust title="cancel_authwit" showLineNumbers +```rust title="cancel_authwit" showLineNumbers #[private] fn cancel_authwit(inner_hash: Field) { let on_behalf_of = context.msg_sender(); @@ -467,7 +467,7 @@ fn cancel_authwit(inner_hash: Field) { Transfers an NFT between two addresses in the private context. Uses [authwits](../../../../aztec/concepts/advanced/authwit.md) to allow contracts to transfer NFTs on behalf of other accounts. -```rust title="transfer_in_private" showLineNumbers +```rust title="transfer_in_private" showLineNumbers #[private] fn transfer_in_private(from: AztecAddress, to: AztecAddress, token_id: Field, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -495,7 +495,7 @@ fn transfer_in_private(from: AztecAddress, to: AztecAddress, token_id: Field, no Transfers and NFT from private storage to public storage. The private call enqueues a call to [`_finish_transfer_to_public`](#_finish_transfer_to_public) which updates the public owner of the `token_id`. -```rust title="transfer_to_public" showLineNumbers +```rust title="transfer_to_public" showLineNumbers #[private] fn transfer_to_public(from: AztecAddress, to: AztecAddress, token_id: Field, nonce: Field) { if (!from.eq(context.msg_sender())) { @@ -527,7 +527,7 @@ It is labeled unsafe because the public function does not check the value of the This is transient storage since the storage is not permanent, but is scoped to the current transaction only, after which it will be reset. The partial note is stored the "hiding point slot" value (computed in `_prepare_private_balance_increase()`) in public storage. However subsequent enqueued call to `_finalize_transfer_to_private_unsafe()` will read the partial note in this slot, complete it and emit it. Since the note is completed, there is no use of storing the hiding point slot anymore so we will reset to empty. This saves a write to public storage too. -```rust title="store_payload_in_transient_storage_unsafe" showLineNumbers +```rust title="store_payload_in_transient_storage_unsafe" showLineNumbers #[public] #[internal] fn _store_nft_set_partial_note(partial_note: PartialNFTNote) { @@ -545,7 +545,7 @@ fn _store_nft_set_partial_note(partial_note: PartialNFTNote) { This function is labeled as unsafe because the sender is not enforced in this function, but it is safe because the sender is enforced in the execution of the private function that calls this function. -```rust title="finalize_transfer_to_private_unsafe" showLineNumbers +```rust title="finalize_transfer_to_private_unsafe" showLineNumbers #[public] #[internal] fn _finalize_transfer_to_private_unsafe( @@ -563,7 +563,7 @@ fn _finalize_transfer_to_private_unsafe( Updates the public owner of the `token_id` to the `to` address. -```rust title="finish_transfer_to_public" showLineNumbers +```rust title="finish_transfer_to_public" showLineNumbers #[public] #[internal] fn _finish_transfer_to_public(to: AztecAddress, token_id: Field) { @@ -581,7 +581,7 @@ NFT implements the following `view` functions: A getter function for reading the public `admin` value. -```rust title="admin" showLineNumbers +```rust title="admin" showLineNumbers #[public] #[view] fn get_admin() -> Field { @@ -595,7 +595,7 @@ fn get_admin() -> Field { A getter function for checking the value of associated with a `minter` in the public `minters` mapping. -```rust title="is_minter" showLineNumbers +```rust title="is_minter" showLineNumbers #[public] #[view] fn is_minter(minter: AztecAddress) -> bool { @@ -633,7 +633,7 @@ The NFT implements the following [utility](../../../../aztec/concepts/call_types A getter function for checking the private balance of the provided Aztec account. Returns an array of token IDs owned by `owner` in private and a flag indicating whether a page limit was reached. -```rust title="get_private_nfts" showLineNumbers +```rust title="get_private_nfts" showLineNumbers #[utility] unconstrained fn get_private_nfts( owner: AztecAddress, diff --git a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md index c6232b7e589b..9395d21ea1e8 100644 --- a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md +++ b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/private_voting_contract.md @@ -9,7 +9,7 @@ import Image from '@theme/IdealImage'; In this tutorial we will go through writing a very simple private voting smart contract in Aztec.nr. You will learn about private functions, public functions, composability between them, state management and creatively using nullifiers to prevent people from voting twice! -This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up v0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up 0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. We will build this: @@ -69,7 +69,7 @@ This defines a contract called `Voter`. Everything will sit inside this block. Inside this, paste these imports: -```rust title="imports" showLineNumbers +```rust title="imports" showLineNumbers use dep::aztec::{ keys::getters::get_public_keys, macros::{functions::{initializer, internal, private, public, utility}, storage::storage}, @@ -82,20 +82,20 @@ use dep::aztec::protocol_types::traits::{Hash, ToField}; We are using various utils within the Aztec `prelude` library: -- `use dep::aztec::keys::getters::get_public_keys;` +- `use dep::aztec::keys::getters::get_public_keys;` Imports a helper to retrieve public keys associated with the caller, used for computing a secure nullifier during voting. -- `use dep::aztec::macros::{functions::{initializer, internal, private, public, utility}, storage::storage};` +- `use dep::aztec::macros::{functions::{initializer, internal, private, public, utility}, storage::storage};` Brings in macros for defining different function types (`initializer`, `internal`, `private`, `public`, `utility`) and for declaring contract storage via `storage`. -- `use dep::aztec::prelude::{AztecAddress, Map, PublicImmutable, PublicMutable};` +- `use dep::aztec::prelude::{AztecAddress, Map, PublicImmutable, PublicMutable};` Imports: - `AztecAddress`: a type for account/contract addresses, - `Map`: a key-value storage structure, - `PublicMutable`: public state that can be updated, - `PublicImmutable`: public state that is read-only after being set once. -- `use dep::aztec::protocol_types::traits::{Hash, ToField};` +- `use dep::aztec::protocol_types::traits::{Hash, ToField};` Provides the `Hash` and `ToField` traits, used for hashing values and converting them to a Field, used for nullifier creation and other computations. @@ -104,7 +104,7 @@ We are using various utils within the Aztec `prelude` library: Under these imports, we need to set up our contract storage. Define the storage struct like so: -```rust title="storage_struct" showLineNumbers +```rust title="storage_struct" showLineNumbers #[storage] struct Storage { admin: PublicMutable, // admin can end vote @@ -127,7 +127,7 @@ In this contract, we will store three vars: The next step is to initialize the contract with a constructor. The constructor will take an address as a parameter and set the admin. -```rust title="constructor" showLineNumbers +```rust title="constructor" showLineNumbers #[public] #[initializer] // annotation to mark function as a constructor @@ -154,7 +154,7 @@ To ensure someone only votes once, we will create a nullifier as part of the fun Create a private function called `cast_vote`: -```rust title="cast_vote" showLineNumbers +```rust title="cast_vote" showLineNumbers #[private] // annotation to mark function as private and expose private context fn cast_vote(candidate: Field) { @@ -179,7 +179,7 @@ After pushing the nullifier, we update the `tally` to reflect this vote. As we k Create this new public function like this: -```rust title="add_to_tally_public" showLineNumbers +```rust title="add_to_tally_public" showLineNumbers #[public] #[internal] fn add_to_tally_public(candidate: Field) { @@ -201,7 +201,7 @@ The code after the assertion will only run if the assertion is true. In this sni We will create a function that anyone can call that will return the number of votes at a given vote Id. Paste this in your contract: -```rust title="get_vote" showLineNumbers +```rust title="get_vote" showLineNumbers #[utility] unconstrained fn get_vote(candidate: Field) -> Field { storage.tally.at(candidate).read() @@ -218,7 +218,7 @@ To ensure that only an `admin` can end a voting period, we can use another `asse Paste this function in your contract: -```rust title="end_vote" showLineNumbers +```rust title="end_vote" showLineNumbers #[public] fn end_vote() { assert(storage.admin.read().eq(context.msg_sender()), "Only admin can end votes"); // assert that caller is admin diff --git a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/token_contract.md b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/token_contract.md index 4598f318790f..8cc188a0973c 100644 --- a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/token_contract.md +++ b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/token_contract.md @@ -19,7 +19,7 @@ In this tutorial you will learn how to: We are going to start with a blank project and fill in the token contract source code defined [here (GitHub Link)](https://github.com/AztecProtocol/aztec-packages/blob/v0.87.0/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr), and explain what is being added as we go. -This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up v0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up 0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Requirements diff --git a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md index beaa9e5b4ea9..c10c2ea4a555 100644 --- a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md +++ b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/contract_tutorials/write_accounts_contract.md @@ -15,7 +15,7 @@ You will learn: - Typescript glue code to format and authenticate transactions - Deploying and testing the account contract -This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up v0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up 0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. Writing your own account contract allows you to define the rules by which user transactions are authorized and paid for, as well as how user keys are managed (including key rotation and recovery). In other words, writing an account contract lets you make the most out of account abstraction in the Aztec network. @@ -31,7 +31,7 @@ For the sake of simplicity, we will hardcode the signing public key into the con Let's start with the account contract itself in Aztec.nr. Create a new Aztec.nr contract project that will contain a file with the code for the account contract, with a hardcoded public key: -```rust title="contract" showLineNumbers +```rust title="contract" showLineNumbers // Account contract that uses Schnorr signatures for authentication using a hardcoded public key. use dep::aztec::macros::aztec; @@ -98,7 +98,7 @@ schnorr = { git = "https://github.com/noir-lang/schnorr", tag = "v0.1.1" } The important part of this contract is the `entrypoint` function, which will be the first function executed in any transaction originated from this account. This function has two main responsibilities: authenticating the transaction and executing calls. It receives a `payload` with the list of function calls to execute, and requests a corresponding authentication witness from an oracle to validate it. Authentication witnesses are used for authorizing actions for an account, whether it is just checking a signature, like in this case, or granting authorization for another account to act on an accounts behalf (e.g. token approvals). You will find this logic implemented in the `AccountActions` module, which use the `AppPayload` and `FeePayload` structs: -```rust title="entrypoint" showLineNumbers +```rust title="entrypoint" showLineNumbers pub fn entrypoint(self, app_payload: AppPayload, fee_payload: FeePayload, cancellable: bool) { let valid_fn = self.is_valid_impl; @@ -121,7 +121,7 @@ pub fn entrypoint(self, app_payload: AppPayload, fee_payload: FeePayload, cancel > Source code: noir-projects/aztec-nr/authwit/src/account.nr#L40-L59 -```rust title="app-payload-struct" showLineNumbers +```rust title="app-payload-struct" showLineNumbers #[derive(Serialize)] pub struct AppPayload { function_calls: [FunctionCall; ACCOUNT_MAX_CALLS], @@ -131,7 +131,7 @@ pub struct AppPayload { > Source code: noir-projects/aztec-nr/authwit/src/entrypoint/app.nr#L19-L25 -```rust title="fee-payload-struct" showLineNumbers +```rust title="fee-payload-struct" showLineNumbers #[derive(Serialize)] pub struct FeePayload { function_calls: [FunctionCall; MAX_FEE_FUNCTION_CALLS], @@ -148,7 +148,7 @@ Using the `AccountActions` module and the payload structs is not mandatory. You The `AccountActions` module provides default implementations for most of the account contract methods needed, but it requires a function for validating an auth witness. In this function you will customize how your account validates an action: whether it is using a specific signature scheme, a multi-party approval, a password, etc. -```rust title="is-valid" showLineNumbers +```rust title="is-valid" showLineNumbers #[contract_library_method] fn is_valid_impl(_context: &mut PrivateContext, outer_hash: Field) -> bool { // Load auth witness and format as an u8 array @@ -190,7 +190,7 @@ A side-effect of not having nonces at the protocol level is that it is not possi Now that we have a valid account contract, we need to write the typescript glue code that will take care of formatting and authenticating transactions so they can be processed by our contract, as well as deploying the contract during account setup. This takes the form of implementing the `AccountContract` interface from `@aztec/aztec.js`: -```typescript title="account-contract-interface" showLineNumbers +```typescript title="account-contract-interface" showLineNumbers /** * An account contract instance. Knows its artifact, deployment arguments, how to create * transaction execution requests out of function calls, and how to authorize actions. @@ -236,7 +236,7 @@ export interface AccountContract { However, if you are using the default `AccountActions` module, then you can leverage the `DefaultAccountContract` class from `@aztec/accounts` and just implement the logic for generating an auth witness that matches the one you wrote in Noir: -```typescript title="account-contract" showLineNumbers +```typescript title="account-contract" showLineNumbers const PRIVATE_KEY = GrumpkinScalar.fromHexString('0xd35d743ac0dfe3d6dbe6be8c877cb524a00ab1e3d52d7bada095dfc8894ccfa'); /** Account contract implementation that authenticates txs using Schnorr signatures. */ @@ -287,7 +287,7 @@ Let's try creating a new account backed by our account contract, and interact wi To create and deploy the account, we will use the `AccountManager` class, which takes an instance of an Private Execution Environment (PXE), a [privacy private key](../../../../aztec/concepts/accounts/keys.md#incoming-viewing-keys), and an instance of our `AccountContract` class: -```typescript title="account-contract-deploy" showLineNumbers +```typescript title="account-contract-deploy" showLineNumbers const secretKey = Fr.random(); const account = await AccountManager.create(pxe, secretKey, new SchnorrHardcodedKeyAccountContract()); @@ -308,7 +308,7 @@ const address = wallet.getAddress(); Note that we used a funded wallet to deploy the account contract and pay for the transaction fee. The new account doesn't have any funds yet. We will continue using the funded wallet to deploy the token contract: -```typescript title="token-contract-deploy" showLineNumbers +```typescript title="token-contract-deploy" showLineNumbers const token = await TokenContract.deploy(fundedWallet, fundedWallet.getAddress(), 'TokenName', 'TokenSymbol', 18) .send() .deployed(); @@ -328,7 +328,7 @@ If we run this, we get `Balance of wallet is now 150`, which shows that the `min To make sure that we are actually validating the provided signature in our account contract, we can try signing with a different key. To do this, we will set up a new `Account` instance pointing to the contract we already deployed but using a wrong signing key: -```typescript title="account-contract-fails" showLineNumbers +```typescript title="account-contract-fails" showLineNumbers const wrongKey = GrumpkinScalar.random(); const wrongAccountContract = new SchnorrHardcodedKeyAccountContract(wrongKey); const wrongAccount = await AccountManager.create(pxe, secretKey, wrongAccountContract, account.salt); diff --git a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/js_tutorials/token_bridge.md b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/js_tutorials/token_bridge.md index f28f964fa6ca..a74bec2cea8d 100644 --- a/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/js_tutorials/token_bridge.md +++ b/docs/versioned_docs/version-v0.87.0/developers/tutorials/codealong/js_tutorials/token_bridge.md @@ -20,7 +20,7 @@ The first half of this page reviews the process and contracts for bridging token - sending tokens from L2 back to L1 - withdrawing tokens from the L1 portal -This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up v0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. +This tutorial is compatible with the Aztec version `v0.87.0`. Install the correct version with `aztec-up 0.87.0`. Or if you'd like to use a different version, you can find the relevant tutorial by clicking the version dropdown at the top of the page. ## Components @@ -75,7 +75,7 @@ Note that because L1 is public, everyone can inspect and figure out the contentH #### `depositToAztecPublic` (TokenPortal.sol) -```solidity title="deposit_public" showLineNumbers +```solidity title="deposit_public" showLineNumbers /** * @notice Deposit funds into the portal and adds an L2 message which can only be consumed publicly on Aztec * @param _to - The aztec address of the recipient @@ -92,7 +92,7 @@ function depositToAztecPublic(bytes32 _to, uint256 _amount, bytes32 _secretHash) #### `depositToAztecPrivate` (TokenPortal.sol) -```solidity title="deposit_private" showLineNumbers +```solidity title="deposit_private" showLineNumbers /** * @notice Deposit funds into the portal and adds an L2 message which can only be consumed privately on Aztec * @param _amount - The amount to deposit @@ -116,7 +116,7 @@ The previous code snippets moved funds to the bridge and created a L1->L2 messag This happens inside the `TokenBridge` contract on Aztec. -```rust title="claim_public" showLineNumbers +```rust title="claim_public" showLineNumbers // Consumes a L1->L2 message and calls the token contract to mint the appropriate amount publicly #[public] fn claim_public(to: AztecAddress, amount: u128, secret: Field, message_leaf_index: Field) { @@ -154,7 +154,7 @@ For both the public and private flow, we use the same mechanism to determine the #### `exit_to_L1_public` (TokenBridge.nr) -```rust title="exit_to_l1_public" showLineNumbers +```rust title="exit_to_l1_public" showLineNumbers // Burns the appropriate amount of tokens and creates a L2 to L1 withdraw message publicly // Requires `msg.sender` to give approval to the bridge to burn tokens on their behalf using witness signatures #[public] @@ -181,7 +181,7 @@ fn exit_to_l1_public( This function works very similarly to the public version, except here we burn user’s private notes. -```rust title="exit_to_l1_private" showLineNumbers +```rust title="exit_to_l1_private" showLineNumbers // Burns the appropriate amount of tokens and creates a L2 to L1 withdraw message privately // Requires `msg.sender` (caller of the method) to give approval to the bridge to burn tokens on their behalf using witness signatures #[private] @@ -218,7 +218,7 @@ A user must sign an approval message to let the contract burn tokens on their be After the transaction is completed on L2, the portal must call the outbox to successfully transfer funds to the user on L1. Like with deposits, things can be complex here. For example, what happens if the transaction was done on L2 to burn tokens but can’t be withdrawn to L1? Then the funds are lost forever! How do we prevent this? -```solidity title="token_portal_withdraw" showLineNumbers +```solidity title="token_portal_withdraw" showLineNumbers /** * @notice Withdraw funds from the portal * @dev Second part of withdraw, must be initiated from L2 first as it will consume a message from outbox @@ -336,7 +336,7 @@ You can run the script we will build in `index.ts` at any point with `yarn start Add the following imports to your `index.ts`: -```typescript title="imports" showLineNumbers +```typescript title="imports" showLineNumbers import { getInitialTestAccountsWallets } from '@aztec/accounts/testing'; import { EthAddress, @@ -368,7 +368,7 @@ import { getContract } from 'viem'; Add the following utility functions to your `index.ts` below the imports: -```typescript title="utils" showLineNumbers +```typescript title="utils" showLineNumbers const MNEMONIC = 'test test test test test test test test test test test junk'; const { ETHEREUM_HOSTS = 'http://localhost:8545' } = process.env; @@ -452,7 +452,7 @@ Run the script with `yarn start` and you should see the L1 contract addresses pr Add the following code to `index.ts` to deploy the L2 token contract: -```typescript title="deploy-l2-token" showLineNumbers +```typescript title="deploy-l2-token" showLineNumbers const l2TokenContract = await TokenContract.deploy(ownerWallet, ownerAztecAddress, 'L2 Token', 'L2', 18) .send() .deployed(); @@ -463,7 +463,7 @@ logger.info(`L2 token contract deployed at ${l2TokenContract.address}`); Add the following code to `index.ts` to deploy the L1 token contract and set up the `L1TokenManager` (a utility class to interact with the L1 token contract): -```typescript title="deploy-l1-token" showLineNumbers +```typescript title="deploy-l1-token" showLineNumbers const l1TokenContract = await deployTestERC20(); logger.info('erc20 contract deployed'); @@ -477,7 +477,7 @@ const l1TokenManager = new L1TokenManager(l1TokenContract, feeAssetHandler, l1Cl Add the following code to `index.ts` to deploy the L1 portal contract: -```typescript title="deploy-portal" showLineNumbers +```typescript title="deploy-portal" showLineNumbers const l1PortalContractAddress = await deployTokenPortal(); logger.info('L1 portal contract deployed'); @@ -492,7 +492,7 @@ const l1Portal = getContract({ Add the following code to `index.ts` to deploy the L2 bridge contract: -```typescript title="deploy-l2-bridge" showLineNumbers +```typescript title="deploy-l2-bridge" showLineNumbers const l2BridgeContract = await TokenBridgeContract.deploy( ownerWallet, l2TokenContract.address, @@ -511,7 +511,7 @@ Run `yarn start` to confirm that all of the contracts are deployed. Add the following code to `index.ts` to authorize the L2 bridge contract to mint tokens on the L2 token contract: -```typescript title="authorize-l2-bridge" showLineNumbers +```typescript title="authorize-l2-bridge" showLineNumbers await l2TokenContract.methods.set_minter(l2BridgeContract.address, true).send().wait(); ``` > Source code: yarn-project/end-to-end/src/composed/e2e_token_bridge_tutorial_test.test.ts#L133-L135 @@ -519,7 +519,7 @@ await l2TokenContract.methods.set_minter(l2BridgeContract.address, true).send(). Add the following code to `index.ts` to set up the L1 portal contract and `L1TokenPortalManager` (a utility class to interact with the L1 portal contract): -```typescript title="setup-portal" showLineNumbers +```typescript title="setup-portal" showLineNumbers await l1Portal.write.initialize( [l1ContractAddresses.registryAddress.toString(), l1TokenContract.toString(), l2BridgeContract.address.toString()], {}, @@ -542,7 +542,7 @@ const l1PortalManager = new L1TokenPortalManager( Add the following code to `index.ts` to bridge tokens from L1 to L2: -```typescript title="l1-bridge-public" showLineNumbers +```typescript title="l1-bridge-public" showLineNumbers const claim = await l1PortalManager.bridgeTokensPublic(ownerAztecAddress, MINT_AMOUNT, true); // Do 2 unrleated actions because @@ -559,7 +559,7 @@ We have to send two additional transactions because the network must process 2 b Add the following code to `index.ts` to claim the tokens publicly on Aztec: -```typescript title="claim" showLineNumbers +```typescript title="claim" showLineNumbers await l2BridgeContract.methods .claim_public(ownerAztecAddress, MINT_AMOUNT, claim.claimSecret, claim.messageLeafIndex) .send() @@ -576,7 +576,7 @@ Run `yarn start` to confirm that tokens are claimed on Aztec. Add the following code to `index.ts` to start the withdraw the tokens to L1: -```typescript title="setup-withdrawal" showLineNumbers +```typescript title="setup-withdrawal" showLineNumbers const withdrawAmount = 9n; const nonce = Fr.random(); @@ -597,7 +597,7 @@ We have to send a public authwit to allow the bridge contract to burn tokens on Add the following code to `index.ts` to start the withdraw process on Aztec: -```typescript title="l2-withdraw" showLineNumbers +```typescript title="l2-withdraw" showLineNumbers const l2ToL1Message = await l1PortalManager.getL2ToL1MessageLeaf( withdrawAmount, EthAddress.fromString(ownerEthAddress), @@ -617,7 +617,7 @@ logger.info(`New L2 balance of ${ownerAztecAddress} is ${newL2Balance}`); Add the following code to `index.ts` to complete the withdraw process on L1: -```typescript title="l1-withdraw" showLineNumbers +```typescript title="l1-withdraw" showLineNumbers const [l2ToL1MessageIndex, siblingPath] = await pxe.getL2ToL1MembershipWitness( await pxe.getBlockNumber(), l2ToL1Message,