From c9906292364b5dbf1b76510d2b9b5c5b3bfaad6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Mon, 25 Nov 2024 16:05:05 +0000 Subject: [PATCH 1/2] Remove SharedImmutable --- docs/docs/migration_notes.md | 9 +++ .../smart_contract_reference/storage/index.md | 4 +- .../storage/public_state.md | 19 ++++- .../storage/shared_state.md | 28 ------- .../private_voting_contract.md | 2 +- noir-projects/aztec-nr/aztec/src/prelude.nr | 2 +- .../aztec-nr/aztec/src/state_vars/mod.nr | 2 - .../aztec/src/state_vars/public_immutable.nr | 28 ++++++- .../aztec/src/state_vars/shared_immutable.nr | 78 ------------------- .../app_subscription_contract/src/main.nr | 15 ++-- .../contracts/claim_contract/src/main.nr | 6 +- .../crowdfunding_contract/src/main.nr | 8 +- .../docs_example_contract/src/main.nr | 57 +++++--------- .../easy_private_voting_contract/src/main.nr | 4 +- .../contracts/fee_juice_contract/src/main.nr | 4 +- .../contracts/fpc_contract/src/main.nr | 6 +- .../contracts/nft_contract/src/main.nr | 6 +- .../token_bridge_contract/src/main.nr | 6 +- .../contracts/token_contract/src/main.nr | 12 +-- .../contracts/uniswap_contract/src/main.nr | 4 +- .../end-to-end/src/e2e_state_vars.test.ts | 62 +++++---------- 21 files changed, 127 insertions(+), 235 deletions(-) delete mode 100644 noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr diff --git a/docs/docs/migration_notes.md b/docs/docs/migration_notes.md index 64407b34c36..2d3c4822628 100644 --- a/docs/docs/migration_notes.md +++ b/docs/docs/migration_notes.md @@ -8,6 +8,15 @@ Aztec is in full-speed development. Literally every version breaks compatibility ## TBD +### [aztec.nr] Removed SharedImmutable + +The `SharedImmutable` state variable has been removed, since it was essentially the exact same as `PublicImmutable`, which now contains functions for reading from private: + +```diff +- foo: SharedImmutable. ++ foo: PublicImmutable. +``` + ### [aztec.nr] SharedImmutable renamings `SharedImmutable::read_private` and `SharedImmutable::read_public` were renamed to simply `read`, since only one of these versions is ever available depending on the current context. diff --git a/docs/docs/reference/developer_references/smart_contract_reference/storage/index.md b/docs/docs/reference/developer_references/smart_contract_reference/storage/index.md index 02f38916a48..f85fd6f3a82 100644 --- a/docs/docs/reference/developer_references/smart_contract_reference/storage/index.md +++ b/docs/docs/reference/developer_references/smart_contract_reference/storage/index.md @@ -11,13 +11,13 @@ You control this storage in Aztec using a struct annotated with `#[storage]`. Th These state variables come in two forms: [public](./public_state.md) and [private](./private_state.md). Public variables are visible to anyone, and private variables remain hidden within the contract. A state variable with both public and private components is said to be [shared](./shared_state.md). -Aztec.nr has a few abstractions to help define the type of data your contract holds. These include PrivateMutable, PrivateImmutable, PublicMutable, PrivateSet, and SharedImmutable. +Aztec.nr has a few abstractions to help define the type of data your contract holds. These include PrivateMutable, PrivateImmutable, PublicMutable, PublicImmutable, PrivateSet, and SharedMutable. On this and the following pages in this section, you’ll learn: - How to manage a smart contract's storage structure - The distinctions and applications of public and private state variables -- How to use PrivateMutable, PrivateImmutable, PrivateSet, PublicMutable, SharedImmutable and Map +- How to use PrivateMutable, PrivateImmutable, PrivateSet, PublicMutable, SharedMutable and Map - An overview of 'notes' and the UTXO model - Practical implications of Storage in real smart contracts In an Aztec.nr contract, storage is to be defined as a single struct, that contains both public and private state variables. diff --git a/docs/docs/reference/developer_references/smart_contract_reference/storage/public_state.md b/docs/docs/reference/developer_references/smart_contract_reference/storage/public_state.md index 61208e17cc2..4a298e6bbd9 100644 --- a/docs/docs/reference/developer_references/smart_contract_reference/storage/public_state.md +++ b/docs/docs/reference/developer_references/smart_contract_reference/storage/public_state.md @@ -4,7 +4,7 @@ title: Public State On this page we will look at how to manage public state in Aztec contracts. We will look at how to declare public state, how to read and write to it, and how to use it in your contracts. -For a higher level overview of the state model in Aztec, see the [state model](../../../../aztec/concepts/state_model/index.md) concepts page. +For a higher level overview of the state model in Aztec, see the [state model](../../../../aztec/concepts/state_model/index.md) concepts page. ## `PublicMutable` @@ -71,9 +71,11 @@ We have a `write` method on the `PublicMutable` struct that takes the value to w ## `PublicImmutable` -`PublicImmutable` is a type that can be written once during a contract deployment and read later on from public only. For a version of `PublicImmutable` that can also be read in private, head to [`SharedImmutable`](./shared_state.md#sharedimmutable). +`PublicImmutable` is a type that is initialized from public once, typically during a contract deployment, but which can later be read from public, private and unconstrained execution contexts. This state variable is useful for stuff that you would usually have in `immutable` values in Solidity, e.g. this can be the name of a token or its number of decimals. -Just like the `PublicMutable` it is generic over the variable type `T`. The type `MUST` implement Serialize and Deserialize traits. +Just like the `PublicMutable` it is generic over the variable type `T`. The type `MUST` implement the `Serialize` and `Deserialize` traits. + +#include_code storage-public-immutable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust You can find the details of `PublicImmutable` in the implementation [here (GitHub link)](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr). @@ -87,9 +89,18 @@ Is done exactly like the `PublicMutable` struct, but with the `PublicImmutable` ### `initialize` +This function sets the immutable value. It can only be called once. + +#include_code initialize_decimals /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust + +:::warning +A `PublicImmutable`'s storage **must** only be set once via `initialize`. Attempting to override this by manually accessing the underlying storage slots breaks all properties of the data structure, rendering it useless. +::: + #include_code initialize_public_immutable /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust ### `read` -Reading the value is just like `PublicMutable`. +Returns the stored immutable value. This function is available in public, private and unconstrained contexts. + #include_code read_public_immutable /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust diff --git a/docs/docs/reference/developer_references/smart_contract_reference/storage/shared_state.md b/docs/docs/reference/developer_references/smart_contract_reference/storage/shared_state.md index 6978398613e..6dbb7673805 100644 --- a/docs/docs/reference/developer_references/smart_contract_reference/storage/shared_state.md +++ b/docs/docs/reference/developer_references/smart_contract_reference/storage/shared_state.md @@ -97,31 +97,3 @@ Returns the last scheduled value change, along with the block number at which th #include_code shared_mutable_get_scheduled_public /noir-projects/noir-contracts/contracts/auth_contract/src/main.nr rust It is not possible to call this function in private: doing so would not be very useful at it cannot be asserted that a scheduled value change will not be immediately replaced if `shcedule_value_change` where to be called. - -## `SharedImmutable` - -`SharedImmutable` (formerly known as `StablePublicState`) is a simplification of the `SharedMutable` case, where the value can only be set once during initialization. Because there's no further mutation, there's no need for delays. These state variables are useful for stuff that you would usually have in `immutable` values in Solidity, e.g. this can be the name of a token or its number of decimals. - -Like most state variables, `SharedImmutable` is generic over the variable type `T`. This type `MUST` implement the `Serialize` and `Deserialize` traits. - -#include_code storage-shared-immutable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust - -You can find the details of `SharedImmutable` in the implementation [here (GitHub link)](https://github.com/AztecProtocol/aztec-packages/blob/#include_aztec_version/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr). - -### `initialize` - -This function sets the immutable value. It must only be called once during contract construction. - -#include_code initialize_decimals /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust - -:::warning -A `SharedImmutable`'s storage **must** only be set once via `initialize`. Attempting to override this by manually accessing the underlying storage slots breaks all properties of the data structure, rendering it useless. -::: - -### `read` - -Returns the stored immutable value. This function is available in public, private and unconstrained contexts. - -#include_code read_shared_immutable_public /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust - -#include_code read_shared_immutable_private /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust diff --git a/docs/docs/tutorials/codealong/contract_tutorials/private_voting_contract.md b/docs/docs/tutorials/codealong/contract_tutorials/private_voting_contract.md index 78dc4f779f0..7f3aba4aa76 100644 --- a/docs/docs/tutorials/codealong/contract_tutorials/private_voting_contract.md +++ b/docs/docs/tutorials/codealong/contract_tutorials/private_voting_contract.md @@ -74,7 +74,7 @@ We are using various utils within the Aztec `prelude` library: - `PrivateContext` - exposes things such as the contract address, msg_sender, etc - `Map` - A data storage type for storing candidates with the number of votes they have - `PublicMutable` - A type of storage, which holds a mutable public value. We'll store votes as PublicMutables -- `SharedImmutable` - an immutable storage value that is accessible in private and public execution. +- `PublicImmutable` - an immutable storage value that is accessible in private and public execution. ## Set up storage diff --git a/noir-projects/aztec-nr/aztec/src/prelude.nr b/noir-projects/aztec-nr/aztec/src/prelude.nr index d1b5b34475a..861ef71f2ba 100644 --- a/noir-projects/aztec-nr/aztec/src/prelude.nr +++ b/noir-projects/aztec-nr/aztec/src/prelude.nr @@ -11,7 +11,7 @@ pub use crate::{ state_vars::{ map::Map, private_immutable::PrivateImmutable, private_mutable::PrivateMutable, private_set::PrivateSet, public_immutable::PublicImmutable, public_mutable::PublicMutable, - shared_immutable::SharedImmutable, shared_mutable::SharedMutable, storage::Storable, + shared_mutable::SharedMutable, storage::Storable, }, }; pub use dep::protocol_types::{ diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/mod.nr b/noir-projects/aztec-nr/aztec/src/state_vars/mod.nr index 609cf778506..38230bdef98 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/mod.nr @@ -4,7 +4,6 @@ pub mod private_mutable; pub mod public_immutable; pub mod public_mutable; pub mod private_set; -pub mod shared_immutable; pub mod shared_mutable; pub mod storage; @@ -14,6 +13,5 @@ pub use crate::state_vars::private_mutable::PrivateMutable; pub use crate::state_vars::private_set::PrivateSet; pub use crate::state_vars::public_immutable::PublicImmutable; pub use crate::state_vars::public_mutable::PublicMutable; -pub use crate::state_vars::shared_immutable::SharedImmutable; pub use crate::state_vars::shared_mutable::SharedMutable; pub use crate::state_vars::storage::Storage; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr index ae971bc9c35..a3e5df8b9c8 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr @@ -1,10 +1,14 @@ -use crate::{context::{PublicContext, UnconstrainedContext}, state_vars::storage::Storage}; +use crate::{ + context::{PrivateContext, PublicContext, UnconstrainedContext}, + state_vars::storage::Storage, +}; use dep::protocol_types::{ constants::INITIALIZATION_SLOT_SEPARATOR, traits::{Deserialize, Serialize}, }; -// Just like SharedImmutable but without the ability to read from private functions. +/// Stores an immutable value in public state which can be read from public, private and unconstrained execution +/// contexts. // docs:start:public_immutable_struct pub struct PublicImmutable { context: Context, @@ -57,9 +61,27 @@ where impl PublicImmutable where - T: Deserialize, + T: Serialize + Deserialize, { pub unconstrained fn read(self) -> T { self.context.storage_read(self.storage_slot) } } + +impl PublicImmutable +where + T: Serialize + Deserialize, +{ + pub fn read(self) -> T { + let header = self.context.get_header(); + let mut fields = [0; T_SERIALIZED_LEN]; + + for i in 0..fields.len() { + fields[i] = header.public_storage_historical_read( + self.storage_slot + i as Field, + (*self.context).this_address(), + ); + } + T::deserialize(fields) + } +} diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr deleted file mode 100644 index ea5ac0b46d0..00000000000 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr +++ /dev/null @@ -1,78 +0,0 @@ -use crate::{ - context::{PrivateContext, PublicContext, UnconstrainedContext}, - state_vars::storage::Storage, -}; -use dep::protocol_types::{ - constants::INITIALIZATION_SLOT_SEPARATOR, - traits::{Deserialize, Serialize}, -}; - -// Just like PublicImmutable but with the ability to read from private functions. -pub struct SharedImmutable { - context: Context, - storage_slot: Field, -} - -impl Storage for SharedImmutable -where - T: Serialize + Deserialize, -{} - -impl SharedImmutable { - pub fn new( - // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. - context: Context, - storage_slot: Field, - ) -> Self { - assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); - Self { context, storage_slot } - } -} - -impl SharedImmutable -where - T: Serialize + Deserialize, -{ - // Intended to be only called once. - pub fn initialize(self, value: T) { - // We check that the struct is not yet initialized by checking if the initialization slot is 0 - let initialization_slot = INITIALIZATION_SLOT_SEPARATOR + self.storage_slot; - let init_field: Field = self.context.storage_read(initialization_slot); - assert(init_field == 0, "SharedImmutable already initialized"); - - // We populate the initialization slot with a non-zero value to indicate that the struct is initialized - self.context.storage_write(initialization_slot, 0xdead); - self.context.storage_write(self.storage_slot, value); - } - - pub fn read(self) -> T { - self.context.storage_read(self.storage_slot) - } -} - -impl SharedImmutable -where - T: Serialize + Deserialize, -{ - pub unconstrained fn read(self) -> T { - self.context.storage_read(self.storage_slot) - } -} - -impl SharedImmutable -where - T: Serialize + Deserialize, -{ - pub fn read(self) -> T { - let header = self.context.get_header(); - let mut fields = [0; T_SERIALIZED_LEN]; - - for i in 0..fields.len() { - fields[i] = header.public_storage_historical_read( - self.storage_slot + i as Field, - (*self.context).this_address(), - ); - } - T::deserialize(fields) - } -} diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr index 2f8cd94a604..c00ac191060 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr @@ -12,7 +12,7 @@ contract AppSubscription { encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys, macros::{functions::{initializer, private, public}, storage::storage}, - prelude::{AztecAddress, Map, PrivateMutable, SharedImmutable}, + prelude::{AztecAddress, Map, PrivateMutable, PublicImmutable}, protocol_types::constants::MAX_FIELD_VALUE, utils::comparison::Comparator, }; @@ -21,15 +21,12 @@ contract AppSubscription { #[storage] struct Storage { - // The following is only needed in private but we use ShareImmutable here instead of PrivateImmutable because - // the value can be publicly known and SharedImmutable provides us with a better devex here because we don't - // have to bother with sharing the note between pixies of users. - target_address: SharedImmutable, - subscription_token_address: SharedImmutable, - subscription_recipient_address: SharedImmutable, - subscription_price: SharedImmutable, + target_address: PublicImmutable, + subscription_token_address: PublicImmutable, + subscription_recipient_address: PublicImmutable, + subscription_price: PublicImmutable, subscriptions: Map, Context>, - fee_juice_limit_per_tx: SharedImmutable, + fee_juice_limit_per_tx: PublicImmutable, } global SUBSCRIPTION_DURATION_IN_BLOCKS = 5; diff --git a/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr b/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr index bbaf23913b3..1318e17f192 100644 --- a/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr @@ -6,7 +6,7 @@ contract Claim { macros::{functions::{initializer, private, public}, storage::storage}, note::utils::compute_note_hash_for_nullify, protocol_types::address::AztecAddress, - state_vars::SharedImmutable, + state_vars::PublicImmutable, }; use dep::value_note::value_note::ValueNote; use token::Token; @@ -14,9 +14,9 @@ contract Claim { #[storage] struct Storage { // Address of a contract based on whose notes we distribute the rewards - target_contract: SharedImmutable, + target_contract: PublicImmutable, // Token to be distributed as a reward when claiming - reward_token: SharedImmutable, + reward_token: PublicImmutable, } #[public] diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr index 056cc5d80b0..40d738a512c 100644 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr @@ -14,7 +14,7 @@ contract Crowdfunding { functions::{initializer, internal, private, public}, storage::storage, }, - prelude::{AztecAddress, PrivateSet, SharedImmutable}, + prelude::{AztecAddress, PrivateSet, PublicImmutable}, protocol_types::traits::Serialize, unencrypted_logs::unencrypted_event_emission::encode_event, utils::comparison::Comparator, @@ -38,11 +38,11 @@ contract Crowdfunding { #[storage] struct Storage { // Token used for donations (e.g. DAI) - donation_token: SharedImmutable, + donation_token: PublicImmutable, // Crowdfunding campaign operator - operator: SharedImmutable, + operator: PublicImmutable, // End of the crowdfunding campaign after which no more donations are accepted - deadline: SharedImmutable, + deadline: PublicImmutable, // Notes emitted to donors when they donate (can be used as proof to obtain rewards, eg in Claim contracts) donation_receipts: PrivateSet, } diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index 6ca4ad621f6..2583f21c524 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -23,7 +23,7 @@ contract DocsExample { }; use dep::aztec::prelude::{ AztecAddress, Map, NoteViewerOptions, PrivateContext, PrivateImmutable, PrivateMutable, - PrivateSet, PublicImmutable, PublicMutable, SharedImmutable, + PrivateSet, PublicImmutable, PublicMutable, }; // how to import methods from other files/folders within your workspace @@ -46,15 +46,12 @@ contract DocsExample { // docs:start:storage-private-immutable-declaration private_immutable: PrivateImmutable, // docs:end:storage-private-immutable-declaration - // docs:start:storage-shared-immutable-declaration - shared_immutable: SharedImmutable, - // docs:end:storage-shared-immutable-declaration - // docs:start:storage-minters-declaration - minters: Map, Context>, - // docs:end:storage-minters-declaration // docs:start:storage-public-immutable-declaration public_immutable: PublicImmutable, // docs:end:storage-public-immutable-declaration + // docs:start:storage-minters-declaration + minters: Map, Context>, + // docs:end:storage-minters-declaration } // Note: The following is no longer necessary to implement manually as our macros do this for us. It is left here @@ -80,7 +77,7 @@ contract DocsExample { set: PrivateSet::new(context, 5), // docs:end:storage-set-init private_immutable: PrivateImmutable::new(context, 6), - shared_immutable: SharedImmutable::new(context, 7), + public_immutable: PublicImmutable::new(context, 7), // docs:start:storage-minters-init minters: Map::new( context, @@ -88,48 +85,48 @@ contract DocsExample { |context, slot| PublicMutable::new(context, slot), ), // docs:end:storage-minters-init - // docs:start:storage-public-immutable - public_immutable: PublicImmutable::new(context, 9), // docs:end:storage-public-immutable } } } + // docs:start:initialize_public_immutable #[public] - fn initialize_shared_immutable(points: u8) { + fn initialize_public_immutable(points: u8) { let mut new_leader = Leader { account: context.msg_sender(), points }; - storage.shared_immutable.initialize(new_leader); + storage.public_immutable.initialize(new_leader); + // docs:end:initialize_public_immutable } #[private] - fn match_shared_immutable(account: AztecAddress, points: u8) { + fn match_public_immutable(account: AztecAddress, points: u8) { let expected = Leader { account, points }; - let read = storage.shared_immutable.read(); + let read = storage.public_immutable.read(); assert(read.account == expected.account, "Invalid account"); assert(read.points == expected.points, "Invalid points"); } #[private] - fn get_shared_immutable_constrained_private_indirect() -> Leader { + fn get_public_immutable_constrained_private_indirect() -> Leader { // This is a private function that calls another private function // and returns the response. // Used to test that we can retrieve values through calls and // correctly return them in the simulation let mut leader = DocsExample::at(context.this_address()) - .get_shared_immutable_constrained_private() + .get_public_immutable_constrained_private() .view(&mut context); leader.points += 1; leader } #[public] - fn get_shared_immutable_constrained_public_indirect() -> Leader { + fn get_public_immutable_constrained_public_indirect() -> Leader { // This is a public function that calls another public function // and returns the response. // Used to test that we can retrieve values through calls and // correctly return them in the simulation let mut leader = DocsExample::at(context.this_address()) - .get_shared_immutable_constrained_public() + .get_public_immutable_constrained_public() .view(&mut context); leader.points += 1; leader @@ -137,32 +134,20 @@ contract DocsExample { #[public] #[view] - fn get_shared_immutable_constrained_public() -> Leader { - storage.shared_immutable.read() + fn get_public_immutable_constrained_public() -> Leader { + storage.public_immutable.read() } #[public] - fn get_shared_immutable_constrained_public_multiple() -> [Leader; 5] { - let a = storage.shared_immutable.read(); + fn get_public_immutable_constrained_public_multiple() -> [Leader; 5] { + let a = storage.public_immutable.read(); [a, a, a, a, a] } #[private] #[view] - fn get_shared_immutable_constrained_private() -> Leader { - storage.shared_immutable.read() - } - - unconstrained fn get_shared_immutable() -> Leader { - storage.shared_immutable.read() - } - - #[public] - fn initialize_public_immutable(points: u8) { - // docs:start:initialize_public_immutable - let mut new_leader = Leader { account: context.msg_sender(), points }; - storage.public_immutable.initialize(new_leader); - // docs:end:initialize_public_immutable + fn get_public_immutable_constrained_private() -> Leader { + storage.public_immutable.read() } // docs:start:read_public_immutable diff --git a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr index 31e1a32ed95..eb1d7c4af50 100644 --- a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr @@ -7,7 +7,7 @@ contract EasyPrivateVoting { keys::getters::get_public_keys, macros::{functions::{initializer, internal, private, public}, storage::storage}, }; - use dep::aztec::prelude::{AztecAddress, Map, PublicMutable, SharedImmutable}; + use dep::aztec::prelude::{AztecAddress, Map, PublicImmutable, PublicMutable}; // docs:end:imports // docs:start:storage_struct #[storage] @@ -15,7 +15,7 @@ contract EasyPrivateVoting { admin: PublicMutable, // admin can end vote tally: Map, Context>, // we will store candidate as key and number of votes as value vote_ended: PublicMutable, // vote_ended is boolean - active_at_block: SharedImmutable, // when people can start voting + active_at_block: PublicImmutable, // when people can start voting } // docs:end:storage_struct diff --git a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/main.nr index 01757a26de8..f9fe168949f 100644 --- a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/main.nr @@ -7,7 +7,7 @@ contract FeeJuice { use dep::aztec::{ macros::{functions::{internal, private, public, view}, storage::storage}, protocol_types::{address::{AztecAddress, EthAddress}, constants::FEE_JUICE_INITIAL_MINT}, - state_vars::{Map, PublicMutable, SharedImmutable}, + state_vars::{Map, PublicImmutable, PublicMutable}, }; use crate::lib::get_bridge_gas_msg_hash; @@ -17,7 +17,7 @@ contract FeeJuice { // This map is accessed directly by protocol circuits to check balances for fee payment. // Do not change this storage layout unless you also update the base rollup circuits. balances: Map, Context>, - portal_address: SharedImmutable, + portal_address: PublicImmutable, } // Not flagged as initializer to reduce cost of checking init nullifier in all functions. diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr index a35be34fca8..96ca07817a2 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr @@ -10,13 +10,13 @@ contract FPC { use dep::aztec::{ macros::{functions::{initializer, internal, private, public}, storage::storage}, protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, - state_vars::SharedImmutable, + state_vars::PublicImmutable, }; use dep::token::Token; #[storage] struct Storage { - settings: SharedImmutable, + settings: PublicImmutable, } #[public] @@ -28,7 +28,7 @@ contract FPC { #[private] fn fee_entrypoint_private(amount: Field, asset: AztecAddress, nonce: Field) { - // TODO(PR #8022): Once SharedImmutable performs only 1 merkle proof here, we'll save ~4k gates + // TODO(PR #8022): Once PublicImmutable performs only 1 merkle proof here, we'll save ~4k gates let settings = storage.settings.read(); assert(asset == settings.other_asset); diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr index 1df5506002c..0f7c9b35fb1 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr @@ -24,7 +24,7 @@ contract NFT { oracle::random::random, prelude::{ AztecAddress, Map, NoteGetterOptions, NoteViewerOptions, PrivateContext, PrivateSet, - PublicContext, PublicMutable, SharedImmutable, + PublicContext, PublicImmutable, PublicMutable, }, protocol_types::{point::Point, traits::Serialize}, utils::comparison::Comparator, @@ -45,9 +45,9 @@ contract NFT { #[storage] struct Storage { // The symbol of the NFT - symbol: SharedImmutable, + symbol: PublicImmutable, // The name of the NFT - name: SharedImmutable, + name: PublicImmutable, // The admin of the contract admin: PublicMutable, // Addresses that can mint diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index c104e23a505..e7298d32e3c 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -9,7 +9,7 @@ use dep::aztec::macros::aztec; #[aztec] contract TokenBridge { - use dep::aztec::prelude::{AztecAddress, EthAddress, SharedImmutable}; + use dep::aztec::prelude::{AztecAddress, EthAddress, PublicImmutable}; use dep::token_portal_content_hash_lib::{ get_mint_to_private_content_hash, get_mint_to_public_content_hash, @@ -28,8 +28,8 @@ contract TokenBridge { // Storage structure, containing all storage, and specifying what slots they use. #[storage] struct Storage { - token: SharedImmutable, - portal_address: SharedImmutable, + token: PublicImmutable, + portal_address: PublicImmutable, } // Constructs the contract. diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index 677a585dc72..53eff85b18e 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -32,7 +32,7 @@ contract Token { }, oracle::random::random, prelude::{ - AztecAddress, FunctionSelector, Map, PublicContext, PublicMutable, SharedImmutable, + AztecAddress, FunctionSelector, Map, PublicContext, PublicImmutable, PublicMutable, }, protocol_types::{point::Point, traits::Serialize}, }; @@ -81,10 +81,10 @@ contract Token { // docs:end:storage_balances total_supply: PublicMutable, public_balances: Map, Context>, - symbol: SharedImmutable, - name: SharedImmutable, + symbol: PublicImmutable, + name: PublicImmutable, // docs:start:storage_decimals - decimals: SharedImmutable, + decimals: PublicImmutable, // docs:end:storage_decimals } // docs:end:storage_struct @@ -138,21 +138,17 @@ contract Token { storage.symbol.read() } - // docs:start:read_shared_immutable_public #[public] #[view] fn public_get_decimals() -> pub u8 { storage.decimals.read() } - // docs:end:read_shared_immutable_public - // docs:start:read_shared_immutable_private #[private] #[view] fn private_get_decimals() -> pub u8 { storage.decimals.read() } - // docs:end:read_shared_immutable_private // docs:start:admin #[public] diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr index 66b78d4430d..f1162a9df11 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -8,7 +8,7 @@ use dep::aztec::macros::aztec; #[aztec] contract Uniswap { - use dep::aztec::prelude::{AztecAddress, EthAddress, FunctionSelector, SharedImmutable}; + use dep::aztec::prelude::{AztecAddress, EthAddress, FunctionSelector, PublicImmutable}; use dep::authwit::auth::{ assert_current_call_valid_authwit_public, compute_authwit_message_hash_from_call, @@ -25,7 +25,7 @@ contract Uniswap { #[storage] struct Storage { - portal_address: SharedImmutable, + portal_address: PublicImmutable, } #[public] diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index c3130166f2c..7a47098bc32 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -26,90 +26,70 @@ describe('e2e_state_vars', () => { afterAll(() => teardown()); - describe('SharedImmutable', () => { - it('private read of uninitialized SharedImmutable', async () => { - const s = await contract.methods.get_shared_immutable().simulate(); + describe('PublicImmutable', () => { + it('private read of uninitialized PublicImmutable', async () => { + const s = await contract.methods.get_public_immutable().simulate(); // Send the transaction and wait for it to be mined (wait function throws if the tx is not mined) - await contract.methods.match_shared_immutable(s.account, s.points).send().wait(); + await contract.methods.match_public_immutable(s.account, s.points).send().wait(); }); - it('initialize and read SharedImmutable', async () => { - // Initializes the shared immutable and then reads the value using an unconstrained function + it('initialize and read PublicImmutable', async () => { + // Initializes the public immutable and then reads the value using an unconstrained function // checking the return values: - await contract.methods.initialize_shared_immutable(1).send().wait(); + await contract.methods.initialize_public_immutable(1).send().wait(); - const read = await contract.methods.get_shared_immutable().simulate(); + const read = await contract.methods.get_public_immutable().simulate(); expect(read).toEqual({ account: wallet.getAddress(), points: read.points }); }); - it('private read of SharedImmutable', async () => { + it('private read of PublicImmutable', async () => { // Reads the value using an unconstrained function checking the return values with: // 1. A constrained private function that reads it directly // 2. A constrained private function that calls another private function that reads. // The indirect, adds 1 to the point to ensure that we are returning the correct value. const [a, b, c] = await new BatchCall(wallet, [ - contract.methods.get_shared_immutable_constrained_private().request(), - contract.methods.get_shared_immutable_constrained_private_indirect().request(), - contract.methods.get_shared_immutable().request(), + contract.methods.get_public_immutable_constrained_private().request(), + contract.methods.get_public_immutable_constrained_private_indirect().request(), + contract.methods.get_public_immutable().request(), ]).simulate(); expect(a).toEqual(c); expect(b).toEqual({ account: c.account, points: c.points + 1n }); - await contract.methods.match_shared_immutable(c.account, c.points).send().wait(); + await contract.methods.match_public_immutable(c.account, c.points).send().wait(); }); - it('public read of SharedImmutable', async () => { + it('public read of PublicImmutable', async () => { // Reads the value using an unconstrained function checking the return values with: // 1. A constrained public function that reads it directly // 2. A constrained public function that calls another public function that reads. // The indirect, adds 1 to the point to ensure that we are returning the correct value. const [a, b, c] = await new BatchCall(wallet, [ - contract.methods.get_shared_immutable_constrained_public().request(), - contract.methods.get_shared_immutable_constrained_public_indirect().request(), - contract.methods.get_shared_immutable().request(), + contract.methods.get_public_immutable_constrained_public().request(), + contract.methods.get_public_immutable_constrained_public_indirect().request(), + contract.methods.get_public_immutable().request(), ]).simulate(); expect(a).toEqual(c); expect(b).toEqual({ account: c.account, points: c.points + 1n }); - await contract.methods.match_shared_immutable(c.account, c.points).send().wait(); + await contract.methods.match_public_immutable(c.account, c.points).send().wait(); }); - it('public multiread of SharedImmutable', async () => { + it('public multiread of PublicImmutable', async () => { // Reads the value using an unconstrained function checking the return values with: // 1. A constrained public function that reads 5 times directly (going beyond the previous 4 Field return value) - const a = await contract.methods.get_shared_immutable_constrained_public_multiple().simulate(); - const c = await contract.methods.get_shared_immutable().simulate(); + const a = await contract.methods.get_public_immutable_constrained_public_multiple().simulate(); + const c = await contract.methods.get_public_immutable().simulate(); expect(a).toEqual([c, c, c, c, c]); }); - it('initializing SharedImmutable the second time should fail', async () => { - // Jest executes the tests sequentially and the first call to initialize_shared_immutable was executed - // in the previous test, so the call below should fail. - await expect(contract.methods.initialize_shared_immutable(1).prove()).rejects.toThrow( - 'Assertion failed: SharedImmutable already initialized', - ); - }); - }); - - describe('PublicImmutable', () => { - it('initialize and read public immutable', async () => { - const numPoints = 1n; - - await contract.methods.initialize_public_immutable(numPoints).send().wait(); - const p = await contract.methods.get_public_immutable().simulate(); - - expect(p.account).toEqual(wallet.getCompleteAddress().address); - expect(p.points).toEqual(numPoints); - }); - it('initializing PublicImmutable the second time should fail', async () => { // Jest executes the tests sequentially and the first call to initialize_public_immutable was executed // in the previous test, so the call below should fail. From 60ea064ae60169f215f515c74370b6a27b16903b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Mon, 25 Nov 2024 17:04:19 +0000 Subject: [PATCH 2/2] Fix docs --- .../smart_contract_reference/storage/public_state.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/docs/reference/developer_references/smart_contract_reference/storage/public_state.md b/docs/docs/reference/developer_references/smart_contract_reference/storage/public_state.md index 4a298e6bbd9..1c2c46cded4 100644 --- a/docs/docs/reference/developer_references/smart_contract_reference/storage/public_state.md +++ b/docs/docs/reference/developer_references/smart_contract_reference/storage/public_state.md @@ -85,8 +85,6 @@ Is done exactly like the `PublicMutable` struct, but with the `PublicImmutable` #include_code storage-public-immutable-declaration /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust -#include_code storage-public-immutable /noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr rust - ### `initialize` This function sets the immutable value. It can only be called once.