From 53e048ff54964b68efac06683e91e9554fff7b56 Mon Sep 17 00:00:00 2001 From: benesjan Date: Wed, 29 Oct 2025 18:24:35 +0000 Subject: [PATCH] refactor: introducing ContractSelf --- boxes/boxes/react/src/contracts/src/main.nr | 6 +- boxes/boxes/vanilla/contracts/src/main.nr | 30 +-- boxes/boxes/vite/src/contracts/src/main.nr | 6 +- .../functions/attributes.md | 22 +- .../docs/resources/migration_notes.md | 134 +++++++++++ .../contracts/bob_token_contract/src/main.nr | 64 +++--- .../contracts/counter_contract/src/main.nr | 6 +- .../contracts/aztec/nft/src/main.nr | 22 +- .../contracts/aztec/nft_bridge/src/main.nr | 10 +- .../aztec-nr/aztec/src/authwit/account.nr | 21 +- .../aztec-nr/aztec/src/contract_self.nr | 215 ++++++++++++++++++ noir-projects/aztec-nr/aztec/src/lib.nr | 1 + .../aztec-nr/aztec/src/macros/aztec.nr | 2 +- .../aztec/src/macros/functions/utils.nr | 142 +++++++----- .../aztec-nr/aztec/src/state_vars/map.nr | 2 +- .../ecdsa_k_account_contract/src/main.nr | 18 +- .../ecdsa_r_account_contract/src/main.nr | 18 +- .../schnorr_account_contract/src/main.nr | 27 ++- .../src/main.nr | 6 +- .../src/main.nr | 6 +- .../simulated_account_contract/src/main.nr | 4 +- .../contracts/app/amm_contract/src/main.nr | 112 +++++---- .../app/app_subscription_contract/src/main.nr | 29 +-- .../contracts/app/auth_contract/src/main.nr | 20 +- .../app/card_game_contract/src/main.nr | 46 ++-- .../contracts/app/claim_contract/src/main.nr | 18 +- .../app/crowdfunding_contract/src/main.nr | 33 ++- .../contracts/app/escrow_contract/src/main.nr | 8 +- .../app/lending_contract/src/main.nr | 137 +++++------ .../contracts/app/nft_contract/src/main.nr | 81 +++---- .../app/orderbook_contract/src/main.nr | 41 ++-- .../app/price_feed_contract/src/main.nr | 4 +- .../app/private_token_contract/src/main.nr | 8 +- .../app/private_voting_contract/src/main.nr | 33 +-- .../app/simple_token_contract/src/main.nr | 127 ++++++----- .../app/token_blacklist_contract/src/main.nr | 106 +++++---- .../app/token_bridge_contract/src/main.nr | 41 ++-- .../contracts/app/token_contract/src/main.nr | 180 ++++++++------- .../app/uniswap_contract/src/main.nr | 53 ++--- .../docs/docs_example_contract/src/main.nr | 65 +++--- .../contracts/fees/fpc_contract/src/main.nr | 61 +++-- .../fees/sponsored_fpc_contract/src/main.nr | 4 +- .../auth_registry_contract/src/main.nr | 34 +-- .../contract_class_registry/src/main.nr | 28 +-- .../contract_instance_registry/src/main.nr | 27 +-- .../protocol/fee_juice_contract/src/main.nr | 14 +- .../src/main.nr | 2 +- .../protocol/router_contract/src/main.nr | 8 +- .../test/auth_wit_test_contract/src/main.nr | 4 +- .../avm_initializer_test_contract/src/main.nr | 4 +- .../test/avm_test_contract/src/main.nr | 155 ++++++------- .../test/benchmarking_contract/src/main.nr | 12 +- .../contracts/test/child_contract/src/main.nr | 52 ++--- .../test/counter_contract/src/main.nr | 16 +- .../test/event_only_contract/src/main.nr | 10 +- .../test/import_test_contract/src/main.nr | 6 +- .../test/no_constructor_contract/src/main.nr | 10 +- .../test/note_getter_contract/src/main.nr | 8 +- .../test/offchain_effect_contract/src/main.nr | 14 +- .../test/parent_contract/src/main.nr | 80 +++---- .../pending_note_hashes_contract/src/main.nr | 58 ++--- .../public_immutable_contract/src/main.nr | 6 +- .../contracts/test/spam_contract/src/main.nr | 20 +- .../test/state_vars_contract/src/main.nr | 56 ++--- .../test/stateful_test_contract/src/main.nr | 38 ++-- .../test/static_child_contract/src/main.nr | 30 +-- .../test/static_parent_contract/src/main.nr | 48 ++-- .../contracts/test/test_contract/src/main.nr | 99 ++++---- .../test/test_log_contract/src/main.nr | 40 +--- .../test/updatable_contract/src/main.nr | 21 +- .../test/updated_contract/src/main.nr | 12 +- 71 files changed, 1600 insertions(+), 1281 deletions(-) create mode 100644 noir-projects/aztec-nr/aztec/src/contract_self.nr diff --git a/boxes/boxes/react/src/contracts/src/main.nr b/boxes/boxes/react/src/contracts/src/main.nr index c28b742d4db5..ea7c649ac562 100644 --- a/boxes/boxes/react/src/contracts/src/main.nr +++ b/boxes/boxes/react/src/contracts/src/main.nr @@ -18,7 +18,7 @@ contract BoxReact { #[external("private")] #[initializer] fn constructor(number: Field, owner: AztecAddress) { - let numbers = storage.numbers; + let numbers = self.storage.numbers; let new_number = ValueNote::new(number, owner); numbers.at(owner).initialize(new_number).emit( @@ -29,7 +29,7 @@ contract BoxReact { #[external("private")] fn setNumber(number: Field, owner: AztecAddress) { - let numbers = storage.numbers; + let numbers = self.storage.numbers; numbers.at(owner) .replace(|_old| { @@ -44,7 +44,7 @@ contract BoxReact { #[external("utility")] unconstrained fn getNumber(owner: AztecAddress) -> ValueNote { - let numbers = storage.numbers; + let numbers = self.storage.numbers; numbers.at(owner).view_note() } } diff --git a/boxes/boxes/vanilla/contracts/src/main.nr b/boxes/boxes/vanilla/contracts/src/main.nr index 2831b8e6b1df..08748e29a607 100644 --- a/boxes/boxes/vanilla/contracts/src/main.nr +++ b/boxes/boxes/vanilla/contracts/src/main.nr @@ -29,39 +29,39 @@ pub contract PrivateVoting { #[external("public")] #[initializer] fn constructor(admin: AztecAddress) { - storage.admin.write(admin); - storage.vote_ended.write(false); - storage.active_at_block.initialize(context.block_number()); + self.storage.admin.write(admin); + self.storage.vote_ended.write(false); + self.storage.active_at_block.initialize(self.context.block_number()); } #[external("private")] fn cast_vote(candidate: Field) { - let msg_sender_npk_m_hash = get_public_keys(context.msg_sender().unwrap()).npk_m.hash(); + let msg_sender_npk_m_hash = get_public_keys(self.context.msg_sender().unwrap()).npk_m.hash(); - let secret = context.request_nsk_app(msg_sender_npk_m_hash); // get secret key of caller of function - let nullifier = std::hash::pedersen_hash([context.msg_sender().unwrap().to_field(), secret]); // derive nullifier from sender and secret - context.push_nullifier(nullifier); - PrivateVoting::at(context.this_address()).add_to_tally_public(candidate).enqueue( - &mut context, + let secret = self.context.request_nsk_app(msg_sender_npk_m_hash); // get secret key of caller of function + let nullifier = std::hash::pedersen_hash([self.msg_sender().unwrap().to_field(), secret]); // derive nullifier from sender and secret + self.context.push_nullifier(nullifier); + PrivateVoting::at(self.address).add_to_tally_public(candidate).enqueue( + self.context, ); } #[external("public")] #[internal] fn add_to_tally_public(candidate: Field) { - assert(storage.vote_ended.read() == false, "Vote has ended"); // assert that vote has not ended - let new_tally = storage.tally.at(candidate).read() + 1; - storage.tally.at(candidate).write(new_tally); + assert(self.storage.vote_ended.read() == false, "Vote has ended"); // assert that vote has not ended + let new_tally = self.storage.tally.at(candidate).read() + 1; + self.storage.tally.at(candidate).write(new_tally); } #[external("public")] fn end_vote() { - assert(storage.admin.read().eq(context.msg_sender().unwrap()), "Only admin can end votes"); // assert that caller is admin - storage.vote_ended.write(true); + assert(self.storage.admin.read().eq(self.msg_sender().unwrap()), "Only admin can end votes"); // assert that caller is admin + self.storage.vote_ended.write(true); } #[external("utility")] unconstrained fn get_vote(candidate: Field) -> Field { - storage.tally.at(candidate).read() + self.storage.tally.at(candidate).read() } } diff --git a/boxes/boxes/vite/src/contracts/src/main.nr b/boxes/boxes/vite/src/contracts/src/main.nr index c1741aa7805c..bf1fc5a20996 100644 --- a/boxes/boxes/vite/src/contracts/src/main.nr +++ b/boxes/boxes/vite/src/contracts/src/main.nr @@ -18,7 +18,7 @@ contract BoxReact { #[external("private")] #[initializer] fn constructor(number: Field, owner: AztecAddress) { - let numbers = storage.numbers; + let numbers = self.storage.numbers; let mut new_number = ValueNote::new(number, owner); numbers.at(owner).initialize(new_number).emit( @@ -29,7 +29,7 @@ contract BoxReact { #[external("private")] fn setNumber(number: Field, owner: AztecAddress) { - let numbers = storage.numbers; + let numbers = self.storage.numbers; numbers.at(owner) @@ -43,7 +43,7 @@ contract BoxReact { #[external("utility")] unconstrained fn getNumber(owner: AztecAddress) -> ValueNote { - let numbers = storage.numbers; + let numbers = self.storage.numbers; numbers.at(owner).view_note() } } diff --git a/docs/docs/developers/docs/aztec-nr/framework-description/functions/attributes.md b/docs/docs/developers/docs/aztec-nr/framework-description/functions/attributes.md index 23337209b85b..3cd6b29e37fe 100644 --- a/docs/docs/developers/docs/aztec-nr/framework-description/functions/attributes.md +++ b/docs/docs/developers/docs/aztec-nr/framework-description/functions/attributes.md @@ -53,27 +53,27 @@ The contract function must return information about the execution back to the ke This structure contains a host of information about the executed program. It will contain any newly created nullifiers, any messages to be sent to l2 and most importantly it will contain the return values of the function. -**Hashing the function inputs.** -#include_code context-example-hasher /noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr rust - -_What is the hasher and why is it needed?_ -Inside the kernel circuits, the inputs to functions are reduced to a single value; the inputs hash. This prevents the need for multiple different kernel circuits; each supporting differing numbers of inputs. The hasher abstraction that allows us to create an array of all of the inputs that can be reduced to a single value. +**Creating the function's `self.`** +#include_code contract_self_creation /noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr rust -**Creating the function's context.** -#include_code context-example-context /noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr rust - -Each Aztec function has access to a [context](context) object. This object, although labelled a global variable, is created locally on a users' device. It is initialized from the inputs provided by the kernel, and a hash of the function's inputs. +Each Aztec function has access to a `self` object. Upon creation it accepts storage and context. Context is initialized from the inputs provided by the kernel, and a hash of the function's inputs. #include_code context-example-context-return /noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr rust We use the kernel to pass information between circuits. This means that the return values of functions must also be passed to the kernel (where they can be later passed on to another function). We achieve this by pushing return values to the execution context, which we then pass to the kernel. +**Hashing the function inputs.** + +Inside the kernel circuits, the inputs to functions are reduced to a single value; the inputs hash. This prevents the need for multiple different kernel circuits; each supporting differing numbers of inputs. Hashing the inputs allows to reduce all of the inputs to a single value. + **Making the contract's storage available** -#include_code storage-example-context /noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr rust -When a `Storage` struct is declared within a contract, the `storage` keyword is made available. As shown in the macro expansion above, this calls the init function on the storage struct with the current function's context. +Each `self` has a `storage` variable exposed on it. +When a `Storage` struct is declared within a contract, the `self.storage` contains real variables. + +If Storage is note defined `self.storage` contains only a placeholder value. Any state variables declared in the `Storage` struct can now be accessed as normal struct members. diff --git a/docs/docs/developers/docs/resources/migration_notes.md b/docs/docs/developers/docs/resources/migration_notes.md index 17e3fe723018..28cea99e4cf3 100644 --- a/docs/docs/developers/docs/resources/migration_notes.md +++ b/docs/docs/developers/docs/resources/migration_notes.md @@ -197,6 +197,140 @@ The following commands were dropped from the `aztec` command: ## [Aztec.nr] +### Introducing `self` in contracts + +Aztec contracts now automatically inject a `self` parameter into every contract function, providing a unified interface for accessing the contract's address, storage, and execution context. + +#### What is `self`? + +`self` is an instance of `ContractSelf` that provides: + +- `self.address` - The contract's own address +- `self.storage` - Access to your contract's storage +- `self.context` - The execution context (private, public, or utility) +- `self.msg_sender()` - Get the address of the caller +- `self.emit(...)` - Emit events + +And soon to be implemented also: +- `self.call(...)` - Make contract calls + +#### How it works + +The `#[external(...)]` macro automatically injects `self` into your function. When you write: + +```noir +#[external("private")] +fn transfer(amount: u128, recipient: AztecAddress) { + let sender = self.msg_sender().unwrap(); + self.storage.balances.at(sender).sub(amount); + self.storage.balances.at(recipient).add(amount); +} +``` + +The macro transforms it to initialize `self` with the context and storage before your code executes. + +#### Migration guide + +**Before:** Access context and storage as separate parameters + +```noir +#[external("private")] +fn old_transfer(amount: u128, recipient: AztecAddress) { + let storage = Storage::init(context); + let sender = context.msg_sender().unwrap(); + storage.balances.at(sender).sub(amount); +} +``` + +**After:** Use `self` to access everything + +```noir +#[external("private")] +fn new_transfer(amount: u128, recipient: AztecAddress) { + let sender = self.msg_sender().unwrap(); + self.storage.balances.at(sender).sub(amount); +} +``` + +#### Key changes + +1. **Storage and context access:** + +Storage and context are no longer injected into the function as standalone variables and instead you need to access them via `self`: + + ```diff + - let balance = storage.balances.at(owner).read(); + + let balance = self.storage.balances.at(owner).read(); + ``` + + ```diff + - context.push_nullifier(nullifier); + + self.context.push_nullifier(nullifier); + ``` + +Note that `context` is expected to be use only when needing to access a low-level API (like directly emitting a nullifier). + +2. **Getting caller address:** Use `self.msg_sender()` instead of `context.msg_sender()` + + ```diff + - let caller = context.msg_sender().unwrap(); + + let caller = self.msg_sender().unwrap(); + ``` + +3. **Getting contract address:** Use `self.address` instead of `context.this_address()` + + ```diff + - let this_contract = context.this_address(); + + let this_contract = self.address; + ``` + +4. **Emitting events:** + + In private functions: + + ```diff + - emit_event_in_private(event, context, recipient, delivery_mode); + + self.emit(event, recipient, delivery_mode); + ``` + + In public functions: + + ```diff + - emit_event_in_public(event, context); + + self.emit(event); + ``` + +#### Example: Full contract migration + +**Before:** + +```noir +#[external("private")] +fn withdraw(amount: u128, recipient: AztecAddress) { + let storage = Storage::init(context); + let sender = context.msg_sender().unwrap(); + let token = storage.donation_token.get_note().get_address(); + + // ... withdrawal logic + + emit_event_in_private(Withdraw { withdrawer, amount }, context, withdrawer, MessageDelivery.UNCONSTRAINED_ONCHAIN); +} +``` + +**After:** + +```noir +#[external("private")] +fn withdraw(amount: u128, recipient: AztecAddress) { + let sender = self.msg_sender().unwrap(); + let token = self.storage.donation_token.get_note().get_address(); + + // ... withdrawal logic + + self.emit(Withdraw { withdrawer, amount }, withdrawer, MessageDelivery.UNCONSTRAINED_ONCHAIN); +} +``` + ### Replacing #[private], #[public], #[utility] with #[external(...)] macro The original naming was not great in that it did not sufficiently communicate what the given macro did. diff --git a/docs/examples/contracts/bob_token_contract/src/main.nr b/docs/examples/contracts/bob_token_contract/src/main.nr index ebeebadd4ded..c2a19f604b18 100644 --- a/docs/examples/contracts/bob_token_contract/src/main.nr +++ b/docs/examples/contracts/bob_token_contract/src/main.nr @@ -33,7 +33,7 @@ pub contract BobToken { #[external("public")] fn setup() { // Giggle becomes the owner who can mint mental health tokens - storage.owner.write(context.msg_sender().unwrap()); + self.storage.owner.write(self.msg_sender().unwrap()); } // docs:end:setup @@ -41,46 +41,46 @@ pub contract BobToken { #[external("public")] fn mint_public(employee: AztecAddress, amount: u64) { // Only Giggle can mint tokens - assert_eq(context.msg_sender().unwrap(), storage.owner.read(), "Only Giggle can mint BOB tokens"); + assert_eq(self.msg_sender().unwrap(), self.storage.owner.read(), "Only Giggle can mint BOB tokens"); // Add tokens to employee's public balance - let current_balance = storage.public_balances.at(employee).read(); - storage.public_balances.at(employee).write(current_balance + amount); + let current_balance = self.storage.public_balances.at(employee).read(); + self.storage.public_balances.at(employee).write(current_balance + amount); } // docs:end:mint_public // docs:start:transfer_public #[external("public")] fn transfer_public(to: AztecAddress, amount: u64) { - let sender = context.msg_sender().unwrap(); - let sender_balance = storage.public_balances.at(sender).read(); + let sender = self.msg_sender().unwrap(); + let sender_balance = self.storage.public_balances.at(sender).read(); assert(sender_balance >= amount, "Insufficient BOB tokens"); // Deduct from sender - storage.public_balances.at(sender).write(sender_balance - amount); + self.storage.public_balances.at(sender).write(sender_balance - amount); // Add to recipient - let recipient_balance = storage.public_balances.at(to).read(); - storage.public_balances.at(to).write(recipient_balance + amount); + let recipient_balance = self.storage.public_balances.at(to).read(); + self.storage.public_balances.at(to).write(recipient_balance + amount); } // docs:end:transfer_public // docs:start:transfer_ownership #[external("public")] fn transfer_ownership(new_owner: AztecAddress) { - assert_eq(context.msg_sender().unwrap(), storage.owner.read(), "Only current admin can transfer ownership"); - storage.owner.write(new_owner); + assert_eq(self.msg_sender().unwrap(), self.storage.owner.read(), "Only current admin can transfer ownership"); + self.storage.owner.write(new_owner); } // docs:end:transfer_ownership // docs:start:public_to_private #[external("private")] fn public_to_private(amount: u64) { - let sender = context.msg_sender().unwrap(); + let sender = self.msg_sender().unwrap(); // This will enqueue a public function to deduct from public balance - BobToken::at(context.this_address())._deduct_public_balance(sender, amount).enqueue(&mut context); + BobToken::at(self.address)._deduct_public_balance(sender, amount).enqueue(self.context); // Add to private balance - storage.private_balances.at(sender).add(amount, sender); + self.storage.private_balances.at(sender).add(amount, sender); } // docs:end:public_to_private @@ -88,9 +88,9 @@ pub contract BobToken { #[external("public")] #[internal] fn _deduct_public_balance(owner: AztecAddress, amount: u64) { - let balance = storage.public_balances.at(owner).read(); + let balance = self.storage.public_balances.at(owner).read(); assert(balance >= amount, "Insufficient public BOB tokens"); - storage.public_balances.at(owner).write(balance - amount); + self.storage.public_balances.at(owner).write(balance - amount); } // docs:end:_deduct_public_balance @@ -98,23 +98,23 @@ pub contract BobToken { // docs:start:transfer_private #[external("private")] fn transfer_private(to: AztecAddress, amount: u64) { - let sender = context.msg_sender().unwrap(); + let sender = self.msg_sender().unwrap(); // Spend sender's notes (consumes existing notes) - storage.private_balances.at(sender).sub(amount, sender); + self.storage.private_balances.at(sender).sub(amount, sender); // Create new notes for recipient - storage.private_balances.at(to).add(amount, to); + self.storage.private_balances.at(to).add(amount, to); } // docs:end:transfer_private // docs:start:check_balances #[external("utility")] unconstrained fn private_balance_of(owner: AztecAddress) -> Field { - storage.private_balances.at(owner).get_value() + self.storage.private_balances.at(owner).get_value() } #[external("utility")] unconstrained fn public_balance_of(owner: AztecAddress) -> pub u64 { - storage.public_balances.at(owner).read() + self.storage.public_balances.at(owner).read() } // docs:end:check_balances @@ -122,7 +122,7 @@ pub contract BobToken { #[external("public")] #[internal] fn _assert_is_owner(address: AztecAddress) { - assert_eq(address, storage.owner.read(), "Only Giggle can mint BOB tokens"); + assert_eq(address, self.storage.owner.read(), "Only Giggle can mint BOB tokens"); } // docs:end:_assert_is_owner @@ -130,12 +130,12 @@ pub contract BobToken { #[external("private")] fn mint_private(employee: AztecAddress, amount: u64) { // Enqueue ownership check (will revert if not Giggle) - BobToken::at(context.this_address()) - ._assert_is_owner(context.msg_sender().unwrap()) - .enqueue(&mut context); + BobToken::at(self.address) + ._assert_is_owner(self.msg_sender().unwrap()) + .enqueue(self.context); // If check passes, mint tokens privately - storage.private_balances.at(employee).add(amount, employee); + self.storage.private_balances.at(employee).add(amount, employee); } // docs:end:mint_private @@ -143,20 +143,20 @@ pub contract BobToken { // docs:start:private_to_public #[external("private")] fn private_to_public(amount: u64) { - let sender = context.msg_sender().unwrap(); + let sender = self.msg_sender().unwrap(); // Remove from private balance - storage.private_balances.at(sender).sub(amount, sender); + self.storage.private_balances.at(sender).sub(amount, sender); // Enqueue public credit - BobToken::at(context.this_address()) + BobToken::at(self.address) ._credit_public_balance(sender, amount) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] #[internal] fn _credit_public_balance(owner: AztecAddress, amount: u64) { - let balance = storage.public_balances.at(owner).read(); - storage.public_balances.at(owner).write(balance + amount); + let balance = self.storage.public_balances.at(owner).read(); + self.storage.public_balances.at(owner).write(balance + amount); } // docs:end:private_to_public } diff --git a/docs/examples/contracts/counter_contract/src/main.nr b/docs/examples/contracts/counter_contract/src/main.nr index 579209f13a06..65d81bda9959 100644 --- a/docs/examples/contracts/counter_contract/src/main.nr +++ b/docs/examples/contracts/counter_contract/src/main.nr @@ -25,7 +25,7 @@ pub contract Counter { #[external("private")] // We can name our initializer anything we want as long as it's marked as aztec(initializer) fn initialize(headstart: u64, owner: AztecAddress) { - let counters = storage.counters; + let counters = self.storage.counters; counters.at(owner).add(headstart, owner); } // docs:end:constructor @@ -34,7 +34,7 @@ pub contract Counter { #[external("private")] fn increment(owner: AztecAddress) { debug_log_format("Incrementing counter for owner {0}", [owner.to_field()]); - let counters = storage.counters; + let counters = self.storage.counters; counters.at(owner).add(1, owner); } // docs:end:increment @@ -42,7 +42,7 @@ pub contract Counter { // docs:start:get_counter #[external("utility")] unconstrained fn get_counter(owner: AztecAddress) -> Field { - storage.counters.at(owner).get_value() + self.storage.counters.at(owner).get_value() } // docs:end:get_counter } diff --git a/docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft/src/main.nr b/docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft/src/main.nr index 1ca73428d376..632930125d51 100644 --- a/docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft/src/main.nr +++ b/docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft/src/main.nr @@ -24,15 +24,15 @@ pub contract NFTPunk { #[external("public")] #[initializer] fn constructor(admin: AztecAddress) { - storage.admin.initialize(admin); + self.storage.admin.initialize(admin); } // docs:end:contract_setup // docs:start:set_minter #[external("public")] fn set_minter(minter: AztecAddress) { - assert(storage.admin.read().eq(context.msg_sender().unwrap()), "caller is not admin"); - storage.minter.initialize(minter); + assert(self.storage.admin.read().eq(self.msg_sender().unwrap()), "caller is not admin"); + self.storage.minter.initialize(minter); } // docs:end:set_minter @@ -40,28 +40,28 @@ pub contract NFTPunk { #[external("public")] #[internal] fn _mark_nft_exists(token_id: Field, exists: bool) { - storage.nfts.at(token_id).schedule_value_change(exists); + self.storage.nfts.at(token_id).schedule_value_change(exists); } // docs:end:mark_nft_exists // docs:start:mint #[external("private")] fn mint(to: AztecAddress, token_id: Field) { - assert(storage.minter.read().eq(context.msg_sender().unwrap()), "caller is not the authorized minter"); + assert(self.storage.minter.read().eq(self.msg_sender().unwrap()), "caller is not the authorized minter"); // we create an NFT note and insert it to the PrivateSet - a collection of notes meant to be read in private let new_nft = NFTNote::new(to, token_id); - storage.owners.at(to).insert(new_nft).emit( to, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.owners.at(to).insert(new_nft).emit( to, MessageDelivery.CONSTRAINED_ONCHAIN); // calling the internal public function above to indicate that the NFT is taken - NFTPunk::at(context.this_address())._mark_nft_exists(token_id, true).enqueue(&mut context); + NFTPunk::at(self.address)._mark_nft_exists(token_id, true).enqueue(self.context); } // docs:end:mint // docs:start:notes_of #[utility] unconstrained fn notes_of(from: AztecAddress) -> Field { - let notes = storage.owners.at(from).view_notes(NoteViewerOptions::new()); + let notes = self.storage.owners.at(from).view_notes(NoteViewerOptions::new()); notes.len() as Field } // docs:end:notes_of @@ -69,14 +69,14 @@ pub contract NFTPunk { // docs:start:burn #[external("private")] fn burn(from: AztecAddress, token_id: Field) { - assert(storage.minter.read().eq(context.msg_sender().unwrap()), "caller is not the authorized minter"); + assert(self.storage.minter.read().eq(self.msg_sender().unwrap()), "caller is not the authorized minter"); // from the NFTNote properties, selects token_id and compares it against the token_id to be burned let options = NoteGetterOptions::new().select(NFTNote::properties().token_id, Comparator.EQ, token_id).set_limit(1); - let notes = storage.owners.at(from).pop_notes(options); + let notes = self.storage.owners.at(from).pop_notes(options); assert(notes.len() == 1, "NFT not found"); - NFTPunk::at(context.this_address())._mark_nft_exists(token_id, false).enqueue(&mut context); + NFTPunk::at(self.address)._mark_nft_exists(token_id, false).enqueue(self.context); } // docs:end:burn } diff --git a/docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft_bridge/src/main.nr b/docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft_bridge/src/main.nr index 1ff37bec4254..054fecbf850f 100644 --- a/docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft_bridge/src/main.nr +++ b/docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft_bridge/src/main.nr @@ -19,12 +19,12 @@ pub contract NFTBridge { #[external("public")] #[initializer] fn constructor(nft: AztecAddress) { - storage.nft.initialize(nft); + self.storage.nft.initialize(nft); } #[external("public")] fn set_portal(portal: EthAddress) { - storage.portal.initialize(portal); + self.storage.portal.initialize(portal); } // docs:end:bridge_setup @@ -39,12 +39,12 @@ pub contract NFTBridge { context.consume_l1_to_l2_message( content_hash, secret, - storage.portal.read(), + self.storage.portal.read(), message_leaf_index ); // Mint the NFT on L2 - let nft = storage.nft.read(); + let nft = self.storage.nft.read(); NFTPunk::at(nft).mint(to, token_id).call(&mut context); } // docs:end:claim @@ -62,7 +62,7 @@ pub contract NFTBridge { context.message_portal(storage.portal.read(), content); // Burn the NFT on L2 - let nft = storage.nft.read(); + let nft = self.storage.nft.read(); NFTPunk::at(nft).burn(context.msg_sender().unwrap(), token_id).call(&mut context); } // docs:end:exit diff --git a/noir-projects/aztec-nr/aztec/src/authwit/account.nr b/noir-projects/aztec-nr/aztec/src/authwit/account.nr index 8dbd94efb3ef..7b68d3f318a2 100644 --- a/noir-projects/aztec-nr/aztec/src/authwit/account.nr +++ b/noir-projects/aztec-nr/aztec/src/authwit/account.nr @@ -43,15 +43,20 @@ impl AccountActions<&mut PrivateContext> { /// /// @param app_payload The payload that contains the calls to be executed in the app phase. /// - /// @param is_fee_payer Allows the account contract to set itself as fee payer, using its FeeJuice balance to pay - /// the transaction fee + /// @param fee_payment_method The mechanism via which the account contract will pay for the transaction: + /// - EXTERNAL (0): Signals that some other contract is in charge of paying the fee, nothing needs to be done. + /// - PREEXISTING_FEE_JUICE (1): Makes the account contract publicly pay for the transaction with its own FeeJuice + /// balance, which it must already have prior to this transaction. The contract will + /// set itself as the fee payer and end the setup phase. + /// - FEE_JUICE_WITH_CLAIM (2): Makes the account contract publicly pay for the transaction with its own FeeJuice + /// balance which is being claimed in the same transaction. The contract will set + /// itself as the fee payer but not end setup phase - this is done by the FeeJuice + /// contract after enqueuing a public call, which unlike most public calls is + /// whitelisted to be executable during setup. /// - /// @param end_setup If paying transactions with fee juice, the account contract itself usually has to signal the end of the setup phase since - /// no other contract will do it. This is configurable independe sntly of the previous flag because in the case of using - /// FeeJuiceWithClaim the account contract is the fee payer, but the end of the setup is handled by the FeeJuice contract. - /// - /// @param cancellable Controls whether to emit app_payload.tx_nonce as a nullifier, allowing a subsequent transaction to be - /// sent with a higher priority fee. This can be used to cancel the first transaction sent, assuming it hasn't been mined yet. + /// @param cancellable Controls whether to emit app_payload.tx_nonce as a nullifier, allowing a subsequent + /// transaction to be sent with a higher priority fee. This can be used to cancel the first transaction sent, + /// assuming it hasn't been mined yet. /// // docs:start:entrypoint pub fn entrypoint(self, app_payload: AppPayload, fee_payment_method: u8, cancellable: bool) { diff --git a/noir-projects/aztec-nr/aztec/src/contract_self.nr b/noir-projects/aztec-nr/aztec/src/contract_self.nr new file mode 100644 index 000000000000..a6ebbcd58440 --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/contract_self.nr @@ -0,0 +1,215 @@ +use crate::{ + context::{private_context::PrivateContext, public_context::PublicContext}, + event::{event_emission::emit_event_in_private, event_interface::EventInterface}, +}; +use super::{context::utility_context::UtilityContext, event::event_emission::emit_event_in_public}; +use protocol_types::{ + address::AztecAddress, constants::NULL_MSG_SENDER_CONTRACT_ADDRESS, traits::Serialize, +}; + +/// `ContractSelf` is the core interface for interacting with an Aztec contract's own state and context. +/// +/// This struct is automatically injected into every #[external(...)] contract function by the Aztec macro system and is +/// accessible through the `self` variable. +/// +/// # Usage in Contract Functions +/// +/// Once injected, you can use `self` to: +/// - Access storage: `self.storage.balances.at(owner).read()` +/// - Call contracts: `self.call(Token::at(address).transfer(recipient, amount))` +/// - Emit events: `self.emit(event, recipient, delivery_mode)` (private) or `self.emit(event)` (public) +/// - Get the contract address: `self.address` +/// - Get the caller: `self.msg_sender()` +/// - Access low-level Aztec.nr APIs through the context: `self.context` +/// +/// # Example +/// +/// ```noir +/// #[external("private")] +/// fn withdraw(amount: u128, recipient: AztecAddress) { +/// // Get the caller of this function +/// let sender = self.msg_sender().unwrap(); +/// +/// // Access storage +/// let token = self.storage.donation_token.get_note().get_address(); +/// +/// // Call contracts +/// self.call(Token::at(token).transfer(recipient, amount)); +/// } +/// ``` +/// +/// # Type Parameters +/// +/// - `Context`: The execution context type - either `&mut PrivateContext`, `&mut PublicContext`, or `UtilityContext` +/// - `Storage`: The contract's storage struct (defined with `#[storage]`), or `()` if the contract has no storage +pub struct ContractSelf { + /// The address of this contract + pub address: AztecAddress, + /// The contract's storage instance, representing the struct to which the `#[storage]` macro was applied in your + /// contract. If the contract has no storage, the type of this will be `()`. + /// + /// This storage instance is specialized for the current execution context (private, public, or utility) and + /// provides access to the contract's state variables. Each state variable accepts the context as a generic + /// parameter, which determines its available functionality. For example, a PublicImmutable variable can be read + /// from any context (public, private, or utility) but can only be written to from public contexts. + /// + /// # Developer Note + /// If you've arrived here while trying to access your contract's storage while the `Storage` generic type is set to + /// unit type `()`, it means you haven't yet defined a Storage struct using the #[storage] macro in your contract. + /// For guidance on setting this up, please refer to our docs: + /// https://docs.aztec.network/developers/docs/guides/smart_contracts/storage + pub storage: Storage, + /// The execution context whose type is determined by the #[external(...)] attribute of the contract function based + /// on the external function type (private, public, or utility). + pub context: Context, +} + +/// Implementation for `ContractSelf` in private execution contexts. +/// +/// This implementation is used when a contract function is marked with `#[external("private")]`. +/// Private functions execute client-side and generate zero-knowledge proofs of their execution. +impl ContractSelf<&mut PrivateContext, Storage> { + /// Creates a new `ContractSelf` instance for a private function. + /// + /// This constructor is called automatically by the macro system and should not be called directly. + pub fn new_private(context: &mut PrivateContext, storage: Storage) -> Self { + Self { context, storage, address: context.this_address() } + } + + /// Returns the contract address that initiated this function call. This is similar to `msg.sender` in Solidity. + /// + /// Important Note: Since Aztec doesn't have a concept of an EoA ( Externally-owned Account), the msg_sender is + /// "null" for the first function call of every transaction. The first function call of a tx is likely to be a call + /// to the user's account contract, so this quirk will most often be handled by account contract developers. + /// + /// # Returns + /// * `Option` - The address of the smart contract that called this function (be it an app contract or + /// a user's account contract). Returns `Option::none` for the first function call of the tx. No + /// other _private_ function calls in the tx will have a `none` msg_sender, but _public_ function calls might (see + /// the PublicContext). + /// + pub fn msg_sender(self) -> Option { + let maybe_msg_sender = self.context.msg_sender_unsafe(); + if maybe_msg_sender == NULL_MSG_SENDER_CONTRACT_ADDRESS { + Option::none() + } else { + Option::some(maybe_msg_sender) + } + } + + /// Emits an event from a private function. Private events can be delivered either via private logs or offchain + /// messages, with configurable encryption and tagging constraints. + /// + /// Events in private functions are encrypted and sent to a specific recipient. This ensures that only the intended + /// recipient can read the event data. + /// + /// # Parameters + /// - `event`: The event to emit (must implement `EventInterface` and `Serialize`) + /// - `recipient`: The address that should be able to decrypt and read this event + /// - `delivery_mode`: The delivery mode for the event (e.g., `MessageDelivery.CONSTRAINED_ONCHAIN`) + /// + /// # Example + /// ```noir + /// #[external("private")] + /// fn transfer(amount: u128, to: AztecAddress) { + /// // ... transfer logic ... + /// self.emit( + /// TransferEvent { from: sender, to, amount }, + /// to, + /// MessageDelivery.CONSTRAINED_ONCHAIN + /// ); + /// } + /// ``` + pub fn emit(&mut self, event: Event, recipient: AztecAddress, delivery_mode: u8) + where + Event: EventInterface + Serialize, + { + emit_event_in_private(event, self.context, recipient, delivery_mode); + } +} + +/// Implementation for `ContractSelf` in public execution contexts. +/// +/// This implementation is used when a contract function is marked with `#[external("public")]`. +/// Public functions are executed by the sequencer in the Aztec Virtual Machine (AVM) and can work only with public +/// state. +impl ContractSelf<&mut PublicContext, Storage> { + /// Creates a new `ContractSelf` instance for a public function. + /// + /// This constructor is called automatically by the macro system and should not be called directly. + /// + /// # Parameters + /// - `context`: A mutable reference to the public execution context + /// - `storage`: The contract's storage instance + pub fn new_public(context: &mut PublicContext, storage: Storage) -> Self { + Self { context, storage, address: context.this_address() } + } + + /// Returns the contract address that initiated this function call. + /// + /// This is similar to `msg.sender` in Solidity (hence the name). + /// + /// Important Note: If the calling function is a _private_ function, then it had the option of hiding its address + /// when enqueuing this public function call. In such cases, this `context.msg_sender()` method will return + /// `Option::none`. If the calling function is a _public_ function, it will always return an + /// `Option::some` (i.e. a non-null value). + /// + /// # Returns + /// * `Option` - The address of the smart contract that called this function (be it an app contract or + /// a user's account contract). + /// + /// # Advanced + /// * Value is provided by the AVM sender opcode + /// * In nested calls, this is the immediate caller, not the original transaction sender + /// + pub fn msg_sender(self: Self) -> Option { + // Safety: AVM opcodes are constrained by the AVM itself + let maybe_msg_sender = self.context.msg_sender_unsafe(); + if maybe_msg_sender == NULL_MSG_SENDER_CONTRACT_ADDRESS { + Option::none() + } else { + Option::some(maybe_msg_sender) + } + } + + /// Emits an event from a public function. + /// + /// Events in public functions are emitted in plaintext and are visible to everyone. + /// Unlike private events, they don't require a recipient parameter. + /// + /// # Parameters + /// - `event`: The event to emit (must implement `EventInterface` and `Serialize`) + /// + /// # Example + /// ```noir + /// #[external("public")] + /// fn publish_update(value: Field) { + /// // ... update logic ... + /// self.emit(UpdateEvent { value }); + /// } + /// ``` + pub fn emit(&mut self, event: Event) + where + Event: EventInterface + Serialize, + { + emit_event_in_public(event, self.context); + } +} + +/// Implementation for `ContractSelf` in utility execution contexts. +/// +/// This implementation is used when a contract function is marked with `#[external("utility")]`. +/// Utility functions are unconstrained functions that can read private state for offchain queries. +/// They are typically used for view functions that need to access private notes (e.g. a Token's balance_of function). +impl ContractSelf { + /// Creates a new `ContractSelf` instance for a utility function. + /// + /// This constructor is called automatically by the macro system and should not be called directly. + /// + /// # Parameters + /// - `context`: The utility execution context (not a mutable reference, as utility functions don't modify state) + /// - `storage`: The contract's storage instance + pub fn new_utility(context: UtilityContext, storage: Storage) -> Self { + Self { context, storage, address: context.this_address() } + } +} diff --git a/noir-projects/aztec-nr/aztec/src/lib.nr b/noir-projects/aztec-nr/aztec/src/lib.nr index 8e28420ff67e..9024440fed06 100644 --- a/noir-projects/aztec-nr/aztec/src/lib.nr +++ b/noir-projects/aztec-nr/aztec/src/lib.nr @@ -1,4 +1,5 @@ pub mod context; +pub mod contract_self; pub mod publish_contract_instance; pub mod hash; pub mod history; diff --git a/noir-projects/aztec-nr/aztec/src/macros/aztec.nr b/noir-projects/aztec-nr/aztec/src/macros/aztec.nr index 112aec3b90f1..363050dd42f3 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/aztec.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/aztec.nr @@ -276,7 +276,7 @@ comptime fn generate_process_message() -> Quoted { message_context: aztec::messages::processing::message_context::MessageContext, ) { aztec::messages::discovery::process_message::process_message_ciphertext( - context.this_address(), + self.address, _compute_note_hash_and_nullifier, message_ciphertext, message_context, diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/utils.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/utils.nr index 540c30f1f4f8..1b136308bd2e 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/utils.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/functions/utils.nr @@ -39,10 +39,29 @@ pub(crate) comptime fn transform_private(f: FunctionDefinition) { let (args_serialization, _, serialized_args_name) = derive_serialization_quotes(original_params, false); - let context_creation = quote { - $args_serialization - let args_hash = dep::aztec::hash::hash_args_array($serialized_args_name); - let mut context = dep::aztec::context::private_context::PrivateContext::new(inputs, args_hash); + let storage_init = if module_has_storage { + // Contract has Storage defined so we initialize it. + quote { + let storage = Storage::init(&mut context); + } + } else { + // Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelf requires a + // storage struct in its constructor. Using an Option type would lead to worse developer experience and higher + // constraint counts so we use the unit type `()` instead. + quote { + let storage = (); + } + }; + + let contract_self_creation = quote { + #[allow(unused_variables)] + let mut self = { + $args_serialization + let args_hash = aztec::hash::hash_args_array($serialized_args_name); + let mut context = aztec::context::private_context::PrivateContext::new(inputs, args_hash); + $storage_init + aztec::contract_self::ContractSelf::new_private(&mut context, storage) + }; }; let function_name = f.name(); @@ -50,7 +69,7 @@ pub(crate) comptime fn transform_private(f: FunctionDefinition) { // Modifications introduced by the different marker attributes. let internal_check = if is_fn_internal(f) { let assertion_message = f"Function {function_name} can only be called internally"; - quote { assert(context.msg_sender().unwrap() == context.this_address(), $assertion_message); } + quote { assert(self.msg_sender().unwrap() == self.address, $assertion_message); } } else { quote {} }; @@ -58,34 +77,23 @@ pub(crate) comptime fn transform_private(f: FunctionDefinition) { let view_check = if is_fn_view(f) { let assertion_message = f"Function {function_name} can only be called statically".as_ctstring().as_quoted_str(); - quote { assert(context.inputs.call_context.is_static_call, $assertion_message); } + quote { assert(self.context.inputs.call_context.is_static_call, $assertion_message); } } else { quote {} }; let (assert_initializer, mark_as_initialized) = if is_fn_initializer(f) { ( - quote { aztec::macros::functions::initialization_utils::assert_initialization_matches_address_preimage_private(context); }, - quote { aztec::macros::functions::initialization_utils::mark_as_initialized_private(&mut context); }, + quote { aztec::macros::functions::initialization_utils::assert_initialization_matches_address_preimage_private(*self.context); }, + quote { aztec::macros::functions::initialization_utils::mark_as_initialized_private(self.context); }, ) } else { (quote {}, quote {}) }; - let storage_init = if module_has_storage { - quote { - // Some functions don't access storage, but it'd be quite difficult to only inject this variable if it is - // referenced. We instead ignore 'unused variable' warnings for it. - #[allow(unused_variables)] - let storage = Storage::init(&mut context); - } - } else { - quote {} - }; - // Initialization checks are not included in contracts that don't have initializers. let init_check = if module_has_initializer & !is_fn_initializer(f) & !fn_has_noinitcheck(f) { - quote { aztec::macros::functions::initialization_utils::assert_is_initialized_private(&mut context); } + quote { aztec::macros::functions::initialization_utils::assert_is_initialized_private(self.context); } } else { quote {} }; @@ -129,7 +137,7 @@ pub(crate) comptime fn transform_private(f: FunctionDefinition) { quote { $return_value_assignment $return_serialization - context.set_return_hash($serialized_return_name); + self.context.set_return_hash($serialized_return_name); } } else { let (body_without_return, last_body_expr) = body.pop_back(); @@ -147,17 +155,16 @@ pub(crate) comptime fn transform_private(f: FunctionDefinition) { quote {} }; - let context_finish = quote { context.finish() }; + let context_finish = quote { self.context.finish() }; // A quote to be injected at the beginning of the function body. let to_prepend = quote { dep::aztec::oracle::version::assert_compatible_oracle_version(); - $context_creation + $contract_self_creation $assert_initializer $init_check $internal_check $view_check - $storage_init $message_discovery_call $authorize_once_check }; @@ -199,20 +206,38 @@ pub(crate) comptime fn transform_public(f: FunctionDefinition) { .join(quote {+}) }; + let storage_init = if module_has_storage { + quote { + let storage = Storage::init(&mut context); + } + } else { + // Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelf requires a + // storage struct in its constructor. Using an Option type would lead to worse developer experience and higher + // constraint counts so we use the unit type `()` instead. + quote { + let storage = (); + } + }; + // Unlike in the private case, in public the `context` does not need to receive the hash of the original params. - let context_creation = quote { - let mut context = dep::aztec::context::public_context::PublicContext::new(|| { - // We start from 1 because we skip the selector for the dispatch function. - let serialized_args : [Field; $args_len_quote] = dep::aztec::context::public_context::calldata_copy(1, $args_len_quote); - dep::aztec::hash::hash_args_array(serialized_args) - }); + let contract_self_creation = quote { + #[allow(unused_variables)] + let mut self = { + let mut context = dep::aztec::context::public_context::PublicContext::new(|| { + // We start from 1 because we skip the selector for the dispatch function. + let serialized_args : [Field; $args_len_quote] = dep::aztec::context::public_context::calldata_copy(1, $args_len_quote); + dep::aztec::hash::hash_args_array(serialized_args) + }); + $storage_init + aztec::contract_self::ContractSelf::new_public(&mut context, storage) + }; }; let name = f.name(); // Modifications introduced by the different marker attributes. let internal_check = if is_fn_internal(f) { let assertion_message = f"Function {name} can only be called internally"; - quote { assert(context.msg_sender().unwrap() == context.this_address(), $assertion_message); } + quote { assert(self.msg_sender().unwrap() == self.address, $assertion_message); } } else { quote {} }; @@ -221,34 +246,23 @@ pub(crate) comptime fn transform_public(f: FunctionDefinition) { let name = f.name(); let assertion_message = f"Function {name} can only be called statically".as_ctstring().as_quoted_str(); - quote { assert(context.is_static_call(), $assertion_message); } + quote { assert(self.context.is_static_call(), $assertion_message); } } else { quote {} }; let (assert_initializer, mark_as_initialized) = if is_fn_initializer(f) { ( - quote { aztec::macros::functions::initialization_utils::assert_initialization_matches_address_preimage_public(context); }, - quote { aztec::macros::functions::initialization_utils::mark_as_initialized_public(&mut context); }, + quote { aztec::macros::functions::initialization_utils::assert_initialization_matches_address_preimage_public(*self.context); }, + quote { aztec::macros::functions::initialization_utils::mark_as_initialized_public(self.context); }, ) } else { (quote {}, quote {}) }; - let storage_init = if module_has_storage { - // Some functions don't access storage, but it'd be quite difficult to only inject this variable if it is - // referenced. We instead ignore 'unused variable' warnings for it. - quote { - #[allow(unused_variables)] - let storage = Storage::init(&mut context); - } - } else { - quote {} - }; - // Initialization checks are not included in contracts that don't have initializers. let init_check = if module_has_initializer & !fn_has_noinitcheck(f) & !is_fn_initializer(f) { - quote { aztec::macros::functions::initialization_utils::assert_is_initialized_public(&mut context); } + quote { aztec::macros::functions::initialization_utils::assert_is_initialized_public(self.context); } } else { quote {} }; @@ -261,12 +275,11 @@ pub(crate) comptime fn transform_public(f: FunctionDefinition) { }; let to_prepend = quote { - $context_creation + $contract_self_creation $assert_initializer $init_check $internal_check $view_check - $storage_init $authorize_once_check }; @@ -288,20 +301,28 @@ pub(crate) comptime fn transform_public(f: FunctionDefinition) { pub(crate) comptime fn transform_utility(f: FunctionDefinition) { register_utility_fn_stub(f); - // Create utility context - let context_creation = - quote { let mut context = dep::aztec::context::utility_context::UtilityContext::new(); }; - // Initialize Storage if module has storage let storage_init = if module_has_storage(f.module()) { quote { - // Some functions don't access storage, but it'd be quite difficult to only inject this variable if it is - // referenced. We instead ignore 'unused variable' warnings for it. - #[allow(unused_variables)] let storage = Storage::init(context); } } else { - quote {} + // Contract does not have Storage defined, so we set storage to the unit type `()`. ContractSelf requires a + // storage struct in its constructor. Using an Option type would lead to worse developer experience and higher + // constraint counts so we use the unit type `()` instead. + quote { + let storage = (); + } + }; + + // Create utility context + let contract_self_creation = quote { + #[allow(unused_variables)] + let mut self = { + let context = dep::aztec::context::utility_context::UtilityContext::new(); + $storage_init + aztec::contract_self::ContractSelf::new_utility(context, storage) + }; }; // All utility functions perform message discovery, since they may need to access private notes that would be @@ -312,8 +333,7 @@ pub(crate) comptime fn transform_utility(f: FunctionDefinition) { // A quote to be injected at the beginning of the function body. let to_prepend = quote { dep::aztec::oracle::version::assert_compatible_oracle_version(); - $context_creation - $storage_init + $contract_self_creation $message_discovery_call }; let body = f.body().as_block().unwrap(); @@ -331,7 +351,7 @@ pub(crate) comptime fn create_message_discovery_call() -> Quoted { /// always safe to call. unsafe { dep::aztec::messages::discovery::discover_new_messages( - context.this_address(), + self.address, _compute_note_hash_and_nullifier, ); }; @@ -419,8 +439,8 @@ pub(crate) comptime fn create_authorize_once_check( .as_ctstring() .as_quoted_str(); quote { - if (!$from_arg_name_quoted.eq(context.msg_sender().unwrap())) { - $fn_call(&mut context, $from_arg_name_quoted); + if (!$from_arg_name_quoted.eq(self.msg_sender().unwrap())) { + $fn_call(self.context, $from_arg_name_quoted); } else { assert($nonce_check_quote, $invalid_nonce_message); } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/map.nr b/noir-projects/aztec-nr/aztec/src/state_vars/map.nr index 1588a0ca7a50..dc29c8c42ba1 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/map.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/map.nr @@ -139,7 +139,7 @@ impl Map { /// /// ```noir /// // Get a user's balance (assuming PrivateMutable) - /// let user_balance = storage.balances.at(user_address); + /// let user_balance = self.storage.balances.at(user_address); /// let current_note = user_balance.get_note(); /// /// // Update the balance diff --git a/noir-projects/noir-contracts/contracts/account/ecdsa_k_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/account/ecdsa_k_account_contract/src/main.nr index e31c0b7039f3..98140bc6a1e9 100644 --- a/noir-projects/noir-contracts/contracts/account/ecdsa_k_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/account/ecdsa_k_account_contract/src/main.nr @@ -24,14 +24,14 @@ pub contract EcdsaKAccount { #[external("private")] #[initializer] fn constructor(signing_pub_key_x: [u8; 32], signing_pub_key_y: [u8; 32]) { - let this = context.this_address(); - let pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this); + let pub_key_note = + EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, self.address); // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs. // Since this value is only used for unconstrained tagging and not for any constrained logic, // it is safe to load from an unconstrained context. // TODO(#15752): Improve the sender_for_tags handling here when the original sender is undefined. - let original_sender = unsafe { get_sender_for_tags().unwrap_or(this) }; + let original_sender = unsafe { get_sender_for_tags().unwrap_or(self.address) }; // We set the sender for tags to this contract because we don't want to force the user corresponding to this // account to add the account deployer as a sender to their PXE. By setting it to this contract, user's PXE @@ -39,9 +39,9 @@ pub contract EcdsaKAccount { // `pxe.registerSender(accountDeployer)` was not called) // Safety: Comment from above applies here as well. - unsafe { set_sender_for_tags(this) }; - storage.signing_public_key.initialize(pub_key_note).emit( - this, + unsafe { set_sender_for_tags(self.address) }; + self.storage.signing_public_key.initialize(pub_key_note).emit( + self.address, MessageDelivery.CONSTRAINED_ONCHAIN, ); // Safety: Comment from above applies here as well. @@ -56,9 +56,9 @@ pub contract EcdsaKAccount { // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs. // Since this value is only used for unconstrained tagging and not for any constrained logic, // it is safe to set from a constrained context. - unsafe { set_sender_for_tags(context.this_address()) }; + unsafe { set_sender_for_tags(self.address) }; - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.entrypoint(app_payload, fee_payment_method, cancellable); } @@ -66,7 +66,7 @@ pub contract EcdsaKAccount { #[noinitcheck] #[view] fn verify_private_authwit(inner_hash: Field) -> Field { - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.verify_private_authwit(inner_hash) } diff --git a/noir-projects/noir-contracts/contracts/account/ecdsa_r_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/account/ecdsa_r_account_contract/src/main.nr index bf8d6c201fb6..9c33fb09e07e 100644 --- a/noir-projects/noir-contracts/contracts/account/ecdsa_r_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/account/ecdsa_r_account_contract/src/main.nr @@ -23,14 +23,14 @@ pub contract EcdsaRAccount { #[external("private")] #[initializer] fn constructor(signing_pub_key_x: [u8; 32], signing_pub_key_y: [u8; 32]) { - let this = context.this_address(); - let pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this); + let pub_key_note = + EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, self.address); // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs. // Since this value is only used for unconstrained tagging and not for any constrained logic, // it is safe to load from an unconstrained context. // TODO(#15752): Improve the sender_for_tags handling here when the original sender is undefined. - let original_sender = unsafe { get_sender_for_tags().unwrap_or(this) }; + let original_sender = unsafe { get_sender_for_tags().unwrap_or(self.address) }; // We set the sender for tags to this contract because we don't want to force the user corresponding to this // account to add the account deployer as a sender to their PXE. By setting it to this contract, user's PXE @@ -38,9 +38,9 @@ pub contract EcdsaRAccount { // `pxe.registerSender(accountDeployer)` was not called) // Safety: Comment from above applies here as well. - unsafe { set_sender_for_tags(this) }; - storage.signing_public_key.initialize(pub_key_note).emit( - this, + unsafe { set_sender_for_tags(self.address) }; + self.storage.signing_public_key.initialize(pub_key_note).emit( + self.address, MessageDelivery.CONSTRAINED_ONCHAIN, ); // Safety: Comment from above applies here as well. @@ -55,9 +55,9 @@ pub contract EcdsaRAccount { // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs. // Since this value is only used for unconstrained tagging and not for any constrained logic, // it is safe to set from a constrained context. - unsafe { set_sender_for_tags(context.this_address()) }; + unsafe { set_sender_for_tags(self.address) }; - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.entrypoint(app_payload, fee_payment_method, cancellable); } @@ -65,7 +65,7 @@ pub contract EcdsaRAccount { #[noinitcheck] #[view] fn verify_private_authwit(inner_hash: Field) -> Field { - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.verify_private_authwit(inner_hash) } diff --git a/noir-projects/noir-contracts/contracts/account/schnorr_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/account/schnorr_account_contract/src/main.nr index 0869399b83df..5100d859a187 100644 --- a/noir-projects/noir-contracts/contracts/account/schnorr_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/account/schnorr_account_contract/src/main.nr @@ -38,14 +38,13 @@ pub contract SchnorrAccount { #[external("private")] #[initializer] fn constructor(signing_pub_key_x: Field, signing_pub_key_y: Field) { - let this = context.this_address(); - let pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this); + let pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, self.address); // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs. // Since this value is only used for unconstrained tagging and not for any constrained logic, // it is safe to load from an unconstrained context. // TODO(#15752): Improve the sender_for_tags handling here when the original sender is undefined. - let original_sender = unsafe { get_sender_for_tags().unwrap_or(this) }; + let original_sender = unsafe { get_sender_for_tags().unwrap_or(self.address) }; // We set the sender for tags to this contract because we don't want to force the user corresponding to this // account to add the account deployer as a sender to their PXE. By setting it to this contract, user's PXE @@ -53,9 +52,9 @@ pub contract SchnorrAccount { // `pxe.registerSender(accountDeployer)` was not called) // Safety: Comment from above applies here as well. - unsafe { set_sender_for_tags(this) }; - storage.signing_public_key.initialize(pub_key_note).emit( - this, + unsafe { set_sender_for_tags(self.address) }; + self.storage.signing_public_key.initialize(pub_key_note).emit( + self.address, MessageDelivery.CONSTRAINED_ONCHAIN, ); // Safety: Comment from above applies here as well. @@ -70,9 +69,9 @@ pub contract SchnorrAccount { // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs. // Since this value is only used for unconstrained tagging and not for any constrained logic, // it is safe to set from a constrained context. - unsafe { set_sender_for_tags(context.this_address()) }; + unsafe { set_sender_for_tags(self.address) }; - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.entrypoint(app_payload, fee_payment_method, cancellable); } @@ -80,7 +79,7 @@ pub contract SchnorrAccount { #[noinitcheck] #[view] fn verify_private_authwit(inner_hash: Field) -> Field { - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.verify_private_authwit(inner_hash) } @@ -118,12 +117,12 @@ pub contract SchnorrAccount { */ #[external("utility")] unconstrained fn lookup_validity(consumer: AztecAddress, inner_hash: Field) -> bool { - let public_key = storage.signing_public_key.view_note(); + let public_key = self.storage.signing_public_key.view_note(); let message_hash = compute_authwit_message_hash( consumer, - context.chain_id(), - context.version(), + self.context.chain_id(), + self.context.version(), inner_hash, ); @@ -143,10 +142,10 @@ pub contract SchnorrAccount { // Compute the nullifier and check if it is spent // This will BLINDLY TRUST the oracle, but the oracle is us, and // it is not as part of execution of the contract, so we are good. - let nullifier = compute_authwit_nullifier(context.this_address(), inner_hash); + let nullifier = compute_authwit_nullifier(self.address, inner_hash); let siloed_nullifier = compute_siloed_nullifier(consumer, nullifier); let lower_wit = - get_low_nullifier_membership_witness(context.block_number(), siloed_nullifier); + get_low_nullifier_membership_witness(self.context.block_number(), siloed_nullifier); let is_spent = lower_wit.leaf_preimage.nullifier == siloed_nullifier; !is_spent & valid_in_private diff --git a/noir-projects/noir-contracts/contracts/account/schnorr_hardcoded_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/account/schnorr_hardcoded_account_contract/src/main.nr index a20d5a9fd84e..db1305cc98bc 100644 --- a/noir-projects/noir-contracts/contracts/account/schnorr_hardcoded_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/account/schnorr_hardcoded_account_contract/src/main.nr @@ -23,16 +23,16 @@ pub contract SchnorrHardcodedAccount { // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs. // Since this value is only used for unconstrained tagging and not for any constrained logic, // it is safe to set from a constrained context. - unsafe { set_sender_for_tags(context.this_address()) }; + unsafe { set_sender_for_tags(self.address) }; - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.entrypoint(app_payload, fee_payment_method, cancellable); } #[external("private")] #[view] fn verify_private_authwit(inner_hash: Field) -> Field { - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.verify_private_authwit(inner_hash) } diff --git a/noir-projects/noir-contracts/contracts/account/schnorr_single_key_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/account/schnorr_single_key_account_contract/src/main.nr index 8b41ca19d61f..6ccdd160922d 100644 --- a/noir-projects/noir-contracts/contracts/account/schnorr_single_key_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/account/schnorr_single_key_account_contract/src/main.nr @@ -21,16 +21,16 @@ pub contract SchnorrSingleKeyAccount { // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs. // Since this value is only used for unconstrained tagging and not for any constrained logic, // it is safe to set from a constrained context. - unsafe { set_sender_for_tags(context.this_address()) }; + unsafe { set_sender_for_tags(self.address) }; - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.entrypoint(app_payload, fee_payment_method, cancellable); } #[external("private")] #[view] fn verify_private_authwit(inner_hash: Field) -> Field { - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.verify_private_authwit(inner_hash) } diff --git a/noir-projects/noir-contracts/contracts/account/simulated_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/account/simulated_account_contract/src/main.nr index 6bfc21760b2f..ac1b8d30ab14 100644 --- a/noir-projects/noir-contracts/contracts/account/simulated_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/account/simulated_account_contract/src/main.nr @@ -21,9 +21,9 @@ pub contract SimulatedAccount { // Safety: The sender for tags is only used to compute unconstrained shared secrets for emitting logs. // Since this value is only used for unconstrained tagging and not for any constrained logic, // it is safe to set from a constrained context. - unsafe { set_sender_for_tags(context.this_address()) }; + unsafe { set_sender_for_tags(self.address) }; - let actions = AccountActions::init(&mut context, is_valid_impl); + let actions = AccountActions::init(self.context, is_valid_impl); actions.entrypoint(app_payload, fee_payment_method, cancellable); } diff --git a/noir-projects/noir-contracts/contracts/app/amm_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/amm_contract/src/main.nr index 796bc3b61d20..211f3d2d639a 100644 --- a/noir-projects/noir-contracts/contracts/app/amm_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/amm_contract/src/main.nr @@ -64,7 +64,7 @@ pub contract AMM { #[external("public")] #[initializer] fn constructor(token0: AztecAddress, token1: AztecAddress, liquidity_token: AztecAddress) { - storage.config.initialize(Config { token0, token1, liquidity_token }); + self.storage.config.initialize(Config { token0, token1, liquidity_token }); } /// Privately adds liquidity to the pool. This function receives the minimum and maximum number of tokens the caller @@ -93,13 +93,13 @@ pub contract AMM { ); assert((0 as u128 < amount0_max) & (0 as u128 < amount1_max), "INSUFFICIENT_INPUT_AMOUNTS"); - let config = storage.config.read(); + let config = self.storage.config.read(); let token0 = Token::at(config.token0); let token1 = Token::at(config.token1); let liquidity_token = Token::at(config.liquidity_token); - let sender = context.msg_sender().unwrap(); + let sender = self.msg_sender().unwrap(); // We don't yet know how many tokens the sender will actually supply - that can only be computed during public // execution since the amounts supplied must have the same ratio as the live balances. We therefore transfer the @@ -107,31 +107,31 @@ pub contract AMM { let refund_token0_partial_note = token0 .transfer_to_public_and_prepare_private_balance_increase( sender, - context.this_address(), + self.address, amount0_max, authwit_nonce, ) - .call(&mut context); + .call(self.context); let refund_token1_partial_note = token1 .transfer_to_public_and_prepare_private_balance_increase( sender, - context.this_address(), + self.address, amount1_max, authwit_nonce, ) - .call(&mut context); + .call(self.context); // The number of liquidity tokens to mint for the caller depends on both the live balances and the amount // supplied, both of which can only be known during public execution. We therefore prepare a partial note that // will get completed via minting. let liquidity_partial_note = - liquidity_token.prepare_private_balance_increase(sender).call(&mut context); + liquidity_token.prepare_private_balance_increase(sender).call(self.context); // We then complete the flow in public. Note that the type of operation and amounts will all be publicly known, // but the identity of the caller is not revealed despite us being able to send tokens to them by completing the // partial notes. - AMM::at(context.this_address()) + AMM::at(self.address) ._add_liquidity( config, refund_token0_partial_note, @@ -142,7 +142,7 @@ pub contract AMM { amount0_min, amount1_min, ) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] @@ -164,12 +164,10 @@ pub contract AMM { // We read the current AMM balance of both tokens. Note that by the time this function is called the token // transfers have already been completed (since those calls were enqueued before this call), and so we need to // subtract the transfer amount to get the pre-deposit balance. - let balance0_plus_amount0_max = - token0.balance_of_public(context.this_address()).view(&mut context); + let balance0_plus_amount0_max = token0.balance_of_public(self.address).view(self.context); let balance0 = balance0_plus_amount0_max - amount0_max; - let balance1_plus_amount1_max = - token1.balance_of_public(context.this_address()).view(&mut context); + let balance1_plus_amount1_max = token1.balance_of_public(self.address).view(self.context); let balance1 = balance1_plus_amount1_max - amount1_max; // With the current balances known, we can calculate the token amounts to the pool, respecting the user's @@ -192,17 +190,17 @@ pub contract AMM { if (refund_amount_token0 > 0 as u128) { token0 .finalize_transfer_to_private(refund_amount_token0, refund_token0_partial_note) - .call(&mut context); + .call(self.context); } if (refund_amount_token1 > 0 as u128) { token1 .finalize_transfer_to_private(refund_amount_token1, refund_token1_partial_note) - .call(&mut context); + .call(self.context); } // With the deposit amounts known, we can compute the number of liquidity tokens to mint and finalize the // depositor's partial note. - let total_supply = liquidity_token.total_supply().view(&mut context); + let total_supply = liquidity_token.total_supply().view(self.context); let liquidity_amount = if total_supply != 0 as u128 { // The liquidity token supply increases by the same ratio as the balances. In case one of the token balances // increased with a ratio different from the other one, we simply take the smallest value. @@ -220,7 +218,7 @@ pub contract AMM { // As part of initialization, we mint some tokens to the zero address to 'lock' them (i.e. make them // impossible to redeem), guaranteeing total supply will never be zero again. liquidity_token.mint_to_public(AztecAddress::zero(), MINIMUM_LIQUIDITY).call( - &mut context, + self.context, ); INITIAL_LIQUIDITY @@ -228,7 +226,7 @@ pub contract AMM { assert(liquidity_amount > 0 as u128, "INSUFFICIENT_LIQUIDITY_MINTED"); liquidity_token.finalize_mint_to_private(liquidity_amount, liquidity_partial_note).call( - &mut context, + self.context, ); } @@ -246,33 +244,33 @@ pub contract AMM { amount1_min: u128, authwit_nonce: Field, ) { - let config = storage.config.read(); + let config = self.storage.config.read(); let liquidity_token = Token::at(config.liquidity_token); let token0 = Token::at(config.token0); let token1 = Token::at(config.token1); - let sender = context.msg_sender().unwrap(); + let sender = self.msg_sender().unwrap(); // Liquidity tokens are burned when liquidity is removed in order to reduce the total supply. However, we lack // a function to privately burn, so we instead transfer the tokens into the AMM's public balance, and then have // the AMM publicly burn its own tokens. // TODO(#10287): consider adding a private burn - liquidity_token - .transfer_to_public(sender, context.this_address(), liquidity, authwit_nonce) - .call(&mut context); + liquidity_token.transfer_to_public(sender, self.address, liquidity, authwit_nonce).call( + self.context, + ); // We don't yet know how many tokens the sender will get - that can only be computed during public execution // since the it depends on the live balances. We therefore simply prepare partial notes to the sender. let token0_partial_note = - token0.prepare_private_balance_increase(sender).call(&mut context); + token0.prepare_private_balance_increase(sender).call(self.context); let token1_partial_note = - token1.prepare_private_balance_increase(sender).call(&mut context); + token1.prepare_private_balance_increase(sender).call(self.context); // We then complete the flow in public. Note that the type of operation and amounts will all be publicly known, // but the identity of the caller is not revealed despite us being able to send tokens to them by completing the // partial notes. - AMM::at(context.this_address()) + AMM::at(self.address) ._remove_liquidity( config, liquidity, @@ -281,7 +279,7 @@ pub contract AMM { amount0_min, amount1_min, ) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] @@ -300,9 +298,9 @@ pub contract AMM { // We need the current balance of both tokens as well as the liquidity token total supply in order to compute // the amounts to send the user. - let balance0 = token0.balance_of_public(context.this_address()).view(&mut context); - let balance1 = token1.balance_of_public(context.this_address()).view(&mut context); - let total_supply = liquidity_token.total_supply().view(&mut context); + let balance0 = token0.balance_of_public(self.address).view(self.context); + let balance1 = token1.balance_of_public(self.address).view(self.context); + let total_supply = liquidity_token.total_supply().view(self.context); // We calculate the amounts of token0 and token1 the user is entitled to based on the amount of liquidity they // are removing, and check that they are above the minimum amounts they requested. @@ -312,9 +310,9 @@ pub contract AMM { // We can now burn the liquidity tokens that had been privately transferred into the AMM, as well as complete // both partial notes. - liquidity_token.burn_public(context.this_address(), liquidity, 0).call(&mut context); - token0.finalize_transfer_to_private(amount0, token0_partial_note).call(&mut context); - token1.finalize_transfer_to_private(amount1, token1_partial_note).call(&mut context); + liquidity_token.burn_public(self.address, liquidity, 0).call(self.context); + token0.finalize_transfer_to_private(amount0, token0_partial_note).call(self.context); + token1.finalize_transfer_to_private(amount1, token1_partial_note).call(self.context); } /// Privately swaps `amount_in` `token_in` tokens for at least `amount_out_mint` `token_out` tokens with the pool. @@ -331,23 +329,23 @@ pub contract AMM { amount_out_min: u128, authwit_nonce: Field, ) { - let config = storage.config.read(); + let config = self.storage.config.read(); assert((token_in == config.token0) | (token_in == config.token1), "TOKEN_IN_IS_INVALID"); assert((token_out == config.token0) | (token_out == config.token1), "TOKEN_OUT_IS_INVALID"); assert(token_in != token_out, "SAME_TOKEN_SWAP"); - let sender = context.msg_sender().unwrap(); + let sender = self.msg_sender().unwrap(); // We transfer the full amount in, since it is an exact amount, and prepare a partial note for the amount out, // which will only be known during public execution as it depends on the live balances. - Token::at(token_in) - .transfer_to_public(sender, context.this_address(), amount_in, authwit_nonce) - .call(&mut context); + Token::at(token_in).transfer_to_public(sender, self.address, amount_in, authwit_nonce).call( + self.context, + ); let token_out_partial_note = - Token::at(token_out).prepare_private_balance_increase(sender).call(&mut context); + Token::at(token_out).prepare_private_balance_increase(sender).call(self.context); - AMM::at(context.this_address()) + AMM::at(self.address) ._swap_exact_tokens_for_tokens( token_in, token_out, @@ -355,7 +353,7 @@ pub contract AMM { amount_out_min, token_out_partial_note, ) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] @@ -371,18 +369,17 @@ pub contract AMM { // transfer has already been completed as that function call was enqueued before this one. We therefore need to // subtract the amount in to get the pre-swap balances. let balance_in_plus_amount_in = - Token::at(token_in).balance_of_public(context.this_address()).view(&mut context); + Token::at(token_in).balance_of_public(self.address).view(self.context); let balance_in = balance_in_plus_amount_in - amount_in; - let balance_out = - Token::at(token_out).balance_of_public(context.this_address()).view(&mut context); + let balance_out = Token::at(token_out).balance_of_public(self.address).view(self.context); // We can now compute the number of tokens to transfer and complete the partial note. let amount_out = get_amount_out(amount_in, balance_in, balance_out); assert(amount_out >= amount_out_min, "INSUFFICIENT_OUTPUT_AMOUNT"); Token::at(token_out).finalize_transfer_to_private(amount_out, token_out_partial_note).call( - &mut context, + self.context, ); } @@ -400,13 +397,13 @@ pub contract AMM { amount_in_max: u128, authwit_nonce: Field, ) { - let config = storage.config.read(); + let config = self.storage.config.read(); assert((token_in == config.token0) | (token_in == config.token1), "TOKEN_IN_IS_INVALID"); assert((token_out == config.token0) | (token_out == config.token1), "TOKEN_OUT_IS_INVALID"); assert(token_in != token_out, "SAME_TOKEN_SWAP"); - let sender = context.msg_sender().unwrap(); + let sender = self.msg_sender().unwrap(); // We don't know how many tokens we'll receive from the user, since the swap amount will only be known during // public execution as it depends on the live balances. We therefore transfer the full maximum amount and @@ -417,16 +414,16 @@ pub contract AMM { let change_token_in_partial_note = Token::at(token_in) .transfer_to_public_and_prepare_private_balance_increase( sender, - context.this_address(), + self.address, amount_in_max, authwit_nonce, ) - .call(&mut context); + .call(self.context); let token_out_partial_note = - Token::at(token_out).prepare_private_balance_increase(sender).call(&mut context); + Token::at(token_out).prepare_private_balance_increase(sender).call(self.context); - AMM::at(context.this_address()) + AMM::at(self.address) ._swap_tokens_for_exact_tokens( token_in, token_out, @@ -435,7 +432,7 @@ pub contract AMM { change_token_in_partial_note, token_out_partial_note, ) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] @@ -452,11 +449,10 @@ pub contract AMM { // transfer has already been completed as that function call was enqueued before this one. We therefore need to // subtract the amount in to get the pre-swap balances. let balance_in_plus_amount_in_max = - Token::at(token_in).balance_of_public(context.this_address()).view(&mut context); + Token::at(token_in).balance_of_public(self.address).view(self.context); let balance_in = balance_in_plus_amount_in_max - amount_in_max; - let balance_out = - Token::at(token_out).balance_of_public(context.this_address()).view(&mut context); + let balance_out = Token::at(token_out).balance_of_public(self.address).view(self.context); // We can now compute the number of tokens we need to receive and complete the partial note with the change. let amount_in = get_amount_in(amount_out, balance_in, balance_out); @@ -466,13 +462,13 @@ pub contract AMM { if (change > 0 as u128) { Token::at(token_in) .finalize_transfer_to_private(change, change_token_in_partial_note) - .call(&mut context); + .call(self.context); } // Note again that we already knew the amount out, but for consistency we want to only commit this note once // all other steps have been performed. Token::at(token_out).finalize_transfer_to_private(amount_out, token_out_partial_note).call( - &mut context, + self.context, ); } diff --git a/noir-projects/noir-contracts/contracts/app/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/app_subscription_contract/src/main.nr index f369dc25e09d..42759b668c4f 100644 --- a/noir-projects/noir-contracts/contracts/app/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/app_subscription_contract/src/main.nr @@ -75,33 +75,33 @@ pub contract AppSubscription { // This function takes a generic argument that corresponds to the number of params // the parent takes. See aztec-nr/src/authwit/auth.nr for more details. - assert_current_call_valid_authwit::<2>(&mut context, user_address); + assert_current_call_valid_authwit::<2>(self.context, user_address); - let emission = storage.subscriptions.at(user_address).replace(|mut note| { + let emission = self.storage.subscriptions.at(user_address).replace(|mut note| { assert(note.remaining_txs > 0, "you're out of txs"); note.remaining_txs -= 1; note }); emission.emit(user_address, MessageDelivery.CONSTRAINED_ONCHAIN); - context.set_as_fee_payer(); + self.context.set_as_fee_payer(); - let config = storage.config.read(); + let config = self.storage.config.read(); // TODO(palla/gas) Assert fee_juice_limit_per_tx is less than this tx gas_limit let _gas_limit = config.fee_juice_limit_per_tx; - context.end_setup(); + self.context.end_setup(); // We check that the note is not expired. We do that via the router contract to conceal which contract // is performing the check. privately_check_block_number( Comparator.LT, emission.content.note.expiry_block_number, - &mut context, + self.context, ); - payload.execute_calls(&mut context, config.target_address); + payload.execute_calls(self.context, config.target_address); } #[external("public")] @@ -113,7 +113,7 @@ pub contract AppSubscription { subscription_price: u128, fee_juice_limit_per_tx: Field, ) { - storage.config.initialize( + self.storage.config.initialize( Config { target_address, subscription_recipient_address, @@ -133,26 +133,27 @@ pub contract AppSubscription { ) { assert(tx_count <= SUBSCRIPTION_TXS); - let config = storage.config.read(); + let config = self.storage.config.read(); Token::at(config.subscription_token_address) .transfer_in_private( - context.msg_sender().unwrap(), + self.msg_sender().unwrap(), config.subscription_recipient_address, config.subscription_price, authwit_nonce, ) - .call(&mut context); + .call(self.context); // Assert that the `current_block_number > expiry_block_number - SUBSCRIPTION_DURATION_IN_BLOCKS`. // --> We do that via the router contract to conceal which contract is performing the check. privately_check_block_number( Comparator.GT, expiry_block_number - SUBSCRIPTION_DURATION_IN_BLOCKS, - &mut context, + self.context, ); - storage + self + .storage .subscriptions .at(subscriber) .initialize_or_replace(|_| { @@ -163,6 +164,6 @@ pub contract AppSubscription { #[external("utility")] unconstrained fn is_initialized(subscriber: AztecAddress) -> bool { - storage.subscriptions.at(subscriber).is_initialized() + self.storage.subscriptions.at(subscriber).is_initialized() } } diff --git a/noir-projects/noir-contracts/contracts/app/auth_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/auth_contract/src/main.nr index afba10290e78..e6a990c8d1f7 100644 --- a/noir-projects/noir-contracts/contracts/app/auth_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/auth_contract/src/main.nr @@ -26,38 +26,38 @@ pub contract Auth { #[initializer] fn constructor(admin: AztecAddress) { assert(!admin.is_zero(), "invalid admin"); - storage.admin.initialize(admin); + self.storage.admin.initialize(admin); } #[external("public")] fn set_authorized(authorized: AztecAddress) { - assert_eq(storage.admin.read(), context.msg_sender().unwrap(), "caller is not admin"); - storage.authorized.schedule_value_change(authorized); + assert_eq(self.storage.admin.read(), self.msg_sender().unwrap(), "caller is not admin"); + self.storage.authorized.schedule_value_change(authorized); } // docs:start:public_getter #[external("public")] #[view] fn get_authorized() -> AztecAddress { - storage.authorized.get_current_value() + self.storage.authorized.get_current_value() } // docs:end:public_getter #[external("public")] #[view] fn get_scheduled_authorized() -> (AztecAddress, u64) { - storage.authorized.get_scheduled_value() + self.storage.authorized.get_scheduled_value() } #[external("public")] #[view] fn get_authorized_delay() -> pub u64 { - storage.authorized.get_current_delay() + self.storage.authorized.get_current_delay() } #[external("public")] fn set_authorized_delay(new_delay: u64) { - storage.authorized.schedule_delay_change(new_delay); + self.storage.authorized.schedule_delay_change(new_delay); } #[external("private")] @@ -66,13 +66,13 @@ pub contract Auth { // circuit will reject this tx if timestamp of the block being built is past the time horizon of // the DelayedPublicMutable, which is as far as the circuit can guarantee the value will not change from some // historical value (due to CHANGE_AUTHORIZED_DELAY). - let authorized = storage.authorized.get_current_value(); - assert_eq(authorized, context.msg_sender().unwrap(), "caller is not authorized"); + let authorized = self.storage.authorized.get_current_value(); + assert_eq(authorized, self.msg_sender().unwrap(), "caller is not authorized"); } #[external("private")] #[view] fn get_authorized_in_private() -> AztecAddress { - storage.authorized.get_current_value() + self.storage.authorized.get_current_value() } } diff --git a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/main.nr index de61ed0e365b..7c2583b7c815 100644 --- a/noir-projects/noir-contracts/contracts/app/card_game_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/card_game_contract/src/main.nr @@ -27,10 +27,10 @@ pub contract CardGame { fn buy_pack( seed: Field, // The randomness used to generate the cards. Passed in for now. ) { - let buyer = context.msg_sender().unwrap(); - let mut cards = get_pack_cards(seed, buyer, &mut context); + let buyer = self.msg_sender().unwrap(); + let mut cards = get_pack_cards(seed, buyer, self.context); - let mut collection = storage.collections.at(buyer); + let mut collection = self.storage.collections.at(buyer); let _inserted_cards = collection.add_cards(cards, buyer); } @@ -38,22 +38,22 @@ pub contract CardGame { fn join_game(game: u32, cards_fields: [Field; 2]) { let cards = cards_fields.map(|card_field| Card::from_field(card_field)); - let player = context.msg_sender().unwrap(); + let player = self.msg_sender().unwrap(); - let mut collection = storage.collections.at(player); + let mut collection = self.storage.collections.at(player); collection.remove_cards(cards); - let mut game_deck = storage.game_decks.at(game as Field).at(player); + let mut game_deck = self.storage.game_decks.at(game as Field).at(player); let _added_to_game_deck = game_deck.add_cards(cards, player); let strength = compute_deck_strength(cards); - CardGame::at(context.this_address()).on_game_joined(game, player, strength as u32).enqueue( - &mut context, + CardGame::at(self.address).on_game_joined(game, player, strength as u32).enqueue( + self.context, ); } #[external("public")] #[internal] fn on_game_joined(game: u32, player: AztecAddress, deck_strength: u32) { - let game_storage = storage.games.at(game as Field); + let game_storage = self.storage.games.at(game as Field); let mut game_data = game_storage.read(); assert( @@ -66,7 +66,7 @@ pub contract CardGame { #[external("public")] fn start_game(game: u32) { - let game_storage = storage.games.at(game as Field); + let game_storage = self.storage.games.at(game as Field); let mut game_data = game_storage.read(); game_data.start_game(); @@ -75,20 +75,20 @@ pub contract CardGame { #[external("private")] fn play_card(game: u32, card: Card) { - let player = context.msg_sender().unwrap(); + let player = self.msg_sender().unwrap(); - let mut game_deck = storage.game_decks.at(game as Field).at(player); + let mut game_deck = self.storage.game_decks.at(game as Field).at(player); game_deck.remove_cards([card]); - CardGame::at(context.this_address()).on_card_played(game, player, card.to_field()).enqueue( - &mut context, + CardGame::at(self.address).on_card_played(game, player, card.to_field()).enqueue( + self.context, ); } #[external("public")] #[internal] fn on_card_played(game: u32, player: AztecAddress, card_as_field: Field) { - let game_storage = storage.games.at(game as Field); + let game_storage = self.storage.games.at(game as Field); let mut game_data = game_storage.read(); @@ -102,20 +102,20 @@ pub contract CardGame { #[external("private")] fn claim_cards(game: u32, cards_fields: [Field; PLAYABLE_CARDS]) { - let player = context.msg_sender().unwrap(); + let player = self.msg_sender().unwrap(); let cards = cards_fields.map(|card_field| Card::from_field(card_field)); - let mut collection = storage.collections.at(player); + let mut collection = self.storage.collections.at(player); let _inserted_cards = collection.add_cards(cards, player); - CardGame::at(context.this_address()) + CardGame::at(self.address) .on_cards_claimed(game, player, pedersen_hash(cards_fields, 0)) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] #[internal] fn on_cards_claimed(game: u32, player: AztecAddress, cards_hash: Field) { - let game_storage = storage.games.at(game as Field); + let game_storage = self.storage.games.at(game as Field); let mut game_data = game_storage.read(); assert(!game_data.claimed, "Already claimed"); @@ -137,7 +137,7 @@ pub contract CardGame { owner: AztecAddress, offset: u32, ) -> BoundedVec { - let collection = storage.collections.at(owner); + let collection = self.storage.collections.at(owner); collection.view_cards(offset) } @@ -147,13 +147,13 @@ pub contract CardGame { player: AztecAddress, offset: u32, ) -> BoundedVec { - let game_deck = storage.game_decks.at(game as Field).at(player); + let game_deck = self.storage.game_decks.at(game as Field).at(player); game_deck.view_cards(offset) } #[external("utility")] unconstrained fn view_game(game: u32) -> Game { - storage.games.at(game as Field).read() + self.storage.games.at(game as Field).read() } } diff --git a/noir-projects/noir-contracts/contracts/app/claim_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/claim_contract/src/main.nr index 0bcd3fde34f9..f8798a2a7bae 100644 --- a/noir-projects/noir-contracts/contracts/app/claim_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/claim_contract/src/main.nr @@ -28,20 +28,20 @@ pub contract Claim { #[external("public")] #[initializer] fn constructor(target_contract: AztecAddress, reward_token: AztecAddress) { - storage.target_contract.initialize(target_contract); - storage.reward_token.initialize(reward_token); + self.storage.target_contract.initialize(target_contract); + self.storage.reward_token.initialize(reward_token); } #[external("private")] fn claim(proof_retrieved_note: RetrievedNote, recipient: AztecAddress) { // 1) Check that the note corresponds to the target contract and belongs to the sender - let target_address = storage.target_contract.read(); + let target_address = self.storage.target_contract.read(); let owner = proof_retrieved_note.note.get_owner(); assert( target_address == proof_retrieved_note.contract_address, "Note does not correspond to the target contract", ); - assert_eq(owner, context.msg_sender().unwrap(), "Note does not belong to the sender"); + assert_eq(owner, self.msg_sender().unwrap(), "Note does not belong to the sender"); // 2) Prove that the note hash exists in the note hash tree // Note: The note has been inserted into the donation_receipts set in a map under the owner address in @@ -50,7 +50,7 @@ pub contract Claim { Crowdfunding::storage_layout().donation_receipts.slot, owner, ); - let header = context.get_anchor_block_header(); + let header = self.context.get_anchor_block_header(); header.prove_note_inclusion(proof_retrieved_note, note_storage_slot); // 3) Compute and emit a nullifier which is unique to the note and this contract to ensure the reward can be @@ -63,12 +63,12 @@ pub contract Claim { let note_hash_for_nullification = compute_note_hash_for_nullification(proof_retrieved_note, note_storage_slot); let nullifier = - proof_retrieved_note.note.compute_nullifier(&mut context, note_hash_for_nullification); - context.push_nullifier(nullifier); + proof_retrieved_note.note.compute_nullifier(self.context, note_hash_for_nullification); + self.context.push_nullifier(nullifier); // 4) Finally we mint the reward token to the sender of the transaction - Token::at(storage.reward_token.read()) + Token::at(self.storage.reward_token.read()) .mint_to_public(recipient, proof_retrieved_note.note.get_value()) - .enqueue(&mut context); + .enqueue(self.context); } } diff --git a/noir-projects/noir-contracts/contracts/app/crowdfunding_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/crowdfunding_contract/src/main.nr index fda4d5ab23f3..71a95fbd9b97 100644 --- a/noir-projects/noir-contracts/contracts/app/crowdfunding_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/crowdfunding_contract/src/main.nr @@ -6,7 +6,6 @@ use aztec::macros::aztec; pub contract Crowdfunding { use crate::config::Config; use aztec::{ - event::event_emission::emit_event_in_public, macros::{events::event, functions::{external, initializer, internal}, storage::storage}, messages::message_delivery::MessageDelivery, protocol_types::address::AztecAddress, @@ -40,24 +39,24 @@ pub contract Crowdfunding { #[initializer] // this-will-error:init-header-error fn init(donation_token: AztecAddress, operator: AztecAddress, deadline: u64) { - storage.config.initialize(Config { donation_token, operator, deadline }); + self.storage.config.initialize(Config { donation_token, operator, deadline }); } #[external("private")] fn donate(amount: u128) { - let config = storage.config.read(); + let config = self.storage.config.read(); // 1) Check that the deadline has not passed --> we do that via the router contract to conceal which contract // is performing the check. // docs:start:call-check-deadline - privately_check_timestamp(Comparator.LT, config.deadline, &mut context); + privately_check_timestamp(Comparator.LT, config.deadline, self.context); // docs:end:call-check-deadline // 2) Transfer the donation tokens from donor to this contract - let donor = context.msg_sender().unwrap(); - Token::at(config.donation_token) - .transfer_in_private(donor, context.this_address(), amount, 0) - .call(&mut context); + let donor = self.msg_sender().unwrap(); + Token::at(config.donation_token).transfer_in_private(donor, self.address, amount, 0).call( + self.context, + ); // 3) Create a value note for the donor so that he can later on claim a rewards token in the Claim // contract by proving that the hash of this note exists in the note hash tree. @@ -65,7 +64,7 @@ pub contract Crowdfunding { // We don't constrain encryption because the donor is sending the note to himself. And hence by performing // encryption incorrectly would harm himself only. - storage.donation_receipts.at(donor).insert(note).emit( + self.storage.donation_receipts.at(donor).insert(note).emit( donor, MessageDelivery.UNCONSTRAINED_ONCHAIN, ); @@ -74,24 +73,24 @@ pub contract Crowdfunding { // Withdraws balance to the operator. Requires that msg_sender() is the operator. #[external("private")] fn withdraw(amount: u128) { - let config = storage.config.read(); + let config = self.storage.config.read(); let operator_address = config.operator; // 1) Check that msg_sender() is the operator - assert(context.msg_sender().unwrap() == operator_address, "Not an operator"); + assert(self.msg_sender().unwrap() == operator_address, "Not an operator"); // 2) Transfer the donation tokens from this contract to the operator - Token::at(config.donation_token).transfer(operator_address, amount).call(&mut context); + Token::at(config.donation_token).transfer(operator_address, amount).call(self.context); // 3) Emit a public event so that anyone can audit how much the operator has withdrawn - Crowdfunding::at(context.this_address()) - ._publish_donation_receipts(amount, operator_address) - .enqueue(&mut context); + Crowdfunding::at(self.address)._publish_donation_receipts(amount, operator_address).enqueue( + self.context, + ); } #[external("public")] #[internal] fn _publish_donation_receipts(amount: u128, to: AztecAddress) { - emit_event_in_public(WithdrawalProcessed { amount, who: to }, &mut context); + self.emit(WithdrawalProcessed { amount, who: to }); } #[external("utility")] @@ -99,7 +98,7 @@ pub contract Crowdfunding { donor: AztecAddress, page_index: u32, ) -> BoundedVec, MAX_NOTES_PER_PAGE> { - let storage_slot = storage.donation_receipts.at(donor).get_storage_slot(); + let storage_slot = self.storage.donation_receipts.at(donor).get_storage_slot(); // We bypass Aztec.nr's higher-level abstractions here to access the metadata available only in RetrievedNote // type that is not returned by view_notes function. We on the other hand need this metadata because we will diff --git a/noir-projects/noir-contracts/contracts/app/escrow_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/escrow_contract/src/main.nr index c045a48c4bbc..7206fd4c3939 100644 --- a/noir-projects/noir-contracts/contracts/app/escrow_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/escrow_contract/src/main.nr @@ -23,16 +23,16 @@ pub contract Escrow { #[initializer] fn constructor(owner: AztecAddress) { let note = AddressNote::new(owner, owner); - storage.owner.initialize(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.owner.initialize(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); } // Withdraws balance. Requires that msg.sender is the owner. #[external("private")] fn withdraw(token: AztecAddress, amount: u128, recipient: AztecAddress) { - let sender = context.msg_sender().unwrap(); + let sender = self.msg_sender().unwrap(); - let note = storage.owner.get_note(); + let note = self.storage.owner.get_note(); assert(note.get_address() == sender); - Token::at(token).transfer(recipient, amount).call(&mut context); + Token::at(token).transfer(recipient, amount).call(self.context); } } diff --git a/noir-projects/noir-contracts/contracts/app/lending_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/lending_contract/src/main.nr index 279259d9dfd1..db07d696c62a 100644 --- a/noir-projects/noir-contracts/contracts/app/lending_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/lending_contract/src/main.nr @@ -49,7 +49,7 @@ pub contract Lending { collateral_asset: AztecAddress, stable_coin: AztecAddress, ) { - let asset_loc = storage.assets.at(0); + let asset_loc = self.storage.assets.at(0); let asset: Asset = asset_loc.read(); let loan_to_value = loan_to_value; @@ -58,7 +58,7 @@ pub contract Lending { assert(asset.last_updated_ts == 0); assert(asset.interest_accumulator == 0 as u128); - let last_updated_ts = context.timestamp(); + let last_updated_ts = self.context.timestamp(); asset_loc.write( Asset { @@ -69,17 +69,17 @@ pub contract Lending { }, ); - storage.collateral_asset.write(collateral_asset); - storage.stable_coin.write(stable_coin); + self.storage.collateral_asset.write(collateral_asset); + self.storage.stable_coin.write(stable_coin); } // Create a position. #[external("public")] fn update_accumulator() -> Asset { - let asset_loc = storage.assets.at(0); + let asset_loc = self.storage.assets.at(0); let mut asset: Asset = asset_loc.read(); - let timestamp = context.timestamp(); + let timestamp = self.context.timestamp(); let dt = timestamp - asset.last_updated_ts; // Only update if time has passed. @@ -108,18 +108,15 @@ pub contract Lending { on_behalf_of: Field, collateral_asset: AztecAddress, ) { - let on_behalf_of = compute_identifier( - secret, - on_behalf_of, - context.msg_sender().unwrap().to_field(), - ); + let on_behalf_of = + compute_identifier(secret, on_behalf_of, self.msg_sender().unwrap().to_field()); let _res = Token::at(collateral_asset) - .transfer_to_public(from, context.this_address(), amount, authwit_nonce) - .call(&mut context); + .transfer_to_public(from, self.address, amount, authwit_nonce) + .call(self.context); // docs:start:enqueue_public - Lending::at(context.this_address()) + Lending::at(self.address) ._deposit(AztecAddress::from_field(on_behalf_of), amount, collateral_asset) - .enqueue(&mut context); + .enqueue(self.context); // docs:end:enqueue_public } @@ -131,56 +128,51 @@ pub contract Lending { collateral_asset: AztecAddress, ) { let _ = Token::at(collateral_asset) - .transfer_in_public( - context.msg_sender().unwrap(), - context.this_address(), - amount, - authwit_nonce, - ) - .call(&mut context); - let _ = Lending::at(context.this_address()) + .transfer_in_public(self.msg_sender().unwrap(), self.address, amount, authwit_nonce) + .call(self.context); + let _ = Lending::at(self.address) ._deposit(AztecAddress::from_field(on_behalf_of), amount, collateral_asset) - .call(&mut context); + .call(self.context); } #[external("public")] #[internal] fn _deposit(owner: AztecAddress, amount: u128, collateral_asset: AztecAddress) { - let _asset = Lending::at(context.this_address()).update_accumulator().call(&mut context); + let _asset = Lending::at(self.address).update_accumulator().call(self.context); - let coll_asset = storage.collateral_asset.read(); + let coll_asset = self.storage.collateral_asset.read(); assert(coll_asset.eq(collateral_asset)); - let coll_loc = storage.collateral.at(owner); + let coll_loc = self.storage.collateral.at(owner); let collateral = coll_loc.read(); coll_loc.write(collateral + amount); } #[external("private")] fn withdraw_private(secret: Field, to: AztecAddress, amount: u128) { - let on_behalf_of = compute_identifier(secret, 0, context.msg_sender().unwrap().to_field()); - Lending::at(context.this_address()) + let on_behalf_of = compute_identifier(secret, 0, self.msg_sender().unwrap().to_field()); + Lending::at(self.address) ._withdraw(AztecAddress::from_field(on_behalf_of), to, amount) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] fn withdraw_public(to: AztecAddress, amount: u128) { - let _ = Lending::at(context.this_address()) - ._withdraw(context.msg_sender().unwrap(), to, amount) - .call(&mut context); + let _ = Lending::at(self.address)._withdraw(self.msg_sender().unwrap(), to, amount).call( + self.context, + ); } #[external("public")] #[internal] fn _withdraw(owner: AztecAddress, recipient: AztecAddress, amount: u128) { - let asset = Lending::at(context.this_address()).update_accumulator().call(&mut context); - let price = PriceFeed::at(asset.oracle).get_price(0).view(&mut context).price; + let asset = Lending::at(self.address).update_accumulator().call(self.context); + let price = PriceFeed::at(asset.oracle).get_price(0).view(self.context).price; - let coll_loc = storage.collateral.at(owner); + let coll_loc = self.storage.collateral.at(owner); let collateral = coll_loc.read(); - let debt_loc = storage.static_debt.at(owner); + let debt_loc = self.storage.static_debt.at(owner); let static_debt = debt_loc.read(); // debt_covered will revert if decrease would leave insufficient collateral to cover debt. @@ -199,36 +191,36 @@ pub contract Lending { coll_loc.write(collateral - amount); // @todo @LHerskind Support both shielding and transfers (for now just transfer) - let collateral_asset = storage.collateral_asset.read(); + let collateral_asset = self.storage.collateral_asset.read(); let _ = Token::at(collateral_asset) - .transfer_in_public(context.this_address(), recipient, amount, 0) - .call(&mut context); + .transfer_in_public(self.address, recipient, amount, 0) + .call(self.context); } #[external("private")] fn borrow_private(secret: Field, to: AztecAddress, amount: u128) { - let on_behalf_of = compute_identifier(secret, 0, context.msg_sender().unwrap().to_field()); - let _ = Lending::at(context.this_address()) + let on_behalf_of = compute_identifier(secret, 0, self.msg_sender().unwrap().to_field()); + let _ = Lending::at(self.address) ._borrow(AztecAddress::from_field(on_behalf_of), to, amount) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] fn borrow_public(to: AztecAddress, amount: u128) { - let _ = Lending::at(context.this_address()) - ._borrow(context.msg_sender().unwrap(), to, amount) - .call(&mut context); + let _ = Lending::at(self.address)._borrow(self.msg_sender().unwrap(), to, amount).call( + self.context, + ); } #[external("public")] #[internal] fn _borrow(owner: AztecAddress, to: AztecAddress, amount: u128) { - let asset = Lending::at(context.this_address()).update_accumulator().call(&mut context); - let price = PriceFeed::at(asset.oracle).get_price(0).view(&mut context).price; + let asset = Lending::at(self.address).update_accumulator().call(self.context); + let price = PriceFeed::at(asset.oracle).get_price(0).view(self.context).price; // Fetch collateral and static_debt, compute health of current position - let collateral = storage.collateral.at(owner).read(); - let static_debt = storage.static_debt.at(owner).read(); + let collateral = self.storage.collateral.at(owner).read(); + let static_debt = self.storage.static_debt.at(owner).read(); let debt_covered = covered_by_collateral(price, asset.loan_to_value, collateral, 0 as u128, 0 as u128); @@ -236,11 +228,11 @@ pub contract Lending { assert(debt_returns.debt_value < debt_covered); - storage.static_debt.at(owner).write(debt_returns.static_debt); + self.storage.static_debt.at(owner).write(debt_returns.static_debt); // @todo @LHerskind Need to support both private and public minting. - let stable_coin = storage.stable_coin.read(); - let _ = Token::at(stable_coin).mint_to_public(to, amount).call(&mut context); + let stable_coin = self.storage.stable_coin.read(); + let _ = Token::at(stable_coin).mint_to_public(to, amount).call(self.context); } #[external("private")] @@ -252,17 +244,14 @@ pub contract Lending { on_behalf_of: Field, stable_coin: AztecAddress, ) { - let on_behalf_of = compute_identifier( - secret, - on_behalf_of, - context.msg_sender().unwrap().to_field(), - ); + let on_behalf_of = + compute_identifier(secret, on_behalf_of, self.msg_sender().unwrap().to_field()); // docs:start:private_call - let _ = Token::at(stable_coin).burn_private(from, amount, authwit_nonce).call(&mut context); + let _ = Token::at(stable_coin).burn_private(from, amount, authwit_nonce).call(self.context); // docs:end:private_call - let _ = Lending::at(context.this_address()) + let _ = Lending::at(self.address) ._repay(AztecAddress::from_field(on_behalf_of), amount, stable_coin) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] @@ -273,39 +262,37 @@ pub contract Lending { stable_coin: AztecAddress, ) { let _ = Token::at(stable_coin) - .burn_public(context.msg_sender().unwrap(), amount, authwit_nonce) - .call(&mut context); - let _ = Lending::at(context.this_address())._repay(owner, amount, stable_coin).call( - &mut context, - ); + .burn_public(self.msg_sender().unwrap(), amount, authwit_nonce) + .call(self.context); + let _ = Lending::at(self.address)._repay(owner, amount, stable_coin).call(self.context); } #[external("public")] #[internal] fn _repay(owner: AztecAddress, amount: u128, stable_coin: AztecAddress) { - let asset = Lending::at(context.this_address()).update_accumulator().call(&mut context); + let asset = Lending::at(self.address).update_accumulator().call(self.context); // To ensure that private is using the correct token. - assert(stable_coin.eq(storage.stable_coin.read())); + assert(stable_coin.eq(self.storage.stable_coin.read())); - let static_debt = storage.static_debt.at(owner).read(); + let static_debt = self.storage.static_debt.at(owner).read(); let debt_returns = debt_updates(asset.interest_accumulator, static_debt, 0 as u128, amount); - storage.static_debt.at(owner).write(debt_returns.static_debt); + self.storage.static_debt.at(owner).write(debt_returns.static_debt); } #[external("public")] #[view] fn get_asset(asset_id: Field) -> Asset { - storage.assets.at(asset_id).read() + self.storage.assets.at(asset_id).read() } #[external("public")] #[view] fn get_position(owner: AztecAddress) -> pub Position { - let collateral = storage.collateral.at(owner).read(); - let static_debt = storage.static_debt.at(owner).read(); - let asset: Asset = storage.assets.at(0).read(); + let collateral = self.storage.collateral.at(owner).read(); + let static_debt = self.storage.static_debt.at(owner).read(); + let asset: Asset = self.storage.assets.at(0).read(); let debt = debt_value(static_debt, asset.interest_accumulator); Position { collateral, static_debt, debt } } @@ -313,6 +300,6 @@ pub contract Lending { #[external("public")] #[view] fn get_assets() -> pub [AztecAddress; 2] { - [storage.collateral_asset.read(), storage.stable_coin.read()] + [self.storage.collateral_asset.read(), self.storage.stable_coin.read()] } } diff --git a/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr index 28d49f606330..1dbedc384ba4 100644 --- a/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/nft_contract/src/main.nr @@ -63,72 +63,75 @@ pub contract NFT { #[initializer] fn constructor(admin: AztecAddress, name: str<31>, symbol: str<31>) { assert(!admin.is_zero(), "invalid admin"); - storage.admin.write(admin); - storage.minters.at(admin).write(true); - storage.name.initialize(FieldCompressedString::from_string(name)); - storage.symbol.initialize(FieldCompressedString::from_string(symbol)); + self.storage.admin.write(admin); + self.storage.minters.at(admin).write(true); + self.storage.name.initialize(FieldCompressedString::from_string(name)); + self.storage.symbol.initialize(FieldCompressedString::from_string(symbol)); } // docs:end:constructor #[external("public")] fn set_admin(new_admin: AztecAddress) { - assert(storage.admin.read().eq(context.msg_sender().unwrap()), "caller is not an admin"); - storage.admin.write(new_admin); + assert(self.storage.admin.read().eq(self.msg_sender().unwrap()), "caller is not an admin"); + self.storage.admin.write(new_admin); } // docs:start:set_minter #[external("public")] fn set_minter(minter: AztecAddress, approve: bool) { - assert(storage.admin.read().eq(context.msg_sender().unwrap()), "caller is not an admin"); - storage.minters.at(minter).write(approve); + assert(self.storage.admin.read().eq(self.msg_sender().unwrap()), "caller is not an admin"); + self.storage.minters.at(minter).write(approve); } // docs:end:set_minter #[external("public")] fn mint(to: AztecAddress, token_id: Field) { assert(token_id != 0, "zero token ID not supported"); - assert(storage.minters.at(context.msg_sender().unwrap()).read(), "caller is not a minter"); - assert(storage.nft_exists.at(token_id).read() == false, "token already exists"); + assert( + self.storage.minters.at(self.msg_sender().unwrap()).read(), + "caller is not a minter", + ); + assert(self.storage.nft_exists.at(token_id).read() == false, "token already exists"); - storage.nft_exists.at(token_id).write(true); + self.storage.nft_exists.at(token_id).write(true); - storage.public_owners.at(token_id).write(to); + self.storage.public_owners.at(token_id).write(to); } #[external("public")] #[view] fn public_get_name() -> pub FieldCompressedString { - storage.name.read() + self.storage.name.read() } #[external("private")] #[view] fn private_get_name() -> pub FieldCompressedString { - storage.name.read() + self.storage.name.read() } #[external("public")] #[view] fn public_get_symbol() -> pub FieldCompressedString { - storage.symbol.read() + self.storage.symbol.read() } #[external("private")] #[view] fn private_get_symbol() -> pub FieldCompressedString { - storage.symbol.read() + self.storage.symbol.read() } #[external("public")] #[view] fn get_admin() -> Field { - storage.admin.read().to_field() + self.storage.admin.read().to_field() } #[external("public")] #[view] fn is_minter(minter: AztecAddress) -> bool { - storage.minters.at(minter).read() + self.storage.minters.at(minter).read() } #[authorize_once("from", "authwit_nonce")] @@ -139,7 +142,7 @@ pub contract NFT { token_id: Field, authwit_nonce: Field, ) { - let public_owners_storage = storage.public_owners.at(token_id); + let public_owners_storage = self.storage.public_owners.at(token_id); assert(public_owners_storage.read().eq(from), "invalid owner"); public_owners_storage.write(to); @@ -148,23 +151,23 @@ pub contract NFT { // Transfers token with `token_id` from public balance of message sender to a private balance of `to`. #[external("private")] fn transfer_to_private(to: AztecAddress, token_id: Field) { - let from = context.msg_sender().unwrap(); + let from = self.msg_sender().unwrap(); - let nft = NFT::at(context.this_address()); + let nft = NFT::at(self.address); // We prepare the private balance increase. - let partial_note = _prepare_private_balance_increase(to, &mut context, storage); + let partial_note = _prepare_private_balance_increase(to, self.context, self.storage); // At last we finalize the transfer. Usage of the `unsafe` method here is safe because we set the `from` // function argument to a message sender, guaranteeing that he can transfer only his own NFTs. - nft._finalize_transfer_to_private_unsafe(from, token_id, partial_note).enqueue(&mut context); + nft._finalize_transfer_to_private_unsafe(from, token_id, partial_note).enqueue(self.context); } /// Prepares an increase of private balance of `to` (partial note). The increase needs to be finalized by calling /// `finalize_transfer_to_private` with the returned partial note. #[external("private")] fn prepare_private_balance_increase(to: AztecAddress) -> PartialNFTNote { - _prepare_private_balance_increase(to, &mut context, storage) + _prepare_private_balance_increase(to, self.context, self.storage) } /// This function exists separately from `prepare_private_balance_increase` solely as an optimization as it allows @@ -202,13 +205,13 @@ pub contract NFT { fn finalize_transfer_to_private(token_id: Field, partial_note: PartialNFTNote) { // Completer is the entity that can complete the partial note. In this case, it's the same as the account // `from` from whose account the token is being transferred. - let from_and_completer = context.msg_sender().unwrap(); + let from_and_completer = self.msg_sender().unwrap(); _finalize_transfer_to_private( from_and_completer, token_id, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -226,8 +229,8 @@ pub contract NFT { from_and_completer, token_id, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -257,9 +260,9 @@ pub contract NFT { */ #[external("private")] fn cancel_authwit(inner_hash: Field) { - let on_behalf_of = context.msg_sender().unwrap(); + let on_behalf_of = self.msg_sender().unwrap(); let nullifier = compute_authwit_nullifier(on_behalf_of, inner_hash); - context.push_nullifier(nullifier); + self.context.push_nullifier(nullifier); } #[authorize_once("from", "authwit_nonce")] @@ -270,7 +273,7 @@ pub contract NFT { token_id: Field, authwit_nonce: Field, ) { - let nfts = storage.private_nfts; + let nfts = self.storage.private_nfts; let notes = nfts.at(from).pop_notes(NoteGetterOptions::new() .select(NFTNote::properties().token_id, Comparator.EQ, token_id) @@ -290,28 +293,26 @@ pub contract NFT { token_id: Field, authwit_nonce: Field, ) { - let notes = storage.private_nfts.at(from).pop_notes(NoteGetterOptions::new() + let notes = self.storage.private_nfts.at(from).pop_notes(NoteGetterOptions::new() .select(NFTNote::properties().token_id, Comparator.EQ, token_id) .set_limit(1)); assert(notes.len() == 1, "NFT not found when transferring to public"); - NFT::at(context.this_address())._finish_transfer_to_public(to, token_id).enqueue( - &mut context, - ); + NFT::at(self.address)._finish_transfer_to_public(to, token_id).enqueue(self.context); } #[external("public")] #[internal] fn _finish_transfer_to_public(to: AztecAddress, token_id: Field) { - storage.public_owners.at(token_id).write(to); + self.storage.public_owners.at(token_id).write(to); } // Returns zero address when the token does not have a public owner. Reverts if the token does not exist. #[external("public")] #[view] fn owner_of(token_id: Field) -> AztecAddress { - assert(storage.nft_exists.at(token_id).read(), "token does not exist"); - storage.public_owners.at(token_id).read() + assert(self.storage.nft_exists.at(token_id).read(), "token does not exist"); + self.storage.public_owners.at(token_id).read() } /// Returns an array of token IDs owned by `owner` in private and a flag indicating whether a page limit was @@ -324,7 +325,7 @@ pub contract NFT { ) -> ([Field; MAX_NOTES_PER_PAGE], bool) { let offset = page_index * MAX_NOTES_PER_PAGE; let mut options = NoteViewerOptions::new(); - let notes = storage.private_nfts.at(owner).view_notes(options.set_offset(offset)); + let notes = self.storage.private_nfts.at(owner).view_notes(options.set_offset(offset)); let mut owned_nft_ids = [0; MAX_NOTES_PER_PAGE]; for i in 0..options.limit { diff --git a/noir-projects/noir-contracts/contracts/app/orderbook_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/orderbook_contract/src/main.nr index 353a47652df8..29bbd7b3d5d1 100644 --- a/noir-projects/noir-contracts/contracts/app/orderbook_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/orderbook_contract/src/main.nr @@ -34,7 +34,6 @@ use aztec::macros::aztec; pub contract Orderbook { use crate::{config::Config, order::Order}; use aztec::{ - event::event_emission::emit_event_in_public, macros::{events::event, functions::{external, initializer, internal}, storage::storage}, oracle::notes::check_nullifier_exists, protocol_types::{address::AztecAddress, traits::{FromField, ToField}}, @@ -64,7 +63,7 @@ pub contract Orderbook { #[external("public")] #[initializer] fn constructor(token0: AztecAddress, token1: AztecAddress) { - storage.config.initialize(Config::new(token0, token1)); + self.storage.config.initialize(Config::new(token0, token1)); } /// Privately creates a new order in the orderbook @@ -77,22 +76,22 @@ pub contract Orderbook { ask_amount: u128, authwit_nonce: Field, ) -> Field { - let config = storage.config.read(); + let config = self.storage.config.read(); // Create the order (this validates the input tokens and amounts). let order = Order::new(config, bid_amount, ask_amount, bid_token, ask_token); - let maker = context.msg_sender().unwrap(); + let maker = self.msg_sender().unwrap(); // Transfer tokens from maker to the public balance of this contract. Token::at(bid_token) - .transfer_to_public(maker, context.this_address(), bid_amount, authwit_nonce) - .call(&mut context); + .transfer_to_public(maker, self.address, bid_amount, authwit_nonce) + .call(self.context); // Prepare a partial note that will get completed once the order is fulfilled. Note that only the Orderbook // contract can complete the partial note. let maker_partial_note = - Token::at(ask_token).prepare_private_balance_increase(maker).call(&mut context); + Token::at(ask_token).prepare_private_balance_increase(maker).call(self.context); // We use the partial note as the order ID. Because partial notes emit a nullifier when created they are // unique, and so this guarantees that our order IDs are also unique without having to keep track of past @@ -100,7 +99,7 @@ pub contract Orderbook { let order_id = maker_partial_note.to_field(); // Store the order in public storage and emit an event. - Orderbook::at(context.this_address())._create_order(order_id, order).enqueue(&mut context); + Orderbook::at(self.address)._create_order(order_id, order).enqueue(self.context); order_id } @@ -110,18 +109,18 @@ pub contract Orderbook { fn _create_order(order_id: Field, order: Order) { // Note that PublicImmutable can be initialized only once so this is a secondary check that the order is // unique. - storage.orders.at(order_id).initialize(order); + self.storage.orders.at(order_id).initialize(order); - emit_event_in_public(OrderCreated { order_id }, &mut context); + self.emit(OrderCreated { order_id }); } /// Privately fulfills an existing order in the orderbook /// The taker provides the order ID they want to fulfill #[external("private")] fn fulfill_order(order_id: Field, authwit_nonce: Field) { - let config = storage.config.read(); - let order = storage.orders.at(order_id).read(); - let taker = context.msg_sender().unwrap(); + let config = self.storage.config.read(); + let order = self.storage.orders.at(order_id).read(); + let taker = self.msg_sender().unwrap(); // Determine which tokens are being exchanged based on bid_token_is_zero flag let (bid_token, ask_token) = config.get_tokens(order.bid_token_is_zero); @@ -137,23 +136,23 @@ pub contract Orderbook { order.ask_amount, authwit_nonce, ) - .call(&mut context); + .call(self.context); // Prepare partial note for taker to receive bid_token let taker_partial_note = - Token::at(bid_token).prepare_private_balance_increase(taker).call(&mut context); + Token::at(bid_token).prepare_private_balance_increase(taker).call(self.context); // Nullify the order such that it cannot be fulfilled again. We emit a nullifier instead of deleting the order // from public storage because we get no refund for resetting public storage to zero and just emitting // a nullifier is cheaper (1 Field in DA instead of multiple Fields for the order). We use the `order_id` // itself as the nullifier because this contract does not work with notes and hence there is no risk of // colliding with a real note nullifier. - context.push_nullifier(order_id); + self.context.push_nullifier(order_id); // Enqueue the fulfillment to finalize both partial notes - Orderbook::at(context.this_address()) + Orderbook::at(self.address) ._fulfill_order(order_id, taker_partial_note, bid_token, order.bid_amount) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] @@ -166,16 +165,16 @@ pub contract Orderbook { ) { // Finalize transfer of bid_amount of bid_token to taker Token::at(bid_token).finalize_transfer_to_private(bid_amount, taker_partial_note).call( - &mut context, + self.context, ); - emit_event_in_public(OrderFulfilled { order_id }, &mut context); + self.emit(OrderFulfilled { order_id }); } /// Returns the order and whether it has been fulfilled. #[external("utility")] unconstrained fn get_order(order_id: Field) -> pub (Order, bool) { - let order = storage.orders.at(order_id).read(); + let order = self.storage.orders.at(order_id).read(); let is_fulfilled = check_nullifier_exists(order_id); (order, is_fulfilled) diff --git a/noir-projects/noir-contracts/contracts/app/price_feed_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/price_feed_contract/src/main.nr index 1e18140394be..b7a4ae1bc23d 100644 --- a/noir-projects/noir-contracts/contracts/app/price_feed_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/price_feed_contract/src/main.nr @@ -17,13 +17,13 @@ pub contract PriceFeed { #[external("public")] fn set_price(asset_id: Field, price: u128) { - let asset = storage.assets.at(asset_id); + let asset = self.storage.assets.at(asset_id); asset.write(Asset { price }); } #[external("public")] #[view] fn get_price(asset_id: Field) -> Asset { - storage.assets.at(asset_id).read() + self.storage.assets.at(asset_id).read() } } diff --git a/noir-projects/noir-contracts/contracts/app/private_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/private_token_contract/src/main.nr index 08f6ec4eefc0..18fb336b81ab 100644 --- a/noir-projects/noir-contracts/contracts/app/private_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/private_token_contract/src/main.nr @@ -17,7 +17,7 @@ pub contract PrivateToken { #[external("private")] #[initializer] fn constructor(initial_supply: u64, owner: AztecAddress) { - let balances = storage.balances; + let balances = self.storage.balances; balances.at(owner).add(initial_supply, owner); } @@ -25,7 +25,7 @@ pub contract PrivateToken { // Mints `amount` of tokens to `owner`. #[external("private")] fn mint(amount: u64, owner: AztecAddress) { - let balances = storage.balances; + let balances = self.storage.balances; balances.at(owner).add(amount, owner); } @@ -33,7 +33,7 @@ pub contract PrivateToken { // Transfers `amount` of tokens from `sender` to a `recipient`. #[external("private")] fn transfer(amount: u64, sender: AztecAddress, recipient: AztecAddress) { - let balances = storage.balances; + let balances = self.storage.balances; balances.at(sender).sub(amount, sender); balances.at(recipient).add(amount, recipient); @@ -42,6 +42,6 @@ pub contract PrivateToken { // Helper function to get the balance of a user. #[external("utility")] unconstrained fn get_balance(owner: AztecAddress) -> Field { - storage.balances.at(owner).get_value() + self.storage.balances.at(owner).get_value() } } diff --git a/noir-projects/noir-contracts/contracts/app/private_voting_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/private_voting_contract/src/main.nr index 54adcfdf74a0..cf79a0012772 100644 --- a/noir-projects/noir-contracts/contracts/app/private_voting_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/private_voting_contract/src/main.nr @@ -39,9 +39,9 @@ pub contract PrivateVoting { #[initializer] // annotation to mark function as a constructor fn constructor(admin: AztecAddress) { - storage.admin.write(admin); - storage.vote_ended.write(false); - storage.active_at_block.initialize(context.block_number()); + self.storage.admin.write(admin); + self.storage.vote_ended.write(false); + self.storage.active_at_block.initialize(self.context.block_number()); } // docs:end:constructor @@ -49,31 +49,32 @@ pub contract PrivateVoting { // annotation to mark function as private and expose private context fn cast_vote(candidate: Field) { let msg_sender_nullifier_public_key_message_hash = - get_public_keys(context.msg_sender().unwrap()).npk_m.hash(); + get_public_keys(self.msg_sender().unwrap()).npk_m.hash(); - let secret = context.request_nsk_app(msg_sender_nullifier_public_key_message_hash); // get secret key of caller of function - let nullifier = poseidon2_hash([context.msg_sender().unwrap().to_field(), secret]); // derive nullifier from sender and secret - context.push_nullifier(nullifier); - PrivateVoting::at(context.this_address()).add_to_tally_public(candidate).enqueue( - &mut context, - ); + let secret = self.context.request_nsk_app(msg_sender_nullifier_public_key_message_hash); // get secret key of caller of function + let nullifier = poseidon2_hash([self.msg_sender().unwrap().to_field(), secret]); // derive nullifier from sender and secret + self.context.push_nullifier(nullifier); + PrivateVoting::at(self.address).add_to_tally_public(candidate).enqueue(self.context); } #[external("public")] #[internal] fn add_to_tally_public(candidate: Field) { - assert(storage.vote_ended.read() == false, "Vote has ended"); // assert that vote has not ended - let new_tally = storage.tally.at(candidate).read() + 1; - storage.tally.at(candidate).write(new_tally); + assert(self.storage.vote_ended.read() == false, "Vote has ended"); // assert that vote has not ended + let new_tally = self.storage.tally.at(candidate).read() + 1; + self.storage.tally.at(candidate).write(new_tally); } #[external("public")] fn end_vote() { - assert(storage.admin.read().eq(context.msg_sender().unwrap()), "Only admin can end votes"); // assert that caller is admin - storage.vote_ended.write(true); + assert( + self.storage.admin.read().eq(self.msg_sender().unwrap()), + "Only admin can end votes", + ); // assert that caller is admin + self.storage.vote_ended.write(true); } #[external("utility")] unconstrained fn get_vote(candidate: Field) -> Field { - storage.tally.at(candidate).read() + self.storage.tally.at(candidate).read() } } diff --git a/noir-projects/noir-contracts/contracts/app/simple_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/simple_token_contract/src/main.nr index ffefdf2b6c63..b8c4aac49498 100644 --- a/noir-projects/noir-contracts/contracts/app/simple_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/simple_token_contract/src/main.nr @@ -15,7 +15,6 @@ pub contract SimpleToken { use aztec::{ authwit::auth::compute_authwit_nullifier, context::{PrivateCallInterface, PrivateContext, PublicContext}, - event::event_emission::emit_event_in_private, macros::{ events::event, functions::{authorize_once, external, initializer, internal, view}, @@ -53,70 +52,70 @@ pub contract SimpleToken { #[external("public")] #[initializer] fn constructor(name: str<31>, symbol: str<31>, decimals: u8) { - storage.name.initialize(FieldCompressedString::from_string(name)); - storage.symbol.initialize(FieldCompressedString::from_string(symbol)); - storage.decimals.initialize(decimals); + self.storage.name.initialize(FieldCompressedString::from_string(name)); + self.storage.symbol.initialize(FieldCompressedString::from_string(symbol)); + self.storage.decimals.initialize(decimals); } #[external("public")] #[view] fn public_get_name() -> FieldCompressedString { - storage.name.read() + self.storage.name.read() } #[external("public")] #[view] fn public_get_symbol() -> pub FieldCompressedString { - storage.symbol.read() + self.storage.symbol.read() } #[external("public")] #[view] fn public_get_decimals() -> pub u8 { - storage.decimals.read() + self.storage.decimals.read() } #[external("public")] #[view] fn public_total_supply() -> u128 { - storage.total_supply.read() + self.storage.total_supply.read() } #[external("public")] #[view] fn public_balance_of(owner: AztecAddress) -> u128 { - storage.public_balances.at(owner).read() + self.storage.public_balances.at(owner).read() } #[external("utility")] unconstrained fn private_balance_of(owner: AztecAddress) -> u128 { - storage.balances.at(owner).balance_of() + self.storage.balances.at(owner).balance_of() } #[external("public")] fn mint_publicly(to: AztecAddress, amount: u128) { - let new_balance = storage.public_balances.at(to).read().add(amount); - let supply = storage.total_supply.read().add(amount); - storage.public_balances.at(to).write(new_balance); - storage.total_supply.write(supply); + let new_balance = self.storage.public_balances.at(to).read().add(amount); + let supply = self.storage.total_supply.read().add(amount); + self.storage.public_balances.at(to).write(new_balance); + self.storage.total_supply.write(supply); } #[authorize_once("from", "authwit_nonce")] #[external("public")] fn public_transfer(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { - let from_balance = storage.public_balances.at(from).read().sub(amount); - storage.public_balances.at(from).write(from_balance); - let to_balance = storage.public_balances.at(to).read().add(amount); - storage.public_balances.at(to).write(to_balance); + let from_balance = self.storage.public_balances.at(from).read().sub(amount); + self.storage.public_balances.at(from).write(from_balance); + let to_balance = self.storage.public_balances.at(to).read().add(amount); + self.storage.public_balances.at(to).write(to_balance); } #[authorize_once("from", "authwit_nonce")] #[external("public")] fn burn_public(from: AztecAddress, amount: u128, authwit_nonce: Field) { - let from_balance = storage.public_balances.at(from).read().sub(amount); - storage.public_balances.at(from).write(from_balance); - let new_supply = storage.total_supply.read().sub(amount); - storage.total_supply.write(new_supply); + let from_balance = self.storage.public_balances.at(from).read().sub(amount); + self.storage.public_balances.at(from).write(from_balance); + let new_supply = self.storage.total_supply.read().sub(amount); + self.storage.total_supply.write(new_supply); } #[authorize_once("from", "authwit_nonce")] @@ -127,53 +126,55 @@ pub contract SimpleToken { amount: u128, authwit_nonce: Field, ) { - storage.balances.at(from).sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); - SimpleToken::at(context.this_address())._increase_public_balance(to, amount).enqueue( - &mut context, + self.storage.balances.at(from).sub(from, amount).emit( + from, + MessageDelivery.CONSTRAINED_ONCHAIN, ); + SimpleToken::at(self.address)._increase_public_balance(to, amount).enqueue(self.context); } #[external("private")] fn private_transfer(to: AztecAddress, amount: u128) { - let from = context.msg_sender().unwrap(); + let from = self.msg_sender().unwrap(); let change = subtract_balance( - &mut context, - storage, + self.context, + self.storage, from, amount, INITIAL_TRANSFER_CALL_MAX_NOTES, ); - storage.balances.at(from).add(from, change).emit(from, MessageDelivery.UNCONSTRAINED_ONCHAIN); - storage.balances.at(to).add(to, amount).emit(to, MessageDelivery.UNCONSTRAINED_ONCHAIN); - - emit_event_in_private( - Transfer { from, to, amount }, - &mut context, - to, + self.storage.balances.at(from).add(from, change).emit( + from, MessageDelivery.UNCONSTRAINED_ONCHAIN, ); + self.storage.balances.at(to).add(to, amount).emit(to, MessageDelivery.UNCONSTRAINED_ONCHAIN); + + self.emit(Transfer { from, to, amount }, to, MessageDelivery.UNCONSTRAINED_ONCHAIN); } #[authorize_once("from", "authwit_nonce")] #[external("private")] fn burn_private(from: AztecAddress, amount: u128, authwit_nonce: Field) { - storage.balances.at(from).sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); - SimpleToken::at(context.this_address())._reduce_total_supply(amount).enqueue(&mut context); + self.storage.balances.at(from).sub(from, amount).emit( + from, + MessageDelivery.CONSTRAINED_ONCHAIN, + ); + SimpleToken::at(self.address)._reduce_total_supply(amount).enqueue(self.context); } #[external("private")] fn transfer_from_public_to_private(to: AztecAddress, amount: u128) { - let from = context.msg_sender().unwrap(); - let token = SimpleToken::at(context.this_address()); + let from = self.msg_sender().unwrap(); + let token = SimpleToken::at(self.address); - let partial_note = _prepare_private_balance_increase(to, &mut context, storage); - token._finalize_transfer_to_private_unsafe(from, amount, partial_note).enqueue(&mut context); + let partial_note = _prepare_private_balance_increase(to, self.context, self.storage); + token._finalize_transfer_to_private_unsafe(from, amount, partial_note).enqueue(self.context); } #[external("private")] fn prepare_private_balance_increase(to: AztecAddress, from: AztecAddress) -> PartialUintNote { - _prepare_private_balance_increase(to, &mut context, storage) + _prepare_private_balance_increase(to, self.context, self.storage) } #[contract_library_method] @@ -195,13 +196,13 @@ pub contract SimpleToken { #[external("public")] fn finalize_transfer_to_private(amount: u128, partial_note: PartialUintNote) { - let from_and_completer = context.msg_sender().unwrap(); + let from_and_completer = self.msg_sender().unwrap(); _finalize_transfer_to_private( from_and_completer, amount, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -216,8 +217,8 @@ pub contract SimpleToken { from_and_completer, amount, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -237,21 +238,21 @@ pub contract SimpleToken { #[external("private")] fn mint_privately(from: AztecAddress, to: AztecAddress, amount: u128) { - let token = SimpleToken::at(context.this_address()); - let partial_note = _prepare_private_balance_increase(to, &mut context, storage); + let token = SimpleToken::at(self.address); + let partial_note = _prepare_private_balance_increase(to, self.context, self.storage); token - ._finalize_mint_to_private_unsafe(context.msg_sender().unwrap(), amount, partial_note) - .enqueue(&mut context); + ._finalize_mint_to_private_unsafe(self.msg_sender().unwrap(), amount, partial_note) + .enqueue(self.context); } #[external("public")] fn finalize_mint_to_private(amount: u128, partial_note: PartialUintNote) { _finalize_mint_to_private( - context.msg_sender().unwrap(), + self.msg_sender().unwrap(), amount, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -266,8 +267,8 @@ pub contract SimpleToken { minter_and_completer, amount, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -288,7 +289,7 @@ pub contract SimpleToken { #[external("public")] #[internal] fn _increase_public_balance(to: AztecAddress, amount: u128) { - _increase_public_balance_inner(to, amount, storage); + _increase_public_balance_inner(to, amount, self.storage); } #[contract_library_method] @@ -304,15 +305,15 @@ pub contract SimpleToken { #[external("public")] #[internal] fn _reduce_total_supply(amount: u128) { - let new_supply = storage.total_supply.read().sub(amount); - storage.total_supply.write(new_supply); + let new_supply = self.storage.total_supply.read().sub(amount); + self.storage.total_supply.write(new_supply); } #[external("private")] fn cancel_authwit(inner_hash: Field) { - let on_behalf_of = context.msg_sender().unwrap(); + let on_behalf_of = self.msg_sender().unwrap(); let nullifier = compute_authwit_nullifier(on_behalf_of, inner_hash); - context.push_nullifier(nullifier); + self.context.push_nullifier(nullifier); } #[contract_library_method] @@ -347,8 +348,8 @@ pub contract SimpleToken { #[external("private")] fn _recurse_subtract_balance(account: AztecAddress, amount: u128) -> u128 { subtract_balance( - &mut context, - storage, + self.context, + self.storage, account, amount, RECURSIVE_TRANSFER_CALL_MAX_NOTES, diff --git a/noir-projects/noir-contracts/contracts/app/token_blacklist_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/token_blacklist_contract/src/main.nr index d4e29d03970b..47bcb5171fb6 100644 --- a/noir-projects/noir-contracts/contracts/app/token_blacklist_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/token_blacklist_contract/src/main.nr @@ -62,119 +62,119 @@ pub contract TokenBlacklist { #[initializer] fn constructor(admin: AztecAddress) { let admin_roles = UserFlags { is_admin: true, is_minter: false, is_blacklisted: false }; - storage.roles.at(admin).schedule_value_change(admin_roles); + self.storage.roles.at(admin).schedule_value_change(admin_roles); } #[external("public")] #[view] fn total_supply() -> pub Field { - storage.total_supply.read().to_field() + self.storage.total_supply.read().to_field() } #[external("public")] #[view] fn balance_of_public(owner: AztecAddress) -> pub Field { - storage.public_balances.at(owner).read().to_field() + self.storage.public_balances.at(owner).read().to_field() } #[external("public")] #[view] fn get_roles(user: AztecAddress) -> UserFlags { - storage.roles.at(user).get_current_value() + self.storage.roles.at(user).get_current_value() } #[external("public")] fn update_roles(user: AztecAddress, roles: UserFlags) { - let caller_roles = storage.roles.at(context.msg_sender().unwrap()).get_current_value(); + let caller_roles = self.storage.roles.at(self.msg_sender().unwrap()).get_current_value(); assert(caller_roles.is_admin, "caller is not admin"); - storage.roles.at(user).schedule_value_change(roles); + self.storage.roles.at(user).schedule_value_change(roles); } #[external("public")] fn mint_public(to: AztecAddress, amount: u128) { - let to_roles = storage.roles.at(to).get_current_value(); + let to_roles = self.storage.roles.at(to).get_current_value(); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); - let caller_roles = storage.roles.at(context.msg_sender().unwrap()).get_current_value(); + let caller_roles = self.storage.roles.at(self.msg_sender().unwrap()).get_current_value(); assert(caller_roles.is_minter, "caller is not minter"); - let new_balance = storage.public_balances.at(to).read().add(amount); - let supply = storage.total_supply.read().add(amount); + let new_balance = self.storage.public_balances.at(to).read().add(amount); + let supply = self.storage.total_supply.read().add(amount); - storage.public_balances.at(to).write(new_balance); - storage.total_supply.write(supply); + self.storage.public_balances.at(to).write(new_balance); + self.storage.total_supply.write(supply); } #[external("public")] fn mint_private(amount: u128, secret_hash: Field) { - let caller_roles = storage.roles.at(context.msg_sender().unwrap()).get_current_value(); + let caller_roles = self.storage.roles.at(self.msg_sender().unwrap()).get_current_value(); assert(caller_roles.is_minter, "caller is not minter"); - let pending_shields = storage.pending_shields; + let pending_shields = self.storage.pending_shields; let note = TransparentNote::new(amount, secret_hash); - let supply = storage.total_supply.read().add(amount); + let supply = self.storage.total_supply.read().add(amount); - storage.total_supply.write(supply); + self.storage.total_supply.write(supply); // We insert the note hash into the pending_shields. Since the TransparentNote flow is deprecated (use partial // notes instead), we no longer have utility a function exposed on the PrivateSet to insert the note hash from // public context. Hence we need to manually get the slot and insert the note hash into the context. let note_hash = note.compute_note_hash(pending_shields.storage_slot); - context.push_note_hash(note_hash); + self.context.push_note_hash(note_hash); } #[authorize_once("from", "authwit_nonce")] #[external("public")] fn shield(from: AztecAddress, amount: u128, secret_hash: Field, authwit_nonce: Field) { - let from_roles = storage.roles.at(from).get_current_value(); + let from_roles = self.storage.roles.at(from).get_current_value(); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let from_balance = storage.public_balances.at(from).read().sub(amount); + let from_balance = self.storage.public_balances.at(from).read().sub(amount); - let pending_shields = storage.pending_shields; + let pending_shields = self.storage.pending_shields; let note = TransparentNote::new(amount, secret_hash); - storage.public_balances.at(from).write(from_balance); + self.storage.public_balances.at(from).write(from_balance); // We insert the note hash into the pending_shields. Since the TransparentNote flow is deprecated (use partial // notes instead), we no longer have utility a function exposed on the PrivateSet to insert the note hash from // public context. Hence we need to manually get the slot and insert the note hash into the context. let note_hash = note.compute_note_hash(pending_shields.storage_slot); - context.push_note_hash(note_hash); + self.context.push_note_hash(note_hash); } #[authorize_once("from", "authwit_nonce")] #[external("public")] fn transfer_public(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { - let from_roles = storage.roles.at(from).get_current_value(); + let from_roles = self.storage.roles.at(from).get_current_value(); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let to_roles = storage.roles.at(to).get_current_value(); + let to_roles = self.storage.roles.at(to).get_current_value(); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); - let from_balance = storage.public_balances.at(from).read().sub(amount); - storage.public_balances.at(from).write(from_balance); + let from_balance = self.storage.public_balances.at(from).read().sub(amount); + self.storage.public_balances.at(from).write(from_balance); - let to_balance = storage.public_balances.at(to).read().add(amount); - storage.public_balances.at(to).write(to_balance); + let to_balance = self.storage.public_balances.at(to).read().add(amount); + self.storage.public_balances.at(to).write(to_balance); } #[authorize_once("from", "authwit_nonce")] #[external("public")] fn burn_public(from: AztecAddress, amount: u128, authwit_nonce: Field) { - let from_roles = storage.roles.at(from).get_current_value(); + let from_roles = self.storage.roles.at(from).get_current_value(); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let from_balance = storage.public_balances.at(from).read().sub(amount); - storage.public_balances.at(from).write(from_balance); + let from_balance = self.storage.public_balances.at(from).read().sub(amount); + self.storage.public_balances.at(from).write(from_balance); - let new_supply = storage.total_supply.read().sub(amount); - storage.total_supply.write(new_supply); + let new_supply = self.storage.total_supply.read().sub(amount); + self.storage.total_supply.write(new_supply); } #[external("private")] fn redeem_shield(to: AztecAddress, amount: u128, secret: Field) { - let to_roles = storage.roles.at(to).get_current_value(); + let to_roles = self.storage.roles.at(to).get_current_value(); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); let secret_hash = compute_secret_hash(secret); @@ -187,71 +187,69 @@ pub contract TokenBlacklist { .select(TransparentNote::properties().secret_hash, Comparator.EQ, secret_hash) .set_limit(1); - let notes = storage.pending_shields.pop_notes(options); + let notes = self.storage.pending_shields.pop_notes(options); assert(notes.len() == 1, "note not popped"); // Add the token note to user's balances set - storage.balances.add(to, amount).emit(to, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.balances.add(to, amount).emit(to, MessageDelivery.CONSTRAINED_ONCHAIN); } #[authorize_once("from", "authwit_nonce")] #[external("private")] fn unshield(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { - let from_roles = storage.roles.at(from).get_current_value(); + let from_roles = self.storage.roles.at(from).get_current_value(); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let to_roles = storage.roles.at(to).get_current_value(); + let to_roles = self.storage.roles.at(to).get_current_value(); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); - storage.balances.sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.balances.sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); - TokenBlacklist::at(context.this_address())._increase_public_balance(to, amount).enqueue( - &mut context, - ); + TokenBlacklist::at(self.address)._increase_public_balance(to, amount).enqueue(self.context); } // docs:start:transfer_private #[authorize_once("from", "authwit_nonce")] #[external("private")] fn transfer(from: AztecAddress, to: AztecAddress, amount: u128, authwit_nonce: Field) { - let from_roles = storage.roles.at(from).get_current_value(); + let from_roles = self.storage.roles.at(from).get_current_value(); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let to_roles = storage.roles.at(to).get_current_value(); + let to_roles = self.storage.roles.at(to).get_current_value(); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); - storage.balances.sub(from, amount).emit(from, MessageDelivery.UNCONSTRAINED_ONCHAIN); - storage.balances.add(to, amount).emit(to, MessageDelivery.UNCONSTRAINED_ONCHAIN); + self.storage.balances.sub(from, amount).emit(from, MessageDelivery.UNCONSTRAINED_ONCHAIN); + self.storage.balances.add(to, amount).emit(to, MessageDelivery.UNCONSTRAINED_ONCHAIN); } #[authorize_once("from", "authwit_nonce")] #[external("private")] fn burn(from: AztecAddress, amount: u128, authwit_nonce: Field) { - let from_roles = storage.roles.at(from).get_current_value(); + let from_roles = self.storage.roles.at(from).get_current_value(); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - storage.balances.sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.balances.sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); - TokenBlacklist::at(context.this_address())._reduce_total_supply(amount).enqueue(&mut context); + TokenBlacklist::at(self.address)._reduce_total_supply(amount).enqueue(self.context); } /// Internal /// #[external("public")] #[internal] fn _increase_public_balance(to: AztecAddress, amount: u128) { - let new_balance = storage.public_balances.at(to).read().add(amount); - storage.public_balances.at(to).write(new_balance); + let new_balance = self.storage.public_balances.at(to).read().add(amount); + self.storage.public_balances.at(to).write(new_balance); } #[external("public")] #[internal] fn _reduce_total_supply(amount: u128) { // Only to be called from burn. - let new_supply = storage.total_supply.read().sub(amount); - storage.total_supply.write(new_supply); + let new_supply = self.storage.total_supply.read().sub(amount); + self.storage.total_supply.write(new_supply); } #[external("utility")] unconstrained fn balance_of_private(owner: AztecAddress) -> Field { - storage.balances.balance_of(owner).to_field() + self.storage.balances.balance_of(owner).to_field() } // We cannot replace this function with the standard `process_message` function because the transparent note diff --git a/noir-projects/noir-contracts/contracts/app/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/token_bridge_contract/src/main.nr index d347434d26c8..140e741c3618 100644 --- a/noir-projects/noir-contracts/contracts/app/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/token_bridge_contract/src/main.nr @@ -35,19 +35,19 @@ pub contract TokenBridge { #[external("public")] #[initializer] fn constructor(token: AztecAddress, portal: EthAddress) { - storage.config.initialize(Config { token, portal }); + self.storage.config.initialize(Config { token, portal }); } #[external("private")] #[view] fn get_config() -> Config { - storage.config.read() + self.storage.config.read() } #[external("public")] #[view] fn get_config_public() -> Config { - storage.config.read() + self.storage.config.read() } // docs:start:claim_public @@ -56,13 +56,18 @@ pub contract TokenBridge { fn claim_public(to: AztecAddress, amount: u128, secret: Field, message_leaf_index: Field) { let content_hash = get_mint_to_public_content_hash(to, amount); - let config = storage.config.read(); + let config = self.storage.config.read(); // Consume message and emit nullifier - context.consume_l1_to_l2_message(content_hash, secret, config.portal, message_leaf_index); + self.context.consume_l1_to_l2_message( + content_hash, + secret, + config.portal, + message_leaf_index, + ); // Mint tokens - Token::at(config.token).mint_to_public(to, amount).call(&mut context); + Token::at(config.token).mint_to_public(to, amount).call(self.context); } // docs:end:claim_public @@ -76,16 +81,16 @@ pub contract TokenBridge { caller_on_l1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) authwit_nonce: Field, // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 ) { - let config = storage.config.read(); + let config = self.storage.config.read(); // Send an L2 to L1 message let content = get_withdraw_content_hash(recipient, amount, caller_on_l1); - context.message_portal(config.portal, content); + self.context.message_portal(config.portal, content); // Burn tokens - Token::at(config.token) - .burn_public(context.msg_sender().unwrap(), amount, authwit_nonce) - .call(&mut context); + Token::at(config.token).burn_public(self.msg_sender().unwrap(), amount, authwit_nonce).call( + self.context, + ); } // docs:end:exit_to_l1_public @@ -99,11 +104,11 @@ pub contract TokenBridge { secret_for_L1_to_L2_message_consumption: Field, // secret used to consume the L1 to L2 message message_leaf_index: Field, ) { - let config = storage.config.read(); + let config = self.storage.config.read(); // Consume L1 to L2 message and emit nullifier let content_hash = get_mint_to_private_content_hash(amount); - context.consume_l1_to_l2_message( + self.context.consume_l1_to_l2_message( content_hash, secret_for_L1_to_L2_message_consumption, config.portal, @@ -111,7 +116,7 @@ pub contract TokenBridge { ); // At last we mint the tokens - Token::at(config.token).mint_to_private(recipient, amount).call(&mut context); + Token::at(config.token).mint_to_private(recipient, amount).call(self.context); } // docs:start:exit_to_l1_private @@ -125,18 +130,18 @@ pub contract TokenBridge { caller_on_l1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) authwit_nonce: Field, // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 ) { - let config = storage.config.read(); + let config = self.storage.config.read(); // Assert that user provided token address is same as seen in storage. assert_eq(config.token, token, "Token address is not the same as seen in storage"); // Send an L2 to L1 message let content = get_withdraw_content_hash(recipient, amount, caller_on_l1); - context.message_portal(config.portal, content); + self.context.message_portal(config.portal, content); // Burn tokens - Token::at(token).burn_private(context.msg_sender().unwrap(), amount, authwit_nonce).call( - &mut context, + Token::at(token).burn_private(self.msg_sender().unwrap(), amount, authwit_nonce).call( + self.context, ); } // docs:end:exit_to_l1_private diff --git a/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr index 4cd02bc3f6a7..4ed1e322e6a3 100644 --- a/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/token_contract/src/main.nr @@ -19,7 +19,6 @@ pub contract Token { use dep::aztec::{ context::{PrivateCallInterface, PrivateContext, PublicContext}, - event::event_emission::emit_event_in_private, macros::{ events::event, functions::{authorize_once, external, initializer, internal, view}, @@ -73,95 +72,95 @@ pub contract Token { #[initializer] fn constructor(admin: AztecAddress, name: str<31>, symbol: str<31>, decimals: u8) { assert(!admin.is_zero(), "invalid admin"); - storage.admin.write(admin); - storage.minters.at(admin).write(true); - storage.name.initialize(FieldCompressedString::from_string(name)); - storage.symbol.initialize(FieldCompressedString::from_string(symbol)); - storage.decimals.initialize(decimals); + self.storage.admin.write(admin); + self.storage.minters.at(admin).write(true); + self.storage.name.initialize(FieldCompressedString::from_string(name)); + self.storage.symbol.initialize(FieldCompressedString::from_string(symbol)); + self.storage.decimals.initialize(decimals); } // docs:end:constructor #[external("public")] fn set_admin(new_admin: AztecAddress) { - assert(storage.admin.read().eq(context.msg_sender().unwrap()), "caller is not admin"); - storage.admin.write(new_admin); + assert(self.storage.admin.read().eq(self.msg_sender().unwrap()), "caller is not admin"); + self.storage.admin.write(new_admin); } #[external("public")] #[view] fn public_get_name() -> FieldCompressedString { - storage.name.read() + self.storage.name.read() } #[external("private")] #[view] fn private_get_name() -> FieldCompressedString { - storage.name.read() + self.storage.name.read() } #[external("public")] #[view] fn public_get_symbol() -> pub FieldCompressedString { - storage.symbol.read() + self.storage.symbol.read() } #[external("private")] #[view] fn private_get_symbol() -> pub FieldCompressedString { - storage.symbol.read() + self.storage.symbol.read() } #[external("public")] #[view] fn public_get_decimals() -> pub u8 { - storage.decimals.read() + self.storage.decimals.read() } #[external("private")] #[view] fn private_get_decimals() -> pub u8 { - storage.decimals.read() + self.storage.decimals.read() } #[external("public")] #[view] fn get_admin() -> Field { - storage.admin.read().to_field() + self.storage.admin.read().to_field() } #[external("public")] #[view] fn is_minter(minter: AztecAddress) -> bool { - storage.minters.at(minter).read() + self.storage.minters.at(minter).read() } #[external("public")] #[view] fn total_supply() -> u128 { - storage.total_supply.read() + self.storage.total_supply.read() } #[external("public")] #[view] fn balance_of_public(owner: AztecAddress) -> u128 { - storage.public_balances.at(owner).read() + self.storage.public_balances.at(owner).read() } // docs:start:set_minter #[external("public")] fn set_minter(minter: AztecAddress, approve: bool) { - assert(storage.admin.read().eq(context.msg_sender().unwrap()), "caller is not admin"); - storage.minters.at(minter).write(approve); + assert(self.storage.admin.read().eq(self.msg_sender().unwrap()), "caller is not admin"); + self.storage.minters.at(minter).write(approve); } // docs:end:set_minter #[external("public")] fn mint_to_public(to: AztecAddress, amount: u128) { - assert(storage.minters.at(context.msg_sender().unwrap()).read(), "caller is not minter"); - let new_balance = storage.public_balances.at(to).read().add(amount); - let supply = storage.total_supply.read().add(amount); - storage.public_balances.at(to).write(new_balance); - storage.total_supply.write(supply); + assert(self.storage.minters.at(self.msg_sender().unwrap()).read(), "caller is not minter"); + let new_balance = self.storage.public_balances.at(to).read().add(amount); + let supply = self.storage.total_supply.read().add(amount); + self.storage.public_balances.at(to).write(new_balance); + self.storage.total_supply.write(supply); } #[authorize_once("from", "authwit_nonce")] @@ -172,19 +171,19 @@ pub contract Token { amount: u128, authwit_nonce: Field, ) { - let from_balance = storage.public_balances.at(from).read().sub(amount); - storage.public_balances.at(from).write(from_balance); - let to_balance = storage.public_balances.at(to).read().add(amount); - storage.public_balances.at(to).write(to_balance); + let from_balance = self.storage.public_balances.at(from).read().sub(amount); + self.storage.public_balances.at(from).write(from_balance); + let to_balance = self.storage.public_balances.at(to).read().add(amount); + self.storage.public_balances.at(to).write(to_balance); } #[authorize_once("from", "authwit_nonce")] #[external("public")] fn burn_public(from: AztecAddress, amount: u128, authwit_nonce: Field) { - let from_balance = storage.public_balances.at(from).read().sub(amount); - storage.public_balances.at(from).write(from_balance); - let new_supply = storage.total_supply.read().sub(amount); - storage.total_supply.write(new_supply); + let from_balance = self.storage.public_balances.at(from).read().sub(amount); + self.storage.public_balances.at(from).write(from_balance); + let new_supply = self.storage.total_supply.read().sub(amount); + self.storage.total_supply.write(new_supply); } #[authorize_once("from", "authwit_nonce")] @@ -195,8 +194,11 @@ pub contract Token { amount: u128, authwit_nonce: Field, ) { - storage.balances.at(from).sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); - Token::at(context.this_address())._increase_public_balance(to, amount).enqueue(&mut context); + self.storage.balances.at(from).sub(from, amount).emit( + from, + MessageDelivery.CONSTRAINED_ONCHAIN, + ); + Token::at(self.address)._increase_public_balance(to, amount).enqueue(self.context); } /// Transfers tokens from private balance of `from` to public balance of `to` and prepares a partial note for @@ -221,16 +223,19 @@ pub contract Token { amount: u128, authwit_nonce: Field, ) -> PartialUintNote { - storage.balances.at(from).sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); - Token::at(context.this_address())._increase_public_balance(to, amount).enqueue(&mut context); + self.storage.balances.at(from).sub(from, amount).emit( + from, + MessageDelivery.CONSTRAINED_ONCHAIN, + ); + Token::at(self.address)._increase_public_balance(to, amount).enqueue(self.context); // We prepare the private balance increase (the partial note for the change). - _prepare_private_balance_increase(from, &mut context, storage) + _prepare_private_balance_increase(from, self.context, self.storage) } #[external("private")] fn transfer(to: AztecAddress, amount: u128) { - let from = context.msg_sender().unwrap(); + let from = self.msg_sender().unwrap(); // We reduce `from`'s balance by amount by recursively removing notes over potentially multiple calls. This // method keeps the gate count for each individual call low - reading too many notes at once could result in @@ -239,25 +244,23 @@ pub contract Token { // note for `from` with the change amount, e.g. if `amount` is 10 and two notes are nullified with amounts 8 and // 5, then the change will be 3 (since 8 + 5 - 10 = 3). let change = subtract_balance( - &mut context, - storage, + self.context, + self.storage, from, amount, INITIAL_TRANSFER_CALL_MAX_NOTES, ); - storage.balances.at(from).add(from, change).emit(from, MessageDelivery.UNCONSTRAINED_ONCHAIN); - storage.balances.at(to).add(to, amount).emit(to, MessageDelivery.UNCONSTRAINED_ONCHAIN); + self.storage.balances.at(from).add(from, change).emit( + from, + MessageDelivery.UNCONSTRAINED_ONCHAIN, + ); + self.storage.balances.at(to).add(to, amount).emit(to, MessageDelivery.UNCONSTRAINED_ONCHAIN); // We don't constrain encryption of the note log in `transfer` (unlike in `transfer_in_private`) because the transfer // function is only designed to be used in situations where the event is not strictly necessary (e.g. payment to // another person where the payment is considered to be successful when the other party successfully decrypts a // note). - emit_event_in_private( - Transfer { from, to, amount }, - &mut context, - to, - MessageDelivery.UNCONSTRAINED_ONCHAIN, - ); + self.emit(Transfer { from, to, amount }, to, MessageDelivery.UNCONSTRAINED_ONCHAIN); } #[contract_library_method] @@ -301,8 +304,8 @@ pub contract Token { #[external("private")] fn _recurse_subtract_balance(account: AztecAddress, amount: u128) -> u128 { subtract_balance( - &mut context, - storage, + self.context, + self.storage, account, amount, RECURSIVE_TRANSFER_CALL_MAX_NOTES, @@ -315,9 +318,9 @@ pub contract Token { */ #[external("private")] fn cancel_authwit(inner_hash: Field) { - let on_behalf_of = context.msg_sender().unwrap(); + let on_behalf_of = self.msg_sender().unwrap(); let nullifier = compute_authwit_nullifier(on_behalf_of, inner_hash); - context.push_nullifier(nullifier); + self.context.push_nullifier(nullifier); } #[authorize_once("from", "authwit_nonce")] @@ -329,31 +332,37 @@ pub contract Token { authwit_nonce: Field, ) { // docs:start:increase_private_balance - storage.balances.at(from).sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.balances.at(from).sub(from, amount).emit( + from, + MessageDelivery.CONSTRAINED_ONCHAIN, + ); // docs:end:increase_private_balance - storage.balances.at(to).add(to, amount).emit(to, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.balances.at(to).add(to, amount).emit(to, MessageDelivery.CONSTRAINED_ONCHAIN); } #[authorize_once("from", "authwit_nonce")] #[external("private")] fn burn_private(from: AztecAddress, amount: u128, authwit_nonce: Field) { - storage.balances.at(from).sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); - Token::at(context.this_address())._reduce_total_supply(amount).enqueue(&mut context); + self.storage.balances.at(from).sub(from, amount).emit( + from, + MessageDelivery.CONSTRAINED_ONCHAIN, + ); + Token::at(self.address)._reduce_total_supply(amount).enqueue(self.context); } // Transfers token `amount` from public balance of message sender to a private balance of `to`. #[external("private")] fn transfer_to_private(to: AztecAddress, amount: u128) { // `from` is the owner of the public balance from which we'll subtract the `amount`. - let from = context.msg_sender().unwrap(); - let token = Token::at(context.this_address()); + let from = self.msg_sender().unwrap(); + let token = Token::at(self.address); // We prepare the private balance increase (the partial note). - let partial_note = _prepare_private_balance_increase(to, &mut context, storage); + let partial_note = _prepare_private_balance_increase(to, self.context, self.storage); // At last we finalize the transfer. Usage of the `unsafe` method here is safe because we set the `from` // function argument to a message sender, guaranteeing that he can transfer only his own tokens. - token._finalize_transfer_to_private_unsafe(from, amount, partial_note).enqueue(&mut context); + token._finalize_transfer_to_private_unsafe(from, amount, partial_note).enqueue(self.context); } /// Prepares an increase of private balance of `to` (partial note). The increase needs to be finalized by calling @@ -361,7 +370,7 @@ pub contract Token { /// returned partial note. #[external("private")] fn prepare_private_balance_increase(to: AztecAddress) -> PartialUintNote { - _prepare_private_balance_increase(to, &mut context, storage) + _prepare_private_balance_increase(to, self.context, self.storage) } /// This function exists separately from `prepare_private_balance_increase` solely as an optimization as it allows @@ -400,13 +409,13 @@ pub contract Token { fn finalize_transfer_to_private(amount: u128, partial_note: PartialUintNote) { // Completer is the entity that can complete the partial note. In this case, it's the same as the account // `from` from whose balance we're subtracting the `amount`. - let from_and_completer = context.msg_sender().unwrap(); + let from_and_completer = self.msg_sender().unwrap(); _finalize_transfer_to_private( from_and_completer, amount, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -427,9 +436,12 @@ pub contract Token { authwit_nonce: Field, ) { // First we subtract the `amount` from the private balance of `from` - storage.balances.at(from).sub(from, amount).emit(from, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.balances.at(from).sub(from, amount).emit( + from, + MessageDelivery.CONSTRAINED_ONCHAIN, + ); - partial_note.complete_from_private(&mut context, context.msg_sender().unwrap(), amount); + partial_note.complete_from_private(self.context, self.msg_sender().unwrap(), amount); } /// This is a wrapper around `_finalize_transfer_to_private` placed here so that a call @@ -446,8 +458,8 @@ pub contract Token { from_and_completer, amount, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -474,17 +486,17 @@ pub contract Token { /// in the enqueued call). #[external("private")] fn mint_to_private(to: AztecAddress, amount: u128) { - let token = Token::at(context.this_address()); + let token = Token::at(self.address); // We prepare the partial note to which we'll "send" the minted amount. - let partial_note = _prepare_private_balance_increase(to, &mut context, storage); + let partial_note = _prepare_private_balance_increase(to, self.context, self.storage); // At last we finalize the mint. Usage of the `unsafe` method here is safe because we set // the `minter_and_completer` function argument to a message sender, guaranteeing that only a message sender // with minter permissions can successfully execute the function. token - ._finalize_mint_to_private_unsafe(context.msg_sender().unwrap(), amount, partial_note) - .enqueue(&mut context); + ._finalize_mint_to_private_unsafe(self.msg_sender().unwrap(), amount, partial_note) + .enqueue(self.context); } /// Finalizes a mint of token `amount` to a private balance of `to`. The mint must be prepared by calling @@ -498,15 +510,15 @@ pub contract Token { fn finalize_mint_to_private(amount: u128, partial_note: PartialUintNote) { // Completer is the entity that can complete the partial note. In this case, it's the same as the minter // account. - let minter_and_completer = context.msg_sender().unwrap(); - assert(storage.minters.at(minter_and_completer).read(), "caller is not minter"); + let minter_and_completer = self.msg_sender().unwrap(); + assert(self.storage.minters.at(minter_and_completer).read(), "caller is not minter"); _finalize_mint_to_private( minter_and_completer, amount, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -521,13 +533,13 @@ pub contract Token { partial_note: PartialUintNote, ) { // We check the minter permissions as it was not done in `mint_to_private` function. - assert(storage.minters.at(minter_and_completer).read(), "caller is not minter"); + assert(self.storage.minters.at(minter_and_completer).read(), "caller is not minter"); _finalize_mint_to_private( minter_and_completer, amount, partial_note, - &mut context, - storage, + self.context, + self.storage, ); } @@ -553,7 +565,7 @@ pub contract Token { #[external("public")] #[internal] fn _increase_public_balance(to: AztecAddress, amount: u128) { - _increase_public_balance_inner(to, amount, storage); + _increase_public_balance_inner(to, amount, self.storage); } #[contract_library_method] @@ -570,14 +582,14 @@ pub contract Token { #[internal] fn _reduce_total_supply(amount: u128) { // Only to be called from burn. - let new_supply = storage.total_supply.read().sub(amount); - storage.total_supply.write(new_supply); + let new_supply = self.storage.total_supply.read().sub(amount); + self.storage.total_supply.write(new_supply); } // docs:start:balance_of_private #[external("utility")] unconstrained fn balance_of_private(owner: AztecAddress) -> u128 { - storage.balances.at(owner).balance_of() + self.storage.balances.at(owner).balance_of() } // docs:end:balance_of_private } diff --git a/noir-projects/noir-contracts/contracts/app/uniswap_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app/uniswap_contract/src/main.nr index 07a122a44fd4..c1d3c0d6369d 100644 --- a/noir-projects/noir-contracts/contracts/app/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app/uniswap_contract/src/main.nr @@ -34,7 +34,7 @@ pub contract Uniswap { #[external("public")] #[initializer] fn constructor(portal_address: EthAddress) { - storage.portal_address.initialize(portal_address); + self.storage.portal_address.initialize(portal_address); } // docs:end:uniswap_setup @@ -57,38 +57,33 @@ pub contract Uniswap { // nonce for someone to call swap on sender's behalf _nonce_for_swap_approval: Field, ) { - if (!sender.eq(context.msg_sender().unwrap())) { - assert_current_call_valid_authwit_public(&mut context, sender); + if (!sender.eq(self.msg_sender().unwrap())) { + assert_current_call_valid_authwit_public(self.context, sender); } let input_asset_bridge_config = - TokenBridge::at(input_asset_bridge).get_config_public().view(&mut context); + TokenBridge::at(input_asset_bridge).get_config_public().view(self.context); let input_asset = input_asset_bridge_config.token; let input_asset_bridge_portal_address = input_asset_bridge_config.portal; // Transfer funds to this contract Token::at(input_asset) - .transfer_in_public( - sender, - context.this_address(), - input_amount, - nonce_for_transfer_approval, - ) - .call(&mut context); + .transfer_in_public(sender, self.address, input_amount, nonce_for_transfer_approval) + .call(self.context); // Approve bridge to burn this contract's funds and exit to L1 Uniswap Portal - Uniswap::at(context.this_address()) + Uniswap::at(self.address) ._approve_bridge_and_exit_input_asset_to_L1( input_asset, input_asset_bridge, input_amount, ) - .call(&mut context); + .call(self.context); // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. let output_asset_bridge_portal_address = - TokenBridge::at(output_asset_bridge).get_config_public().view(&mut context).portal; + TokenBridge::at(output_asset_bridge).get_config_public().view(self.context).portal; // ensure portal exists - else funds might be lost assert( !input_asset_bridge_portal_address.is_zero(), @@ -109,7 +104,7 @@ pub contract Uniswap { secret_hash_for_L1_to_l2_message, caller_on_L1, ); - context.message_portal(storage.portal_address.read(), content_hash); + self.context.message_portal(self.storage.portal_address.read(), content_hash); } // docs:end:swap_public @@ -130,9 +125,9 @@ pub contract Uniswap { caller_on_L1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { let input_asset_bridge_config = - TokenBridge::at(input_asset_bridge).get_config().view(&mut context); + TokenBridge::at(input_asset_bridge).get_config().view(self.context); let output_asset_bridge_config = - TokenBridge::at(output_asset_bridge).get_config().view(&mut context); + TokenBridge::at(output_asset_bridge).get_config().view(self.context); // Assert that user provided token address is same as expected by token bridge. // we can't directly use `input_asset_bridge.token` because that is a public method and public can't return data to private @@ -144,21 +139,21 @@ pub contract Uniswap { // Transfer funds to this contract Token::at(input_asset) .transfer_to_public( - context.msg_sender().unwrap(), - context.this_address(), + self.msg_sender().unwrap(), + self.address, input_amount, nonce_for_transfer_to_public_approval, ) - .call(&mut context); + .call(self.context); // Approve bridge to burn this contract's funds and exit to L1 Uniswap Portal - Uniswap::at(context.this_address()) + Uniswap::at(self.address) ._approve_bridge_and_exit_input_asset_to_L1( input_asset, input_asset_bridge, input_amount, ) - .enqueue(&mut context); + .enqueue(self.context); // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. @@ -182,7 +177,7 @@ pub contract Uniswap { secret_hash_for_L1_to_l2_message, caller_on_L1, ); - context.message_portal(storage.portal_address.read(), content_hash); + self.context.message_portal(self.storage.portal_address.read(), content_hash); } // docs:end:swap_private @@ -207,20 +202,20 @@ pub contract Uniswap { let message_hash = compute_authwit_message_hash_from_call( token_bridge, token, - context.chain_id(), - context.version(), + self.context.chain_id(), + self.context.version(), selector, - [context.this_address().to_field(), amount as Field, authwit_nonce], + [self.address.to_field(), amount as Field, authwit_nonce], ); // We need to make a call to update it. - set_authorized(&mut context, message_hash, true); + set_authorized(self.context, message_hash, true); - let this_portal_address = storage.portal_address.read(); + let this_portal_address = self.storage.portal_address.read(); // Exit to L1 Uniswap Portal ! TokenBridge::at(token_bridge) .exit_to_l1_public(this_portal_address, amount, this_portal_address, authwit_nonce) - .call(&mut context) + .call(self.context) } // docs:end:authwit_uniswap_set } diff --git a/noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr index 0a94112e2007..dbcf992ee0ee 100644 --- a/noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs/docs_example_contract/src/main.nr @@ -61,21 +61,21 @@ pub contract DocsExample { #[external("public")] fn initialize_public_immutable(points: u8) { - let mut new_leader = Leader { account: context.msg_sender().unwrap(), points }; - storage.public_immutable.initialize(new_leader); + let mut new_leader = Leader { account: self.msg_sender().unwrap(), points }; + self.storage.public_immutable.initialize(new_leader); } #[external("utility")] unconstrained fn get_public_immutable() -> Leader { - storage.public_immutable.read() + self.storage.public_immutable.read() } #[external("private")] fn initialize_private_immutable(points: u8) { - let new_card = CardNote::new(points, context.msg_sender().unwrap()); + let new_card = CardNote::new(points, self.msg_sender().unwrap()); - storage.private_immutable.initialize(new_card).emit( - context.msg_sender().unwrap(), + self.storage.private_immutable.initialize(new_card).emit( + self.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN, ); } @@ -83,33 +83,38 @@ pub contract DocsExample { #[external("utility")] unconstrained fn read_note(comparator: u8, amount: Field) -> BoundedVec { let mut options = NoteViewerOptions::new(); - storage.set.view_notes(options.select(CardNote::properties().points, comparator, amount)) + self.storage.set.view_notes(options.select( + CardNote::properties().points, + comparator, + amount, + )) } #[external("private")] fn read_legendary_points() { - storage.legendary_card.get_note() + self.storage.legendary_card.get_note() } #[external("private")] fn increase_legendary_points() { - storage + self + .storage .legendary_card .replace(|old_card| { let points = old_card.get_points() + 1; - CardNote::new(points, context.msg_sender().unwrap()) + CardNote::new(points, self.msg_sender().unwrap()) }) - .emit(context.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN); + .emit(self.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN); } #[external("utility")] unconstrained fn is_legendary_initialized() -> bool { - storage.legendary_card.is_initialized() + self.storage.legendary_card.is_initialized() } #[external("private")] fn get_imm_card() -> CardNote { - storage.private_immutable.get_note() + self.storage.private_immutable.get_note() } /// Macro equivalence section @@ -142,31 +147,33 @@ pub contract DocsExample { ) -> PrivateCircuitPublicInputs { // docs:end:context-example-return // ************************************************************ - // The args are serialized and hashed to generate the args hash for the circuit inputs. - // docs:start:context-example-hasher - let serialized_args = [a, b]; - let args_hash = dep::aztec::hash::hash_args_array(serialized_args); - // docs:end:context-example-hasher - // The context object is created with the inputs and the hash of the inputs - // docs:start:context-example-context - let mut context = PrivateContext::new(inputs, args_hash); - // docs:end:context-example-context - // docs:start:storage-example-context - #[allow(unused_variables)] - let mut storage = Storage::init(&mut context); - // docs:end:storage-example-context + // Oracle version compatibility check + dep::aztec::oracle::version::assert_compatible_oracle_version(); + + // Create ContractSelf instance with storage initialization + // docs:start:contract_self_creation + let mut self = { + let serialized_args = [a, b]; + let args_hash = dep::aztec::hash::hash_args_array(serialized_args); + let mut context = PrivateContext::new(inputs, args_hash); + let storage = Storage::init(&mut context); + aztec::contract_self::ContractSelf::new_private(&mut context, storage) + }; + // docs:end:contract_self_creation + // ************************************************************ // Our actual program let result = a + b; // ************************************************************ // Return values are serialized and passed to the context // docs:start:context-example-context-return - let serialized_return = [result]; - context.set_return_hash(serialized_return); + let macro__returned__values: Field = result; + let serialized_return = [macro__returned__values]; + self.context.set_return_hash(serialized_return); // docs:end:context-example-context-return // The context is returned to be consumed by the kernel circuit! // docs:start:context-example-finish - context.finish() + self.context.finish() // docs:end:context-example-finish // ************************************************************ } diff --git a/noir-projects/noir-contracts/contracts/fees/fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fees/fpc_contract/src/main.nr index f9786d247273..1145f5a44927 100644 --- a/noir-projects/noir-contracts/contracts/fees/fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fees/fpc_contract/src/main.nr @@ -31,7 +31,7 @@ pub contract FPC { #[initializer] fn constructor(accepted_asset: AztecAddress, admin: AztecAddress) { let config = Config { accepted_asset, admin }; - storage.config.initialize(config); + self.storage.config.initialize(config); } /// Pays for the tx fee with msg_sender's private balance of accepted asset (AA). The maximum fee a user is willing @@ -78,31 +78,29 @@ pub contract FPC { // docs:start:fee_entrypoint_private #[external("private")] fn fee_entrypoint_private(max_fee: u128, authwit_nonce: Field) { - let accepted_asset = storage.config.read().accepted_asset; + let accepted_asset = self.storage.config.read().accepted_asset; - let user = context.msg_sender().unwrap(); + let user = self.msg_sender().unwrap(); let token = Token::at(accepted_asset); // TODO(#10805): Here we should check that `max_fee` converted to fee juice is enough to cover the tx // fee juice/mana/gas limit. Currently the fee juice/AA exchange rate is fixed 1:1. // Pull the max fee from the user's balance of the accepted asset to the public balance of this contract. - token.transfer_to_public(user, context.this_address(), max_fee, authwit_nonce).call( - &mut context, - ); + token.transfer_to_public(user, self.address, max_fee, authwit_nonce).call(self.context); // Prepare a partial note for the refund for the user. - let partial_note = token.prepare_private_balance_increase(user).call(&mut context); + let partial_note = token.prepare_private_balance_increase(user).call(self.context); // Set a public teardown function in which the refund will be paid back to the user by finalizing the partial note. - FPC::at(context.this_address()) + FPC::at(self.address) ._complete_refund(accepted_asset, partial_note, max_fee) - .set_as_teardown(&mut context); + .set_as_teardown(self.context); // Set the FPC as the fee payer of the tx. - context.set_as_fee_payer(); + self.context.set_as_fee_payer(); // End the setup phase, from now on all side effects are revertible - context.end_setup(); + self.context.end_setup(); } // docs:end:fee_entrypoint_private @@ -116,7 +114,7 @@ pub contract FPC { partial_note: PartialUintNote, max_fee: u128, ) { - let tx_fee = safe_cast_to_u128(context.transaction_fee()); + let tx_fee = safe_cast_to_u128(self.context.transaction_fee()); // 1. Check that user funded the fee payer contract with at least the transaction fee. // TODO(#10805): Nuke this check once we have a proper max_fee check in the fee_entrypoint_private. @@ -127,7 +125,7 @@ pub contract FPC { let refund_amount = max_fee - tx_fee; Token::at(accepted_asset).finalize_transfer_to_private(refund_amount, partial_note).call( - &mut context, + self.context, ); } // docs:end:complete_refund @@ -154,28 +152,23 @@ pub contract FPC { /// 4. The protocol deducts the actual fee denominated in fee juice from the FPC's balance. #[external("private")] fn fee_entrypoint_public(max_fee: u128, authwit_nonce: Field) { - let config = storage.config.read(); + let config = self.storage.config.read(); // We pull the max fee from the user's balance of the accepted asset to this contract. // docs:start:public_call Token::at(config.accepted_asset) - .transfer_in_public( - context.msg_sender().unwrap(), - context.this_address(), - max_fee, - authwit_nonce, - ) - .enqueue(&mut context); + .transfer_in_public(self.msg_sender().unwrap(), self.address, max_fee, authwit_nonce) + .enqueue(self.context); // docs:end:public_call - FPC::at(context.this_address()) - ._pay_refund(context.msg_sender().unwrap(), max_fee, config.accepted_asset) - .set_as_teardown(&mut context); + FPC::at(self.address) + ._pay_refund(self.msg_sender().unwrap(), max_fee, config.accepted_asset) + .set_as_teardown(self.context); // Set the FPC as the fee payer of the tx. - context.set_as_fee_payer(); + self.context.set_as_fee_payer(); // End the setup phase, from now on all side effects are revertible - context.end_setup(); + self.context.end_setup(); } /// Pays the refund to the `refund_recipient` as part of the public fee payment flow. The refund is the difference @@ -184,36 +177,36 @@ pub contract FPC { #[external("public")] #[internal] fn _pay_refund(refund_recipient: AztecAddress, max_fee: u128, accepted_asset: AztecAddress) { - let actual_fee = safe_cast_to_u128(context.transaction_fee()); + let actual_fee = safe_cast_to_u128(self.context.transaction_fee()); assert(actual_fee <= max_fee, "Max fee paid to the paymaster does not cover actual fee"); // TODO(#10805): Introduce a real exchange rate let refund = max_fee - actual_fee; Token::at(accepted_asset) - .transfer_in_public(context.this_address(), refund_recipient, refund, 0) - .call(&mut context); + .transfer_in_public(self.address, refund_recipient, refund, 0) + .call(self.context); } /// Pulls all the accepted asset funds from this contract to the `to` address. Only the admin can call /// this function. #[external("public")] fn pull_funds(to: AztecAddress) { - let config = storage.config.read(); + let config = self.storage.config.read(); - assert(context.msg_sender().unwrap() == config.admin, "Only admin can pull funds"); + assert(self.msg_sender().unwrap() == config.admin, "Only admin can pull funds"); let token = Token::at(config.accepted_asset); // We send the full balance to `to`. - let balance = token.balance_of_public(context.this_address()).view(&mut context); - token.transfer_in_public(context.this_address(), to, balance, 0).call(&mut context); + let balance = token.balance_of_public(self.address).view(self.context); + token.transfer_in_public(self.address, to, balance, 0).call(self.context); } /// Note: Not marked as view as we need it to be callable as an entrypoint since in some places we need to obtain /// this value before we have access to an account contract (kernels do not allow for static entrypoints). #[external("private")] fn get_accepted_asset() -> AztecAddress { - storage.config.read().accepted_asset + self.storage.config.read().accepted_asset } } diff --git a/noir-projects/noir-contracts/contracts/fees/sponsored_fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fees/sponsored_fpc_contract/src/main.nr index 4684fe7d60f1..123d2bd847ce 100644 --- a/noir-projects/noir-contracts/contracts/fees/sponsored_fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fees/sponsored_fpc_contract/src/main.nr @@ -11,8 +11,8 @@ pub contract SponsoredFPC { #[external("private")] fn sponsor_unconditionally() { // Set the FPC as the fee payer of the tx. - context.set_as_fee_payer(); + self.context.set_as_fee_payer(); // End the setup phase - context.end_setup(); + self.context.end_setup(); } } diff --git a/noir-projects/noir-contracts/contracts/protocol/auth_registry_contract/src/main.nr b/noir-projects/noir-contracts/contracts/protocol/auth_registry_contract/src/main.nr index 10e6e5611df6..397b3cb6cf03 100644 --- a/noir-projects/noir-contracts/contracts/protocol/auth_registry_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol/auth_registry_contract/src/main.nr @@ -37,8 +37,8 @@ pub contract AuthRegistry { // We use the unsafe method, because for some use cases a "null" // msg_sender might be acceptable (e.g. if it doesn't matter who takes // an action). - let msg_sender = context.msg_sender_unsafe(); - storage.approved_actions.at(msg_sender).at(message_hash).write(authorize); + let msg_sender = self.context.msg_sender_unsafe(); + self.storage.approved_actions.at(msg_sender).at(message_hash).write(authorize); } /** @@ -50,7 +50,7 @@ pub contract AuthRegistry { */ #[external("public")] fn set_reject_all(reject: bool) { - storage.reject_all.at(context.msg_sender().unwrap()).write(reject); + self.storage.reject_all.at(self.msg_sender().unwrap()).write(reject); } /** @@ -65,19 +65,19 @@ pub contract AuthRegistry { */ #[external("public")] fn consume(on_behalf_of: AztecAddress, inner_hash: Field) -> Field { - assert_eq(false, storage.reject_all.at(on_behalf_of).read(), "rejecting all"); + assert_eq(false, self.storage.reject_all.at(on_behalf_of).read(), "rejecting all"); let message_hash = compute_authwit_message_hash( - context.msg_sender_unsafe(), // we allow "null" msg_sender. - context.chain_id(), - context.version(), + self.context.msg_sender_unsafe(), // we allow "null" msg_sender. + self.context.chain_id(), + self.context.version(), inner_hash, ); - let authorized = storage.approved_actions.at(on_behalf_of).at(message_hash).read(); + let authorized = self.storage.approved_actions.at(on_behalf_of).at(message_hash).read(); assert_eq(true, authorized, "unauthorized"); - storage.approved_actions.at(on_behalf_of).at(message_hash).write(false); + self.storage.approved_actions.at(on_behalf_of).at(message_hash).write(false); IS_VALID_SELECTOR } @@ -95,10 +95,10 @@ pub contract AuthRegistry { */ #[external("private")] fn set_authorized_private(approver: AztecAddress, message_hash: Field, authorize: bool) { - assert_current_call_valid_authwit::<3>(&mut context, approver); - AuthRegistry::at(context.this_address()) - ._set_authorized(approver, message_hash, authorize) - .enqueue(&mut context); + assert_current_call_valid_authwit::<3>(self.context, approver); + AuthRegistry::at(self.address)._set_authorized(approver, message_hash, authorize).enqueue( + self.context, + ); } /** @@ -112,7 +112,7 @@ pub contract AuthRegistry { #[external("public")] #[internal] fn _set_authorized(approver: AztecAddress, message_hash: Field, authorize: bool) { - storage.approved_actions.at(approver).at(message_hash).write(authorize); + self.storage.approved_actions.at(approver).at(message_hash).write(authorize); } /** @@ -124,7 +124,7 @@ pub contract AuthRegistry { #[external("public")] #[view] fn is_reject_all(on_behalf_of: AztecAddress) -> bool { - storage.reject_all.at(on_behalf_of).read() + self.storage.reject_all.at(on_behalf_of).read() } /** @@ -137,7 +137,7 @@ pub contract AuthRegistry { #[external("public")] #[view] fn is_consumable(on_behalf_of: AztecAddress, message_hash: Field) -> bool { - storage.approved_actions.at(on_behalf_of).at(message_hash).read() + self.storage.approved_actions.at(on_behalf_of).at(message_hash).read() } /** @@ -148,6 +148,6 @@ pub contract AuthRegistry { on_behalf_of: AztecAddress, message_hash: Field, ) -> bool { - storage.approved_actions.at(on_behalf_of).at(message_hash).read() + self.storage.approved_actions.at(on_behalf_of).at(message_hash).read() } } diff --git a/noir-projects/noir-contracts/contracts/protocol/contract_class_registry/src/main.nr b/noir-projects/noir-contracts/contracts/protocol/contract_class_registry/src/main.nr index 45a21de10531..6082c1e98401 100644 --- a/noir-projects/noir-contracts/contracts/protocol/contract_class_registry/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol/contract_class_registry/src/main.nr @@ -40,11 +40,7 @@ pub contract ContractClassRegistry { // Safety: We load the bytecode via a capsule, which is unconstrained. In order to ensure the loaded bytecode // matches the expected one, we recompute the commitment and assert it matches the one provided by the caller. let mut packed_public_bytecode: [Field; MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS] = unsafe { - capsules::load( - context.this_address(), - CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT, - ) - .unwrap() + capsules::load(self.address, CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT).unwrap() }; // Compute and check the public bytecode commitment let computed_public_bytecode_commitment = @@ -61,7 +57,7 @@ pub contract ContractClassRegistry { // Emit the contract class id as a nullifier: // - to demonstrate that this contract class hasn't been published before // - to enable apps to read that this contract class has been published. - context.push_nullifier(contract_class_id.to_field()); + self.context.push_nullifier(contract_class_id.to_field()); // Broadcast class info including public bytecode dep::aztec::oracle::debug_log::debug_log_format( @@ -81,7 +77,7 @@ pub contract ContractClassRegistry { private_functions_root, packed_public_bytecode, }; - context.emit_contract_class_log(event.serialize_non_standard()); + self.context.emit_contract_class_log(event.serialize_non_standard()); } #[external("private")] @@ -100,11 +96,7 @@ pub contract ContractClassRegistry { // 2. This broadcast simply provides convenient bytecode sharing vs offchain distribution. // 3. Computing the VK for private bytecode in-circuit is not possible, so we can't do better. let private_bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS] = unsafe { - capsules::load( - context.this_address(), - CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT, - ) - .unwrap() + capsules::load(self.address, CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT).unwrap() }; let event = ClassPrivateFunctionBroadcasted { @@ -133,7 +125,7 @@ pub contract ContractClassRegistry { function_data.metadata_hash, ], ); - context.emit_contract_class_log(event.serialize_non_standard()); + self.context.emit_contract_class_log(event.serialize_non_standard()); } #[external("private")] @@ -149,11 +141,7 @@ pub contract ContractClassRegistry { // 1. Unlike public functions, we don't need execution guarantees for utility functions. // 2. This broadcast simply provides convenient bytecode sharing vs offchain distribution. let utility_bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS] = unsafe { - capsules::load( - context.this_address(), - CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT, - ) - .unwrap() + capsules::load(self.address, CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT).unwrap() }; let event = ClassUtilityFunctionBroadcasted { contract_class_id, @@ -177,11 +165,11 @@ pub contract ContractClassRegistry { function_data.metadata_hash, ], ); - context.emit_contract_class_log(event.serialize_non_standard()); + self.context.emit_contract_class_log(event.serialize_non_standard()); } #[external("private")] fn assert_class_id_is_published(contract_class_id: ContractClassId) { - context.push_nullifier_read_request(contract_class_id.to_field()); + self.context.push_nullifier_read_request(contract_class_id.to_field()); } } diff --git a/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry/src/main.nr b/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry/src/main.nr index 991a51ad86e1..dfc872ab0e77 100644 --- a/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry/src/main.nr @@ -106,12 +106,12 @@ pub contract ContractInstanceRegistry { // contract class must be published in order to publish an instance ContractClassRegistry::at(CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS) .assert_class_id_is_published(contract_class_id) - .call(&mut context); + .call(self.context); let deployer = if universal_deploy { AztecAddress::zero() } else { - context.msg_sender().unwrap() + self.msg_sender().unwrap() }; let partial_address = @@ -122,7 +122,7 @@ pub contract ContractInstanceRegistry { // Emit the address as a nullifier: // - to demonstrate that this contract instance hasn't been published before // - to enable apps to read that this contract instance has been published. - context.push_nullifier(address.to_field()); + self.context.push_nullifier(address.to_field()); // Broadcast the event let event = ContractInstancePublished { @@ -143,27 +143,28 @@ pub contract ContractInstanceRegistry { // Only the payload needs to be emitted. Since the siloed tag of this event log is publicly known, it's // acceptable to pad the log with 0s and reveal the actual payload length. let length = payload.len(); - context.emit_private_log(padded_log, length); + self.context.emit_private_log(padded_log, length); } #[external("public")] fn update(new_contract_class_id: ContractClassId) { - let address = context.msg_sender().unwrap(); + let address = self.msg_sender().unwrap(); assert( - context.nullifier_exists(address.to_field(), context.this_address()), + self.context.nullifier_exists(address.to_field(), self.address), "msg.sender is not deployed", ); assert( - context.nullifier_exists( + self.context.nullifier_exists( new_contract_class_id.to_field(), CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS, ), "New contract class is not registered", ); - let scheduled_value_update = storage + let scheduled_value_update = self + .storage .updated_class_ids .at(address) .schedule_and_return_value_change(new_contract_class_id); @@ -177,26 +178,26 @@ pub contract ContractInstanceRegistry { timestamp_of_change, }; - context.emit_public_log(event); + self.context.emit_public_log(event); } #[external("public")] fn set_update_delay(new_update_delay: u64) { - let address = context.msg_sender().unwrap(); + let msg_sender = self.msg_sender().unwrap(); assert( - context.nullifier_exists(address.to_field(), context.this_address()), + self.context.nullifier_exists(msg_sender.to_field(), self.address), "msg.sender is not deployed", ); assert(new_update_delay >= MINIMUM_UPDATE_DELAY, "New update delay is too low"); - storage.updated_class_ids.at(address).schedule_delay_change(new_update_delay); + self.storage.updated_class_ids.at(msg_sender).schedule_delay_change(new_update_delay); } #[external("public")] #[view] fn get_update_delay() -> u64 { - storage.updated_class_ids.at(context.msg_sender().unwrap()).get_current_delay() + self.storage.updated_class_ids.at(self.msg_sender().unwrap()).get_current_delay() } } diff --git a/noir-projects/noir-contracts/contracts/protocol/fee_juice_contract/src/main.nr b/noir-projects/noir-contracts/contracts/protocol/fee_juice_contract/src/main.nr index 951d6e023516..cf7514bd7700 100644 --- a/noir-projects/noir-contracts/contracts/protocol/fee_juice_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol/fee_juice_contract/src/main.nr @@ -50,7 +50,7 @@ pub contract FeeJuice { /// Claims FeeJuice by consuming an L1 to L2 message with the provided information. #[external("private")] fn claim(to: AztecAddress, amount: u128, secret: Field, message_leaf_index: Field) { - claim_helper(&mut context, to, amount, secret, message_leaf_index); + claim_helper(self.context, to, amount, secret, message_leaf_index); } /// Claims FeeJuice by consuming an L1 to L2 message with the provided information. After enqueuing the @@ -64,22 +64,22 @@ pub contract FeeJuice { secret: Field, message_leaf_index: Field, ) { - claim_helper(&mut context, to, amount, secret, message_leaf_index); - context.end_setup(); + claim_helper(self.context, to, amount, secret, message_leaf_index); + self.context.end_setup(); } #[external("public")] #[internal] fn _increase_public_balance(to: AztecAddress, amount: u128) { - let new_balance = storage.balances.at(to).read().add(amount); - storage.balances.at(to).write(new_balance); + let new_balance = self.storage.balances.at(to).read().add(amount); + self.storage.balances.at(to).write(new_balance); } #[external("public")] #[view] fn check_balance(fee_limit: u128) { assert( - storage.balances.at(context.msg_sender().unwrap()).read() >= fee_limit, + self.storage.balances.at(self.msg_sender().unwrap()).read() >= fee_limit, "Balance too low", ); } @@ -88,6 +88,6 @@ pub contract FeeJuice { #[external("public")] #[view] fn balance_of_public(owner: AztecAddress) -> pub u128 { - storage.balances.at(owner).read() + self.storage.balances.at(owner).read() } } diff --git a/noir-projects/noir-contracts/contracts/protocol/multi_call_entrypoint_contract/src/main.nr b/noir-projects/noir-contracts/contracts/protocol/multi_call_entrypoint_contract/src/main.nr index 2f40476e05b9..10f48e6fa0b9 100644 --- a/noir-projects/noir-contracts/contracts/protocol/multi_call_entrypoint_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol/multi_call_entrypoint_contract/src/main.nr @@ -8,6 +8,6 @@ pub contract MultiCallEntrypoint { #[external("private")] fn entrypoint(app_payload: AppPayload) { - app_payload.execute_calls(&mut context); + app_payload.execute_calls(self.context); } } diff --git a/noir-projects/noir-contracts/contracts/protocol/router_contract/src/main.nr b/noir-projects/noir-contracts/contracts/protocol/router_contract/src/main.nr index 9ad7e37c655d..a930d4cc13cb 100644 --- a/noir-projects/noir-contracts/contracts/protocol/router_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/protocol/router_contract/src/main.nr @@ -15,7 +15,7 @@ pub contract Router { #[external("public")] #[view] fn check_timestamp(operation: u8, value: u64) { - let lhs_field = context.timestamp() as Field; + let lhs_field = self.context.timestamp() as Field; let rhs_field = value as Field; assert(compare(lhs_field, operation, rhs_field), "Timestamp mismatch."); } @@ -27,7 +27,11 @@ pub contract Router { #[view] fn check_block_number(operation: u8, value: u32) { assert( - compare(context.block_number() as Field, operation, value as Field), + compare( + self.context.block_number() as Field, + operation, + value as Field, + ), "Block number mismatch.", ); } diff --git a/noir-projects/noir-contracts/contracts/test/auth_wit_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/auth_wit_test_contract/src/main.nr index f226117492df..524cf162a5f0 100644 --- a/noir-projects/noir-contracts/contracts/test/auth_wit_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/auth_wit_test_contract/src/main.nr @@ -10,11 +10,11 @@ pub contract AuthWitTest { #[external("private")] fn consume(on_behalf_of: AztecAddress, inner_hash: Field) { - assert_inner_hash_valid_authwit(&mut context, on_behalf_of, inner_hash); + assert_inner_hash_valid_authwit(self.context, on_behalf_of, inner_hash); } #[external("public")] fn consume_public(on_behalf_of: AztecAddress, inner_hash: Field) { - assert_inner_hash_valid_authwit_public(&mut context, on_behalf_of, inner_hash); + assert_inner_hash_valid_authwit_public(self.context, on_behalf_of, inner_hash); } } diff --git a/noir-projects/noir-contracts/contracts/test/avm_initializer_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/avm_initializer_test_contract/src/main.nr index a00710d94c59..8cbd3af73cce 100644 --- a/noir-projects/noir-contracts/contracts/test/avm_initializer_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/avm_initializer_test_contract/src/main.nr @@ -19,11 +19,11 @@ pub contract AvmInitializerTest { #[external("public")] #[initializer] fn constructor() { - storage.immutable.initialize(42); + self.storage.immutable.initialize(42); } #[external("public")] fn read_storage_immutable() -> pub Field { - storage.immutable.read() + self.storage.immutable.read() } } diff --git a/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr index e0922df5d08e..1e0025bdb6cc 100644 --- a/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/avm_test_contract/src/main.nr @@ -61,55 +61,55 @@ pub contract AvmTest { ************************************************************************/ #[external("public")] fn set_storage_single(a: Field) { - storage.single.write(a); + self.storage.single.write(a); } #[external("public")] fn read_storage_single() -> Field { - storage.single.read() + self.storage.single.read() } #[external("public")] fn read_assert_storage_single(a: Field) { - assert(a == storage.single.read(), "Storage value does not match input"); + assert(a == self.storage.single.read(), "Storage value does not match input"); } // should still be able to use ` -> pub *` for return type even though macro forces `pub` #[external("public")] fn set_read_storage_single(a: Field) -> pub Field { - storage.single.write(a); - storage.single.read() + self.storage.single.write(a); + self.storage.single.read() } #[external("public")] fn set_storage_list(a: Field, b: Field) { - storage.list.write(Note { a, b }); + self.storage.list.write(Note { a, b }); } #[external("public")] fn read_storage_list() -> [Field; 2] { - let note: Note = storage.list.read(); + let note: Note = self.storage.list.read(); note.serialize() } #[external("public")] fn set_storage_map(to: AztecAddress, amount: u32) -> Field { - storage.map.at(to).write(amount); + self.storage.map.at(to).write(amount); // returns storage slot for key - derive_storage_slot_in_map(storage.map.get_storage_slot(), to) + derive_storage_slot_in_map(self.storage.map.get_storage_slot(), to) } #[external("public")] fn add_storage_map(to: AztecAddress, amount: u32) -> Field { - let new_balance = storage.map.at(to).read().add(amount); - storage.map.at(to).write(new_balance); + let new_balance = self.storage.map.at(to).read().add(amount); + self.storage.map.at(to).write(new_balance); // returns storage slot for key - derive_storage_slot_in_map(storage.map.get_storage_slot(), to) + derive_storage_slot_in_map(self.storage.map.get_storage_slot(), to) } #[external("public")] fn read_storage_map(address: AztecAddress) -> u32 { - storage.map.at(address).read() + self.storage.map.at(address).read() } #[external("public")] @@ -270,7 +270,7 @@ pub contract AvmTest { #[external("public")] fn external_call_to_assertion_failure() { - AvmTest::at(context.this_address()).assertion_failure().call(&mut context); + AvmTest::at(self.address).assertion_failure().call(self.context); } #[external("public")] @@ -281,7 +281,7 @@ pub contract AvmTest { #[external("public")] fn external_call_to_divide_by_zero() { - let _ = AvmTest::at(context.this_address()).divide_by_zero(0).call(&mut context); + let _ = AvmTest::at(self.address).divide_by_zero(0).call(self.context); } #[external("public")] @@ -291,15 +291,15 @@ pub contract AvmTest { // Get the gas remaining and allocate some smaller amount to nested call. // We don't want to allocate too much to the nested call // since it will all be consumed on exceptional halt. - let l2_gas_left = context.l2_gas_left(); - let da_gas_left = context.da_gas_left(); + let l2_gas_left = self.context.l2_gas_left(); + let da_gas_left = self.context.da_gas_left(); let selector = FunctionSelector::from_signature("divide_by_zero(u8)"); // Call without capturing a return value since call no longer returns success call( l2_gas_left - 200_000, da_gas_left - 200_000, - context.this_address(), + self.address, &[selector.to_field(), 0], ); @@ -352,7 +352,7 @@ pub contract AvmTest { #[external("public")] fn returndata_copy_oracle() { - let _ = AvmTest::at(context.this_address()).return_oracle().call(&mut context); + let _ = AvmTest::at(self.address).return_oracle().call(self.context); let returndatasize = returndata_size(); let returndata = returndata_copy(0, returndatasize); assert(returndata == &[1, 2, 3], "Returndata copy failed"); @@ -431,72 +431,72 @@ pub contract AvmTest { ************************************************************************/ #[external("public")] fn get_address() -> AztecAddress { - context.this_address() + self.address } #[external("public")] fn get_sender() -> AztecAddress { - context.msg_sender_unsafe() + self.context.msg_sender_unsafe() } #[external("public")] fn get_transaction_fee() -> Field { - context.transaction_fee() + self.context.transaction_fee() } #[external("public")] fn get_chain_id() -> Field { - context.chain_id() + self.context.chain_id() } #[external("public")] fn get_version() -> Field { - context.version() + self.context.version() } #[external("public")] fn get_block_number() -> u32 { - context.block_number() + self.context.block_number() } #[external("public")] fn get_timestamp() -> u64 { - context.timestamp() + self.context.timestamp() } #[external("public")] fn get_fee_per_l2_gas() -> u128 { - context.base_fee_per_l2_gas() + self.context.base_fee_per_l2_gas() } #[external("public")] fn get_fee_per_da_gas() -> u128 { - context.base_fee_per_da_gas() + self.context.base_fee_per_da_gas() } #[external("public")] fn get_l2_gas_left() -> u32 { - context.l2_gas_left() + self.context.l2_gas_left() } #[external("public")] fn get_da_gas_left() -> u32 { - context.da_gas_left() + self.context.da_gas_left() } #[external("public")] fn get_args_hash(_a: u8, _fields: [Field; 3]) -> Field { - context.get_args_hash() + self.context.get_args_hash() } #[external("public")] fn emit_public_log() { - context.emit_public_log(/*message=*/ [10, 20, 30]); - context.emit_public_log(/*message=*/ "Hello, world!"); + self.context.emit_public_log(/*message=*/ [10, 20, 30]); + self.context.emit_public_log(/*message=*/ "Hello, world!"); let s: CompressedString<2, 44> = CompressedString::from_string("A long time ago, in a galaxy far far away..."); - context.emit_public_log(/*message=*/ s); - context.emit_public_log(/*message=*/ [ + self.context.emit_public_log(/*message=*/ s); + self.context.emit_public_log(/*message=*/ [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, ]); // Large log @@ -504,94 +504,91 @@ pub contract AvmTest { #[external("public")] fn note_hash_exists(note_hash: Field, leaf_index: u64) -> bool { - context.note_hash_exists(note_hash, leaf_index) + self.context.note_hash_exists(note_hash, leaf_index) } // Use the standard context interface to emit a new note hash #[external("public")] fn new_note_hash(note_hash: Field) { - context.push_note_hash(note_hash); + self.context.push_note_hash(note_hash); } // Use the standard context interface to emit a new nullifier #[external("public")] fn new_nullifier(nullifier: Field) { - context.push_nullifier(nullifier); + self.context.push_nullifier(nullifier); } #[external("public")] fn n_storage_writes(num: u32) { for i in 0..num { - storage.map.at(AztecAddress::from_field(i as Field)).write(i); + self.storage.map.at(AztecAddress::from_field(i as Field)).write(i); } } #[external("public")] fn n_new_note_hashes(num: u32) { for i in 0..num { - context.push_note_hash(i as Field); + self.context.push_note_hash(i as Field); } } #[external("public")] fn n_new_nullifiers(num: u32) { for i in 0..num { - context.push_nullifier(i as Field); + self.context.push_nullifier(i as Field); } } #[external("public")] fn n_new_l2_to_l1_msgs(num: u32) { for i in 0..num { - context.message_portal(EthAddress::from_field(i as Field), i as Field) + self.context.message_portal(EthAddress::from_field(i as Field), i as Field) } } #[external("public")] fn n_new_public_logs(num: u32) { for i in 0..num { - context.emit_public_log(/*message=*/ [i as Field]); + self.context.emit_public_log(/*message=*/ [i as Field]); } } // Use the standard context interface to check for a nullifier #[external("public")] fn nullifier_exists(nullifier: Field) -> bool { - context.nullifier_exists(nullifier, context.this_address()) + self.context.nullifier_exists(nullifier, self.address) } #[external("public")] fn assert_nullifier_exists(nullifier: Field) { - assert( - context.nullifier_exists(nullifier, context.this_address()), - "Nullifier doesn't exist!", - ); + assert(self.context.nullifier_exists(nullifier, self.address), "Nullifier doesn't exist!"); } // Use the standard context interface to emit a new nullifier #[external("public")] fn emit_nullifier_and_check(nullifier: Field) { - context.push_nullifier(nullifier); - let exists = context.nullifier_exists(nullifier, context.this_address()); + self.context.push_nullifier(nullifier); + let exists = self.context.nullifier_exists(nullifier, self.address); assert(exists, "Nullifier was just created, but its existence wasn't detected!"); } // Create the same nullifier twice (shouldn't work!) #[external("public")] fn nullifier_collision(nullifier: Field) { - context.push_nullifier(nullifier); + self.context.push_nullifier(nullifier); // Can't do this twice! - context.push_nullifier(nullifier); + self.context.push_nullifier(nullifier); } #[external("public")] fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: Field) -> bool { - context.l1_to_l2_msg_exists(msg_hash, msg_leaf_index) + self.context.l1_to_l2_msg_exists(msg_hash, msg_leaf_index) } #[external("public")] fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) { - context.message_portal(recipient, content) + self.context.message_portal(recipient, content) } /************************************************************************ @@ -600,7 +597,7 @@ pub contract AvmTest { #[external("public")] fn nested_call_to_nothing() { let garbageAddress = AztecAddress::from_field(42); - AvmTest::at(garbageAddress).nested_call_to_nothing().call(&mut context) + AvmTest::at(garbageAddress).nested_call_to_nothing().call(self.context) } #[external("public")] @@ -621,16 +618,16 @@ pub contract AvmTest { l2_gas: u32, da_gas: u32, ) -> pub Field { - AvmTest::at(context.this_address()) + AvmTest::at(self.address) .add_args_return(arg_a, arg_b) .with_gas(GasOpts::new(l2_gas, da_gas)) - .call(&mut context) + .call(self.context) } // Use the `call_public_function` wrapper to initiate a nested call to the add function #[external("public")] fn nested_call_to_add(arg_a: Field, arg_b: Field) -> pub Field { - AvmTest::at(context.this_address()).add_args_return(arg_a, arg_b).call(&mut context) + AvmTest::at(self.address).add_args_return(arg_a, arg_b).call(self.context) } #[external("public")] @@ -640,7 +637,7 @@ pub contract AvmTest { for i in 0..MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS + 2 { let addr = addrs[i]; if addr != AztecAddress::empty() { - let _ = AvmTest::at(addr).add_args_return(1, 2).call(&mut context); + let _ = AvmTest::at(addr).add_args_return(1, 2).call(self.context); } } } @@ -648,30 +645,30 @@ pub contract AvmTest { // Indirectly call_static the external call opcode to initiate a nested call to the add function #[external("public")] fn nested_static_call_to_add(arg_a: Field, arg_b: Field) -> pub Field { - AvmTest::at(context.this_address()).add_args_return(arg_a, arg_b).view(&mut context) + AvmTest::at(self.address).add_args_return(arg_a, arg_b).view(self.context) } - // Indirectly call_static `set_storage_single`. Should revert since it's accessing storage. + // Indirectly call_static `set_storage_single`. Should revert since it's accessing self.storage. #[external("public")] fn nested_static_call_to_set_storage() { - AvmTest::at(context.this_address()).set_storage_single(20).view(&mut context); + AvmTest::at(self.address).set_storage_single(20).view(self.context); } #[external("public")] fn create_same_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) { - context.push_nullifier(nullifier); - AvmTest::at(nestedAddress).new_nullifier(nullifier).call(&mut context); + self.context.push_nullifier(nullifier); + AvmTest::at(nestedAddress).new_nullifier(nullifier).call(self.context); } #[external("public")] fn create_different_nullifier_in_nested_call(nestedAddress: AztecAddress, nullifier: Field) { - context.push_nullifier(nullifier); - AvmTest::at(nestedAddress).new_nullifier(nullifier + 1).call(&mut context); + self.context.push_nullifier(nullifier); + AvmTest::at(nestedAddress).new_nullifier(nullifier + 1).call(self.context); } #[external("public")] fn nested_call_to_assert_same(arg_a: Field, arg_b: Field) -> pub Field { - AvmTest::at(context.this_address()).assert_same(arg_a, arg_b).call(&mut context) + AvmTest::at(self.address).assert_same(arg_a, arg_b).call(self.context) } // function with large array as calldata (for benchmarking call interface macros) @@ -682,7 +679,7 @@ pub contract AvmTest { } #[external("public")] fn nested_call_large_calldata(arr: [Field; 300]) -> pub Field { - AvmTest::at(context.this_address()).fn_w_large_calldata(arr).call(&mut context) + AvmTest::at(self.address).fn_w_large_calldata(arr).call(self.context) } /** @@ -690,8 +687,8 @@ pub contract AvmTest { */ #[external("private")] fn enqueue_public_from_private() { - AvmTest::at(context.this_address()).set_opcode_u8().enqueue_view(&mut context); - AvmTest::at(context.this_address()).set_read_storage_single(5).enqueue(&mut context); + AvmTest::at(self.address).set_opcode_u8().enqueue_view(self.context); + AvmTest::at(self.address).set_read_storage_single(5).enqueue(self.context); } /************************************************************************ @@ -699,23 +696,21 @@ pub contract AvmTest { ************************************************************************/ #[external("public")] fn call_fee_juice() { - let _ = FeeJuice::at(FEE_JUICE_ADDRESS).balance_of_public(context.this_address()).view( - &mut context, - ); + let _ = FeeJuice::at(FEE_JUICE_ADDRESS).balance_of_public(self.address).view(self.context); } #[external("public")] fn call_auth_registry() { - let _ = AuthRegistry::at(CANONICAL_AUTH_REGISTRY_ADDRESS) - .is_reject_all(context.this_address()) - .view(&mut context); + let _ = AuthRegistry::at(CANONICAL_AUTH_REGISTRY_ADDRESS).is_reject_all(self.address).view( + self.context, + ); } #[external("public")] fn call_instance_registry() { let _ = ContractInstanceRegistry::at(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS) .get_update_delay() - .view(&mut context); + .view(self.context); } /************************************************************************ @@ -742,11 +737,11 @@ pub contract AvmTest { dep::aztec::oracle::debug_log::debug_log("set_storage_list"); set_storage_list(40, 50); dep::aztec::oracle::debug_log::debug_log("read_storage_list"); - let _ = set_storage_map(context.this_address(), 60); + let _ = set_storage_map(self.address, 60); dep::aztec::oracle::debug_log::debug_log("add_storage_map"); - let _ = add_storage_map(context.this_address(), 10); + let _ = add_storage_map(self.address, 10); dep::aztec::oracle::debug_log::debug_log("read_storage_map"); - let _ = read_storage_map(context.this_address()); + let _ = read_storage_map(self.address); dep::aztec::oracle::debug_log::debug_log("keccak_hash"); let _ = keccak256::keccak256(args_u8, args_u8.len()); dep::aztec::oracle::debug_log::debug_log("sha256_hash"); diff --git a/noir-projects/noir-contracts/contracts/test/benchmarking_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/benchmarking_contract/src/main.nr index 5a11c4edbefa..55db934aba41 100644 --- a/noir-projects/noir-contracts/contracts/test/benchmarking_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/benchmarking_contract/src/main.nr @@ -26,7 +26,7 @@ pub contract Benchmarking { #[external("private")] fn create_note(owner: AztecAddress, value: Field) { let note = ValueNote::new(value, owner); - storage.notes.at(owner).insert(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.notes.at(owner).insert(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); } // Deletes a note at a specific index in the set and creates a new one with the same value. // We explicitly pass in the note index so we can ensure we consume different notes when sending @@ -35,7 +35,7 @@ pub contract Benchmarking { // by @rahul-kothari for a full explanation on why this is needed. #[external("private")] fn recreate_note(owner: AztecAddress, index: u32) { - let owner_notes = storage.notes.at(owner); + let owner_notes = self.storage.notes.at(owner); let mut getter_options = NoteGetterOptions::new(); let notes = owner_notes.pop_notes(getter_options.set_limit(1).set_offset(index)); let note = notes.get(0); @@ -45,15 +45,15 @@ pub contract Benchmarking { // Reads and writes to public storage and enqueues a call to another public function. #[external("public")] fn increment_balance(owner: AztecAddress, value: Field) { - let current = storage.balances.at(owner).read(); - storage.balances.at(owner).write(current + value); - Benchmarking::at(context.this_address()).broadcast(owner).call(&mut context); + let current = self.storage.balances.at(owner).read(); + self.storage.balances.at(owner).write(current + value); + Benchmarking::at(self.address).broadcast(owner).call(self.context); } // Emits a public log. #[external("public")] fn broadcast(owner: AztecAddress) { - context.emit_public_log(storage.balances.at(owner).read()); + self.context.emit_public_log(self.storage.balances.at(owner).read()); } // Does a bunch of heavy compute diff --git a/noir-projects/noir-contracts/contracts/test/child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/child_contract/src/main.nr index a3aa56793b5c..90846d3c56b9 100644 --- a/noir-projects/noir-contracts/contracts/test/child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/child_contract/src/main.nr @@ -23,24 +23,24 @@ pub contract Child { // Returns a sum of the input and the chain id and version of the contract in private circuit public input's return_values. #[external("private")] fn value(input: Field) -> Field { - input + context.chain_id() + context.version() + input + self.context.chain_id() + self.context.version() } // Returns a sum of the input and the chain id and version of the contract in private circuit public input's return_values. // Can only be called from this contract. #[external("private")] #[internal] fn value_internal(input: Field) -> Field { - input + context.chain_id() + context.version() + input + self.context.chain_id() + self.context.version() } // Returns base_value + chain_id + version + block_number + timestamp #[external("public")] fn pub_get_value(base_value: Field) -> Field { let return_value = base_value - + context.chain_id() - + context.version() - + context.block_number() as Field - + context.timestamp() as Field; + + self.context.chain_id() + + self.context.version() + + self.context.block_number() as Field + + self.context.timestamp() as Field; return_value } @@ -48,8 +48,8 @@ pub contract Child { // Sets `current_value` to `new_value` #[external("public")] fn pub_set_value(new_value: Field) -> Field { - storage.current_value.write(new_value); - context.emit_public_log(new_value); + self.storage.current_value.write(new_value); + self.context.emit_public_log(new_value); new_value } @@ -58,7 +58,7 @@ pub contract Child { fn private_set_value(new_value: Field, owner: AztecAddress) -> Field { let note = ValueNote::new(new_value, owner); - storage.a_map_with_private_values.at(owner).insert(note).emit( + self.storage.a_map_with_private_values.at(owner).insert(note).emit( owner, MessageDelivery.CONSTRAINED_ONCHAIN, ); @@ -69,16 +69,16 @@ pub contract Child { fn private_get_value(amount: Field, owner: AztecAddress) -> Field { let mut options = NoteGetterOptions::new(); options = options.select(ValueNote::properties().value, Comparator.EQ, amount).set_limit(1); - let retrieved_notes = storage.a_map_with_private_values.at(owner).get_notes(options); + let retrieved_notes = self.storage.a_map_with_private_values.at(owner).get_notes(options); retrieved_notes.get(0).note.value() } // Increments `current_value` by `new_value` #[external("public")] fn pub_inc_value(new_value: Field) -> Field { - let old_value = storage.current_value.read(); - storage.current_value.write(old_value + new_value); - context.emit_public_log(new_value); + let old_value = self.storage.current_value.read(); + self.storage.current_value.write(old_value + new_value); + self.context.emit_public_log(new_value); new_value } @@ -87,32 +87,32 @@ pub contract Child { #[external("public")] #[internal] fn pub_inc_value_internal(new_value: Field) -> Field { - let old_value = storage.current_value.read(); - storage.current_value.write(old_value + new_value); - context.emit_public_log(new_value); + let old_value = self.storage.current_value.read(); + self.storage.current_value.write(old_value + new_value); + self.context.emit_public_log(new_value); new_value } #[external("public")] fn set_value_twice_with_nested_first() { - let _result = Child::at(context.this_address()).pub_set_value(10).call(&mut context); - storage.current_value.write(20); - context.emit_public_log(20); + let _result = Child::at(self.address).pub_set_value(10).call(self.context); + self.storage.current_value.write(20); + self.context.emit_public_log(20); } #[external("public")] fn set_value_twice_with_nested_last() { - storage.current_value.write(20); - context.emit_public_log(20); - let _result = Child::at(context.this_address()).pub_set_value(10).call(&mut context); + self.storage.current_value.write(20); + self.context.emit_public_log(20); + let _result = Child::at(self.address).pub_set_value(10).call(self.context); } #[external("public")] fn set_value_with_two_nested_calls() { - Child::at(context.this_address()).set_value_twice_with_nested_first().call(&mut context); - Child::at(context.this_address()).set_value_twice_with_nested_last().call(&mut context); - storage.current_value.write(20); - context.emit_public_log(20); + Child::at(self.address).set_value_twice_with_nested_first().call(self.context); + Child::at(self.address).set_value_twice_with_nested_last().call(self.context); + self.storage.current_value.write(20); + self.context.emit_public_log(20); } } diff --git a/noir-projects/noir-contracts/contracts/test/counter_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/counter_contract/src/main.nr index 6d7071fc6e24..6f42feef6306 100644 --- a/noir-projects/noir-contracts/contracts/test/counter_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/counter_contract/src/main.nr @@ -26,7 +26,7 @@ pub contract Counter { #[external("private")] // We can name our initializer anything we want as long as it's marked as aztec(initializer) fn initialize(headstart: u64, owner: AztecAddress) { - let counters = storage.counters; + let counters = self.storage.counters; counters.at(owner).add(headstart, owner); } // docs:end:constructor @@ -35,7 +35,7 @@ pub contract Counter { #[external("private")] fn increment(owner: AztecAddress) { debug_log_format("Incrementing counter for owner {0}", [owner.to_field()]); - let counters = storage.counters; + let counters = self.storage.counters; counters.at(owner).add(1, owner); } // docs:end:increment @@ -46,7 +46,7 @@ pub contract Counter { "Incrementing counter twice for owner {0}", [owner.to_field()], ); - let counters = storage.counters; + let counters = self.storage.counters; counters.at(owner).add(1, owner); counters.at(owner).add(1, owner); } @@ -57,7 +57,7 @@ pub contract Counter { "Incrementing and decrementing counter for owner {0}", [owner.to_field()], ); - let counters = storage.counters; + let counters = self.storage.counters; counters.at(owner).add(1, owner); counters.at(owner).sub(1, owner); } @@ -65,14 +65,14 @@ pub contract Counter { #[external("private")] fn decrement(owner: AztecAddress) { debug_log_format("Decrementing counter for owner {0}", [owner.to_field()]); - let counters = storage.counters; + let counters = self.storage.counters; counters.at(owner).sub(1, owner); } // docs:start:get_counter #[external("utility")] unconstrained fn get_counter(owner: AztecAddress) -> Field { - storage.counters.at(owner).get_value() + self.storage.counters.at(owner).get_value() } // docs:end:get_counter @@ -80,10 +80,10 @@ pub contract Counter { fn increment_self_and_other(other_counter: AztecAddress, owner: AztecAddress) { debug_log_format("Incrementing counter for other {0}", [owner.to_field()]); - let counters = storage.counters; + let counters = self.storage.counters; counters.at(owner).add(1, owner); - Counter::at(other_counter).increment(owner).call(&mut context); + Counter::at(other_counter).increment(owner).call(self.context); } mod test { diff --git a/noir-projects/noir-contracts/contracts/test/event_only_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/event_only_contract/src/main.nr index afa41e765e8b..aaf208ae332a 100644 --- a/noir-projects/noir-contracts/contracts/test/event_only_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/event_only_contract/src/main.nr @@ -5,7 +5,6 @@ use aztec::macros::aztec; #[aztec] contract EventOnly { use aztec::{ - event::event_emission::emit_event_in_private, macros::{events::event, functions::external}, messages::message_delivery::MessageDelivery, }; @@ -17,12 +16,7 @@ contract EventOnly { #[external("private")] fn emit_event_for_msg_sender(value: Field) { - let sender = context.msg_sender().unwrap(); - emit_event_in_private( - TestEvent { value }, - &mut context, - sender, - MessageDelivery.UNCONSTRAINED_ONCHAIN, - ); + let sender = self.msg_sender().unwrap(); + self.emit(TestEvent { value }, sender, MessageDelivery.UNCONSTRAINED_ONCHAIN); } } diff --git a/noir-projects/noir-contracts/contracts/test/import_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/import_test_contract/src/main.nr index f95decdfa560..b187ac00a859 100644 --- a/noir-projects/noir-contracts/contracts/test/import_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/import_test_contract/src/main.nr @@ -15,7 +15,7 @@ pub contract ImportTest { // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[external("private")] fn call_no_args(target: AztecAddress) -> AztecAddress { - Test::at(target).get_this_address().call(&mut context) + Test::at(target).get_this_address().call(self.context) } // Calls the emit_nullifier_public on the Test contract at the target address @@ -23,7 +23,7 @@ pub contract ImportTest { // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[external("private")] fn call_public_fn(target: AztecAddress) { - Test::at(target).emit_nullifier_public(1).enqueue(&mut context); + Test::at(target).emit_nullifier_public(1).enqueue(self.context); } // Calls the emit_nullifier_public on the Test contract at the target address @@ -31,6 +31,6 @@ pub contract ImportTest { // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[external("public")] fn pub_call_public_fn(target: AztecAddress) { - Test::at(target).emit_nullifier_public(1).call(&mut context); + Test::at(target).emit_nullifier_public(1).call(self.context); } } diff --git a/noir-projects/noir-contracts/contracts/test/no_constructor_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/no_constructor_contract/src/main.nr index 66a376ca6b6e..e1722da0ed8b 100644 --- a/noir-projects/noir-contracts/contracts/test/no_constructor_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/no_constructor_contract/src/main.nr @@ -20,17 +20,17 @@ pub contract NoConstructor { /// Arbitrary public method used to test that publishing for public execution works for a contract with no constructor. #[external("public")] fn emit_public(value: Field) { - context.emit_public_log(/*message=*/ value); + self.context.emit_public_log(/*message=*/ value); } /// Arbitrary function used to test that we can call private functions on a contract with /// no constructor/initializer. #[external("private")] fn initialize_private_mutable(value: Field) { - let note = ValueNote::new(value, context.msg_sender().unwrap()); + let note = ValueNote::new(value, self.msg_sender().unwrap()); - storage.private_mutable.initialize(note).emit( - context.msg_sender().unwrap(), + self.storage.private_mutable.initialize(note).emit( + self.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN, ); } @@ -38,7 +38,7 @@ pub contract NoConstructor { /// Helper function used to test that call to `initialize_private_mutable` was successful or not yet performed. #[external("utility")] unconstrained fn is_private_mutable_initialized() -> bool { - storage.private_mutable.is_initialized() + self.storage.private_mutable.is_initialized() } } diff --git a/noir-projects/noir-contracts/contracts/test/note_getter_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/note_getter_contract/src/main.nr index 94fd0f219f6c..0df7447ebee7 100644 --- a/noir-projects/noir-contracts/contracts/test/note_getter_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/note_getter_contract/src/main.nr @@ -22,17 +22,17 @@ pub contract NoteGetter { #[external("private")] fn insert_note(value: Field) { - let note = ValueNote::new(value, context.msg_sender().unwrap()); + let note = ValueNote::new(value, self.msg_sender().unwrap()); - storage.set.insert(note).emit( - context.msg_sender().unwrap(), + self.storage.set.insert(note).emit( + self.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN, ); } #[external("utility")] unconstrained fn read_note_values(comparator: u8, value: Field) -> BoundedVec { - let notes = storage.set.view_notes(NoteViewerOptions::new().select( + let notes = self.storage.set.view_notes(NoteViewerOptions::new().select( ValueNote::properties().value, comparator, value, diff --git a/noir-projects/noir-contracts/contracts/test/offchain_effect_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/offchain_effect_contract/src/main.nr index cd51465f99ae..b4310786fd04 100644 --- a/noir-projects/noir-contracts/contracts/test/offchain_effect_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/offchain_effect_contract/src/main.nr @@ -4,7 +4,6 @@ use aztec::macros::aztec; #[aztec] contract OffchainEffect { use aztec::{ - event::event_emission::emit_event_in_private, macros::{events::event, functions::external, storage::storage}, messages::message_delivery::MessageDelivery, note::note_viewer_options::NoteViewerOptions, @@ -43,7 +42,7 @@ contract OffchainEffect { if effects.len() > 0 { OffchainEffect::at(payload.next_contract).emit_offchain_effects(effects).call( - &mut context, + self.context, ); } } @@ -51,10 +50,9 @@ contract OffchainEffect { #[external("private")] fn emit_event_as_offchain_message_for_msg_sender(a: u64, b: u64, c: u64) { - emit_event_in_private( + self.emit( TestEvent { a, b, c }, - &mut context, - context.msg_sender().unwrap(), + self.msg_sender().unwrap(), MessageDelivery.UNCONSTRAINED_OFFCHAIN, ); } @@ -63,8 +61,8 @@ contract OffchainEffect { fn emit_note_as_offchain_message(value: u128, owner: AztecAddress) { let note = UintNote::new(value, owner); - storage.balances.at(owner).insert(note).emit( - context.msg_sender().unwrap(), + self.storage.balances.at(owner).insert(note).emit( + self.msg_sender().unwrap(), MessageDelivery.UNCONSTRAINED_OFFCHAIN, ); } @@ -76,7 +74,7 @@ contract OffchainEffect { #[external("utility")] unconstrained fn get_note_value(owner: AztecAddress) -> u128 { - let notes = storage.balances.at(owner).view_notes(NoteViewerOptions::new()); + let notes = self.storage.balances.at(owner).view_notes(NoteViewerOptions::new()); assert(notes.len() == 1, "No note found"); notes.get(0).get_value() } diff --git a/noir-projects/noir-contracts/contracts/test/parent_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/parent_contract/src/main.nr index 4fbed6b8aac5..151b2d5a4f9a 100644 --- a/noir-projects/noir-contracts/contracts/test/parent_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/parent_contract/src/main.nr @@ -12,7 +12,7 @@ pub contract Parent { #[external("private")] fn entry_point(target_contract: AztecAddress, target_selector: FunctionSelector) -> Field { // Call the target private function - context.call_private_function(target_contract, target_selector, [0]).get_preimage() + self.context.call_private_function(target_contract, target_selector, [0]).get_preimage() } // Public function to directly call another public function to the target_contract using the selector and value provided #[external("public")] @@ -21,7 +21,7 @@ pub contract Parent { target_selector: FunctionSelector, init_value: Field, ) -> Field { - context.call_public_function( + self.context.call_public_function( target_contract, target_selector, [init_value].as_slice(), @@ -35,13 +35,13 @@ pub contract Parent { target_selector: FunctionSelector, init_value: Field, ) -> Field { - let return_value: Field = context.call_public_function( + let return_value: Field = self.context.call_public_function( target_contract, target_selector, [init_value].as_slice(), GasOpts::default(), )[0]; - context.call_public_function( + self.context.call_public_function( target_contract, target_selector, [return_value].as_slice(), @@ -55,7 +55,7 @@ pub contract Parent { target_selector: FunctionSelector, target_value: Field, ) { - context.call_public_function(target_contract, target_selector, [target_value], false); + self.context.call_public_function(target_contract, target_selector, [target_value], false); } #[external("public")] @@ -67,13 +67,11 @@ pub contract Parent { fn enqueue_call_to_child_with_many_args_and_recurse(remaining_recursions: u32) { let args = [0; MAX_FR_CALLDATA_TO_ALL_ENQUEUED_CALLS / 10]; // +1 for function selector brings us to max - Parent::at(context.this_address()).public_call_with_max_over_n_args(args).enqueue( - &mut context, - ); + Parent::at(self.address).public_call_with_max_over_n_args(args).enqueue(self.context); if remaining_recursions > 0 { - Parent::at(context.this_address()) + Parent::at(self.address) .enqueue_call_to_child_with_many_args_and_recurse(remaining_recursions - 1) - .call(&mut context); + .call(self.context); } } @@ -88,12 +86,12 @@ pub contract Parent { let enqueue_call_to_child_selector = comptime { FunctionSelector::from_signature("enqueue_call_to_child((Field),(u32),Field)") }; - let _ret = context.call_private_function( - context.this_address(), + let _ret = self.context.call_private_function( + self.address, enqueue_call_to_child_selector, [target_contract.to_field(), target_selector.to_field(), 10], ); - context.call_public_function(target_contract, target_selector, [20], false); + self.context.call_public_function(target_contract, target_selector, [20], false); } // Private function that enqueues two calls to a child contract: // - one issued directly from this function with value 20, @@ -103,12 +101,12 @@ pub contract Parent { target_contract: AztecAddress, target_selector: FunctionSelector, ) { - context.call_public_function(target_contract, target_selector, [20], false); + self.context.call_public_function(target_contract, target_selector, [20], false); let enqueue_call_to_child_selector = comptime { FunctionSelector::from_signature("enqueue_call_to_child((Field),(u32),Field)") }; - let _ret = context.call_private_function( - context.this_address(), + let _ret = self.context.call_private_function( + self.address, enqueue_call_to_child_selector, [target_contract.to_field(), target_selector.to_field(), 10], ); @@ -121,9 +119,14 @@ pub contract Parent { target_value: Field, ) { // Enqueue the first public call - context.call_public_function(target_contract, target_selector, [target_value], false); + self.context.call_public_function(target_contract, target_selector, [target_value], false); // Enqueue the second public call - context.call_public_function(target_contract, target_selector, [target_value + 1], false); + self.context.call_public_function( + target_contract, + target_selector, + [target_value + 1], + false, + ); } // Private function to enqueue a call to the pub_entry_point function of this same contract, passing the target arguments provided #[external("private")] @@ -134,9 +137,8 @@ pub contract Parent { ) { let pub_entry_point_selector = comptime { FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)") }; - let this_address = context.this_address(); - let _void = context.call_public_function( - this_address, + let _void = self.context.call_public_function( + self.address, pub_entry_point_selector, [target_contract.to_field(), target_selector.to_field(), target_value], false, @@ -151,15 +153,14 @@ pub contract Parent { ) { let pub_entry_point_selector = comptime { FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)") }; - let this_address = context.this_address(); - context.call_public_function( - this_address, + self.context.call_public_function( + self.address, pub_entry_point_selector, [target_contract.to_field(), target_selector.to_field(), target_value], false, ); - context.call_public_function( - this_address, + self.context.call_public_function( + self.address, pub_entry_point_selector, [target_contract.to_field(), target_selector.to_field(), target_value + 1], false, @@ -172,7 +173,10 @@ pub contract Parent { args: [Field; 2], ) -> Field { // Call the target private function - context.static_call_private_function(target_contract, target_selector, args).get_preimage() + self + .context + .static_call_private_function(target_contract, target_selector, args) + .get_preimage() } #[external("private")] fn private_call( @@ -181,7 +185,7 @@ pub contract Parent { args: [Field; 2], ) -> Field { // Call the target private function - context.call_private_function(target_contract, target_selector, args).get_preimage() + self.context.call_private_function(target_contract, target_selector, args).get_preimage() } // Private function to set a static context and verify correct propagation for nested private calls #[external("private")] @@ -193,10 +197,10 @@ pub contract Parent { // Call the target private function statically let private_call_selector = FunctionSelector::from_signature("private_call((Field),(u32),[Field;2])"); - let this_address = context.this_address(); - let return_value: Field = context + let return_value: Field = self + .context .static_call_private_function( - this_address, + self.address, private_call_selector, [target_contract.to_field(), target_selector.to_field(), args[0], args[1]], ) @@ -211,7 +215,7 @@ pub contract Parent { target_selector: FunctionSelector, args: [Field; 1], ) -> Field { - context.static_call_public_function( + self.context.static_call_public_function( target_contract, target_selector, args.as_slice(), @@ -228,9 +232,8 @@ pub contract Parent { // Call the target public function through the pub entrypoint statically let pub_entry_point_selector = FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)"); - let this_address = context.this_address(); - context.static_call_public_function( - this_address, + self.context.static_call_public_function( + self.address, pub_entry_point_selector, [target_contract.to_field(), target_selector.to_field(), args[0]].as_slice(), GasOpts::default(), @@ -246,9 +249,8 @@ pub contract Parent { // Call the target public function through the pub entrypoint statically let pub_entry_point_selector = FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)"); - let this_address = context.this_address(); - context.static_call_public_function( - this_address, + self.context.static_call_public_function( + self.address, pub_entry_point_selector, [target_contract.to_field(), target_selector.to_field(), args[0]], false, @@ -262,7 +264,7 @@ pub contract Parent { args: [Field; 1], ) { // Call the target private function - context.static_call_public_function(target_contract, target_selector, args, false); + self.context.static_call_public_function(target_contract, target_selector, args, false); } use dep::aztec::test::helpers::test_environment::TestEnvironment; use dep::child_contract::Child; diff --git a/noir-projects/noir-contracts/contracts/test/pending_note_hashes_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/pending_note_hashes_contract/src/main.nr index ff37cb971bd4..069a5415cbc5 100644 --- a/noir-projects/noir-contracts/contracts/test/pending_note_hashes_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/pending_note_hashes_contract/src/main.nr @@ -39,7 +39,7 @@ pub contract PendingNoteHashes { owner: AztecAddress, sender: AztecAddress, ) -> Field { - let owner_balance = storage.balances.at(owner); + let owner_balance = self.storage.balances.at(owner); let note = ValueNote::new(amount, owner); @@ -60,7 +60,7 @@ pub contract PendingNoteHashes { // Confirm cannot access note hashes inserted later in same function #[external("private")] fn test_bad_get_then_insert_flat(amount: Field, owner: AztecAddress) -> Field { - let owner_balance = storage.balances.at(owner); + let owner_balance = self.storage.balances.at(owner); let options = NoteGetterOptions::with_filter(filter_notes_min_sum, amount); // get note (note inserted at bottom of function shouldn't exist yet) @@ -82,7 +82,7 @@ pub contract PendingNoteHashes { // Nested/inner function to create and insert a note #[external("private")] fn insert_note(amount: Field, owner: AztecAddress, sender: AztecAddress) { - let owner_balance = storage.balances.at(owner); + let owner_balance = self.storage.balances.at(owner); let note = ValueNote::new(amount, owner); @@ -95,7 +95,7 @@ pub contract PendingNoteHashes { // the same note hash are dealt with correctly #[external("private")] fn insert_note_static_randomness(amount: Field, owner: AztecAddress, sender: AztecAddress) { - let owner_balance = storage.balances.at(owner); + let owner_balance = self.storage.balances.at(owner); let randomness = 2; // Note that the following is severely misusing the Packable trait as we should never be messing with internal @@ -110,7 +110,7 @@ pub contract PendingNoteHashes { // then emit another note log for the same note #[external("private")] fn insert_note_extra_emit(amount: Field, owner: AztecAddress, sender: AztecAddress) { - let owner_balance = storage.balances.at(owner); + let owner_balance = self.storage.balances.at(owner); let note = ValueNote::new(amount, owner); @@ -126,7 +126,7 @@ pub contract PendingNoteHashes { // Nested/inner function to get a note and confirm it matches the expected value #[external("private")] fn get_then_nullify_note(expected_value: Field, owner: AztecAddress) -> Field { - let owner_balance = storage.balances.at(owner); + let owner_balance = self.storage.balances.at(owner); let mut options = NoteGetterOptions::new(); options = options.set_limit(1); @@ -139,7 +139,7 @@ pub contract PendingNoteHashes { // Nested/inner function to get a note and confirms that none is returned #[external("private")] fn get_note_zero_balance(owner: AztecAddress) { - let owner_balance = storage.balances.at(owner); + let owner_balance = self.storage.balances.at(owner); let options = NoteGetterOptions::new(); let notes = owner_balance.get_notes(options); @@ -159,13 +159,13 @@ pub contract PendingNoteHashes { get_then_nullify_fn_selector: FunctionSelector, ) { // nested call to create/insert note - let _res = context.call_private_function( + let _res = self.context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, [amount, owner.to_field(), sender.to_field()], ); // nested call to read and nullify that note - let _res = context.call_private_function( + let _res = self.context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, [amount, owner.to_field()], @@ -186,30 +186,30 @@ pub contract PendingNoteHashes { let getNullifyArgs = [amount, owner.to_field()]; // nested call to create/insert note - let _callStackItem1 = context.call_private_function( + let _callStackItem1 = self.context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, insertArgs, ); - let _callStackItem2 = context.call_private_function( + let _callStackItem2 = self.context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, insertArgs, ); // nested call to read and nullify that note - let _callStackItem3 = context.call_private_function( + let _callStackItem3 = self.context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs, ); - let _callStackItem4 = context.call_private_function( + let _callStackItem4 = self.context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs, ); // nested call to confirm that balance is zero // TODO(dbanks12): once > 4 nested calls is supported, can confirm 0 balance: - //let _callStackItem5 = context.call_private_function(inputs.call_context.contract_address, get_note_zero_fn_selector, [owner]); + //let _callStackItem5 = self.context.call_private_function(inputs.call_context.contract_address, get_note_zero_fn_selector, [owner]); } // same test as above, but insert 2, get 1, nullify 1 @@ -226,18 +226,18 @@ pub contract PendingNoteHashes { let getNullifyArgs = [amount, owner.to_field()]; // nested call to create/insert note - let _callStackItem1 = context.call_private_function( + let _callStackItem1 = self.context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, insertArgs, ); - let _callStackItem2 = context.call_private_function( + let _callStackItem2 = self.context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, insertArgs, ); // nested call to read and nullify that note - let _callStackItem3 = context.call_private_function( + let _callStackItem3 = self.context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs, @@ -260,18 +260,18 @@ pub contract PendingNoteHashes { let getNullifyArgs = [amount, owner.to_field()]; // nested call to create/insert note - let _callStackItem1 = context.call_private_function( + let _callStackItem1 = self.context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, insertArgs, ); // nested call to read and nullify that note - let _callStackItem2 = context.call_private_function( + let _callStackItem2 = self.context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs, ); - let _callStackItem3 = context.call_private_function( + let _callStackItem3 = self.context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, getNullifyArgs, @@ -298,11 +298,11 @@ pub contract PendingNoteHashes { sender: AztecAddress, how_many_recursions: u64, ) { - create_max_notes(owner, storage); + create_max_notes(owner, self.storage); - PendingNoteHashes::at(context.this_address()) + PendingNoteHashes::at(self.address) .recursively_destroy_and_create_notes(owner, sender, how_many_recursions) - .call(&mut context); + .call(self.context); } #[external("private")] @@ -313,15 +313,15 @@ pub contract PendingNoteHashes { ) { assert(executions_left > 0); - destroy_max_notes(owner, storage); - create_max_notes(owner, storage); + destroy_max_notes(owner, self.storage); + create_max_notes(owner, self.storage); let executions_left = executions_left - 1; if executions_left > 0 { - PendingNoteHashes::at(context.this_address()) + PendingNoteHashes::at(self.address) .recursively_destroy_and_create_notes(owner, sender, executions_left) - .call(&mut context); + .call(self.context); } } @@ -330,7 +330,7 @@ pub contract PendingNoteHashes { // the pxe rejects the note log later. #[external("private")] fn test_emit_bad_note_log(owner: AztecAddress, sender: AztecAddress) { - let owner_balance = storage.balances.at(owner); + let owner_balance = self.storage.balances.at(owner); let good_note = ValueNote::new(10, owner); // Insert good note with real log @@ -344,7 +344,7 @@ pub contract PendingNoteHashes { ValueNote::new(5, owner), good_note_emission.content.storage_slot, good_note_emission.content.note_hash_counter, - &mut context, + self.context, ); bad_note_emission.emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); diff --git a/noir-projects/noir-contracts/contracts/test/public_immutable_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/public_immutable_contract/src/main.nr index 708bf7f86faf..c219b0769313 100644 --- a/noir-projects/noir-contracts/contracts/test/public_immutable_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/public_immutable_contract/src/main.nr @@ -12,17 +12,17 @@ contract PublicImmutableContract { #[external("public")] fn initialize_value(value: Field) { - storage.immutable_value.initialize(value); + self.storage.immutable_value.initialize(value); } #[external("public")] fn read_value() -> pub Field { - storage.immutable_value.read() + self.storage.immutable_value.read() } #[external("public")] fn read_value_unsafe() -> pub Field { - storage.immutable_value.read_unsafe() + self.storage.immutable_value.read_unsafe() } } diff --git a/noir-projects/noir-contracts/contracts/test/spam_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/spam_contract/src/main.nr index bc9f85c14074..0f3c9191881b 100644 --- a/noir-projects/noir-contracts/contracts/test/spam_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/spam_contract/src/main.nr @@ -29,11 +29,11 @@ pub contract Spam { #[external("private")] fn spam(nullifier_seed: Field, nullifier_count: u32, call_public: bool) { - let caller = context.msg_sender().unwrap(); + let caller = self.msg_sender().unwrap(); let amount = 1 as u128; for _ in 0..MAX_NOTE_HASHES_PER_CALL { - storage.balances.at(caller).add(caller, amount).emit( + self.storage.balances.at(caller).add(caller, amount).emit( caller, MessageDelivery.UNCONSTRAINED_ONCHAIN, ); @@ -41,7 +41,7 @@ pub contract Spam { for i in 0..MAX_NULLIFIERS_PER_CALL { if (i < nullifier_count) { - context.push_nullifier(poseidon2_hash_with_separator( + self.context.push_nullifier(poseidon2_hash_with_separator( [nullifier_seed, i as Field], GENERATOR_INDEX__NOTE_NULLIFIER as Field, )); @@ -49,15 +49,15 @@ pub contract Spam { } if (call_public) { - Spam::at(context.this_address()) - .public_spam(0, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) - .enqueue(&mut context); - Spam::at(context.this_address()) + Spam::at(self.address).public_spam(0, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX).enqueue( + self.context, + ); + Spam::at(self.address) .public_spam( MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, ) - .enqueue(&mut context); + .enqueue(self.context); } } @@ -66,8 +66,8 @@ pub contract Spam { fn public_spam(start: u32, end: u32) { let one = 1 as u128; for i in start..end { - let prev = storage.public_balances.at(i as Field).read(); - storage.public_balances.at(i as Field).write(prev + one); + let prev = self.storage.public_balances.at(i as Field).read(); + self.storage.public_balances.at(i as Field).write(prev + one); } } } diff --git a/noir-projects/noir-contracts/contracts/test/state_vars_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/state_vars_contract/src/main.nr index 387451f0bf61..78652b544be4 100644 --- a/noir-projects/noir-contracts/contracts/test/state_vars_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/state_vars_contract/src/main.nr @@ -39,14 +39,14 @@ pub contract StateVars { #[external("public")] fn initialize_public_immutable(value: u8) { - let mut new_mock_struct = MockStruct { account: context.msg_sender().unwrap(), value }; - storage.public_immutable.initialize(new_mock_struct); + let mut new_mock_struct = MockStruct { account: self.msg_sender().unwrap(), value }; + self.storage.public_immutable.initialize(new_mock_struct); } #[external("private")] fn match_public_immutable(account: AztecAddress, value: u8) { let expected = MockStruct { account, value }; - let read = storage.public_immutable.read(); + let read = self.storage.public_immutable.read(); assert(read.account == expected.account, "Invalid account"); assert(read.value == expected.value, "Invalid value"); @@ -54,9 +54,9 @@ pub contract StateVars { #[external("private")] fn get_public_immutable_constrained_private_indirect() -> MockStruct { - let mut mock_struct = StateVars::at(context.this_address()) + let mut mock_struct = StateVars::at(self.address) .get_public_immutable_constrained_private() - .view(&mut context); + .view(self.context); mock_struct.value += 1; mock_struct } @@ -67,9 +67,9 @@ pub contract StateVars { // and returns the response. // Used to test that we can retrieve values through calls and // correctly return them in the simulation - let mut mock_struct = StateVars::at(context.this_address()) + let mut mock_struct = StateVars::at(self.address) .get_public_immutable_constrained_public() - .view(&mut context); + .view(self.context); mock_struct.value += 1; mock_struct } @@ -77,83 +77,85 @@ pub contract StateVars { #[external("public")] #[view] fn get_public_immutable_constrained_public() -> MockStruct { - storage.public_immutable.read() + self.storage.public_immutable.read() } #[external("public")] fn get_public_immutable_constrained_public_multiple() -> [MockStruct; 5] { - let a = storage.public_immutable.read(); + let a = self.storage.public_immutable.read(); [a, a, a, a, a] } #[external("private")] #[view] fn get_public_immutable_constrained_private() -> MockStruct { - storage.public_immutable.read() + self.storage.public_immutable.read() } #[external("utility")] unconstrained fn get_public_immutable() -> MockStruct { - storage.public_immutable.read() + self.storage.public_immutable.read() } #[external("private")] fn initialize_private_immutable(randomness: Field, value: Field) { - let new_note = ValueNote::new(value, context.msg_sender().unwrap()); + let new_note = ValueNote::new(value, self.msg_sender().unwrap()); - storage.private_immutable.initialize(new_note).emit( - context.msg_sender().unwrap(), + self.storage.private_immutable.initialize(new_note).emit( + self.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN, ); } #[external("private")] fn initialize_private(randomness: Field, value: Field) { - let private_mutable = ValueNote::new(value, context.msg_sender().unwrap()); + let private_mutable = ValueNote::new(value, self.msg_sender().unwrap()); - storage.private_mutable.initialize(private_mutable).emit( - context.msg_sender().unwrap(), + self.storage.private_mutable.initialize(private_mutable).emit( + self.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN, ); } #[external("private")] fn update_private_mutable(randomness: Field, value: Field) { - storage + self + .storage .private_mutable - .replace(|_old_note| ValueNote::new(value, context.msg_sender().unwrap())) - .emit(context.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN); + .replace(|_old_note| ValueNote::new(value, self.msg_sender().unwrap())) + .emit(self.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN); } #[external("private")] fn increase_private_value() { // Replace existing note with new note containing incremented value - storage + self + .storage .private_mutable .replace(|old_note| { let new_value = old_note.value() + 1; - ValueNote::new(new_value, context.msg_sender().unwrap()) + ValueNote::new(new_value, self.msg_sender().unwrap()) }) - .emit(context.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN); + .emit(self.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN); } #[external("utility")] unconstrained fn get_private_mutable() -> ValueNote { - storage.private_mutable.view_note() + self.storage.private_mutable.view_note() } #[external("utility")] unconstrained fn is_private_mutable_initialized() -> bool { - storage.private_mutable.is_initialized() + self.storage.private_mutable.is_initialized() } #[external("utility")] unconstrained fn view_private_immutable() -> ValueNote { - storage.private_immutable.view_note() + self.storage.private_immutable.view_note() } #[external("utility")] unconstrained fn is_priv_imm_initialized() -> bool { - storage.private_immutable.is_initialized() + self.storage.private_immutable.is_initialized() } } diff --git a/noir-projects/noir-contracts/contracts/test/stateful_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/stateful_test_contract/src/main.nr index dcf5091cd973..99d5359c30c0 100644 --- a/noir-projects/noir-contracts/contracts/test/stateful_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/stateful_test_contract/src/main.nr @@ -27,30 +27,28 @@ pub contract StatefulTest { #[external("private")] #[initializer] fn constructor(owner: AztecAddress, value: Field) { - StatefulTest::at(context.this_address()).create_note_no_init_check(owner, value).call( - &mut context, - ); + StatefulTest::at(self.address).create_note_no_init_check(owner, value).call(self.context); } #[external("private")] #[initializer] fn wrong_constructor() { let selector = FunctionSelector::from_signature("not_exists(Field)"); - let _res = context.call_public_function(context.this_address(), selector, [42], false); + let _res = self.context.call_public_function(self.address, selector, [42], false); } #[external("public")] #[initializer] fn public_constructor(owner: AztecAddress, value: Field) { - StatefulTest::at(context.this_address()) - .increment_public_value_no_init_check(owner, value) - .call(&mut context); + StatefulTest::at(self.address).increment_public_value_no_init_check(owner, value).call( + self.context, + ); } #[external("private")] fn create_note(owner: AztecAddress, value: Field) { if (value != 0) { - let loc = storage.notes.at(owner); + let loc = self.storage.notes.at(owner); let note = ValueNote::new(value, owner); loc.insert(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); } @@ -60,7 +58,7 @@ pub contract StatefulTest { #[noinitcheck] fn create_note_no_init_check(owner: AztecAddress, value: Field) { if (value != 0) { - let loc = storage.notes.at(owner); + let loc = self.storage.notes.at(owner); let note = ValueNote::new(value, owner); loc.insert(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); } @@ -68,13 +66,13 @@ pub contract StatefulTest { #[external("private")] fn destroy_and_create(recipient: AztecAddress) { - assert_is_initialized_private(&mut context); - let sender = context.msg_sender().unwrap(); + assert_is_initialized_private(self.context); + let sender = self.msg_sender().unwrap(); - let sender_notes = storage.notes.at(sender); + let sender_notes = self.storage.notes.at(sender); let _ = sender_notes.pop_notes(NoteGetterOptions::new().set_limit(2)); - storage.notes.at(recipient).insert(ValueNote::new(92, recipient)).emit( + self.storage.notes.at(recipient).insert(ValueNote::new(92, recipient)).emit( recipient, MessageDelivery.CONSTRAINED_ONCHAIN, ); @@ -83,12 +81,12 @@ pub contract StatefulTest { #[external("private")] #[noinitcheck] fn destroy_and_create_no_init_check(recipient: AztecAddress) { - let sender = context.msg_sender().unwrap(); + let sender = self.msg_sender().unwrap(); - let sender_notes = storage.notes.at(sender); + let sender_notes = self.storage.notes.at(sender); let _ = sender_notes.pop_notes(NoteGetterOptions::new().set_limit(2)); - storage.notes.at(recipient).insert(ValueNote::new(92, recipient)).emit( + self.storage.notes.at(recipient).insert(ValueNote::new(92, recipient)).emit( recipient, MessageDelivery.CONSTRAINED_ONCHAIN, ); @@ -96,20 +94,20 @@ pub contract StatefulTest { #[external("public")] fn increment_public_value(owner: AztecAddress, value: Field) { - let loc = storage.public_values.at(owner); + let loc = self.storage.public_values.at(owner); loc.write(loc.read() + value); } #[external("public")] #[noinitcheck] fn increment_public_value_no_init_check(owner: AztecAddress, value: Field) { - let loc = storage.public_values.at(owner); + let loc = self.storage.public_values.at(owner); loc.write(loc.read() + value); } #[external("utility")] unconstrained fn summed_values(owner: AztecAddress) -> Field { - let owner_balance = storage.notes.at(owner); + let owner_balance = self.storage.notes.at(owner); // Return the sum of all notes in the set. balance_utils::get_balance(owner_balance) @@ -119,6 +117,6 @@ pub contract StatefulTest { #[noinitcheck] #[view] fn get_public_value(owner: AztecAddress) -> pub Field { - storage.public_values.at(owner).read() + self.storage.public_values.at(owner).read() } } diff --git a/noir-projects/noir-contracts/contracts/test/static_child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/static_child_contract/src/main.nr index 8e649f69e066..219060eb059a 100644 --- a/noir-projects/noir-contracts/contracts/test/static_child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/static_child_contract/src/main.nr @@ -25,10 +25,10 @@ pub contract StaticChild { #[view] fn pub_get_value(base_value: Field) -> Field { let return_value = base_value - + context.chain_id() - + context.version() - + context.block_number() as Field - + context.timestamp() as Field; + + self.context.chain_id() + + self.context.version() + + self.context.block_number() as Field + + self.context.timestamp() as Field; return_value } @@ -36,8 +36,8 @@ pub contract StaticChild { // Sets `current_value` to `new_value` #[external("public")] fn pub_set_value(new_value: Field) -> Field { - storage.current_value.write(new_value); - context.emit_public_log(new_value); + self.storage.current_value.write(new_value); + self.context.emit_public_log(new_value); new_value } @@ -46,7 +46,7 @@ pub contract StaticChild { #[view] fn private_illegal_set_value(new_value: Field, owner: AztecAddress) -> Field { let note = ValueNote::new(new_value, owner); - storage.a_private_value.insert(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.a_private_value.insert(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); new_value } @@ -55,7 +55,7 @@ pub contract StaticChild { fn private_set_value(new_value: Field, owner: AztecAddress, sender: AztecAddress) -> Field { let note = ValueNote::new(new_value, owner); - storage.a_private_value.insert(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); + self.storage.a_private_value.insert(note).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); new_value } @@ -68,16 +68,16 @@ pub contract StaticChild { .select(ValueNote::properties().value, Comparator.EQ, amount) .select(ValueNote::properties().owner, Comparator.EQ, owner) .set_limit(1); - let retrieved_notes = storage.a_private_value.get_notes(options); + let retrieved_notes = self.storage.a_private_value.get_notes(options); retrieved_notes.get(0).note.value() } // Increments `current_value` by `new_value` #[external("public")] fn pub_inc_value(new_value: Field) -> Field { - let old_value = storage.current_value.read(); - storage.current_value.write(old_value + new_value); - context.emit_public_log(new_value); + let old_value = self.storage.current_value.read(); + self.storage.current_value.write(old_value + new_value); + self.context.emit_public_log(new_value); new_value } @@ -85,9 +85,9 @@ pub contract StaticChild { #[external("public")] #[view] fn pub_illegal_inc_value(new_value: Field) -> Field { - let old_value = storage.current_value.read(); - storage.current_value.write(old_value + new_value); - context.emit_public_log(new_value); + let old_value = self.storage.current_value.read(); + self.storage.current_value.write(old_value + new_value); + self.context.emit_public_log(new_value); new_value } } diff --git a/noir-projects/noir-contracts/contracts/test/static_parent_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/static_parent_contract/src/main.nr index f02d8f706e26..8b4f5cedde19 100644 --- a/noir-projects/noir-contracts/contracts/test/static_parent_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/static_parent_contract/src/main.nr @@ -16,7 +16,7 @@ pub contract StaticParent { target_selector: FunctionSelector, arg: Field, ) -> Field { - context.call_public_function( + self.context.call_public_function( target_contract, target_selector, [arg].as_slice(), @@ -31,7 +31,7 @@ pub contract StaticParent { target_selector: FunctionSelector, args: [Field; 2], ) -> Field { - context.call_private_function(target_contract, target_selector, args).get_preimage() + self.context.call_private_function(target_contract, target_selector, args).get_preimage() } // Just like function above but with 3 args. @@ -41,7 +41,7 @@ pub contract StaticParent { target_selector: FunctionSelector, args: [Field; 3], ) -> Field { - context.call_private_function(target_contract, target_selector, args).get_preimage() + self.context.call_private_function(target_contract, target_selector, args).get_preimage() } // Private function to enqueue a call to a public function of another contract, passing the target arguments provided @@ -51,7 +51,7 @@ pub contract StaticParent { target_selector: FunctionSelector, args: [Field; 1], ) { - context.call_public_function(target_contract, target_selector, args, false); + self.context.call_public_function(target_contract, target_selector, args, false); } #[external("private")] @@ -60,7 +60,10 @@ pub contract StaticParent { target_selector: FunctionSelector, args: [Field; 2], ) -> Field { - context.static_call_private_function(target_contract, target_selector, args).get_preimage() + self + .context + .static_call_private_function(target_contract, target_selector, args) + .get_preimage() } // Private function to statically call another private function to the target_contract using the selector and values provided @@ -70,7 +73,10 @@ pub contract StaticParent { target_selector: FunctionSelector, args: [Field; 3], ) -> Field { - context.static_call_private_function(target_contract, target_selector, args).get_preimage() + self + .context + .static_call_private_function(target_contract, target_selector, args) + .get_preimage() } // Same as above but using a specific function from the interface @@ -80,7 +86,7 @@ pub contract StaticParent { value: Field, owner: AztecAddress, ) -> Field { - StaticChild::at(target_contract).private_get_value(value, owner).view(&mut context) + StaticChild::at(target_contract).private_get_value(value, owner).view(self.context) } // Private function to set a static context and verify correct propagation for nested private calls @@ -90,9 +96,9 @@ pub contract StaticParent { target_selector: FunctionSelector, args: [Field; 2], ) -> Field { - StaticParent::at(context.this_address()) - .private_call(target_contract, target_selector, args) - .view(&mut context) + StaticParent::at(self.address).private_call(target_contract, target_selector, args).view( + self.context, + ) } // Just like function above but with 3 args. @@ -102,9 +108,9 @@ pub contract StaticParent { target_selector: FunctionSelector, args: [Field; 3], ) -> Field { - StaticParent::at(context.this_address()) + StaticParent::at(self.address) .private_call_3_args(target_contract, target_selector, args) - .view(&mut context) + .view(self.context) } // Public function to statically call another public function to the target_contract using the selector and value provided @@ -114,7 +120,7 @@ pub contract StaticParent { target_selector: FunctionSelector, args: [Field; 1], ) -> Field { - context.static_call_public_function( + self.context.static_call_public_function( target_contract, target_selector, args.as_slice(), @@ -125,7 +131,7 @@ pub contract StaticParent { // Same as above but using a specific function from the interface #[external("public")] fn public_get_value_from_child(target_contract: AztecAddress, value: Field) -> Field { - StaticChild::at(target_contract).pub_get_value(value).view(&mut context) + StaticChild::at(target_contract).pub_get_value(value).view(self.context) } // Public function to set a static context and verify correct propagation for nested public calls @@ -136,9 +142,9 @@ pub contract StaticParent { args: [Field; 1], ) -> Field { // Call the target public function through the pub entrypoint statically - StaticParent::at(context.this_address()) - .public_call(target_contract, target_selector, args[0]) - .view(&mut context) + StaticParent::at(self.address).public_call(target_contract, target_selector, args[0]).view( + self.context, + ) } // Private function to enqueue a static call to a public function of another contract, passing the target arguments provided @@ -148,13 +154,13 @@ pub contract StaticParent { target_selector: FunctionSelector, args: [Field; 1], ) { - context.static_call_public_function(target_contract, target_selector, args, false); + self.context.static_call_public_function(target_contract, target_selector, args, false); } // Same as above but using a specific function from the interface #[external("private")] fn enqueue_public_get_value_from_child(target_contract: AztecAddress, value: Field) { - StaticChild::at(target_contract).pub_get_value(value).enqueue_view(&mut context); + StaticChild::at(target_contract).pub_get_value(value).enqueue_view(self.context); } // Private function to set a static context and verify correct propagation of nested enqueuing of public calls @@ -165,8 +171,8 @@ pub contract StaticParent { args: [Field; 1], ) { // Call the target public function through the pub entrypoint statically - StaticParent::at(context.this_address()) + StaticParent::at(self.address) .public_call(target_contract, target_selector, args[0]) - .enqueue_view(&mut context) + .enqueue_view(self.context) } } diff --git a/noir-projects/noir-contracts/contracts/test/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/test_contract/src/main.nr index 34e46f741a91..42a76ee088ab 100644 --- a/noir-projects/noir-contracts/contracts/test/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/test_contract/src/main.nr @@ -34,7 +34,6 @@ pub contract Test { traits::{Hash, Packable, Serialize}, }, // Event related - event::event_emission::emit_event_in_private, messages::message_delivery::MessageDelivery, // Hashing hash::pedersen_hash, @@ -103,7 +102,7 @@ pub contract Test { #[external("private")] fn get_ovsk_app(ovpk_m_hash: Field) -> Field { - context.request_ovsk_app(ovpk_m_hash) + self.context.request_ovsk_app(ovpk_m_hash) } #[external("private")] @@ -116,15 +115,15 @@ pub contract Test { // Get the address of this contract (taken from the input context) #[external("private")] fn get_this_address() -> AztecAddress { - context.this_address() + self.address } #[external("private")] fn set_include_by_timestamp(include_by_timestamp: u64, make_tx_hybrid: bool) { - context.set_include_by_timestamp(include_by_timestamp); + self.context.set_include_by_timestamp(include_by_timestamp); if make_tx_hybrid { - Test::at(context.this_address()).dummy_public_call().enqueue(&mut context) + Test::at(self.address).dummy_public_call().enqueue(self.context) } } @@ -140,30 +139,24 @@ pub contract Test { make_tx_hybrid: bool, ) { let note = UintNote::new(value, owner); - create_note(&mut context, storage_slot, note).emit( + create_note(self.context, storage_slot, note).emit( owner, MessageDelivery.CONSTRAINED_ONCHAIN, ); if make_tx_hybrid { - Test::at(context.this_address()).dummy_public_call().enqueue(&mut context); + Test::at(self.address).dummy_public_call().enqueue(self.context); } } #[external("private")] fn call_create_partial_note(owner: AztecAddress, storage_slot: Field) -> PartialUintNote { - UintNote::partial( - owner, - storage_slot, - &mut context, - owner, - context.this_address(), - ) + UintNote::partial(owner, storage_slot, self.context, owner, self.address) } #[external("public")] fn call_complete_partial_note(partial_note: PartialUintNote, value: u128) { - partial_note.complete(&mut context, context.this_address(), value); + partial_note.complete(self.context, self.address, value); } #[external("private")] @@ -172,17 +165,10 @@ pub contract Test { storage_slot: Field, value: u128, ) { - let partial_note = UintNote::partial( - owner, - storage_slot, - &mut context, - owner, - context.this_address(), - ); + let partial_note = + UintNote::partial(owner, storage_slot, self.context, owner, self.address); - Test::at(context.this_address()).call_complete_partial_note(partial_note, value).enqueue( - &mut context, - ); + Test::at(self.address).call_complete_partial_note(partial_note, value).enqueue(self.context); } #[external("private")] @@ -193,7 +179,7 @@ pub contract Test { } let (retrieved_notes, _): (BoundedVec, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL>, BoundedVec) = - get_notes(&mut context, storage_slot, options); + get_notes(self.context, storage_slot, options); retrieved_notes.get(0).note.get_value() } @@ -206,7 +192,7 @@ pub contract Test { } let (retrieved_notes, _): (BoundedVec, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL>, BoundedVec) = - get_notes(&mut context, storage_slot, options); + get_notes(self.context, storage_slot, options); [retrieved_notes.get(0).note.get_value(), retrieved_notes.get(1).note.get_value()] } @@ -242,12 +228,12 @@ pub contract Test { fn call_destroy_note(storage_slot: Field) { let options = NoteGetterOptions::new(); let (retrieved_notes, note_hashes): (BoundedVec, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL>, BoundedVec) = - get_notes(&mut context, storage_slot, options); + get_notes(self.context, storage_slot, options); let retrieved_note = retrieved_notes.get(0); let note_hash = note_hashes.get(0); - destroy_note_unsafe(&mut context, retrieved_note, note_hash); + destroy_note_unsafe(self.context, retrieved_note, note_hash); } #[external("private")] @@ -256,17 +242,17 @@ pub contract Test { options = options.set_limit(1); let (retrieved_notes, _): (BoundedVec, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL>, BoundedVec) = - get_notes(&mut context, storage_slot, options); + get_notes(self.context, storage_slot, options); - let header = context.get_anchor_block_header(); + let header = self.context.get_anchor_block_header(); header.prove_note_inclusion(retrieved_notes.get(0), storage_slot); } #[external("private")] fn test_setting_teardown() { - context.set_public_teardown_function( - context.this_address(), + self.context.set_public_teardown_function( + self.address, comptime { FunctionSelector::from_signature("dummy_public_call()") }, [], false, @@ -275,30 +261,30 @@ pub contract Test { #[external("private")] fn test_setting_fee_payer() { - context.set_as_fee_payer(); + self.context.set_as_fee_payer(); } #[external("public")] fn create_l2_to_l1_message_arbitrary_recipient_public(content: Field, recipient: EthAddress) { // Public oracle call to emit new commitment. - context.message_portal(recipient, content); + self.context.message_portal(recipient, content); } #[external("private")] fn create_l2_to_l1_message_arbitrary_recipient_private(content: Field, recipient: EthAddress) { // Public oracle call to emit new commitment. - context.message_portal(recipient, content); + self.context.message_portal(recipient, content); } #[external("public")] fn emit_nullifier_public(nullifier: Field) { - context.push_nullifier(nullifier); + self.context.push_nullifier(nullifier); } #[external("private")] #[noinitcheck] fn emit_nullifier(nullifier: Field) { - context.push_nullifier(nullifier); + self.context.push_nullifier(nullifier); } // For testing non-note encrypted logs @@ -312,31 +298,26 @@ pub contract Test { value4: fields[4], }; - emit_event_in_private( - event, - &mut context, - owner, - MessageDelivery.UNCONSTRAINED_ONCHAIN, - ); + self.emit(event, owner, MessageDelivery.UNCONSTRAINED_ONCHAIN); // this contract has reached max number of functions, so using this one fn // to test nested and non nested encrypted logs if nest { - Test::at(context.this_address()) - .emit_array_as_encrypted_log([0, 0, 0, 0, 0], owner, false) - .call(&mut context); + Test::at(self.address).emit_array_as_encrypted_log([0, 0, 0, 0, 0], owner, false).call( + self.context, + ); // Emit a log with non-encrypted content for testing purpose. let leaky_log = event.serialize().concat([0; PRIVATE_LOG_SIZE_IN_FIELDS - 5]); - context.emit_private_log(leaky_log, 5); + self.context.emit_private_log(leaky_log, 5); } } #[external("public")] fn emit_public(value: Field) { - context.emit_public_log(/*message=*/ value); - context.emit_public_log(/*message=*/ [10, 20, 30]); - context.emit_public_log(/*message=*/ "Hello, world!"); + self.context.emit_public_log(/*message=*/ value); + self.context.emit_public_log(/*message=*/ [10, 20, 30]); + self.context.emit_public_log(/*message=*/ "Hello, world!"); } #[external("private")] @@ -348,7 +329,7 @@ pub contract Test { ) { // Consume L1 to L2 message and emit nullifier let content_hash = get_mint_to_private_content_hash(amount); - context.consume_l1_to_l2_message( + self.context.consume_l1_to_l2_message( content_hash, secret_for_L1_to_L2_message_consumption, portal_address, @@ -364,7 +345,7 @@ pub contract Test { message_leaf_index: Field, ) { // Consume message and emit nullifier - context.consume_l1_to_l2_message(content, secret, sender, message_leaf_index); + self.context.consume_l1_to_l2_message(content, secret, sender, message_leaf_index); } #[external("private")] @@ -375,29 +356,29 @@ pub contract Test { message_leaf_index: Field, ) { // Consume message and emit nullifier - context.consume_l1_to_l2_message(content, secret, sender, message_leaf_index); + self.context.consume_l1_to_l2_message(content, secret, sender, message_leaf_index); } #[external("private")] fn assert_private_global_vars(chain_id: Field, version: Field) { - assert(context.chain_id() == chain_id, "Invalid chain id"); - assert(context.version() == version, "Invalid version"); + assert(self.context.chain_id() == chain_id, "Invalid chain id"); + assert(self.context.version() == version, "Invalid version"); } #[external("private")] fn assert_header_private(header_hash: Field) { - assert(context.anchor_block_header.hash() == header_hash, "Invalid header hash"); + assert(self.context.anchor_block_header.hash() == header_hash, "Invalid header hash"); } // TODO(4840): add AVM opcodes for getting header (members) //#[external("public")] //fn assert_header_public(header_hash: Field) { - // assert(context.anchor_block_header.hash() == header_hash, "Invalid header hash"); + // assert(self.context.anchor_block_header.hash() == header_hash, "Invalid header hash"); //} #[external("private")] fn publish_contract_instance(target: AztecAddress) { - publish_contract_instance_for_public_execution(&mut context, target); + publish_contract_instance_for_public_execution(self.context, target); } #[derive(Serialize)] diff --git a/noir-projects/noir-contracts/contracts/test/test_log_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/test_log_contract/src/main.nr index bfe1ce308286..1e65e68a75a5 100644 --- a/noir-projects/noir-contracts/contracts/test/test_log_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/test_log_contract/src/main.nr @@ -3,7 +3,6 @@ use aztec::macros::aztec; #[aztec] pub contract TestLog { use aztec::{ - event::event_emission::{emit_event_in_private, emit_event_in_public}, macros::{events::event, functions::external, storage::storage}, messages::message_delivery::MessageDelivery, oracle::random::random, @@ -33,47 +32,28 @@ pub contract TestLog { fn emit_encrypted_events(other: AztecAddress, preimages: [Field; 4]) { let event0 = ExampleEvent0 { value0: preimages[0], value1: preimages[1] }; - emit_event_in_private( - event0, - &mut context, - context.msg_sender().unwrap(), - MessageDelivery.CONSTRAINED_ONCHAIN, - ); + self.emit(event0, self.context.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN); // We duplicate the emission, but swapping the sender and recipient: - emit_event_in_private( - event0, - &mut context, - other, - MessageDelivery.CONSTRAINED_ONCHAIN, - ); + self.emit(event0, other, MessageDelivery.CONSTRAINED_ONCHAIN); let event1 = ExampleEvent1 { value2: AztecAddress::from_field(preimages[2]), value3: preimages[3] as u8, }; - emit_event_in_private( - event1, - &mut context, - context.msg_sender().unwrap(), - MessageDelivery.CONSTRAINED_ONCHAIN, - ); + self.emit(event1, self.context.msg_sender().unwrap(), MessageDelivery.CONSTRAINED_ONCHAIN); } #[external("public")] fn emit_unencrypted_events(preimages: [Field; 4]) { - emit_event_in_public( - ExampleEvent0 { value0: preimages[0], value1: preimages[1] }, - &mut context, - ); + self.emit(ExampleEvent0 { value0: preimages[0], value1: preimages[1] }); - emit_event_in_public( + self.emit( ExampleEvent1 { value2: AztecAddress::from_field(preimages[2]), value3: preimages[3] as u8, }, - &mut context, ); } @@ -88,24 +68,22 @@ pub contract TestLog { // Safety: We use the following just as an arbitrary test value let random_value_3 = unsafe { random() }; - emit_event_in_private( + self.emit( ExampleEvent0 { value0: random_value_0, value1: random_value_1 }, - &mut context, other, MessageDelivery.UNCONSTRAINED_ONCHAIN, ); - emit_event_in_private( + self.emit( ExampleEvent0 { value0: random_value_2, value1: random_value_3 }, - &mut context, other, MessageDelivery.UNCONSTRAINED_ONCHAIN, ); if num_nested_calls > 0 { - TestLog::at(context.this_address()) + TestLog::at(self.address) .emit_encrypted_events_nested(other, num_nested_calls - 1) - .call(&mut context); + .call(self.context); } } } diff --git a/noir-projects/noir-contracts/contracts/test/updatable_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/updatable_contract/src/main.nr index fdf5ed86e0b1..ff15d9927e59 100644 --- a/noir-projects/noir-contracts/contracts/test/updatable_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/updatable_contract/src/main.nr @@ -24,46 +24,49 @@ contract Updatable { #[initializer] #[external("private")] fn initialize(initial_value: Field) { - let owner = context.msg_sender().unwrap(); + let owner = self.msg_sender().unwrap(); let new_value = ValueNote::new(initial_value, owner); - storage.private_value.initialize(new_value).emit(owner, MessageDelivery.CONSTRAINED_ONCHAIN); - Updatable::at(context.this_address()).set_public_value(initial_value).enqueue(&mut context); + self.storage.private_value.initialize(new_value).emit( + owner, + MessageDelivery.CONSTRAINED_ONCHAIN, + ); + Updatable::at(self.address).set_public_value(initial_value).enqueue(self.context); } #[external("public")] fn set_public_value(new_value: Field) { - storage.public_value.write(new_value); + self.storage.public_value.write(new_value); } #[external("private")] fn update_to(new_class_id: ContractClassId) { ContractInstanceRegistry::at(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS) .update(new_class_id) - .enqueue(&mut context); + .enqueue(self.context); } #[external("private")] fn set_update_delay(new_delay: u64) { ContractInstanceRegistry::at(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS) .set_update_delay(new_delay) - .enqueue(&mut context); + .enqueue(self.context); } #[external("public")] fn get_update_delay() -> u64 { ContractInstanceRegistry::at(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS) .get_update_delay() - .view(&mut context) + .view(self.context) } #[external("utility")] unconstrained fn get_private_value() -> Field { - storage.private_value.view_note().value() + self.storage.private_value.view_note().value() } #[external("utility")] unconstrained fn get_public_value() -> Field { - storage.public_value.read() + self.storage.public_value.read() } } diff --git a/noir-projects/noir-contracts/contracts/test/updated_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test/updated_contract/src/main.nr index 4e464de8bc66..5020135277e9 100644 --- a/noir-projects/noir-contracts/contracts/test/updated_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test/updated_contract/src/main.nr @@ -20,14 +20,14 @@ contract Updated { #[external("public")] fn set_public_value() { - storage.public_value.write(27); + self.storage.public_value.write(27); } #[external("private")] fn set_private_value() { - let owner = context.msg_sender().unwrap(); + let owner = self.msg_sender().unwrap(); - storage.private_value.replace(|_old| ValueNote::new(27, owner)).emit( + self.storage.private_value.replace(|_old| ValueNote::new(27, owner)).emit( owner, MessageDelivery.CONSTRAINED_ONCHAIN, ); @@ -37,17 +37,17 @@ contract Updated { fn get_update_delay() -> u64 { ContractInstanceRegistry::at(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS) .get_update_delay() - .view(&mut context) + .view(self.context) } #[external("utility")] unconstrained fn get_private_value() -> Field { - storage.private_value.view_note().value() + self.storage.private_value.view_note().value() } #[external("utility")] unconstrained fn get_public_value() -> Field { - storage.public_value.read() + self.storage.public_value.read() } }