From bbaebf4ab6c4272a2819800a1edb6d328d9bfea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Wed, 3 Jan 2024 14:18:50 +0100 Subject: [PATCH] feat!: moving `compute_selector` to `FunctionSelector` (#3806) Fixes #3681 --- boxes/token/src/contracts/src/main.nr | 12 ++++--- .../dev_docs/contracts/syntax/functions.md | 1 - .../writing_private_voting_contract.md | 4 +-- noir/aztec_macros/src/lib.rs | 14 +++++--- .../nargo_fmt/tests/expected/contract.nr | 5 +-- .../tooling/nargo_fmt/tests/input/contract.nr | 5 +-- yarn-project/aztec-nr/authwit/src/account.nr | 1 - yarn-project/aztec-nr/aztec/src/lib.nr | 1 - yarn-project/aztec-nr/aztec/src/selector.nr | 17 --------- yarn-project/aztec-nr/aztec/src/utils.nr | 16 --------- .../add_noir_compiler_commander_actions.ts | 4 +-- .../benchmarking_contract/src/main.nr | 8 +++-- .../contracts/card_game_contract/src/main.nr | 8 ++--- .../src/contracts/child_contract/src/main.nr | 10 +++--- .../easy_private_voting_contract/src/main.nr | 6 ++-- .../src/contracts/escrow_contract/src/main.nr | 8 +++-- .../inclusion_proofs_contract/src/main.nr | 4 +-- .../lending_contract/src/interfaces.nr | 22 ++++++------ .../contracts/lending_contract/src/main.nr | 22 ++++++------ .../src/contracts/parent_contract/src/main.nr | 36 ++++++++++++------- .../contracts/slow_tree_contract/src/main.nr | 10 +++--- .../src/interfaces.nr | 17 ++++----- .../token_blacklist_contract/src/main.nr | 14 ++++---- .../token_bridge_contract/src/main.nr | 16 +++++---- .../src/token_interface.nr | 18 +++++----- .../src/contracts/token_contract/src/main.nr | 12 ++++--- .../uniswap_contract/src/interfaces.nr | 20 ++++++----- .../contracts/uniswap_contract/src/main.nr | 18 +++++----- .../types/src/abis/function_selector.nr | 18 +++++++++- .../src/crates/types/src/utils.nr | 5 +-- .../src/crates/types/src/utils/field.nr | 15 ++++++++ 31 files changed, 204 insertions(+), 163 deletions(-) delete mode 100644 yarn-project/aztec-nr/aztec/src/selector.nr create mode 100644 yarn-project/noir-protocol-circuits/src/crates/types/src/utils/field.nr diff --git a/boxes/token/src/contracts/src/main.nr b/boxes/token/src/contracts/src/main.nr index c2348e264ac..686871f1661 100644 --- a/boxes/token/src/contracts/src/main.nr +++ b/boxes/token/src/contracts/src/main.nr @@ -29,9 +29,11 @@ contract Token { bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, }, - selector::compute_selector, }; - use dep::protocol_types::address::AztecAddress; + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + }; // docs:start:import_authwit use dep::authwit::{ @@ -123,7 +125,7 @@ contract Token { // docs:start:constructor #[aztec(private)] fn constructor(admin: AztecAddress) { - let selector = compute_selector("_initialize((Field))"); + let selector = FunctionSelector::from_signature("_initialize((Field))"); context.call_public_function(context.this_address(), selector, [admin.to_field()]); } // docs:end:constructor @@ -268,7 +270,7 @@ contract Token { storage.balances.at(from).sub(SafeU120::new(amount)); - let selector = compute_selector("_increase_public_balance((Field),Field)"); + let selector = FunctionSelector::from_signature("_increase_public_balance((Field),Field)"); let _void = context.call_public_function(context.this_address(), selector, [to.to_field(), amount]); } // docs:end:unshield @@ -303,7 +305,7 @@ contract Token { storage.balances.at(from).sub(SafeU120::new(amount)); - let selector = compute_selector("_reduce_total_supply(Field)"); + let selector = FunctionSelector::from_signature("_reduce_total_supply(Field)"); let _void = context.call_public_function(context.this_address(), selector, [amount]); } // docs:end:burn diff --git a/docs/docs/dev_docs/contracts/syntax/functions.md b/docs/docs/dev_docs/contracts/syntax/functions.md index 8548be6afb6..7c7cb620bcc 100644 --- a/docs/docs/dev_docs/contracts/syntax/functions.md +++ b/docs/docs/dev_docs/contracts/syntax/functions.md @@ -111,7 +111,6 @@ Oracles introduce **non-determinism** into a circuit, and thus are `unconstraine ### A few useful inbuilt oracles -- [`compute_selector`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/selector.nr) - Computes the selector of a function. This is useful for when you want to call a function from within a circuit, but don't have an interface at hand and don't want to hardcode the selector in hex. - [`debug_log`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/debug_log.nr) - Provides a couple of debug functions that can be used to log information to the console. - [`auth_witness`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/authwit/src/auth_witness.nr) - Provides a way to fetch the authentication witness for a given address. This is useful when building account contracts to support approve-like functionality. - [`get_l1_to_l2_message`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec-nr/aztec/src/oracle/get_l1_to_l2_message.nr) - Useful for application that receive messages from L1 to be consumed on L2, such as token bridges or other cross-chain applications. diff --git a/docs/docs/dev_docs/tutorials/writing_private_voting_contract.md b/docs/docs/dev_docs/tutorials/writing_private_voting_contract.md index 24ba1d18515..19049c46357 100644 --- a/docs/docs/dev_docs/tutorials/writing_private_voting_contract.md +++ b/docs/docs/dev_docs/tutorials/writing_private_voting_contract.md @@ -71,7 +71,7 @@ We are using various utils within the Aztec library: * `context` - exposes things such as the contract address, msg_sender, etc * `oracle::get_secret_key` - get your secret key to help us create a randomized nullifier -* `selector::compute_selector` - compute a function selector so we can call functions from other functions +* `FunctionSelector::from_signature` - compute a function selector from signature so we can call functions from other functions * `state_vars::{ map::Map, public_state::PublicState, }` - we will use a Map to store the votes (key = voteId, value = number of votes), and PublicState to hold our public values that we mentioned earlier * `types::type_serialization::{..}` - various serialization methods for defining how to use these types * `types::address::{AztecAddress},` - our admin will be held as an address @@ -113,7 +113,7 @@ Therefore our constructor must call a public function by using `context.call_pub `context.call_public_function()` takes three arguments: 1. The contract address whose method we want to call -2. The selector of the function to call (we can use `compute_selector()` for this) +2. The selector of the function to call (we can use `FunctionSelector::from_signature(...)` for this) 3. The arguments of the function (we pass the `admin`) We now need to write the `_initialize()` function: diff --git a/noir/aztec_macros/src/lib.rs b/noir/aztec_macros/src/lib.rs index 56cd700790b..2ed2f66789e 100644 --- a/noir/aztec_macros/src/lib.rs +++ b/noir/aztec_macros/src/lib.rs @@ -483,11 +483,12 @@ const SIGNATURE_PLACEHOLDER: &str = "SIGNATURE_PLACEHOLDER"; /// Generates the impl for an event selector /// +/// TODO(https://github.com/AztecProtocol/aztec-packages/issues/3590): Make this point to aztec-nr once the issue is fixed. /// Inserts the following code: /// ```noir /// impl SomeStruct { /// fn selector() -> FunctionSelector { -/// aztec::selector::compute_selector("SIGNATURE_PLACEHOLDER") +/// protocol_types::abis::function_selector::FunctionSelector::from_signature("SIGNATURE_PLACEHOLDER") /// } /// } /// ``` @@ -498,15 +499,18 @@ const SIGNATURE_PLACEHOLDER: &str = "SIGNATURE_PLACEHOLDER"; fn generate_selector_impl(structure: &NoirStruct) -> TypeImpl { let struct_type = make_type(UnresolvedTypeData::Named(path(structure.name.clone()), vec![])); + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3590): Make this point to aztec-nr once the issue is fixed. + let selector_path = chained_path!("protocol_types", "abis", "function_selector", "FunctionSelector"); + let mut from_signature_path = selector_path.clone(); + from_signature_path.segments.push(ident("from_signature")); + let selector_fun_body = BlockExpression(vec![make_statement(StatementKind::Expression(call( - variable_path(chained_path!("aztec", "selector", "compute_selector")), + variable_path(from_signature_path), vec![expression(ExpressionKind::Literal(Literal::Str(SIGNATURE_PLACEHOLDER.to_string())))], )))]); // Define `FunctionSelector` return type - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3590): Make this point to aztec-nr once the issue is fixed. - let return_type_path = chained_path!("protocol_types", "abis", "function_selector", "FunctionSelector"); - let return_type = FunctionReturnType::Ty(make_type(UnresolvedTypeData::Named(return_type_path, vec![]))); + let return_type = FunctionReturnType::Ty(make_type(UnresolvedTypeData::Named(selector_path, vec![]))); let mut selector_fn_def = FunctionDefinition::normal( &ident("selector"), diff --git a/noir/tooling/nargo_fmt/tests/expected/contract.nr b/noir/tooling/nargo_fmt/tests/expected/contract.nr index 7d799459aff..0313da832a8 100644 --- a/noir/tooling/nargo_fmt/tests/expected/contract.nr +++ b/noir/tooling/nargo_fmt/tests/expected/contract.nr @@ -3,6 +3,8 @@ // Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. // Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. contract Benchmarking { + use dep::protocol_types::abis::function_selector::FunctionSelector; + use dep::value_note::{ utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, @@ -11,7 +13,6 @@ contract Benchmarking { use dep::aztec::{ context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - selector::compute_selector, log::emit_unencrypted_log, state_vars::{map::Map, public_state::PublicState, set::Set}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, @@ -59,7 +60,7 @@ contract Benchmarking { storage.balances.at(owner).write(current + value); let _callStackItem1 = context.call_public_function( context.this_address(), - compute_selector("broadcast(Field)"), + FunctionSelector::from_signature("broadcast(Field)"), [owner] ); } diff --git a/noir/tooling/nargo_fmt/tests/input/contract.nr b/noir/tooling/nargo_fmt/tests/input/contract.nr index ec27c662fe5..58ae0e909a1 100644 --- a/noir/tooling/nargo_fmt/tests/input/contract.nr +++ b/noir/tooling/nargo_fmt/tests/input/contract.nr @@ -3,6 +3,8 @@ // Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. // Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. contract Benchmarking { + use dep::protocol_types::abis::function_selector::FunctionSelector; + use dep::value_note::{ utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, @@ -11,7 +13,6 @@ contract Benchmarking { use dep::aztec::{ context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - selector::compute_selector, log::emit_unencrypted_log, state_vars::{map::Map, public_state::PublicState, set::Set}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, @@ -57,7 +58,7 @@ contract Benchmarking { fn increment_balance(owner: Field, value: Field) { let current = storage.balances.at(owner).read(); storage.balances.at(owner).write(current + value); - let _callStackItem1 = context.call_public_function(context.this_address(), compute_selector("broadcast(Field)"), [owner]); + let _callStackItem1 = context.call_public_function(context.this_address(), FunctionSelector::from_signature("broadcast(Field)"), [owner]); } // Est ultricies integer quis auctor elit sed. In nibh mauris cursus mattis molestie a iaculis. diff --git a/yarn-project/aztec-nr/authwit/src/account.nr b/yarn-project/aztec-nr/authwit/src/account.nr index 7a79d089f68..33b92954c77 100644 --- a/yarn-project/aztec-nr/authwit/src/account.nr +++ b/yarn-project/aztec-nr/authwit/src/account.nr @@ -1,5 +1,4 @@ use dep::aztec::context::{PrivateContext, PublicContext, Context}; -use dep::aztec::selector::compute_selector; use dep::aztec::state_vars::{map::Map, public_state::PublicState}; use dep::aztec::types::type_serialization::bool_serialization::{BoolSerializationMethods,BOOL_SERIALIZED_LEN}; diff --git a/yarn-project/aztec-nr/aztec/src/lib.nr b/yarn-project/aztec-nr/aztec/src/lib.nr index 2a3f9113224..46f548d4305 100644 --- a/yarn-project/aztec-nr/aztec/src/lib.nr +++ b/yarn-project/aztec-nr/aztec/src/lib.nr @@ -6,7 +6,6 @@ mod log; mod messaging; mod note; mod oracle; -mod selector; mod state_vars; mod types; mod utils; diff --git a/yarn-project/aztec-nr/aztec/src/selector.nr b/yarn-project/aztec-nr/aztec/src/selector.nr deleted file mode 100644 index d59a437b382..00000000000 --- a/yarn-project/aztec-nr/aztec/src/selector.nr +++ /dev/null @@ -1,17 +0,0 @@ -use dep::protocol_types::abis::function_selector::FunctionSelector; - -use crate::utils::field_from_bytes; - -global SELECTOR_SIZE = 4; - -pub fn compute_selector(signature: str) -> FunctionSelector { - let bytes = signature.as_bytes(); - let hash = dep::std::hash::keccak256(bytes, bytes.len() as u32); - - let mut selector_be_bytes = [0; SELECTOR_SIZE]; - for i in 0..SELECTOR_SIZE { - selector_be_bytes[i] = hash[i]; - } - - FunctionSelector::from_field(field_from_bytes(selector_be_bytes, true)) -} diff --git a/yarn-project/aztec-nr/aztec/src/utils.nr b/yarn-project/aztec-nr/aztec/src/utils.nr index a9a766c6b7a..f676d754d76 100644 --- a/yarn-project/aztec-nr/aztec/src/utils.nr +++ b/yarn-project/aztec-nr/aztec/src/utils.nr @@ -5,22 +5,6 @@ pub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: Field) -> [ dst } -pub fn field_from_bytes(bytes: [u8; N], big_endian: bool) -> Field { - assert(bytes.len() as u32 < 32, "field_from_bytes: N must be less than 32"); - let mut as_field = 0; - let mut offset = 1; - for i in 0..N { - let mut index = i; - if big_endian { - index = N - i - 1; - } - as_field += (bytes[index] as Field) * offset; - offset *= 256; - } - - as_field -} - // TODO(#3470): Copied over from https://github.com/AztecProtocol/aztec-packages/blob/a07c4bd47313be6aa604a63f37857eb0136b41ba/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr#L599 // move to a shared place? diff --git a/yarn-project/noir-compiler/src/cli/add_noir_compiler_commander_actions.ts b/yarn-project/noir-compiler/src/cli/add_noir_compiler_commander_actions.ts index 857e39bfb43..31054b548b8 100644 --- a/yarn-project/noir-compiler/src/cli/add_noir_compiler_commander_actions.ts +++ b/yarn-project/noir-compiler/src/cli/add_noir_compiler_commander_actions.ts @@ -40,10 +40,10 @@ export function addNoirCompilerCommanderActions(program: Command, log: LogFn = ( .option('--artifacts ', 'Folder containing the compiled artifacts, relative to the project path', 'target') .option( '-o, --outdir ', - 'Output folder for the generated noir interfaces, relative to the project path', + 'Output folder for the generated typescript interfaces, relative to the project path', 'interfaces', ) - .description('Generates Noir interfaces from the artifacts in the given project') + .description('Generates typescript interfaces from the artifacts in the given project') .action(async (projectPath: string, options) => { const { generateTypescriptInterface } = await import('./generate_typescript_interface.js'); diff --git a/yarn-project/noir-contracts/src/contracts/benchmarking_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/benchmarking_contract/src/main.nr index cd941bc0cfb..e27e1dfb7bb 100644 --- a/yarn-project/noir-contracts/src/contracts/benchmarking_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/benchmarking_contract/src/main.nr @@ -13,13 +13,15 @@ contract Benchmarking { use dep::aztec::{ context::{Context}, note::{utils as note_utils, note_getter_options::NoteGetterOptions, note_header::NoteHeader}, - selector::compute_selector, log::emit_unencrypted_log, state_vars::{map::Map, public_state::PublicState, set::Set}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, }; - use dep::protocol_types::address::AztecAddress; + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + }; struct Storage { notes: Map>, @@ -66,7 +68,7 @@ contract Benchmarking { storage.balances.at(owner.to_field()).write(current + value); let _callStackItem1 = context.call_public_function( context.this_address(), - compute_selector("broadcast((Field))"), + FunctionSelector::from_signature("broadcast((Field))"), [owner.to_field()] ); } diff --git a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/main.nr index a3203aa8a39..b28d27c625b 100644 --- a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/main.nr @@ -3,6 +3,7 @@ mod game; contract CardGame { use dep::protocol_types::{ + abis::function_selector::FunctionSelector, address::AztecAddress, constants::MAX_NOTES_PER_PAGE, }; @@ -33,7 +34,6 @@ contract CardGame { note_header::NoteHeader, utils as note_utils, }, - selector::compute_selector }; use crate::cards::{ @@ -128,7 +128,7 @@ contract CardGame { collection.remove_cards(cards, player); let mut game_deck = storage.game_decks.at(game as Field).at(player.to_field()); let _added_to_game_deck = game_deck.add_cards(cards, player); - let selector = compute_selector("on_game_joined(u32,(Field),u32)"); + let selector = FunctionSelector::from_signature("on_game_joined(u32,(Field),u32)"); let strength = compute_deck_strength(cards); context.call_public_function( context.this_address(), @@ -163,7 +163,7 @@ contract CardGame { let mut game_deck = storage.game_decks.at(game as Field).at(player.to_field()); game_deck.remove_cards([card], player); - let selector = compute_selector("on_card_played(u32,(Field),Field)"); + let selector = FunctionSelector::from_signature("on_card_played(u32,(Field),Field)"); // docs:start:call_public_function context.call_public_function( context.this_address(), @@ -195,7 +195,7 @@ contract CardGame { let mut collection = storage.collections.at(player.to_field()); let _inserted_cards = collection.add_cards(cards, player); - let selector = compute_selector("on_cards_claimed(u32,(Field),Field)"); + let selector = FunctionSelector::from_signature("on_cards_claimed(u32,(Field),Field)"); context.call_public_function( context.this_address(), selector, diff --git a/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr index 0c5897d4598..cc8a29e276e 100644 --- a/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/child_contract/src/main.nr @@ -5,12 +5,14 @@ contract Child { use dep::aztec::{ abi::CallContext, context::{PrivateContext, PublicContext, Context}, - selector::compute_selector, log::emit_unencrypted_log, state_vars::public_state::PublicState, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, }; - use dep::protocol_types::address::AztecAddress; + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + }; struct Storage { current_value: PublicState, @@ -93,7 +95,7 @@ contract Child { #[aztec(public)] fn setValueTwiceWithNestedFirst() { - let pubSetValueSelector = compute_selector("pubSetValue(Field)"); + let pubSetValueSelector = FunctionSelector::from_signature("pubSetValue(Field)"); let _ret = context.call_public_function(context.this_address(), pubSetValueSelector, [10]); storage.current_value.write(20); @@ -105,7 +107,7 @@ contract Child { storage.current_value.write(20); emit_unencrypted_log(&mut context, 20); - let pubSetValueSelector = compute_selector("pubSetValue(Field)"); + let pubSetValueSelector = FunctionSelector::from_signature("pubSetValue(Field)"); let _ret = context.call_public_function(context.this_address(), pubSetValueSelector, [10]); } diff --git a/yarn-project/noir-contracts/src/contracts/easy_private_voting_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/easy_private_voting_contract/src/main.nr index b3a5b86f280..06104942338 100644 --- a/yarn-project/noir-contracts/src/contracts/easy_private_voting_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/easy_private_voting_contract/src/main.nr @@ -1,13 +1,13 @@ contract EasyPrivateVoting { // docs:start:imports use dep::protocol_types::{ + abis::function_selector::FunctionSelector, address::AztecAddress, constants::EMPTY_NULLIFIED_COMMITMENT, }; use dep::aztec::{ context::{PrivateContext, Context}, oracle::get_secret_key::get_secret_key, // used to compute nullifier - selector::compute_selector, // used to compute function selector for calling a function state_vars::{ map::Map, public_state::PublicState,}, types::type_serialization::{ // serialization methods for using booleans and aztec addresses bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, @@ -57,7 +57,7 @@ contract EasyPrivateVoting { context.call_public_function( // we cannot update public state directly from private function but we can call public function (which queues it) context.this_address(),// contract address whose method we want to call - compute_selector("_initialize((Field))"), // function selector + FunctionSelector::from_signature("_initialize((Field))"), // function selector [admin.to_field()] // parameters ); } @@ -77,7 +77,7 @@ contract EasyPrivateVoting { context.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT); // push nullifier context.call_public_function( context.this_address(), - compute_selector("add_to_tally_public(Field)"), + FunctionSelector::from_signature("add_to_tally_public(Field)"), [candidate] ); } diff --git a/yarn-project/noir-contracts/src/contracts/escrow_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/escrow_contract/src/main.nr index 2ade666eb79..5fa92bd1fb4 100644 --- a/yarn-project/noir-contracts/src/contracts/escrow_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/escrow_contract/src/main.nr @@ -2,7 +2,10 @@ contract Escrow { use dep::std::option::Option; - use dep::protocol_types::address::AztecAddress; + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + }; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, @@ -12,7 +15,6 @@ contract Escrow { utils as note_utils, }, oracle::get_public_key::get_public_key, - selector::compute_selector, state_vars::set::Set, }; @@ -59,7 +61,7 @@ contract Escrow { let notes = storage.owners.get_notes(options); assert(notes[0].is_some(), "Sender is not an owner."); - let selector = compute_selector("transfer((Field),(Field),Field,Field)"); + let selector = FunctionSelector::from_signature("transfer((Field),(Field),Field,Field)"); let _callStackItem = context.call_private_function( token, selector, diff --git a/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr index 1a91236bbf1..8a0d20bd5ce 100644 --- a/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr @@ -1,6 +1,7 @@ // A demonstration of inclusion and non-inclusion proofs. contract InclusionProofs { use dep::protocol_types::{ + abis::function_selector::FunctionSelector, address::{ AztecAddress, EthAddress, @@ -13,7 +14,6 @@ contract InclusionProofs { set::Set, public_state::PublicState, }, - selector::compute_selector, types::{ type_serialization::field_serialization::FieldSerializationMethods, }, @@ -75,7 +75,7 @@ contract InclusionProofs { #[aztec(private)] fn constructor(public_value: Field) { - let selector = compute_selector("_initialize(Field)"); + let selector = FunctionSelector::from_signature("_initialize(Field)"); context.call_public_function(context.this_address(), selector, [public_value]); } diff --git a/yarn-project/noir-contracts/src/contracts/lending_contract/src/interfaces.nr b/yarn-project/noir-contracts/src/contracts/lending_contract/src/interfaces.nr index 773ff12bea6..3f48bed4156 100644 --- a/yarn-project/noir-contracts/src/contracts/lending_contract/src/interfaces.nr +++ b/yarn-project/noir-contracts/src/contracts/lending_contract/src/interfaces.nr @@ -4,9 +4,11 @@ use dep::aztec::context::{ }; use crate::asset::Asset; -use dep::protocol_types::constants::RETURN_VALUES_LENGTH; -use dep::protocol_types::address::AztecAddress; -use dep::aztec::selector::compute_selector; +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + constants::RETURN_VALUES_LENGTH, +}; struct PriceFeed { address: AztecAddress, @@ -20,7 +22,7 @@ impl PriceFeed { pub fn get_price(self: Self, context: PublicContext) -> u120 { let return_values = context.call_public_function( self.address, - compute_selector("get_price(Field)"), + FunctionSelector::from_signature("get_price(Field)"), [0] ); @@ -40,7 +42,7 @@ impl Token { pub fn transfer_public(self: Self, context: PublicContext, from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { context.call_public_function( self.address, - compute_selector("transfer_public((Field),(Field),Field,Field)"), + FunctionSelector::from_signature("transfer_public((Field),(Field),Field,Field)"), [from.to_field(), to.to_field(), amount, nonce] ); } @@ -48,7 +50,7 @@ impl Token { pub fn mint_public(self: Self, context: PublicContext, to: AztecAddress, amount: Field) { context.call_public_function( self.address, - compute_selector("mint_public((Field),Field)"), + FunctionSelector::from_signature("mint_public((Field),Field)"), [to.to_field(), amount] ); } @@ -56,7 +58,7 @@ impl Token { pub fn burn_public(self: Self, context: PublicContext, from: AztecAddress, amount: Field, nonce: Field) { context.call_public_function( self.address, - compute_selector("burn_public((Field),Field,Field)"), + FunctionSelector::from_signature("burn_public((Field),Field,Field)"), [from.to_field(), amount, nonce] ); } @@ -65,7 +67,7 @@ impl Token { pub fn unshield(self: Self, context: &mut PrivateContext, from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) -> [Field; RETURN_VALUES_LENGTH] { context.call_private_function( self.address, - compute_selector("unshield((Field),(Field),Field,Field)"), + FunctionSelector::from_signature("unshield((Field),(Field),Field,Field)"), [from.to_field(), to.to_field(), amount, nonce] ) } @@ -73,7 +75,7 @@ impl Token { pub fn burn(self: Self, context: &mut PrivateContext, from: AztecAddress, amount: Field, nonce: Field) -> [Field; RETURN_VALUES_LENGTH] { context.call_private_function( self.address, - compute_selector("burn((Field),Field,Field)"), + FunctionSelector::from_signature("burn((Field),Field,Field)"), [from.to_field(), amount, nonce] ) } @@ -91,7 +93,7 @@ impl Lending { pub fn update_accumulator(self: Self, context: PublicContext) -> Asset { let return_values = context.call_public_function_no_args( self.address, - compute_selector("update_accumulator()"), + FunctionSelector::from_signature("update_accumulator()"), ); Asset { diff --git a/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr index a76a12ccccf..f81555ae990 100644 --- a/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/lending_contract/src/main.nr @@ -11,12 +11,14 @@ mod interfaces; // - A way to repay all debt at once // - Liquidations contract Lending { - use dep::protocol_types::address::AztecAddress; + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + }; use dep::safe_math::SafeU120; use dep::std::option::Option; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, - selector::compute_selector, state_vars::{ map::Map, public_state::PublicState, @@ -166,7 +168,7 @@ contract Lending { let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender().to_field()); let _res = Token::at(collateral_asset).unshield(&mut context, from, context.this_address(), amount, nonce); // _deposit(on_behalf_of, amount, collateral_asset) - let selector = compute_selector("_deposit((Field),Field,(Field))"); + let selector = FunctionSelector::from_signature("_deposit((Field),Field,(Field))"); context.call_public_function( context.this_address(), selector, @@ -183,7 +185,7 @@ contract Lending { amount, nonce ); - let selector = compute_selector("_deposit((Field),Field,(Field))"); + let selector = FunctionSelector::from_signature("_deposit((Field),Field,(Field))"); context.call_public_function( context.this_address(), selector, @@ -206,7 +208,7 @@ contract Lending { #[aztec(private)] fn withdraw_private(secret: Field, to: AztecAddress, amount: Field) { let on_behalf_of = compute_identifier(secret, 0, context.msg_sender().to_field()); - let selector = compute_selector("_withdraw((Field),(Field),Field)"); + let selector = FunctionSelector::from_signature("_withdraw((Field),(Field),Field)"); context.call_public_function( context.this_address(), selector, @@ -216,7 +218,7 @@ contract Lending { #[aztec(public)] fn withdraw_public(to: AztecAddress, amount: Field) { - let selector = compute_selector("_withdraw((Field),(Field),Field)"); + let selector = FunctionSelector::from_signature("_withdraw((Field),(Field),Field)"); context.call_public_function( context.this_address(), selector, @@ -258,7 +260,7 @@ contract Lending { #[aztec(private)] fn borrow_private(secret: Field, to: AztecAddress, amount: Field) { let on_behalf_of = compute_identifier(secret, 0, context.msg_sender().to_field()); - let selector = compute_selector("_borrow((Field),(Field),Field)"); + let selector = FunctionSelector::from_signature("_borrow((Field),(Field),Field)"); context.call_public_function( context.this_address(), selector, @@ -268,7 +270,7 @@ contract Lending { #[aztec(public)] fn borrow_public(to: AztecAddress, amount: Field) { - let selector = compute_selector("_borrow((Field),(Field),Field)"); + let selector = FunctionSelector::from_signature("_borrow((Field),(Field),Field)"); context.call_public_function( context.this_address(), selector, @@ -308,7 +310,7 @@ contract Lending { ) { let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender().to_field()); let _res = Token::at(stable_coin).burn(&mut context, from, amount, nonce); - let selector = compute_selector("_repay((Field),Field,(Field))"); + let selector = FunctionSelector::from_signature("_repay((Field),Field,(Field))"); context.call_public_function( context.this_address(), selector, @@ -319,7 +321,7 @@ contract Lending { #[aztec(public)] fn repay_public(amount: Field, nonce: Field, owner: AztecAddress, stable_coin: AztecAddress) { Token::at(stable_coin).burn_public(context, context.msg_sender(), amount, nonce); - let selector = compute_selector("_repay((Field),Field,(Field))"); + let selector = FunctionSelector::from_signature("_repay((Field),Field,(Field))"); context.call_public_function( context.this_address(), selector, diff --git a/yarn-project/noir-contracts/src/contracts/parent_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/parent_contract/src/main.nr index 38b9c3fcfe1..210216694b7 100644 --- a/yarn-project/noir-contracts/src/contracts/parent_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/parent_contract/src/main.nr @@ -1,6 +1,5 @@ // A contract used along with `Child` contract to test nested calls. contract Parent { - use dep::aztec::selector::compute_selector; use dep::protocol_types::{ address::AztecAddress, abis::function_selector::FunctionSelector, @@ -46,9 +45,13 @@ contract Parent { // - one through a nested call to enqueueCallToChild with value 10, // - followed by one issued directly from this function with value 20. #[aztec(private)] - fn enqueueCallsToChildWithNestedFirst(targetContract: AztecAddress, targetSelector: FunctionSelector) { - let enqueueCallToChildSelector = compute_selector("enqueueCallToChild((Field),(u32),Field)"); - let _ret = context.call_private_function(context.this_address(), + fn enqueueCallsToChildWithNestedFirst( + targetContract: AztecAddress, + targetSelector: FunctionSelector + ) { + let enqueueCallToChildSelector = FunctionSelector::from_signature("enqueueCallToChild((Field),(u32),Field)"); + let _ret = context.call_private_function( + context.this_address(), enqueueCallToChildSelector, [targetContract.to_field(), targetSelector.to_field(), 10]); context.call_public_function(targetContract, targetSelector, [20]); @@ -60,8 +63,9 @@ contract Parent { #[aztec(private)] fn enqueueCallsToChildWithNestedLast(targetContract: AztecAddress, targetSelector: FunctionSelector) { context.call_public_function(targetContract, targetSelector, [20]); - let enqueueCallToChildSelector = compute_selector("enqueueCallToChild((Field),(u32),Field)"); - let _ret = context.call_private_function(context.this_address(), + let enqueueCallToChildSelector = FunctionSelector::from_signature("enqueueCallToChild((Field),(u32),Field)"); + let _ret = context.call_private_function( + context.this_address(), enqueueCallToChildSelector, [targetContract.to_field(), targetSelector.to_field(), 10]); } @@ -76,9 +80,13 @@ contract Parent { } // Private function to enqueue a call to the pubEntryPoint function of this same contract, passing the target arguments provided - #[aztec(private)] - fn enqueueCallToPubEntryPoint(targetContract: AztecAddress, targetSelector: FunctionSelector, targetValue: Field) { - let pubEntryPointSelector = compute_selector("pubEntryPoint((Field),(u32),Field)"); + #[aztec(private)] + fn enqueueCallToPubEntryPoint( + targetContract: AztecAddress, + targetSelector: FunctionSelector, + targetValue: Field + ) { + let pubEntryPointSelector = FunctionSelector::from_signature("pubEntryPoint((Field),(u32),Field)"); let thisAddress = context.this_address(); let _void = context.call_public_function(thisAddress, pubEntryPointSelector, @@ -86,9 +94,13 @@ contract Parent { } // Private function to enqueue two calls to the pubEntryPoint function of this same contract, passing the target arguments provided - #[aztec(private)] - fn enqueueCallsToPubEntryPoint(targetContract: AztecAddress, targetSelector: FunctionSelector, targetValue: Field) { - let pubEntryPointSelector = compute_selector("pubEntryPoint((Field),(u32),Field)"); + #[aztec(private)] + fn enqueueCallsToPubEntryPoint( + targetContract: AztecAddress, + targetSelector: FunctionSelector, + targetValue: Field + ) { + let pubEntryPointSelector = FunctionSelector::from_signature("pubEntryPoint((Field),(u32),Field)"); let thisAddress = context.this_address(); context.call_public_function(thisAddress, diff --git a/yarn-project/noir-contracts/src/contracts/slow_tree_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/slow_tree_contract/src/main.nr index 4f22416d169..a95cb1218df 100644 --- a/yarn-project/noir-contracts/src/contracts/slow_tree_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/slow_tree_contract/src/main.nr @@ -6,7 +6,10 @@ mod types; // https://github.com/AztecProtocol/aztec-packages/issues/1291 // This is made as a separate contract for one thing mainly. Making it simpler to use. contract SlowTree { - use dep::protocol_types::address::AztecAddress; + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + }; use dep::std::option::Option; use dep::value_note::{ balance_utils, @@ -19,7 +22,6 @@ contract SlowTree { note_header::NoteHeader, utils as note_utils, }, - selector::compute_selector, state_vars::{map::Map, public_state::PublicState, set::Set}, types::type_serialization::field_serialization::{ FieldSerializationMethods, FIELD_SERIALIZED_LEN, @@ -87,7 +89,7 @@ contract SlowTree { assert(index == p.index, "Index does not match expected"); let expected_root = compute_merkle_root(p.value, p.index, p.sibling_path); - let selector = compute_selector("_assert_current_root(Field,Field)"); + let selector = FunctionSelector::from_signature("_assert_current_root(Field,Field)"); context.call_public_function( context.this_address(), selector, @@ -124,7 +126,7 @@ contract SlowTree { let after_root = compute_merkle_root(p.after.value, p.index, p.after.sibling_path); let new_after_root = compute_merkle_root(p.new_value, p.index, p.after.sibling_path); - let selector = compute_selector("_update(Field,Field,Field,Field,Field,Field)"); + let selector = FunctionSelector::from_signature("_update(Field,Field,Field,Field,Field,Field)"); context.call_public_function( context.this_address(), selector, diff --git a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/interfaces.nr b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/interfaces.nr index a9011819126..0ff60371f71 100644 --- a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/interfaces.nr +++ b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/interfaces.nr @@ -1,9 +1,10 @@ -use dep::protocol_types::address::AztecAddress; -use dep::aztec::{ - context::{ PrivateContext, PublicContext, Context }, - selector::compute_selector, +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, }; +use dep::aztec::context::{PrivateContext, PublicContext, Context}; + struct SlowMap { address: AztecAddress, } @@ -16,14 +17,14 @@ impl SlowMap { pub fn initialize(self: Self, context: PublicContext) { context.call_public_function_no_args( self.address, - compute_selector("initialize()") + FunctionSelector::from_signature("initialize()") ); } pub fn read_at_pub(self: Self, context: PublicContext, index: Field) -> Field { let _return_values = context.call_public_function( self.address, - compute_selector("read_at_pub(Field)"), + FunctionSelector::from_signature("read_at_pub(Field)"), [index] ); _return_values[0] @@ -32,7 +33,7 @@ impl SlowMap { pub fn read_at(self: Self, context: &mut PrivateContext, index: Field) -> Field { let _return_values = context.call_private_function( self.address, - compute_selector("read_at(Field)"), + FunctionSelector::from_signature("read_at(Field)"), [index] ); _return_values[0] @@ -41,7 +42,7 @@ impl SlowMap { pub fn update_at_private(self: Self, context: &mut PrivateContext, index: Field, new_value: Field) { context.call_private_function( self.address, - compute_selector("update_at_private(Field,Field)"), + FunctionSelector::from_signature("update_at_private(Field,Field)"), [index, new_value] ); } diff --git a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/main.nr index 0df6f550763..aa64ec956fc 100644 --- a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/main.nr @@ -17,7 +17,10 @@ contract TokenBlacklist { use dep::std::option::Option; use dep::safe_math::SafeU120; - use dep::protocol_types::address::AztecAddress; + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + }; use dep::aztec::{ note::{ note_getter_options::NoteGetterOptions, @@ -32,7 +35,6 @@ contract TokenBlacklist { bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, }, - selector::compute_selector, }; use dep::field_note::field_note::{FieldNote, FieldNoteMethods, FIELD_NOTE_LEN}; @@ -110,7 +112,7 @@ contract TokenBlacklist { let mut slow_note = FieldNote::new(slow_updates_contract.to_field()); storage.slow_update.initialize(&mut slow_note, Option::none(), false); // docs:end:constructor - let selector = compute_selector("_initialize((Field),(Field))"); + let selector = FunctionSelector::from_signature("_initialize((Field),(Field))"); context.call_public_function( context.this_address(), selector, @@ -133,7 +135,7 @@ contract TokenBlacklist { // docs:end:get_and_update_private context.call_public_function( context.this_address(), - compute_selector("_init_slow_tree((Field))"), + FunctionSelector::from_signature("_init_slow_tree((Field))"), [context.msg_sender().to_field()] ); } @@ -305,7 +307,7 @@ contract TokenBlacklist { storage.balances.at(from).sub(SafeU120::new(amount)); - let selector = compute_selector("_increase_public_balance((Field),Field)"); + let selector = FunctionSelector::from_signature("_increase_public_balance((Field),Field)"); context.call_public_function(context.this_address(), selector, [to.to_field(), amount]); } @@ -344,7 +346,7 @@ contract TokenBlacklist { storage.balances.at(from).sub(SafeU120::new(amount)); - let selector = compute_selector("_reduce_total_supply(Field)"); + let selector = FunctionSelector::from_signature("_reduce_total_supply(Field)"); context.call_public_function(context.this_address(), selector, [amount]); } diff --git a/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr index b16d30f93a6..2fc7382cad3 100644 --- a/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr @@ -7,9 +7,12 @@ mod token_interface; // Bridge has to be set as a minter on the token before it can be used contract TokenBridge { - use dep::protocol_types::address::{ - AztecAddress, - EthAddress, + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::{ + AztecAddress, + EthAddress, + }, }; use dep::aztec::{ @@ -17,7 +20,6 @@ contract TokenBridge { hash::{compute_secret_hash}, state_vars::{public_state::PublicState}, types::type_serialization::address_serialization::AddressSerializationMethods, - selector::compute_selector, }; use dep::token_portal_content_hash_lib::{get_mint_public_content_hash, get_mint_private_content_hash, get_withdraw_content_hash}; @@ -46,7 +48,7 @@ contract TokenBridge { // Constructs the contract. #[aztec(private)] fn constructor(token: AztecAddress) { - let selector = compute_selector("_initialize((Field))"); + let selector = FunctionSelector::from_signature("_initialize((Field))"); context.call_public_function(context.this_address(), selector, [token.to_field()]); } // docs:end:token_bridge_storage_and_constructor @@ -104,7 +106,7 @@ contract TokenBridge { // Since the secret_hash is passed, no secret is leaked. context.call_public_function( context.this_address(), - compute_selector("_call_mint_on_token(Field,Field)"), + FunctionSelector::from_signature("_call_mint_on_token(Field,Field)"), [amount, secret_hash_for_redeeming_minted_notes] ); } @@ -129,7 +131,7 @@ contract TokenBridge { // Assert that user provided token address is same as seen in storage. context.call_public_function( context.this_address(), - compute_selector("_assert_token_is_same((Field))"), + FunctionSelector::from_signature("_assert_token_is_same((Field))"), [token.to_field()] ); // docs:end:call_assert_token_is_same diff --git a/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/token_interface.nr b/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/token_interface.nr index 88e2fc7639d..721016bc305 100644 --- a/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/token_interface.nr +++ b/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/token_interface.nr @@ -1,11 +1,13 @@ // docs:start:token_bridge_token_interface -use dep::protocol_types::address::{ - AztecAddress, - EthAddress, +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::{ + AztecAddress, + EthAddress, + }, }; use dep::aztec::{ context::{ PrivateContext, PublicContext, Context }, - selector::compute_selector, }; struct Token { @@ -20,7 +22,7 @@ impl Token { pub fn mint_public(self: Self, context: PublicContext, to: AztecAddress, amount: Field) { let _return_values = context.call_public_function( self.address, - compute_selector("mint_public((Field),Field)"), + FunctionSelector::from_signature("mint_public((Field),Field)"), [to.to_field(), amount] ); } @@ -29,7 +31,7 @@ impl Token { pub fn burn_public(self: Self, context: PublicContext, from: AztecAddress, amount: Field, nonce: Field) { let _return_values = context.call_public_function( self.address, - compute_selector("burn_public((Field),Field,Field)"), + FunctionSelector::from_signature("burn_public((Field),Field,Field)"), [from.to_field(), amount, nonce] ); } @@ -38,7 +40,7 @@ impl Token { pub fn mint_private(self: Self, context: PublicContext, amount: Field, secret_hash: Field) { let _return_values = context.call_public_function( self.address, - compute_selector("mint_private(Field,Field)"), + FunctionSelector::from_signature("mint_private(Field,Field)"), [amount, secret_hash] ); } @@ -48,7 +50,7 @@ impl Token { pub fn burn(self: Self, context: &mut PrivateContext, from: AztecAddress, amount: Field, nonce: Field) { let _return_values = context.call_private_function( self.address, - compute_selector("burn((Field),Field,Field)"), + FunctionSelector::from_signature("burn((Field),Field,Field)"), [from.to_field(), amount, nonce] ); } diff --git a/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr index 5bdb91718d2..8710aca8dd7 100644 --- a/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr @@ -29,9 +29,11 @@ contract Token { bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, }, - selector::compute_selector, }; - use dep::protocol_types::address::AztecAddress; + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + }; // docs:start:import_authwit use dep::authwit::{ @@ -123,7 +125,7 @@ contract Token { // docs:start:constructor #[aztec(private)] fn constructor(admin: AztecAddress) { - let selector = compute_selector("_initialize((Field))"); + let selector = FunctionSelector::from_signature("_initialize((Field))"); context.call_public_function(context.this_address(), selector, [admin.to_field()]); } // docs:end:constructor @@ -268,7 +270,7 @@ contract Token { storage.balances.at(from).sub(SafeU120::new(amount)); - let selector = compute_selector("_increase_public_balance((Field),Field)"); + let selector = FunctionSelector::from_signature("_increase_public_balance((Field),Field)"); let _void = context.call_public_function(context.this_address(), selector, [to.to_field(), amount]); } // docs:end:unshield @@ -303,7 +305,7 @@ contract Token { storage.balances.at(from).sub(SafeU120::new(amount)); - let selector = compute_selector("_reduce_total_supply(Field)"); + let selector = FunctionSelector::from_signature("_reduce_total_supply(Field)"); let _void = context.call_public_function(context.this_address(), selector, [amount]); } // docs:end:burn diff --git a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/interfaces.nr b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/interfaces.nr index 22f3e286b98..c6d7b3b90e0 100644 --- a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/interfaces.nr +++ b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/interfaces.nr @@ -1,11 +1,13 @@ // docs:start:interfaces -use dep::protocol_types::address::{ - AztecAddress, - EthAddress, -}; + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::{ + AztecAddress, + EthAddress, + }, + }; use dep::aztec::{ context::{ PrivateContext, PublicContext, Context }, - selector::compute_selector, }; struct Token { @@ -20,7 +22,7 @@ impl Token { pub fn transfer_public(self: Self, context: PublicContext, from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { context.call_public_function( self.address, - compute_selector("transfer_public((Field),(Field),Field,Field)"), + FunctionSelector::from_signature("transfer_public((Field),(Field),Field,Field)"), [from.to_field(), to.to_field(), amount, nonce] ); } @@ -28,7 +30,7 @@ impl Token { pub fn unshield(self: Self, context: &mut PrivateContext, from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { context.call_private_function( self.address, - compute_selector("unshield((Field),(Field),Field,Field)"), + FunctionSelector::from_signature("unshield((Field),(Field),Field,Field)"), [from.to_field(), to.to_field(), amount, nonce] ); } @@ -44,14 +46,14 @@ impl TokenBridge { } pub fn token(self: Self, context: PublicContext) -> AztecAddress { - let return_values = context.call_public_function(self.address, compute_selector("get_token()"), []); + let return_values = context.call_public_function(self.address, FunctionSelector::from_signature("get_token()"), []); AztecAddress::from_field(return_values[0]) } pub fn exit_to_l1_public(self: Self, context: PublicContext, recipient: EthAddress, amount: Field, callerOnL1: EthAddress, nonce: Field) { context.call_public_function( self.address, - compute_selector("exit_to_l1_public((Field),Field,(Field),Field)"), + FunctionSelector::from_signature("exit_to_l1_public((Field),Field,(Field),Field)"), [recipient.to_field(), amount, callerOnL1.to_field(), nonce] ); } diff --git a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr index ade023abcce..7e9e230bbc9 100644 --- a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/main.nr @@ -6,9 +6,12 @@ mod util; // Has two separate flows for private and public respectively // Uses the token bridge contract, which tells which input token we need to talk to and handles the exit funds to L1 contract Uniswap { - use dep::protocol_types::address::{ - AztecAddress, - EthAddress, + use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::{ + AztecAddress, + EthAddress, + }, }; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, @@ -20,7 +23,6 @@ contract Uniswap { types::type_serialization::field_serialization::{ FieldSerializationMethods, FIELD_SERIALIZED_LEN, }, - selector::compute_selector, }; use dep::authwit::auth::{IS_VALID_SELECTOR, assert_current_call_valid_authwit_public, compute_authwit_message_hash}; @@ -94,7 +96,7 @@ contract Uniswap { // Approve bridge to burn this contract's funds and exit to L1 Uniswap Portal let _void = context.call_public_function( context.this_address(), - compute_selector("_approve_bridge_and_exit_input_asset_to_L1((Field),(Field),Field)"), + FunctionSelector::from_signature("_approve_bridge_and_exit_input_asset_to_L1((Field),(Field),Field)"), [input_asset.to_field(), input_asset_bridge.to_field(), input_amount] ); @@ -149,7 +151,7 @@ contract Uniswap { // we can't directly use `input_asset_bridge.token` because that is a public method and public can't return data to private context.call_public_function( context.this_address(), - compute_selector("_assert_token_is_same((Field),(Field))"), + FunctionSelector::from_signature("_assert_token_is_same((Field),(Field))"), [input_asset.to_field(), input_asset_bridge.to_field()] ); @@ -165,7 +167,7 @@ contract Uniswap { // Approve bridge to burn this contract's funds and exit to L1 Uniswap Portal context.call_public_function( context.this_address(), - compute_selector("_approve_bridge_and_exit_input_asset_to_L1((Field),(Field),Field)"), + FunctionSelector::from_signature("_approve_bridge_and_exit_input_asset_to_L1((Field),(Field),Field)"), [input_asset.to_field(), input_asset_bridge.to_field(), input_amount] ); @@ -218,7 +220,7 @@ contract Uniswap { internal fn _approve_bridge_and_exit_input_asset_to_L1(token: AztecAddress, token_bridge: AztecAddress, amount: Field) { // approve bridge to burn this contract's funds (required when exiting on L1, as it burns funds on L2): let nonce_for_burn_approval = storage.nonce_for_burn_approval.read(); - let selector = compute_selector("burn_public((Field),Field,Field)"); + let selector = FunctionSelector::from_signature("burn_public((Field),Field,Field)"); let message_hash = compute_authwit_message_hash( token_bridge, token, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr index 94a5e1f93b6..d166bbdf3f6 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/function_selector.nr @@ -1,3 +1,7 @@ +use crate::utils::field::field_from_bytes; + +global SELECTOR_SIZE = 4; + struct FunctionSelector { // 1st 4-bytes of abi-encoding of function. inner: u32, @@ -20,8 +24,20 @@ impl FunctionSelector { } } + pub fn from_signature(signature: str) -> Self { + let bytes = signature.as_bytes(); + let hash = dep::std::hash::keccak256(bytes, bytes.len() as u32); + + let mut selector_be_bytes = [0; SELECTOR_SIZE]; + for i in 0..SELECTOR_SIZE { + selector_be_bytes[i] = hash[i]; + } + + FunctionSelector::from_field(field_from_bytes(selector_be_bytes, true)) + } + pub fn zero() -> Self { - FunctionSelector { inner: 0 } + Self { inner: 0 } } pub fn eq(self, function_selector: FunctionSelector) -> bool { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/utils.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/utils.nr index fe3c49e0930..fb8e12010f4 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/utils.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/utils.nr @@ -3,9 +3,10 @@ // Reducing the size of this package would be welcome. mod arrays; -mod uint256; -mod uint128; mod bounded_vec; +mod field; +mod uint128; +mod uint256; // if predicate == true then return lhs, else return rhs pub fn conditional_assign(predicate : bool, lhs : Field, rhs: Field) -> Field { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/utils/field.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/utils/field.nr new file mode 100644 index 00000000000..918543b6665 --- /dev/null +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/utils/field.nr @@ -0,0 +1,15 @@ +pub fn field_from_bytes(bytes: [u8; N], big_endian: bool) -> Field { + assert(bytes.len() as u32 < 32, "field_from_bytes: N must be less than 32"); + let mut as_field = 0; + let mut offset = 1; + for i in 0..N { + let mut index = i; + if big_endian { + index = N - i - 1; + } + as_field += (bytes[index] as Field) * offset; + offset *= 256; + } + + as_field +}