diff --git a/docs/docs/dev_docs/contracts/syntax/context.mdx b/docs/docs/dev_docs/contracts/syntax/context.mdx index 1855f59222e..3321cd91c4a 100644 --- a/docs/docs/dev_docs/contracts/syntax/context.mdx +++ b/docs/docs/dev_docs/contracts/syntax/context.mdx @@ -48,7 +48,7 @@ As shown in the snippet, the application context is made up of 4 main structures First of all, the call context. -#include_code call-context /yarn-project/aztec-nr/aztec/src/abi.nr rust +#include_code call-context /yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr rust The call context contains information about the current call being made: @@ -75,13 +75,13 @@ The call context contains information about the current call being made: Another structure that is contained within the context is the Block Header object. This object is a special one as it contains all of the roots of Aztec's data trees. -#include_code block-header /yarn-project/aztec-nr/aztec/src/abi.nr rust +#include_code block-header /yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr rust ### Contract Deployment Data Just like with the `is_contract_deployment` flag mentioned earlier. This data will only be set to true when the current transaction is one in which a contract is being deployed. -#include_code contract-deployment-data /yarn-project/aztec-nr/aztec/src/abi.nr rust +#include_code contract-deployment-data /yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr rust ### Private Global Variables diff --git a/yarn-project/acir-simulator/src/acvm/deserialize.ts b/yarn-project/acir-simulator/src/acvm/deserialize.ts index 649ad620cf0..14daaa18a93 100644 --- a/yarn-project/acir-simulator/src/acvm/deserialize.ts +++ b/yarn-project/acir-simulator/src/acvm/deserialize.ts @@ -169,7 +169,7 @@ export function extractPrivateCircuitPublicInputs( witnessReader.readField(), witnessReader.readField(), witnessReader.readField(), - Fr.ZERO, + Fr.ZERO, // TODO(#3441) witnessReader.readField(), witnessReader.readField(), ); @@ -261,7 +261,7 @@ export function extractPublicCircuitPublicInputs(partialWitness: ACVMWitness, ac witnessReader.readField(), witnessReader.readField(), witnessReader.readField(), - Fr.ZERO, + Fr.ZERO, // TODO(#3441) witnessReader.readField(), witnessReader.readField(), ); diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 18f3b5e4865..7edaa26cbd9 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -539,7 +539,7 @@ export class AztecNodeService implements AztecNode { roots[MerkleTreeId.CONTRACT_TREE], roots[MerkleTreeId.L1_TO_L2_MESSAGES_TREE], roots[MerkleTreeId.ARCHIVE], - Fr.ZERO, + Fr.ZERO, // TODO(#3441) roots[MerkleTreeId.PUBLIC_DATA_TREE], globalsHash, ); diff --git a/yarn-project/aztec-nr/address-note/Nargo.toml b/yarn-project/aztec-nr/address-note/Nargo.toml index 5956d79c62a..27a4845d664 100644 --- a/yarn-project/aztec-nr/address-note/Nargo.toml +++ b/yarn-project/aztec-nr/address-note/Nargo.toml @@ -5,4 +5,5 @@ compiler_version = ">=0.18.0" type = "lib" [dependencies] -aztec = { path = "../aztec" } \ No newline at end of file +aztec = { path = "../aztec" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file diff --git a/yarn-project/aztec-nr/address-note/src/address_note.nr b/yarn-project/aztec-nr/address-note/src/address_note.nr index 1e8f037ac20..314a862c727 100644 --- a/yarn-project/aztec-nr/address-note/src/address_note.nr +++ b/yarn-project/aztec-nr/address-note/src/address_note.nr @@ -1,6 +1,7 @@ // docs:start:encrypted_import use dep::aztec::log::emit_encrypted_log; // docs:end:encrypted_import +use dep::protocol_types::address::AztecAddress; use dep::aztec::{ note::{ note_header::NoteHeader, @@ -21,14 +22,14 @@ global ADDRESS_NOTE_LEN: Field = 3; // docs:start:address_note_def // Stores an address struct AddressNote { - address: Field, - owner: Field, + address: AztecAddress, + owner: AztecAddress, randomness: Field, header: NoteHeader, } impl AddressNote { - pub fn new(address: Field, owner: Field) -> Self { + pub fn new(address: AztecAddress, owner: AztecAddress) -> Self { let randomness = rand(); AddressNote { address, @@ -41,13 +42,13 @@ impl AddressNote { pub fn serialize(self) -> [Field; ADDRESS_NOTE_LEN]{ - [self.address, self.owner, self.randomness] + [self.address.to_field(), self.owner.to_field(), self.randomness] } pub fn deserialize(serialized_note: [Field; ADDRESS_NOTE_LEN]) -> Self { AddressNote { - address: serialized_note[0], - owner: serialized_note[1], + address: AztecAddress::from_field(serialized_note[0]), + owner: AztecAddress::from_field(serialized_note[1]), randomness: serialized_note[2], header: NoteHeader::empty(), } diff --git a/yarn-project/aztec-nr/authwit/src/auth.nr b/yarn-project/aztec-nr/authwit/src/auth.nr index bcf2cad5bca..30bb0ba5c67 100644 --- a/yarn-project/aztec-nr/authwit/src/auth.nr +++ b/yarn-project/aztec-nr/authwit/src/auth.nr @@ -1,9 +1,19 @@ -use dep::protocol_types::constants::{EMPTY_NULLIFIED_COMMITMENT, GENERATOR_INDEX__SIGNATURE_PAYLOAD}; -use dep::aztec::{ - context::{PrivateContext, PublicContext, Context}, - types::address::AztecAddress, - abi::hash_args, - hash::pedersen_hash, +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + constants::{ + EMPTY_NULLIFIED_COMMITMENT, + GENERATOR_INDEX__SIGNATURE_PAYLOAD, + }, + hash::{ + hash_args, + pedersen_hash, + }, +}; +use dep::aztec::context::{ + PrivateContext, + PublicContext, + Context, }; global IS_VALID_SELECTOR = 0xe86ab4ff; @@ -14,7 +24,8 @@ global IS_VALID_PUBLIC_SELECTOR = 0xf3661153; // docs:start:assert_valid_authwit // Assert that `on_behalf_of` have authorized `message_hash` with a valid authentication witness pub fn assert_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress, message_hash: Field) { - let result = context.call_private_function(on_behalf_of.address, IS_VALID_SELECTOR, [message_hash])[0]; + let is_valid_selector = FunctionSelector::from_field(IS_VALID_SELECTOR); + let result = context.call_private_function(on_behalf_of, is_valid_selector, [message_hash])[0]; context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT); assert(result == IS_VALID_SELECTOR, "Message not authorized by account"); } @@ -24,7 +35,7 @@ pub fn assert_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAdd // Assert that `on_behalf_of` have authorized the current call with a valid authentication witness pub fn assert_current_call_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress) { // message_hash = H(caller, contract_this, selector, args_hash) - let message_hash = pedersen_hash([context.msg_sender(), context.this_address(), context.selector(), context.args_hash], + let message_hash = pedersen_hash([context.msg_sender().to_field(), context.this_address().to_field(), context.selector().to_field(), context.args_hash], GENERATOR_INDEX__SIGNATURE_PAYLOAD); assert_valid_authwit(context, on_behalf_of, message_hash); } @@ -33,7 +44,8 @@ pub fn assert_current_call_valid_authwit(context: &mut PrivateContext, on_behalf // docs:start:assert_valid_authwit_public // Assert that `on_behalf_of` have authorized `message_hash` in a public context pub fn assert_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress, message_hash: Field) { - let result = context.call_public_function(on_behalf_of.address, IS_VALID_PUBLIC_SELECTOR, [message_hash])[0]; + let is_valid_public_selector = FunctionSelector::from_field(IS_VALID_PUBLIC_SELECTOR); + let result = context.call_public_function(on_behalf_of, is_valid_public_selector, [message_hash])[0]; context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT); assert(result == IS_VALID_SELECTOR, "Message not authorized by account"); } @@ -43,7 +55,7 @@ pub fn assert_valid_authwit_public(context: &mut PublicContext, on_behalf_of: Az // Assert that `on_behalf_of` have authorized the current call in a public context pub fn assert_current_call_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress) { // message_hash = H(caller, contract_this, selector, args_hash) - let message_hash = pedersen_hash([context.msg_sender(), context.this_address(), context.selector(), context.args_hash], + let message_hash = pedersen_hash([context.msg_sender().to_field(), context.this_address().to_field(), context.selector().to_field(), context.args_hash], GENERATOR_INDEX__SIGNATURE_PAYLOAD); assert_valid_authwit_public(context, on_behalf_of, message_hash); } @@ -51,9 +63,9 @@ pub fn assert_current_call_valid_authwit_public(context: &mut PublicContext, on_ // docs:start:compute_authwit_message_hash // Compute the message hash to be used by an authentication witness -pub fn compute_authwit_message_hash(caller: AztecAddress, target: AztecAddress, selector: Field, args: [Field; N]) -> Field { +pub fn compute_authwit_message_hash(caller: AztecAddress, target: AztecAddress, selector: FunctionSelector, args: [Field; N]) -> Field { let args_hash = hash_args(args); - pedersen_hash([caller.address, target.address, selector, args_hash], + pedersen_hash([caller.to_field(), target.to_field(), selector.to_field(), args_hash], GENERATOR_INDEX__SIGNATURE_PAYLOAD) } // docs:end:compute_authwit_message_hash \ No newline at end of file diff --git a/yarn-project/aztec-nr/authwit/src/entrypoint.nr b/yarn-project/aztec-nr/authwit/src/entrypoint.nr index aac0f72f66c..5f22a8e79b0 100644 --- a/yarn-project/aztec-nr/authwit/src/entrypoint.nr +++ b/yarn-project/aztec-nr/authwit/src/entrypoint.nr @@ -1,10 +1,18 @@ use dep::aztec::abi; use dep::aztec::types::vec::BoundedVec; -use dep::aztec::hash::pedersen_hash; use dep::aztec::context::PrivateContext; -use dep::aztec::private_call_stack_item::PrivateCallStackItem; -use dep::aztec::public_call_stack_item::PublicCallStackItem; -use dep::protocol_types::constants::GENERATOR_INDEX__SIGNATURE_PAYLOAD; +use dep::protocol_types::{ + abis::{ + call_stack_item::{ + PrivateCallStackItem, + PublicCallStackItem, + }, + function_selector::FunctionSelector, + }, + address::AztecAddress, + constants::GENERATOR_INDEX__SIGNATURE_PAYLOAD, + hash::pedersen_hash, +}; global ACCOUNT_MAX_CALLS: Field = 4; // 1 (ARGS_HASH) + 1 (FUNCTION_SELECTOR) + 1 (TARGET_ADDRESS) + 1 (IS_PUBLIC) @@ -14,23 +22,23 @@ global FUNCTION_CALL_SIZE_IN_BYTES: Field = 97; struct FunctionCall { args_hash: Field, - function_selector: Field, - target_address: Field, + function_selector: FunctionSelector, + target_address: AztecAddress, is_public: bool, } impl FunctionCall { fn serialize(self) -> [Field; FUNCTION_CALL_SIZE] { - [self.args_hash, self.function_selector, self.target_address, self.is_public as Field] + [self.args_hash, self.function_selector.to_field(), self.target_address.to_field(), self.is_public as Field] } fn to_be_bytes(self) -> [u8; FUNCTION_CALL_SIZE_IN_BYTES] { let mut bytes: [u8; FUNCTION_CALL_SIZE_IN_BYTES] = [0; FUNCTION_CALL_SIZE_IN_BYTES]; let args_hash_bytes = self.args_hash.to_be_bytes(32); for i in 0..32 { bytes[i] = args_hash_bytes[i]; } - let function_selector_bytes = self.function_selector.to_be_bytes(32); + let function_selector_bytes = self.function_selector.to_field().to_be_bytes(32); for i in 0..32 { bytes[i + 32] = function_selector_bytes[i]; } - let target_address_bytes = self.target_address.to_be_bytes(32); + let target_address_bytes = self.target_address.to_field().to_be_bytes(32); for i in 0..32 { bytes[i + 64] = target_address_bytes[i]; } bytes[96] = self.is_public as u8; bytes @@ -42,6 +50,7 @@ global ENTRYPOINT_PAYLOAD_SIZE: Field = 17; // FUNCTION_CALL_SIZE_IN_BYTES * ACCOUNT_MAX_CALLS + 32 global ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES: Field = 420; +// Note: If you change the following struct you have to update default_entrypoint.ts // docs:start:entrypoint-struct struct EntrypointPayload { function_calls: [FunctionCall; ACCOUNT_MAX_CALLS], @@ -91,7 +100,7 @@ impl EntrypointPayload { // docs:start:entrypoint-execute-calls fn execute_calls(self, context: &mut PrivateContext) { for call in self.function_calls { - if call.target_address != 0 { + if !call.target_address.is_zero() { if call.is_public { context.call_public_function_with_packed_args( call.target_address, call.function_selector, call.args_hash diff --git a/yarn-project/aztec-nr/aztec/src/abi.nr b/yarn-project/aztec-nr/aztec/src/abi.nr index b484842dc2d..b6f5cfa92a9 100644 --- a/yarn-project/aztec-nr/aztec/src/abi.nr +++ b/yarn-project/aztec-nr/aztec/src/abi.nr @@ -1,40 +1,14 @@ -use dep::protocol_types::constants::{ - RETURN_VALUES_LENGTH, - MAX_READ_REQUESTS_PER_CALL, - MAX_PENDING_READ_REQUESTS_PER_CALL, - MAX_NEW_COMMITMENTS_PER_CALL, - MAX_NEW_NULLIFIERS_PER_CALL, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, - MAX_NEW_L2_TO_L1_MSGS_PER_CALL, - NUM_FIELDS_PER_SHA256, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, - MAX_PUBLIC_DATA_READS_PER_CALL, - GENERATOR_INDEX__FUNCTION_ARGS, - BLOCK_HEADER_LENGTH, - CONTRACT_DEPLOYMENT_DATA_LENGTH, - CALL_CONTEXT_LENGTH, - PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, - PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, - CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH, - CONTRACT_STORAGE_READ_LENGTH, - PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH, - PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, - GENERATOR_INDEX__BLOCK_HASH, - GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS, - GENERATOR_INDEX__FUNCTION_DATA, - GENERATOR_INDEX__PUBLIC_DATA_READ, - GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST, - GENERATOR_INDEX__CALL_CONTEXT, - GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS, - GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA, +use dep::protocol_types::{ + abis::{ + block_header::BlockHeader, + call_context::CallContext, + private_circuit_public_inputs::PrivateCircuitPublicInputs, + public_circuit_public_inputs::PublicCircuitPublicInputs, + }, + contrakt::deployment_data::ContractDeploymentData, + hash::hash_args, }; -use crate::oracle::debug_log; -use crate::types::vec::BoundedVec; -use crate::types::point::Point; -use crate::hash::pedersen_hash; - // docs:start:private-global-variables struct PrivateGlobalVariables { chain_id: Field, @@ -63,33 +37,6 @@ impl PublicGlobalVariables { } } -// docs:start:contract-deployment-data -struct ContractDeploymentData { - deployer_public_key: Point, - constructor_vk_hash : Field, - function_tree_root : Field, - contract_address_salt : Field, - portal_contract_address : Field, -} -// docs:end:contract-deployment-data - -impl ContractDeploymentData { - fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] { - [ - self.deployer_public_key.x, - self.deployer_public_key.y, - self.constructor_vk_hash, - self.function_tree_root, - self.contract_address_salt, - self.portal_contract_address, - ] - } - - fn hash(self) -> Field { - pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA) - } -} - // PrivateContextInputs are expected to be provided to each private function // docs:start:private-context-inputs struct PrivateContextInputs { @@ -110,290 +57,6 @@ struct PublicContextInputs { } // docs:end:public-context-inputs -// docs:start:call-context -struct CallContext { - msg_sender : Field, - storage_contract_address : Field, - portal_contract_address : Field, - function_selector: Field, - - is_delegate_call : bool, - is_static_call : bool, - is_contract_deployment: bool, -} -// docs:end:call-context - -impl CallContext { - fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] { - [ - self.msg_sender, - self.storage_contract_address, - self.portal_contract_address, - self.function_selector, - self.is_delegate_call as Field, - self.is_static_call as Field, - self.is_contract_deployment as Field, - ] - } - - fn hash(self) -> Field { - pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT) - } -} - -// docs:start:block-header -struct BlockHeader { - note_hash_tree_root : Field, - nullifier_tree_root : Field, - contract_tree_root : Field, - l1_to_l2_messages_tree_root : Field, - archive_root: Field, - public_data_tree_root: Field, - global_variables_hash: Field, -} -// docs:end:block-header - -impl BlockHeader { - // NOTE: this order must match the order in `private_circuit_public_inputs.hpp` - pub fn serialize(self) -> [Field; BLOCK_HEADER_LENGTH] { - [ - self.note_hash_tree_root, - self.nullifier_tree_root, - self.contract_tree_root, - self.l1_to_l2_messages_tree_root, - self.archive_root, - self.public_data_tree_root, - self.global_variables_hash, - ] - } - - pub fn deserialize(deserialized: [Field; BLOCK_HEADER_LENGTH]) -> Self { - BlockHeader { - note_hash_tree_root: deserialized[0], - nullifier_tree_root: deserialized[1], - contract_tree_root: deserialized[2], - l1_to_l2_messages_tree_root: deserialized[3], - archive_root: deserialized[4], - public_data_tree_root: deserialized[5], - global_variables_hash: deserialized[6], - } - } - - pub fn empty() -> Self { - Self { note_hash_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, archive_root: 0, public_data_tree_root: 0, global_variables_hash: 0 } - } - - pub fn block_hash(self) -> Field { - // TODO(#3442): Unify the ordering in `BlockHeader::serialize` function and the ordering - // in the block hash preimage --> This requires changes in the circuits. - let inputs = [ - self.global_variables_hash, - self.note_hash_tree_root, - self.nullifier_tree_root, - self.contract_tree_root, - self.l1_to_l2_messages_tree_root, - self.public_data_tree_root - ]; - pedersen_hash(inputs, GENERATOR_INDEX__BLOCK_HASH) - } -} - -struct FunctionData { - function_selector: Field, - is_internal: bool, - is_private: bool, - is_constructor: bool, -} - -impl FunctionData { - fn hash(self) -> Field { - pedersen_hash([ - self.function_selector, - self.is_internal as Field, - self.is_private as Field, - self.is_constructor as Field, - ], GENERATOR_INDEX__FUNCTION_DATA) - } -} - -struct PrivateCircuitPublicInputs { - call_context: CallContext, - args_hash: Field, - return_values: [Field; RETURN_VALUES_LENGTH], - read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL], - pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL], - new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL], - new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL], - nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL], - private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], - public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], - new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], - // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that - // we're talking about a single number backed by two field elements. - encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], - unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], - encrypted_log_preimages_length: Field, - unencrypted_log_preimages_length: Field, - block_header: BlockHeader, - contract_deployment_data: ContractDeploymentData, - chain_id: Field, - version: Field, -} - -impl PrivateCircuitPublicInputs { - fn hash(self) -> Field { - let mut fields: BoundedVec = BoundedVec::new(0); - fields.push(self.call_context.hash()); - fields.push(self.args_hash); - fields.push_array(self.return_values); - fields.push_array(self.read_requests); - fields.push_array(self.pending_read_requests); - fields.push_array(self.new_commitments); - fields.push_array(self.new_nullifiers); - fields.push_array(self.nullified_commitments); - fields.push_array(self.private_call_stack); - fields.push_array(self.public_call_stack); - fields.push_array(self.new_l2_to_l1_msgs); - fields.push_array(self.encrypted_logs_hash); - fields.push_array(self.unencrypted_logs_hash); - fields.push(self.encrypted_log_preimages_length); - fields.push(self.unencrypted_log_preimages_length); - fields.push_array(self.block_header.serialize()); - fields.push(self.contract_deployment_data.hash()); - fields.push(self.chain_id); - fields.push(self.version); - - pedersen_hash(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS) - } - - fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] { - let mut fields: BoundedVec = BoundedVec::new(0); - fields.push_array(self.call_context.serialize()); - fields.push(self.args_hash); - fields.push_array(self.return_values); - fields.push_array(self.read_requests); - fields.push_array(self.pending_read_requests); - fields.push_array(self.new_commitments); - fields.push_array(self.new_nullifiers); - fields.push_array(self.private_call_stack); - fields.push_array(self.public_call_stack); - fields.push_array(self.new_l2_to_l1_msgs); - fields.push_array(self.encrypted_logs_hash); - fields.push_array(self.unencrypted_logs_hash); - fields.push(self.encrypted_log_preimages_length); - fields.push(self.unencrypted_log_preimages_length); - fields.push_array(self.block_header.serialize()); - fields.push_array(self.contract_deployment_data.serialize()); - fields.push(self.chain_id); - fields.push(self.version); - fields.storage - } -} - -struct ContractStorageRead { - storage_slot: Field, - value: Field, -} - -impl ContractStorageRead { - pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] { - [self.storage_slot, self.value] - } - - pub fn hash(self) -> Field { - pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ) - } - - pub fn empty() -> Self { - Self { storage_slot: 0, value: 0 } - } -} - -struct ContractStorageUpdateRequest { - storage_slot: Field, - old_value: Field, - new_value: Field, -} - -impl ContractStorageUpdateRequest { - pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] { - [self.storage_slot, self.old_value, self.new_value] - } - - pub fn hash(self) -> Field { - pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST) - } - - pub fn empty() -> Self { - Self { storage_slot: 0, old_value: 0, new_value: 0 } - } -} - -struct PublicCircuitPublicInputs { - call_context: CallContext, - args_hash: Field, - return_values: [Field; RETURN_VALUES_LENGTH], - contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL], - contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL], - public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], - new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL], - new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL], - new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL], - unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], - unencrypted_log_preimages_length: Field, - block_header: BlockHeader, - prover_address: Field, -} - -impl PublicCircuitPublicInputs { - - pub fn hash(self) -> Field { - let mut inputs: BoundedVec = BoundedVec::new(0); - inputs.push(self.call_context.hash()); - inputs.push(self.args_hash); - inputs.push_array(self.return_values); - for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL { - inputs.push(self.contract_storage_update_requests[i].hash()); - } - for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL { - inputs.push(self.contract_storage_read[i].hash()); - } - inputs.push_array(self.public_call_stack); - inputs.push_array(self.new_commitments); - inputs.push_array(self.new_nullifiers); - inputs.push_array(self.new_l2_to_l1_msgs); - - inputs.push_array(self.unencrypted_logs_hash); - inputs.push(self.unencrypted_log_preimages_length); - inputs.push_array(self.block_header.serialize()); - inputs.push(self.prover_address); - - pedersen_hash(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS) - } - - pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] { - let mut fields: BoundedVec = BoundedVec::new(0); - fields.push_array(self.call_context.serialize()); - fields.push(self.args_hash); - fields.push_array(self.return_values); - for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL { - fields.push_array(self.contract_storage_update_requests[i].serialize()); - } - for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL { - fields.push_array(self.contract_storage_read[i].serialize()); - } - fields.push_array(self.public_call_stack); - fields.push_array(self.new_commitments); - fields.push_array(self.new_nullifiers); - fields.push_array(self.new_l2_to_l1_msgs); - fields.push_array(self.unencrypted_logs_hash); - fields.push(self.unencrypted_log_preimages_length); - fields.push_array(self.block_header.serialize()); - fields.push(self.prover_address); - fields.storage - } -} - struct Hasher { fields: [Field], } @@ -417,30 +80,3 @@ impl Hasher { hash_args(self.fields) } } - -global ARGS_HASH_CHUNK_LENGTH: u32 = 32; -global ARGS_HASH_CHUNK_COUNT: u32 = 16; - -pub fn hash_args(args: [Field; N]) -> Field { - if args.len() == 0 { - 0 - } else { - let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT]; - for i in 0..ARGS_HASH_CHUNK_COUNT { - let mut chunk_hash = 0; - let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH; - if start_chunk_index < (args.len() as u32) { - let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH]; - for j in 0..ARGS_HASH_CHUNK_LENGTH { - let item_index = i * ARGS_HASH_CHUNK_LENGTH + j; - if item_index < (args.len() as u32) { - chunk_args[j] = args[item_index]; - } - } - chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS); - } - chunks_hashes[i] = chunk_hash; - } - pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS) - } -} diff --git a/yarn-project/aztec-nr/aztec/src/address.nr b/yarn-project/aztec-nr/aztec/src/address.nr index d569f33eea5..38a1ca0fe56 100644 --- a/yarn-project/aztec-nr/aztec/src/address.nr +++ b/yarn-project/aztec-nr/aztec/src/address.nr @@ -1,7 +1,14 @@ -use dep::protocol_types::constants::GENERATOR_INDEX__CONTRACT_ADDRESS; -use crate::hash::pedersen_hash; +use dep::protocol_types::{ + address::AztecAddress, + constants::GENERATOR_INDEX__CONTRACT_ADDRESS, + hash::pedersen_hash, +}; -pub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field { - pedersen_hash([pub_key_x, pub_key_y, partial_address], - GENERATOR_INDEX__CONTRACT_ADDRESS) +pub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> AztecAddress { + AztecAddress::from_field( + pedersen_hash( + [pub_key_x, pub_key_y, partial_address], + GENERATOR_INDEX__CONTRACT_ADDRESS + ) + ) } diff --git a/yarn-project/aztec-nr/aztec/src/context.nr b/yarn-project/aztec-nr/aztec/src/context.nr index 020a9410ce5..053299fc1cc 100644 --- a/yarn-project/aztec-nr/aztec/src/context.nr +++ b/yarn-project/aztec-nr/aztec/src/context.nr @@ -1,41 +1,54 @@ -use dep::protocol_types::constants::{ - EMPTY_NULLIFIED_COMMITMENT, - MAX_NEW_COMMITMENTS_PER_CALL, - MAX_NEW_L2_TO_L1_MSGS_PER_CALL, - MAX_NEW_NULLIFIERS_PER_CALL, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, - MAX_PUBLIC_DATA_READS_PER_CALL, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, - MAX_READ_REQUESTS_PER_CALL, - MAX_PENDING_READ_REQUESTS_PER_CALL, - NUM_FIELDS_PER_SHA256, - RETURN_VALUES_LENGTH, +use dep::protocol_types::{ + abis::{ + block_header::BlockHeader, + call_context::CallContext, + function_data::FunctionData, + function_selector::FunctionSelector, + private_circuit_public_inputs::PrivateCircuitPublicInputs, + public_circuit_public_inputs::PublicCircuitPublicInputs, + call_stack_item::PrivateCallStackItem, + call_stack_item::PublicCallStackItem, + }, + address::{ + AztecAddress, + EthAddress, + }, + constants::{ + EMPTY_NULLIFIED_COMMITMENT, + MAX_NEW_COMMITMENTS_PER_CALL, + MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_NEW_NULLIFIERS_PER_CALL, + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, + MAX_PUBLIC_DATA_READS_PER_CALL, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, + MAX_READ_REQUESTS_PER_CALL, + MAX_PENDING_READ_REQUESTS_PER_CALL, + NUM_FIELDS_PER_SHA256, + RETURN_VALUES_LENGTH, + }, + contrakt::{ + deployment_data::ContractDeploymentData, + storage_read::StorageRead, + storage_update_request::StorageUpdateRequest, + }, + hash::hash_args, + point::Point, }; -use crate::abi; +// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) +// use dep::std::collections::vec::Vec; use crate::abi::{ - hash_args, - CallContext, - ContractDeploymentData, - BlockHeader, - FunctionData, - PrivateCircuitPublicInputs, - PublicCircuitPublicInputs, + PrivateContextInputs, + PublicContextInputs, }; -// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) -// use dep::std::collections::vec::Vec; - // l1 to l2 messaging use crate::messaging::process_l1_to_l2_message; -use crate::private_call_stack_item::PrivateCallStackItem; -use crate::public_call_stack_item::PublicCallStackItem; use crate::types::{ vec::BoundedVec, - point::Point, }; use crate::utils::arr_copy_slice; @@ -54,7 +67,7 @@ use dep::std::option::Option; // When finished, one can call .finish() to convert back to the abi struct PrivateContext { // docs:start:private-context - inputs: abi::PrivateContextInputs, + inputs: PrivateContextInputs, args_hash : Field, return_values : BoundedVec, @@ -66,8 +79,8 @@ struct PrivateContext { new_nullifiers: BoundedVec, nullified_commitments: BoundedVec, - private_call_stack : BoundedVec, - public_call_stack : BoundedVec, + private_call_stack_hashes : BoundedVec, + public_call_stack_hashes : BoundedVec, new_l2_to_l1_msgs : BoundedVec, // docs:end:private-context @@ -79,7 +92,7 @@ struct PrivateContext { } impl PrivateContext { - pub fn new(inputs: abi::PrivateContextInputs, args_hash: Field) -> PrivateContext { + pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext { PrivateContext { inputs: inputs, @@ -95,8 +108,8 @@ impl PrivateContext { block_header: inputs.block_header, - private_call_stack: BoundedVec::new(0), - public_call_stack: BoundedVec::new(0), + private_call_stack_hashes: BoundedVec::new(0), + public_call_stack_hashes: BoundedVec::new(0), new_l2_to_l1_msgs: BoundedVec::new(0), // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) @@ -105,15 +118,15 @@ impl PrivateContext { } } - pub fn msg_sender(self) -> Field { + pub fn msg_sender(self) -> AztecAddress { self.inputs.call_context.msg_sender } - pub fn this_address(self) -> Field { + pub fn this_address(self) -> AztecAddress { self.inputs.call_context.storage_contract_address } - pub fn this_portal_address(self) -> Field { + pub fn this_portal_address(self) -> EthAddress { self.inputs.call_context.portal_contract_address } @@ -125,7 +138,7 @@ impl PrivateContext { self.inputs.private_global_variables.version } - pub fn selector(self) -> Field { + pub fn selector(self) -> FunctionSelector { self.inputs.call_context.function_selector } @@ -133,14 +146,14 @@ impl PrivateContext { get_block_header(block_number, self) } - pub fn finish(self) -> abi::PrivateCircuitPublicInputs { + pub fn finish(self) -> PrivateCircuitPublicInputs { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256]; let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256]; let encrypted_log_preimages_length = 0; let unencrypted_log_preimages_length = 0; - let priv_circuit_pub_inputs = abi::PrivateCircuitPublicInputs { + let priv_circuit_pub_inputs = PrivateCircuitPublicInputs { call_context: self.inputs.call_context, args_hash: self.args_hash, return_values: self.return_values.storage, @@ -149,8 +162,8 @@ impl PrivateContext { new_commitments: self.new_commitments.storage, new_nullifiers: self.new_nullifiers.storage, nullified_commitments: self.nullified_commitments.storage, - private_call_stack: self.private_call_stack.storage, - public_call_stack: self.public_call_stack.storage, + private_call_stack_hashes: self.private_call_stack_hashes.storage, + public_call_stack_hashes: self.public_call_stack_hashes.storage, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, encrypted_logs_hash: encrypted_logs_hash, unencrypted_logs_hash: unencrypted_logs_hash, @@ -228,8 +241,8 @@ impl PrivateContext { pub fn call_private_function( &mut self, - contract_address: Field, - function_selector: Field, + contract_address: AztecAddress, + function_selector: FunctionSelector, args: [Field; ARGS_COUNT] ) -> [Field; RETURN_VALUES_LENGTH] { let args_hash = hash_args(args); @@ -239,37 +252,37 @@ impl PrivateContext { pub fn call_private_function_no_args( &mut self, - contract_address: Field, - function_selector: Field, + contract_address: AztecAddress, + function_selector: FunctionSelector, ) -> [Field; RETURN_VALUES_LENGTH] { self.call_private_function_with_packed_args(contract_address, function_selector, 0) } pub fn call_private_function_with_packed_args( &mut self, - contract_address: Field, - function_selector: Field, + contract_address: AztecAddress, + function_selector: FunctionSelector, args_hash: Field ) -> [Field; RETURN_VALUES_LENGTH] { let fields = call_private_function_internal( - contract_address, + contract_address, function_selector, args_hash ); let item = PrivateCallStackItem { - contract_address: fields[0], + contract_address: AztecAddress::from_field(fields[0]), function_data: FunctionData { - function_selector: fields[1], + selector: FunctionSelector::from_field(fields[1]), is_internal: fields[2] as bool, is_private: fields[3] as bool, is_constructor: fields[4] as bool, }, public_inputs: PrivateCircuitPublicInputs { call_context: CallContext { - msg_sender : fields[5], - storage_contract_address : fields[6], - portal_contract_address : fields[7], - function_selector: fields[8], // practically same as fields[1] + msg_sender : AztecAddress::from_field(fields[5]), + storage_contract_address : AztecAddress::from_field(fields[6]), + portal_contract_address : EthAddress::from_field(fields[7]), + function_selector: FunctionSelector::from_field(fields[8]), // practically same as fields[1] is_delegate_call : fields[9] as bool, is_static_call : fields[10] as bool, is_contract_deployment: fields[11] as bool, @@ -282,8 +295,8 @@ impl PrivateContext { new_commitments: arr_copy_slice(fields, [0; MAX_NEW_COMMITMENTS_PER_CALL], 81), new_nullifiers: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 97), nullified_commitments: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 113), - private_call_stack: arr_copy_slice(fields, [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], 129), - public_call_stack: arr_copy_slice(fields, [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], 133), + private_call_stack_hashes: arr_copy_slice(fields, [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], 129), + public_call_stack_hashes: arr_copy_slice(fields, [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], 133), new_l2_to_l1_msgs: arr_copy_slice(fields, [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], 137), encrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 139), unencrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 141), @@ -300,19 +313,22 @@ impl PrivateContext { global_variables_hash: fields[151], }, contract_deployment_data: ContractDeploymentData { - deployer_public_key: Point::new(fields[152], fields[153]), + deployer_public_key: Point { + x: fields[152], + y: fields[153], + }, constructor_vk_hash : fields[154], function_tree_root : fields[155], contract_address_salt : fields[156], - portal_contract_address : fields[157], + portal_contract_address : EthAddress::from_field(fields[157]), }, chain_id: fields[158], version: fields[159], }, is_execution_request: fields[160] as bool, }; - assert(contract_address == item.contract_address); - assert(function_selector == item.function_data.function_selector); + assert(contract_address.eq(item.contract_address)); + assert(function_selector.eq(item.function_data.selector)); assert(args_hash == item.public_inputs.args_hash); @@ -325,18 +341,18 @@ impl PrivateContext { assert(item.public_inputs.call_context.is_delegate_call == false); assert(item.public_inputs.call_context.is_static_call == false); assert(item.public_inputs.call_context.is_contract_deployment == false); - assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address); - assert(item.public_inputs.call_context.storage_contract_address == contract_address); + assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)); + assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address)); - self.private_call_stack.push(item.hash()); + self.private_call_stack_hashes.push(item.hash()); item.public_inputs.return_values } pub fn call_public_function( &mut self, - contract_address: Field, - function_selector: Field, + contract_address: AztecAddress, + function_selector: FunctionSelector, args: [Field; ARGS_COUNT] ) { let args_hash = hash_args(args); @@ -346,16 +362,16 @@ impl PrivateContext { pub fn call_public_function_no_args( &mut self, - contract_address: Field, - function_selector: Field, + contract_address: AztecAddress, + function_selector: FunctionSelector, ) { self.call_public_function_with_packed_args(contract_address, function_selector, 0) } pub fn call_public_function_with_packed_args( &mut self, - contract_address: Field, - function_selector: Field, + contract_address: AztecAddress, + function_selector: FunctionSelector, args_hash: Field ) { let fields = enqueue_public_function_call_internal( @@ -364,41 +380,41 @@ impl PrivateContext { args_hash ); let item = PublicCallStackItem { - contract_address: fields[0], + contract_address: AztecAddress::from_field(fields[0]), function_data: FunctionData { - function_selector: fields[1], + selector: FunctionSelector::from_field(fields[1]), is_internal: fields[2] as bool, is_private: fields[3] as bool, is_constructor: fields[4] as bool, }, public_inputs: PublicCircuitPublicInputs { call_context: CallContext { - msg_sender : fields[5], - storage_contract_address : fields[6], - portal_contract_address : fields[7], - function_selector: fields[8], // practically same as fields[1] + msg_sender : AztecAddress::from_field(fields[5]), + storage_contract_address : AztecAddress::from_field(fields[6]), + portal_contract_address : EthAddress::from_field(fields[7]), + function_selector: FunctionSelector::from_field(fields[8]), // practically same as fields[1] is_delegate_call : fields[9] as bool, is_static_call : fields[10] as bool, is_contract_deployment: fields[11] as bool, }, args_hash: fields[12], return_values: [0; RETURN_VALUES_LENGTH], - contract_storage_update_requests: [ContractStorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL], - contract_storage_read: [ContractStorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL], - public_call_stack: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], + contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL], + contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL], + public_call_stack_hashes: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], new_commitments: [0; MAX_NEW_COMMITMENTS_PER_CALL], new_nullifiers: [0; MAX_NEW_NULLIFIERS_PER_CALL], new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256], unencrypted_log_preimages_length: 0, block_header: BlockHeader::empty(), - prover_address: 0, + prover_address: AztecAddress::zero(), }, is_execution_request: true, }; - assert(contract_address == item.contract_address); - assert(function_selector == item.function_data.function_selector); + assert(contract_address.eq(item.contract_address)); + assert(function_selector.eq(item.function_data.selector)); assert(args_hash == item.public_inputs.args_hash); @@ -409,44 +425,39 @@ impl PrivateContext { assert(item.public_inputs.call_context.is_delegate_call == false); assert(item.public_inputs.call_context.is_static_call == false); assert(item.public_inputs.call_context.is_contract_deployment == false); - assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address); - assert(item.public_inputs.call_context.storage_contract_address == contract_address); + assert(item.public_inputs.call_context.msg_sender.eq(self.inputs.call_context.storage_contract_address)); + assert(item.public_inputs.call_context.storage_contract_address.eq(contract_address)); - self.public_call_stack.push(item.hash()); + self.public_call_stack_hashes.push(item.hash()); } } -use crate::abi::{ - ContractStorageRead, - ContractStorageUpdateRequest -}; - struct PublicContext { - inputs: abi::PublicContextInputs, + inputs: PublicContextInputs, args_hash : Field, return_values : BoundedVec, - contract_storage_update_requests: BoundedVec, - contract_storage_read: BoundedVec, - public_call_stack: BoundedVec, + contract_storage_update_requests: BoundedVec, + contract_storage_reads: BoundedVec, + public_call_stack_hashes: BoundedVec, new_commitments: BoundedVec, - new_nullifiers: BoundedVec, + new_nullifiers: BoundedVec, - new_l2_to_l1_msgs: BoundedVec, + new_l2_to_l1_msgs: BoundedVec, unencrypted_logs_hash: BoundedVec, unencrypted_logs_preimages_length: Field, block_header: BlockHeader, - prover_address: Field, + prover_address: AztecAddress, } impl PublicContext { - pub fn new(inputs: abi::PublicContextInputs, args_hash: Field) -> PublicContext { - let empty_storage_read = ContractStorageRead::empty(); - let empty_storage_update = ContractStorageUpdateRequest::empty(); + pub fn new(inputs: PublicContextInputs, args_hash: Field) -> PublicContext { + let empty_storage_read = StorageRead::empty(); + let empty_storage_update = StorageUpdateRequest::empty(); PublicContext { inputs: inputs, @@ -454,8 +465,8 @@ impl PublicContext { return_values: BoundedVec::new(0), contract_storage_update_requests: BoundedVec::new(empty_storage_update), - contract_storage_read: BoundedVec::new(empty_storage_read), - public_call_stack: BoundedVec::new(0), + contract_storage_reads: BoundedVec::new(empty_storage_read), + public_call_stack_hashes: BoundedVec::new(0), new_commitments: BoundedVec::new(0), new_nullifiers: BoundedVec::new(0), @@ -467,7 +478,7 @@ impl PublicContext { unencrypted_logs_preimages_length: 0, block_header: inputs.block_header, - prover_address: 0, + prover_address: AztecAddress::zero(), // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) // encrypted_logs_preimages: Vec::new(), @@ -475,15 +486,15 @@ impl PublicContext { } } - pub fn msg_sender(self) -> Field { + pub fn msg_sender(self) -> AztecAddress { self.inputs.call_context.msg_sender } - pub fn this_address(self) -> Field { + pub fn this_address(self) -> AztecAddress { self.inputs.call_context.storage_contract_address } - pub fn this_portal_address(self) -> Field { + pub fn this_portal_address(self) -> EthAddress { self.inputs.call_context.portal_contract_address } @@ -495,7 +506,7 @@ impl PublicContext { self.inputs.public_global_variables.version } - pub fn selector(self) -> Field { + pub fn selector(self) -> FunctionSelector { self.inputs.call_context.function_selector } @@ -507,22 +518,22 @@ impl PublicContext { self.inputs.public_global_variables.timestamp } - pub fn finish(self) -> abi::PublicCircuitPublicInputs { + pub fn finish(self) -> PublicCircuitPublicInputs { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256]; let unencrypted_log_preimages_length = 0; // Compute the public call stack hashes - let pub_circuit_pub_inputs = abi::PublicCircuitPublicInputs { + let pub_circuit_pub_inputs = PublicCircuitPublicInputs { call_context: self.inputs.call_context, // Done args_hash: self.args_hash, // Done contract_storage_update_requests: self.contract_storage_update_requests.storage, - contract_storage_read: self.contract_storage_read.storage, + contract_storage_reads: self.contract_storage_reads.storage, return_values: self.return_values.storage, new_commitments: self.new_commitments.storage, new_nullifiers: self.new_nullifiers.storage, - public_call_stack: self.public_call_stack.storage, + public_call_stack_hashes: self.public_call_stack_hashes.storage, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, unencrypted_logs_hash: unencrypted_logs_hash, unencrypted_log_preimages_length: unencrypted_log_preimages_length, @@ -568,11 +579,11 @@ impl PublicContext { pub fn call_public_function( _self: Self, - contract_address: Field, - function_selector: Field, + contract_address: AztecAddress, + function_selector: FunctionSelector, args: [Field; ARGS_COUNT], ) -> [Field; RETURN_VALUES_LENGTH] { - let args_hash = abi::hash_args(args); + let args_hash = hash_args(args); assert(args_hash == arguments::pack_arguments(args)); call_public_function_internal( contract_address, @@ -583,8 +594,8 @@ impl PublicContext { pub fn call_public_function_no_args( _self: Self, - contract_address: Field, - function_selector: Field, + contract_address: AztecAddress, + function_selector: FunctionSelector, ) -> [Field; RETURN_VALUES_LENGTH] { call_public_function_internal( contract_address, diff --git a/yarn-project/aztec-nr/aztec/src/hash.nr b/yarn-project/aztec-nr/aztec/src/hash.nr index eb9fb57aff0..03689083fb8 100644 --- a/yarn-project/aztec-nr/aztec/src/hash.nr +++ b/yarn-project/aztec-nr/aztec/src/hash.nr @@ -1,34 +1,9 @@ -use dep::std::hash::{pedersen_hash_with_separator, sha256}; -use dep::protocol_types::constants::{ - GENERATOR_INDEX__SIGNATURE_PAYLOAD, - GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET, +use dep::protocol_types::{ + constants::GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET, + hash::pedersen_hash, }; -pub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field { - let sha256_hashed = sha256(bytes_to_hash); - - // Convert it to a field element - let mut v = 1; - let mut high = 0 as Field; - let mut low = 0 as Field; - - for i in 0..16 { - high = high + (sha256_hashed[15 - i] as Field) * v; - low = low + (sha256_hashed[16 + 15 - i] as Field) * v; - v = v * 256; - } - - // Abuse that a % p + b % p = (a + b) % p and that low < p - let hash_in_a_field = low + high * v; - - hash_in_a_field -} - pub fn compute_secret_hash(secret: Field) -> Field { // TODO(#1205) This is probably not the right index to use pedersen_hash([secret], GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET) } - -pub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field { - pedersen_hash_with_separator(inputs, hash_index) -} diff --git a/yarn-project/aztec-nr/aztec/src/history/public_value_inclusion.nr b/yarn-project/aztec-nr/aztec/src/history/public_value_inclusion.nr index ec666cb69cb..b6eac8fac8a 100644 --- a/yarn-project/aztec-nr/aztec/src/history/public_value_inclusion.nr +++ b/yarn-project/aztec-nr/aztec/src/history/public_value_inclusion.nr @@ -1,12 +1,14 @@ -use dep::protocol_types::constants::{ - PUBLIC_DATA_TREE_HEIGHT, - GENERATOR_INDEX__PUBLIC_LEAF_INDEX, +use dep::protocol_types::{ + constants::{ + PUBLIC_DATA_TREE_HEIGHT, + GENERATOR_INDEX__PUBLIC_LEAF_INDEX, + }, + hash::pedersen_hash, }; use dep::std::merkle::compute_merkle_root; use crate::{ context::PrivateContext, - hash::pedersen_hash, oracle::get_sibling_path::get_sibling_path, }; @@ -24,7 +26,7 @@ pub fn prove_public_value_inclusion( // not siloed with contract address so an oracle could cheat and give us a membership witness for arbitrary // value in the public data tree. let value_leaf_index = pedersen_hash( - [context.this_address(), storage_slot], + [context.this_address().to_field(), storage_slot], GENERATOR_INDEX__PUBLIC_LEAF_INDEX ); diff --git a/yarn-project/aztec-nr/aztec/src/log.nr b/yarn-project/aztec-nr/aztec/src/log.nr index 35bc5ee690c..6c6119025e8 100644 --- a/yarn-project/aztec-nr/aztec/src/log.nr +++ b/yarn-project/aztec-nr/aztec/src/log.nr @@ -1,10 +1,13 @@ use crate::context::{PrivateContext, PublicContext}; use crate::oracle; use crate::types::point::Point; +use dep::protocol_types::{ + address::AztecAddress, +}; pub fn emit_encrypted_log( context: &mut PrivateContext, - contract_address: Field, + contract_address: AztecAddress, storage_slot: Field, encryption_pub_key: Point, log: [Field; N] diff --git a/yarn-project/aztec-nr/aztec/src/messaging.nr b/yarn-project/aztec-nr/aztec/src/messaging.nr index e5bca11b582..ef659f198ec 100644 --- a/yarn-project/aztec-nr/aztec/src/messaging.nr +++ b/yarn-project/aztec-nr/aztec/src/messaging.nr @@ -6,11 +6,16 @@ use l1_to_l2_message_getter_data::make_l1_to_l2_message_getter_data; use crate::abi::PublicContextInputs; use crate::oracle::get_l1_to_l2_message::get_l1_to_l2_message_call; +use dep::protocol_types::address::{ + AztecAddress, + EthAddress, +}; + // Returns the nullifier for the message pub fn process_l1_to_l2_message( l1_to_l2_root: Field, - storage_contract_address: Field, - portal_contract_address: Field, + storage_contract_address: AztecAddress, + portal_contract_address: EthAddress, chain_id: Field, version: Field, msg_key: Field, @@ -24,10 +29,10 @@ pub fn process_l1_to_l2_message( assert(l1_to_l2_message_data.root == l1_to_l2_root); // Validate this is the target contract - assert(l1_to_l2_message_data.message.recipient == storage_contract_address); + assert(l1_to_l2_message_data.message.recipient.eq(storage_contract_address)); // Validate the sender is the portal contract - assert(l1_to_l2_message_data.message.sender == portal_contract_address); + assert(l1_to_l2_message_data.message.sender.eq(portal_contract_address)); // Validate the chain id is correct assert(l1_to_l2_message_data.message.chainId == chain_id); diff --git a/yarn-project/aztec-nr/aztec/src/messaging/l1_to_l2_message.nr b/yarn-project/aztec-nr/aztec/src/messaging/l1_to_l2_message.nr index 0be0fc4b3ac..39aeba68742 100644 --- a/yarn-project/aztec-nr/aztec/src/messaging/l1_to_l2_message.nr +++ b/yarn-project/aztec-nr/aztec/src/messaging/l1_to_l2_message.nr @@ -1,14 +1,23 @@ -use dep::protocol_types::constants::{ - L1_TO_L2_MESSAGE_LENGTH, - GENERATOR_INDEX__NULLIFIER, - GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET, +use dep::protocol_types::{ + address::{ + AztecAddress, + EthAddress, + }, + constants::{ + L1_TO_L2_MESSAGE_LENGTH, + GENERATOR_INDEX__NULLIFIER, + GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET, + }, + hash::{ + pedersen_hash, + sha256_to_field, + }, }; -use crate::hash::{sha256_to_field, pedersen_hash}; struct L1ToL2Message { - sender: Field, + sender: EthAddress, chainId: Field, - recipient: Field, + recipient: AztecAddress, version: Field, content: Field, secret: Field, @@ -25,9 +34,9 @@ impl L1ToL2Message { tree_index: Field ) -> L1ToL2Message { L1ToL2Message { - sender: fields[0], + sender: EthAddress::from_field(fields[0]), chainId: fields[1], - recipient: fields[2], + recipient: AztecAddress::from_field(fields[2]), version: fields[3], content: fields[4], secret: secret, @@ -45,9 +54,9 @@ impl L1ToL2Message { fn message_hash(self: Self) -> Field { let mut hash_bytes: [u8; 256] = [0; 256]; - let sender_bytes = self.sender.to_be_bytes(32); + let sender_bytes = self.sender.to_field().to_be_bytes(32); let chainId_bytes = self.chainId.to_be_bytes(32); - let recipient_bytes = self.recipient.to_be_bytes(32); + let recipient_bytes = self.recipient.to_field().to_be_bytes(32); let version_bytes = self.version.to_be_bytes(32); let content_bytes = self.content.to_be_bytes(32); let secret_hash_bytes = self.secret_hash.to_be_bytes(32); diff --git a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr index 3827e4641e7..8b59242ba76 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_getter.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_getter.nr @@ -20,7 +20,7 @@ fn check_note_header(context: PrivateContext, storage_slot: Field, note let get_header = note_interface.get_header; let header = get_header(note); let contract_address = context.this_address(); - assert(header.contract_address == contract_address); + assert(header.contract_address.eq(contract_address)); assert(header.storage_slot == storage_slot); } diff --git a/yarn-project/aztec-nr/aztec/src/note/note_hash.nr b/yarn-project/aztec-nr/aztec/src/note/note_hash.nr index dc2c6c2c8b3..8f0abd7d3db 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_hash.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_hash.nr @@ -1,13 +1,19 @@ -use crate::hash::pedersen_hash; -use dep::protocol_types::constants::{GENERATOR_INDEX__UNIQUE_COMMITMENT, GENERATOR_INDEX__SILOED_COMMITMENT}; +use dep::protocol_types::{ + address::AztecAddress, + constants::{ + GENERATOR_INDEX__UNIQUE_COMMITMENT, + GENERATOR_INDEX__SILOED_COMMITMENT, + }, + hash::pedersen_hash, +}; pub fn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field { // TODO(#1205) Do we need a generator index here? pedersen_hash([storage_slot, note_hash], 0) } -pub fn compute_siloed_hash(contract_address: Field, inner_note_hash: Field) -> Field { - let inputs = [contract_address, inner_note_hash]; +pub fn compute_siloed_hash(contract_address: AztecAddress, inner_note_hash: Field) -> Field { + let inputs = [contract_address.to_field(), inner_note_hash]; pedersen_hash(inputs, GENERATOR_INDEX__SILOED_COMMITMENT) } diff --git a/yarn-project/aztec-nr/aztec/src/note/note_header.nr b/yarn-project/aztec-nr/aztec/src/note/note_header.nr index 45450638401..306e92a4704 100644 --- a/yarn-project/aztec-nr/aztec/src/note/note_header.nr +++ b/yarn-project/aztec-nr/aztec/src/note/note_header.nr @@ -1,5 +1,7 @@ +use dep::protocol_types::address::AztecAddress; + struct NoteHeader { - contract_address: Field, + contract_address: AztecAddress, nonce: Field, storage_slot: Field, // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386) @@ -8,11 +10,11 @@ struct NoteHeader { } impl NoteHeader { - pub fn new(contract_address: Field, nonce: Field, storage_slot: Field) -> Self { + pub fn new(contract_address: AztecAddress, nonce: Field, storage_slot: Field) -> Self { NoteHeader { contract_address, nonce, storage_slot, is_transient: false } } pub fn empty() -> Self { - NoteHeader { contract_address: 0, nonce: 0, storage_slot: 0, is_transient: false } + NoteHeader { contract_address: AztecAddress::zero(), nonce: 0, storage_slot: 0, is_transient: false } } } diff --git a/yarn-project/aztec-nr/aztec/src/note/utils.nr b/yarn-project/aztec-nr/aztec/src/note/utils.nr index 685c565d538..ac4ab668ad3 100644 --- a/yarn-project/aztec-nr/aztec/src/note/utils.nr +++ b/yarn-project/aztec-nr/aztec/src/note/utils.nr @@ -1,4 +1,7 @@ -use dep::protocol_types::constants::GENERATOR_INDEX__OUTER_NULLIFIER; +use dep::protocol_types::{ + constants::GENERATOR_INDEX__OUTER_NULLIFIER, + hash::pedersen_hash, +}; use crate::{ note::{ note_hash::{compute_inner_hash, compute_siloed_hash, compute_unique_hash}, @@ -6,7 +9,6 @@ use crate::{ note_interface::NoteInterface, }, utils::arr_copy_slice, - hash::pedersen_hash, }; pub fn compute_inner_note_hash(note_interface: NoteInterface, note: Note) -> Field { @@ -44,7 +46,7 @@ pub fn compute_siloed_nullifier(note_interface: NoteInterface, let compute_nullifier = note_interface.compute_nullifier; let inner_nullifier = compute_nullifier(note_with_header); - let input = [header.contract_address, inner_nullifier]; + let input = [header.contract_address.to_field(), inner_nullifier]; pedersen_hash(input, GENERATOR_INDEX__OUTER_NULLIFIER) } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr b/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr index ac687b1d2a3..6250e54b8bb 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr @@ -1,8 +1,12 @@ -use dep::protocol_types::constants::CALL_PRIVATE_FUNCTION_RETURN_SIZE; +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + constants::CALL_PRIVATE_FUNCTION_RETURN_SIZE, +}; #[oracle(callPrivateFunction)] -fn call_private_function_oracle(_contract_address: Field, _function_selector: Field, _args_hash: Field) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {} +fn call_private_function_oracle(_contract_address: AztecAddress, _function_selector: FunctionSelector, _args_hash: Field) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {} -unconstrained pub fn call_private_function_internal(contract_address: Field, function_selector: Field, args_hash: Field) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] { +unconstrained pub fn call_private_function_internal(contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] { call_private_function_oracle(contract_address, function_selector, args_hash) } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/context.nr b/yarn-project/aztec-nr/aztec/src/oracle/context.nr index 5895ec26187..f5fae3b451a 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/context.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/context.nr @@ -1,7 +1,12 @@ +use dep::protocol_types::address::{ + AztecAddress, + EthAddress, +}; + #[oracle(getPortalContractAddress)] -fn _get_portal_address(_contract_address: Field) -> Field {} +fn _get_portal_address(_contract_address: AztecAddress) -> EthAddress {} -unconstrained pub fn get_portal_address(contract_address: Field) -> Field { +unconstrained pub fn get_portal_address(contract_address: AztecAddress) -> EthAddress { let portal_address = _get_portal_address(contract_address); portal_address } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr b/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr index 9d6e1cf80e7..82a6dc96c22 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr @@ -1,3 +1,7 @@ +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, +}; // contract_address + // args_hash + @@ -7,8 +11,8 @@ global ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE: Field = 13; #[oracle(enqueuePublicFunctionCall)] -fn enqueue_public_function_call_oracle(_contract_address: Field, _function_selector: Field, _args_hash: Field) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {} +fn enqueue_public_function_call_oracle(_contract_address: AztecAddress, _function_selector: FunctionSelector, _args_hash: Field) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {} -unconstrained pub fn enqueue_public_function_call_internal(contract_address: Field, function_selector: Field, args_hash: Field) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] { +unconstrained pub fn enqueue_public_function_call_internal(contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] { enqueue_public_function_call_oracle(contract_address, function_selector, args_hash) } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr index 7d10a895646..e8694f10e6e 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr @@ -1,11 +1,13 @@ use dep::std::merkle::compute_merkle_root; -use dep::protocol_types::constants::{ - BLOCK_HEADER_LENGTH, - ARCHIVE_HEIGHT, +use dep::protocol_types::{ + abis::block_header::BlockHeader, + constants::{ + BLOCK_HEADER_LENGTH, + ARCHIVE_HEIGHT, + }, }; use crate::{ - abi::BlockHeader, context::PrivateContext, oracle::get_membership_witness::{ get_membership_witness, diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr index 204bde2b1c1..1ec413874cd 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr @@ -1,6 +1,8 @@ -use dep::protocol_types::constants::NULLIFIER_TREE_HEIGHT; +use dep::protocol_types::{ + constants::NULLIFIER_TREE_HEIGHT, + hash::pedersen_hash, +}; use crate::utils::arr_copy_slice; -use crate::hash::pedersen_hash; global LEAF_DATA_LENGTH: Field = 3; // TODO: move this to constants.hpp so that it gets computed as INDEX_LENGTH + LEAF_DATA_LENGTH + NULLIFIER_TREE_HEIGHT diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr index e2e1684e36f..2dde51102dd 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_public_key.nr @@ -1,21 +1,22 @@ use crate::types::point::Point; use crate::address::compute_address; +use dep::protocol_types::address::AztecAddress; #[oracle(getPublicKeyAndPartialAddress)] -fn get_public_key_and_partial_address_oracle(_address: Field) -> [Field; 3] {} +fn get_public_key_and_partial_address_oracle(_address: AztecAddress) -> [Field; 3] {} -unconstrained fn get_public_key_and_partial_address_internal(address: Field) -> [Field; 3] { +unconstrained fn get_public_key_and_partial_address_internal(address: AztecAddress) -> [Field; 3] { get_public_key_and_partial_address_oracle(address) } -pub fn get_public_key(address: Field) -> Point { +pub fn get_public_key(address: AztecAddress) -> Point { let result = get_public_key_and_partial_address_internal(address); let pub_key_x = result[0]; let pub_key_y = result[1]; let partial_address = result[2]; let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address); - assert(calculated_address == address); + assert(calculated_address.eq(address)); Point::new(pub_key_x, pub_key_y) } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key.nr index fb7de3e56ed..d05415e1893 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key.nr @@ -1,5 +1,6 @@ use crate::oracle::get_public_key::get_public_key; use crate::types::point::Point; +use dep::protocol_types::address::AztecAddress; #[oracle(getSecretKey)] fn get_secret_key_oracle(_owner: Point) -> [Field; dep::std::grumpkin_scalar::GRUMPKIN_SCALAR_SERIALIZED_LEN] {} @@ -8,7 +9,7 @@ unconstrained fn get_secret_key_internal(owner_public_key: Point) -> dep::std::g dep::std::grumpkin_scalar::deserialize_grumpkin_scalar(get_secret_key_oracle(owner_public_key)) } -pub fn get_secret_key(owner: Field) -> dep::std::grumpkin_scalar::GrumpkinScalar { +pub fn get_secret_key(owner: AztecAddress) -> dep::std::grumpkin_scalar::GrumpkinScalar { let owner_public_key = get_public_key(owner); let secret = get_secret_key_internal(owner_public_key); diff --git a/yarn-project/aztec-nr/aztec/src/oracle/logs.nr b/yarn-project/aztec-nr/aztec/src/oracle/logs.nr index 6690243c9f5..c97b326e838 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/logs.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/logs.nr @@ -1,18 +1,21 @@ use crate::types::point::Point; -use dep::protocol_types::constants::NUM_FIELDS_PER_SHA256; +use dep::protocol_types::{ + address::AztecAddress, + constants::NUM_FIELDS_PER_SHA256, +}; // TODO: Should take encrypted data. #[oracle(emitEncryptedLog)] -fn emit_encrypted_log_oracle(_contract_address: Field, _storage_slot: Field, _encryption_pub_key: Point, _preimage: [Field; N]) -> Field {} +fn emit_encrypted_log_oracle(_contract_address: AztecAddress, _storage_slot: Field, _encryption_pub_key: Point, _preimage: [Field; N]) -> Field {} -unconstrained pub fn emit_encrypted_log(contract_address: Field, storage_slot: Field, encryption_pub_key: Point, preimage: [Field; N]) -> [Field; NUM_FIELDS_PER_SHA256] { +unconstrained pub fn emit_encrypted_log(contract_address: AztecAddress, storage_slot: Field, encryption_pub_key: Point, preimage: [Field; N]) -> [Field; NUM_FIELDS_PER_SHA256] { [emit_encrypted_log_oracle(contract_address, storage_slot, encryption_pub_key, preimage), 0] } #[oracle(emitUnencryptedLog)] -fn emit_unencrypted_log_oracle(_contract_address: Field, _event_selector: Field, _message: T) -> Field {} +fn emit_unencrypted_log_oracle(_contract_address: AztecAddress, _event_selector: Field, _message: T) -> Field {} -unconstrained pub fn emit_unencrypted_log(contract_address: Field, event_selector: Field, message: T) -> [Field; NUM_FIELDS_PER_SHA256] { +unconstrained pub fn emit_unencrypted_log(contract_address: AztecAddress, event_selector: Field, message: T) -> [Field; NUM_FIELDS_PER_SHA256] { // https://github.com/AztecProtocol/aztec-packages/issues/885 [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0] } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/notes.nr b/yarn-project/aztec-nr/aztec/src/oracle/notes.nr index e3790168cd9..47985474754 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/notes.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/notes.nr @@ -5,6 +5,8 @@ use crate::note::{ }; use crate::utils::arr_copy_slice; +use dep::protocol_types::address::AztecAddress; + #[oracle(notifyCreatedNote)] fn notify_created_note_oracle(_storage_slot: Field, _serialized_note: [Field; N], _inner_note_hash: Field) -> Field {} @@ -80,7 +82,7 @@ unconstrained pub fn get_notes( offset, placeholder_fields); let num_notes = fields[0] as u32; - let contract_address = fields[1]; + let contract_address = AztecAddress::from_field(fields[1]); let deserialize = note_interface.deserialize; let set_header = note_interface.set_header; for i in 0..placeholder_opt_notes.len() { diff --git a/yarn-project/aztec-nr/aztec/src/oracle/public_call.nr b/yarn-project/aztec-nr/aztec/src/oracle/public_call.nr index e8190c49dd3..0b380bb264d 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/public_call.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/public_call.nr @@ -1,8 +1,12 @@ -use dep::protocol_types::constants::RETURN_VALUES_LENGTH; +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, + address::AztecAddress, + constants::RETURN_VALUES_LENGTH, +}; #[oracle(callPublicFunction)] -fn call_public_function_oracle(_contract_address: Field, _function_selector: Field, _args_hash: Field) -> [Field; RETURN_VALUES_LENGTH] {} +fn call_public_function_oracle(_contract_address: AztecAddress, _function_selector: FunctionSelector, _args_hash: Field) -> [Field; RETURN_VALUES_LENGTH] {} -unconstrained pub fn call_public_function_internal(contract_address: Field, function_selector: Field, args_hash: Field) -> [Field; RETURN_VALUES_LENGTH] { +unconstrained pub fn call_public_function_internal(contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field) -> [Field; RETURN_VALUES_LENGTH] { call_public_function_oracle(contract_address, function_selector, args_hash) } diff --git a/yarn-project/aztec-nr/aztec/src/private_call_stack_item.nr b/yarn-project/aztec-nr/aztec/src/private_call_stack_item.nr deleted file mode 100644 index 73fedb091ff..00000000000 --- a/yarn-project/aztec-nr/aztec/src/private_call_stack_item.nr +++ /dev/null @@ -1,21 +0,0 @@ -use crate::abi::FunctionData; -use crate::abi::PrivateCircuitPublicInputs; -use dep::protocol_types::constants::GENERATOR_INDEX__CALL_STACK_ITEM; -use crate::hash::pedersen_hash; - -struct PrivateCallStackItem { - contract_address: Field, - function_data: FunctionData, - public_inputs: PrivateCircuitPublicInputs, - is_execution_request: bool, -} - -impl PrivateCallStackItem { - pub fn hash(self) -> Field { - pedersen_hash([ - self.contract_address, - self.function_data.hash(), - self.public_inputs.hash(), - ], GENERATOR_INDEX__CALL_STACK_ITEM) - } -} diff --git a/yarn-project/aztec-nr/aztec/src/public_call_stack_item.nr b/yarn-project/aztec-nr/aztec/src/public_call_stack_item.nr deleted file mode 100644 index 734d7ea7ee4..00000000000 --- a/yarn-project/aztec-nr/aztec/src/public_call_stack_item.nr +++ /dev/null @@ -1,35 +0,0 @@ -use crate::{ - abi, - hash::pedersen_hash, - abi::{ - PublicCircuitPublicInputs, - FunctionData, - }, -}; -use dep::protocol_types::constants::{ - RETURN_VALUES_LENGTH, - GENERATOR_INDEX__CALL_STACK_ITEM, -}; - -// oracles -use crate::oracle::{ - enqueue_public_function_call::enqueue_public_function_call_internal, -}; - -struct PublicCallStackItem { - contract_address: Field, - function_data: FunctionData, - public_inputs: PublicCircuitPublicInputs, - is_execution_request: bool, -} - -impl PublicCallStackItem { - pub fn hash(self) -> Field { - pedersen_hash([ - self.contract_address, - self.function_data.hash(), - self.public_inputs.hash(), - ], GENERATOR_INDEX__CALL_STACK_ITEM) - } -} - diff --git a/yarn-project/aztec-nr/aztec/src/selector.nr b/yarn-project/aztec-nr/aztec/src/selector.nr index 6b81188571d..d59a437b382 100644 --- a/yarn-project/aztec-nr/aztec/src/selector.nr +++ b/yarn-project/aztec-nr/aztec/src/selector.nr @@ -1,8 +1,10 @@ +use dep::protocol_types::abis::function_selector::FunctionSelector; + use crate::utils::field_from_bytes; global SELECTOR_SIZE = 4; -pub fn compute_selector(signature: str) -> Field { +pub fn compute_selector(signature: str) -> FunctionSelector { let bytes = signature.as_bytes(); let hash = dep::std::hash::keccak256(bytes, bytes.len() as u32); @@ -11,5 +13,5 @@ pub fn compute_selector(signature: str) -> Field { selector_be_bytes[i] = hash[i]; } - field_from_bytes(selector_be_bytes, true) + FunctionSelector::from_field(field_from_bytes(selector_be_bytes, true)) } diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr index 48537a552b9..350a4cda013 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/immutable_singleton.nr @@ -1,5 +1,9 @@ use dep::std::option::Option; -use dep::protocol_types::constants::EMPTY_NULLIFIED_COMMITMENT; +use dep::protocol_types::{ + address::AztecAddress, + constants::EMPTY_NULLIFIED_COMMITMENT, +}; + use crate::context::{PrivateContext, Context}; use crate::note::{ lifecycle::create_note, @@ -15,7 +19,7 @@ struct ImmutableSingleton { context: Option<&mut PrivateContext>, storage_slot: Field, note_interface: NoteInterface, - compute_initialization_nullifier: fn (Field, Option) -> Field, + compute_initialization_nullifier: fn (Field, Option) -> Field, } // docs:end:struct @@ -37,7 +41,7 @@ impl ImmutableSingleton { // docs:end:new // docs:start:is_initialized - unconstrained pub fn is_initialized(self, owner: Option) -> bool { + unconstrained pub fn is_initialized(self, owner: Option) -> bool { let compute_initialization_nullifier = self.compute_initialization_nullifier; let nullifier = compute_initialization_nullifier(self.storage_slot, owner); check_nullifier_exists(nullifier) @@ -48,7 +52,7 @@ impl ImmutableSingleton { pub fn initialize( self, note: &mut Note, - owner: Option, + owner: Option, broadcast: bool, ) { let context = self.context.unwrap(); diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/map.nr b/yarn-project/aztec-nr/aztec/src/state_vars/map.nr index c55fc32fa46..bca3872b9a9 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/map.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/map.nr @@ -1,6 +1,6 @@ use crate::context::{PrivateContext, PublicContext, Context}; use dep::std::option::Option; -use crate::hash::pedersen_hash; +use dep::protocol_types::hash::pedersen_hash; // docs:start:map struct Map { diff --git a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr index 99ad829f1f5..4007e27f770 100644 --- a/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr +++ b/yarn-project/aztec-nr/aztec/src/state_vars/singleton.nr @@ -1,5 +1,14 @@ use dep::std::option::Option; -use dep::protocol_types::constants::{EMPTY_NULLIFIED_COMMITMENT, GENERATOR_INDEX__INITIALIZATION_NULLIFIER}; + +use dep::protocol_types::{ + address::AztecAddress, + constants::{ + EMPTY_NULLIFIED_COMMITMENT, + GENERATOR_INDEX__INITIALIZATION_NULLIFIER, + }, + hash::pedersen_hash, +}; + use crate::context::{PrivateContext, PublicContext, Context}; use crate::note::{ lifecycle::{create_note, destroy_note}, @@ -11,9 +20,8 @@ use crate::oracle::{ get_secret_key::get_secret_key, notes::check_nullifier_exists, }; -use crate::hash::pedersen_hash; -pub fn compute_singleton_initialization_nullifier(storage_slot: Field, owner: Option) -> Field { +pub fn compute_singleton_initialization_nullifier(storage_slot: Field, owner: Option) -> Field { if owner.is_some() { let secret = get_secret_key(owner.unwrap_unchecked()); pedersen_hash([storage_slot, secret.low, secret.high], @@ -28,7 +36,7 @@ struct Singleton { context: Option<&mut PrivateContext>, storage_slot: Field, note_interface: NoteInterface, - compute_initialization_nullifier: fn (Field, Option) -> Field, + compute_initialization_nullifier: fn (Field, Option) -> Field, } // docs:end:struct @@ -50,7 +58,7 @@ impl Singleton { // docs:end:new // docs:start:is_initialized - unconstrained pub fn is_initialized(self, owner: Option) -> bool { + unconstrained pub fn is_initialized(self, owner: Option) -> bool { let compute_initialization_nullifier = self.compute_initialization_nullifier; let nullifier = compute_initialization_nullifier(self.storage_slot, owner); check_nullifier_exists(nullifier) @@ -61,7 +69,7 @@ impl Singleton { pub fn initialize( self, note: &mut Note, - owner: Option, + owner: Option, broadcast: bool, ) { let context = self.context.unwrap(); diff --git a/yarn-project/aztec-nr/aztec/src/types/address.nr b/yarn-project/aztec-nr/aztec/src/types/address.nr deleted file mode 100644 index c0654e55de0..00000000000 --- a/yarn-project/aztec-nr/aztec/src/types/address.nr +++ /dev/null @@ -1,53 +0,0 @@ -struct AztecAddress { - address: Field -} - -impl AztecAddress { - pub fn new(address: Field) -> Self { - Self { - address - } - } - - pub fn eq(self: Self, other: Self) -> bool { - self.address == other.address - } - - pub fn serialize(self: Self) -> [Field; 1] { - [self.address] - } - - pub fn deserialize(fields: [Field; 1]) -> Self { - Self { - address: fields[0] - } - } -} - -struct EthereumAddress { - address: Field -} - -impl EthereumAddress { - pub fn new(address: Field) -> Self { - // Check that it actually will fit. Spending a lot of constraints here :grimacing: - let bytes = address.to_be_bytes(32); - for i in 0..12 { - assert(bytes[i] == 0, "Value too large for an ethereum address"); - } - Self { - address - } - } - - - pub fn serialize(self: Self) -> [Field; 1] { - [self.address] - } - - pub fn deserialize(fields: [Field; 1]) -> Self { - Self { - address: fields[0] - } - } -} diff --git a/yarn-project/aztec-nr/aztec/src/types/type_serialization.nr b/yarn-project/aztec-nr/aztec/src/types/type_serialization.nr index b1bb9651ba6..0d15ed61441 100644 --- a/yarn-project/aztec-nr/aztec/src/types/type_serialization.nr +++ b/yarn-project/aztec-nr/aztec/src/types/type_serialization.nr @@ -1,7 +1,7 @@ mod bool_serialization; mod field_serialization; mod u32_serialization; -mod aztec_address_serialization; +mod address_serialization; /** * Before Noir supports traits, a way of specifying the serialization and deserialization methods for a type. diff --git a/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization.nr b/yarn-project/aztec-nr/aztec/src/types/type_serialization/address_serialization.nr similarity index 58% rename from yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization.nr rename to yarn-project/aztec-nr/aztec/src/types/type_serialization/address_serialization.nr index 2e53171542d..0441f5b9e2f 100644 --- a/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization.nr +++ b/yarn-project/aztec-nr/aztec/src/types/type_serialization/address_serialization.nr @@ -1,17 +1,22 @@ use crate::types::type_serialization::TypeSerializationInterface; -use crate::types::address::AztecAddress; +use dep::protocol_types::{ + address::{ + AztecAddress, + EthAddress + }, +}; global AZTEC_ADDRESS_SERIALIZED_LEN: Field = 1; fn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> AztecAddress { - AztecAddress::new(fields[0]) + AztecAddress::from_field(fields[0]) } fn serialize(value: AztecAddress) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] { - [value.address] + [value.to_field()] } -global AztecAddressSerializationMethods = TypeSerializationInterface { +global AddressSerializationMethods = TypeSerializationInterface { deserialize, serialize, -}; +}; \ No newline at end of file diff --git a/yarn-project/aztec-nr/easy-private-state/Nargo.toml b/yarn-project/aztec-nr/easy-private-state/Nargo.toml index b3229d288b2..7b193fdfb67 100644 --- a/yarn-project/aztec-nr/easy-private-state/Nargo.toml +++ b/yarn-project/aztec-nr/easy-private-state/Nargo.toml @@ -6,4 +6,5 @@ type = "lib" [dependencies] aztec = { path = "../aztec" } -value_note = { path = "../value-note" } \ No newline at end of file +value_note = { path = "../value-note" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file diff --git a/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr b/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr index d9e4bf7d88f..504686d1374 100644 --- a/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr +++ b/yarn-project/aztec-nr/easy-private-state/src/easy_private_state.nr @@ -1,3 +1,4 @@ +use dep::protocol_types::address::AztecAddress; use dep::aztec::{ context::Context, note::note_getter_options::NoteGetterOptions, @@ -33,7 +34,7 @@ impl EasyPrivateUint { } // Very similar to `value_note::utils::increment`. - pub fn add(self, addend: u120, owner: Field) { + pub fn add(self, addend: u120, owner: AztecAddress) { // Creates new note for the owner. let mut addend_note = ValueNote::new(addend as Field, owner); @@ -44,7 +45,7 @@ impl EasyPrivateUint { } // Very similar to `value_note::utils::decrement`. - pub fn sub(self, subtrahend: u120, owner: Field) { + pub fn sub(self, subtrahend: u120, owner: AztecAddress) { // docs:start:get_notes let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend as Field); let maybe_notes = self.set.get_notes(options); @@ -57,7 +58,7 @@ impl EasyPrivateUint { // Ensure the notes are actually owned by the owner (to prevent user from generating a valid proof while // spending someone else's notes). - assert(note.owner == owner); + assert(note.owner.eq(owner)); // Removes the note from the owner's set of notes. // docs:start:remove diff --git a/yarn-project/aztec-nr/value-note/src/utils.nr b/yarn-project/aztec-nr/value-note/src/utils.nr index 5751bba16f1..889f9a05489 100644 --- a/yarn-project/aztec-nr/value-note/src/utils.nr +++ b/yarn-project/aztec-nr/value-note/src/utils.nr @@ -7,6 +7,7 @@ use crate::{ filter::filter_notes_min_sum, value_note::{ValueNote, VALUE_NOTE_LEN}, }; +use dep::protocol_types::address::AztecAddress; // Sort the note values (0th field) in descending order. // Pick the fewest notes whose sum is equal to or greater than `amount`. @@ -16,7 +17,7 @@ pub fn create_note_getter_options_for_decreasing_balance(amount: Field) -> NoteG // Creates a new note for the recipient. // Inserts it to the recipient's set of notes. -pub fn increment(balance: Set, amount: Field, recipient: Field) { +pub fn increment(balance: Set, amount: Field, recipient: AztecAddress) { let mut note = ValueNote::new(amount, recipient); // Insert the new note to the owner's set of notes and emit the log if value is non-zero. balance.insert(&mut note, amount != 0); @@ -26,7 +27,7 @@ pub fn increment(balance: Set, amount: Field, recipie // Remove those notes. // If the value of the removed notes exceeds the requested `amount`, create a new note containing the excess value, so that exactly `amount` is removed. // Fail if the sum of the selected notes is less than the amount. -pub fn decrement(balance: Set, amount: Field, owner: Field) { +pub fn decrement(balance: Set, amount: Field, owner: AztecAddress) { let sum = decrement_by_at_most(balance, amount, owner); assert(sum == amount, "Balance too low"); } @@ -39,7 +40,7 @@ pub fn decrement(balance: Set, amount: Field, owner: // equal `amount`. // // It returns the decremented amount, which should be less than or equal to max_amount. -pub fn decrement_by_at_most(balance: Set, max_amount: Field, owner: Field) -> Field { +pub fn decrement_by_at_most(balance: Set, max_amount: Field, owner: AztecAddress) -> Field { let options = create_note_getter_options_for_decreasing_balance(max_amount); let opt_notes = balance.get_notes(options); @@ -63,10 +64,10 @@ pub fn decrement_by_at_most(balance: Set, max_amount: // Removes the note from the owner's set of notes. // Returns the value of the destroyed note. -pub fn destroy_note(balance: Set, owner: Field, note: ValueNote) -> Field { +pub fn destroy_note(balance: Set, owner: AztecAddress, note: ValueNote) -> Field { // Ensure the note is actually owned by the owner (to prevent user from generating a valid proof while // spending someone else's notes). - assert(note.owner == owner); + assert(note.owner.eq(owner)); balance.remove(note); diff --git a/yarn-project/aztec-nr/value-note/src/value_note.nr b/yarn-project/aztec-nr/value-note/src/value_note.nr index b5c74d079de..7e7e2db39d8 100644 --- a/yarn-project/aztec-nr/value-note/src/value_note.nr +++ b/yarn-project/aztec-nr/value-note/src/value_note.nr @@ -1,3 +1,4 @@ +use dep::protocol_types::address::AztecAddress; use dep::aztec::{ note::{ note_header::NoteHeader, @@ -19,14 +20,14 @@ global VALUE_NOTE_LEN: Field = 3; // 3 plus a header. // docs:start:value-note-def struct ValueNote { value: Field, - owner: Field, + owner: AztecAddress, randomness: Field, header: NoteHeader, } // docs:end:value-note-def impl ValueNote { - pub fn new(value: Field, owner: Field) -> Self { + pub fn new(value: Field, owner: AztecAddress) -> Self { let randomness = rand(); let header = NoteHeader::empty(); ValueNote { @@ -38,13 +39,13 @@ impl ValueNote { } pub fn serialize(self) -> [Field; VALUE_NOTE_LEN] { - [self.value, self.owner, self.randomness] + [self.value, self.owner.to_field(), self.randomness] } pub fn deserialize(serialized_note: [Field; VALUE_NOTE_LEN]) -> Self { ValueNote { value: serialized_note[0], - owner: serialized_note[1], + owner: AztecAddress::from_field(serialized_note[1]), randomness: serialized_note[2], header: NoteHeader::empty(), } diff --git a/yarn-project/aztec.js/src/account/defaults/default_entrypoint.ts b/yarn-project/aztec.js/src/account/defaults/default_entrypoint.ts index edff78a592f..240fb70c2ff 100644 --- a/yarn-project/aztec.js/src/account/defaults/default_entrypoint.ts +++ b/yarn-project/aztec.js/src/account/defaults/default_entrypoint.ts @@ -66,13 +66,33 @@ export class DefaultAccountEntrypoint implements EntrypointInterface { { name: 'function_selector', type: { - kind: 'field', + kind: 'struct', + path: 'aztec::protocol_types::abis::function_selector::FunctionSelector', + fields: [ + { + name: 'inner', + type: { + kind: 'integer', + sign: 'unsigned', + width: 32, + }, + }, + ], }, }, { name: 'target_address', type: { - kind: 'field', + kind: 'struct', + path: 'aztec::protocol_types::address::AztecAddress', + fields: [ + { + name: 'inner', + type: { + kind: 'field', + }, + }, + ], }, }, { diff --git a/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json b/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json index 061ae56ba1d..e07487ffe04 100644 --- a/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json +++ b/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json @@ -48,7 +48,7 @@ } } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -84,7 +84,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -116,13 +116,33 @@ { "name": "function_selector", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::abis::function_selector::FunctionSelector", + "fields": [ + { + "name": "inner", + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 32 + } + } + ] } }, { "name": "target_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { @@ -147,7 +167,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -164,7 +184,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -183,36 +203,74 @@ "returnTypes": [ { "kind": "struct", - "path": "aztec::abi::PublicCircuitPublicInputs", + "path": "aztec::protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs", "fields": [ { "name": "call_context", "type": { "kind": "struct", - "path": "aztec::abi::CallContext", + "path": "aztec::protocol_types::abis::call_context::CallContext", "fields": [ { "name": "msg_sender", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "storage_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "portal_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::EthAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "function_selector", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::abis::function_selector::FunctionSelector", + "fields": [ + { + "name": "inner", + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 32 + } + } + ] } }, { @@ -259,7 +317,7 @@ "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageUpdateRequest", + "path": "aztec::protocol_types::contrakt::storage_update_request::StorageUpdateRequest", "fields": [ { "name": "storage_slot", @@ -284,13 +342,13 @@ } }, { - "name": "contract_storage_read", + "name": "contract_storage_reads", "type": { "kind": "array", "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageRead", + "path": "aztec::protocol_types::contrakt::storage_read::StorageRead", "fields": [ { "name": "storage_slot", @@ -299,7 +357,7 @@ } }, { - "name": "value", + "name": "current_value", "type": { "kind": "field" } @@ -309,7 +367,7 @@ } }, { - "name": "public_call_stack", + "name": "public_call_stack_hashes", "type": { "kind": "array", "length": 4, @@ -368,7 +426,7 @@ "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::BlockHeader", + "path": "aztec::protocol_types::abis::block_header::BlockHeader", "fields": [ { "name": "note_hash_tree_root", @@ -418,13 +476,22 @@ { "name": "prover_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } } ] } ], - "bytecode": "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", + "bytecode": "H4sIAAAAAAAA/+3dB3jcxpUH8AVJUQJXpHovXIpUbyTVrE5JllWtahXLapRIFatQFqnmIndZLpJc4hq39O70nku95FIvycUpl1wSJ5fk4kt8ycW59HIz2HnRnxC84cRvzFnz4fueFhgAM7+ZAbDAAhCfTKVSQSo7FKrolbpwoPl15rP6xQ01AV9e1S6dBXniLMwTZ1GeODvlibM4T5yd88TZJU+cYZ44S/LEmc4TZ9c8cZbmibMsT5zd8sTZPU+cPfLE2TNPnL0YnQPA2dt89jGffc1nP/PZ33zSOgPN5yBTxyIzPVjFEBVDVZSbedQgGRUVKoapqFRRpWK4ihEqRqoYpWK0ijEqxqoYp2K8igkqJpp8alTUqpikYrKKKSqmqpim4iIV01XMUDFTxSwVs1XMUTHXtNs8FfNVLFBxsYqFKi5RsUjFYhVLVCxVsUzFchWXqlihYqWpS8bUZZWK1SrWqFir4jIV61SsV7FBxUYVl6vYpOIKFZtVbFGxVcU2FdtV1KvYoWKnigYVjSp2qditYo+KvSquVLFPxX4VB1QcVNEUa/NDKq5ScVhFs5nX3cxrUXFExVEVx1QcV3FCxdUqrlFxrYrrVJxUcb2KG1TcqOImFTfH8rpFxa0qTqm4TcVpFberuEPFnSruUnFGxVkV51TcreIeFfequM/kVWDyeoWK+2NpD6h40Iw/ZD4fNp+PmM9Xms9Hzedj5vNx8/mE+XxSxe/KsuP6HC5+ra3TaJsPII22/wJIo32hENJovyiCNNpHOkEa7S/FkEb7TmdIG2TGu0DaYBinzyFmvATShprxNKSVm/GukJYx46WQVmHGyyBtmBnvBmmVZrw7pFWZ8R6QNtyM9zSfVG891JnP6hc56DyZj6vV2k593gvqQ33eG9Koz/tAGvV5X0ijuveDNOrz/pBGfT4A0qjPB0Ia9fkgSKM+x22F+nwIpFGfD4U06vNySKM+z0Aa9XkFpFGfD4M06vNKSKO2rII0akvaVnTbLYD5NOA+iL+bURrNx32wEPKkNJqP+yDNx32Q5uM+iPPpk+bjPkjzcX+j+bhvUX/hfkTr9IQ06i/c7igf3Maov3B7orxx26H+wm2HysNth/oLtx0y4LZD2z5uO+TKQBpt+7jtkJW2HV2vYrDVmc/qFzfU4LGWhiA2XQfjVH4x1J/JMgmP522xDAHLUOZ2SUO7DIVyMszl4PdQW+qcAUsFs0XnOYw3z+i0thL8VFcqJw3ze0PdKpnrFkCZlC9NV4JlcMyJ3/WDPfBRWgZ8lQm+Kl5fbZBq3Y91MF0FPkqrAAvzNlUbxix6yLXPDAPLCFZLTTWe47XFMgIsw1kt2f13JG+e0XnkKOY8dR6joU2o/ciehvmjoL1GM7dXAGVSvjSNPrGKVaxiFatYxSpWsXZsK17n4G92tFylBz5KGw4W7msD/I2L8ta/Iz4FZfL+RlFTjdfJ9HsMGaisQljmC6XnXe8yaSWpC6+tw9T5a2rsv3JWf7b/qBzKl6bLwUd1ycTqym2piFlevuXW7uT/nbCmWv8urX/rpu1paKweSb/9UpreJj8O9fXlt1387bMAfMy/99b8o7/34u90heDj3le1b6iFrxx8tB7eV+H+vRaPWW3xVYCP1usEPu7fNPG307b4kn7nLIZP7t/LbH+7Gw4+Wq8z+Ji/XyPfCAsfnivRel3Ax30uon2jLHx4fkLrheAb68A3xsI3Fny0Xgn4xjvwjbPwjQffOBgn30QHvgkWvolgovW6gq/Gga861XZfDfhovVLwTXLgq7XwTQIfrVcGvikOfJMtfFPAR+t1A980B76pFr5p4KP1uoNvugPfRRa+6eCj9XqAb6YD3wwL30zw0Xr4jNJsB75ZFr7Z4KP1eoFvrgPfHAvfXPDRen3BN4/XF90HrbPwzQPLxbyWydoy38JyMVgW8Fqi+6ALefOM7oNewpynzmMRtAm1H9nTMP8SaK9FzO0VQJmUL02jT6wd24rvJZEzTF24r7Wnj9IWOLSEMYsech3rknzYl0t4fdH3wmIL3xKwLGe1TIp+I15qYVkOlmWsluz3wqW8eUbH8BXgp7pSOWmYj32+grluAZRJ+dI0+sQqVrGKVaxiFatYxSpWsYpVrGIVq1jFKlaxilWsYhWrWMUqVrGKVaxiFSu/VVsWx5whLLfYAx+lLXNoCWMWPeR6TiTJh325itcXPVOz0sK3CixrWS210TM1qy0sa8GyhtWSfabmMt48o2dq1oGf6krlpGE+9vk65roFUCblS9PoE6tYxSpWsYpVrGIVq1jFKlaxilWsYhWrWMUq1nyxasvKmDOE5VZ64KO0NQ4tYcyih1y/syf5sC838PqiexLrLXwbwLKJ1xL9/w8bLSybwHI5ryW6J3EFb57RPYnN4Ke6UjlpmI99vpm5bgGUSfnSNPrE2rGt2rI+5gxhufUe+CjtcoeWMGbRQ67jUpIP+3Irry86hm+x8G0FSz2rJfu3TLZZWOrBsp3Vkj2G7+DNMzqG7wQ/1ZXKScN87POdzHULoEzKl6bRJ1axilWsYhWrWMUq1o5t1ZYtMWcIy23xwEdp2x1awphFD7muU5J82JeNvL7omq7BwtcIlj2sluw13S4Lyx6w7Ga1ZK/p9vLmGV3TXQl+qiuVk4b52OdXMtctgDIpX5pGn1jFKlaxilWsYhWrWDu2VVsaYs4QlmvwwEdpux1awphFD7muU5J82Jf7eX3RNd0+C99+sDQ5sBywsDSB5SCvJbqmO8SbZ3RNdxX4qa5UThrmY59fxVy3AMqkfGkaffli1ZZ9MWcIy+3zwEdpBx1awphFD7n2nyQf9mUzry/avw9b+JrBctSBpcXCchQsR3gt0bHmGG+e0bHmOPiprlROGuZjnx9nrlsAZVK+NI2+fLFqy+GYM4TlDnvgo7QjDi1hzKKHXPtPkg/78moHvhMWvqvBdyLBd60D3zUWvmvBR+uF4DvpwHedhe8k+Gi9EvDd4MB3vYXvBvBdD+Pku8mB70YL301govXwb4ze4sB3s4XvFvDReqXgO+XAd6uF7xT4aL0y8J124LvNwncafLQe/o3ROxz4brfw3QE+Wg+Pf3c58N1p4bsLfHcm+M468J2x8J0F35kE390OfOcsfHeD71yC714HvnssfPeC5T5eS3UaLPdBOfc7qPMrUm2v8/1gecBBncnyAJTzkIM6P5hqe52p/DSsh75HHPgetvA9Ar6HE3yPOvC90sL3KPhoPdyPH3fge8zC9zj4HkvwPenA94SF70nwPZHge7UD36ssfK8G36sSfK914HuNhe+14HtNgu/1Dnyvs/C9HnyvS/C90YHvDRa+N4LvDQm+NzvwvcnC92bwvSnB91YHvrdY+N4Kvrck+J5y4Hubhe8p8L0twfcOB763W/jeAb63J/je5cD3Tgvfu8D3zgTfexz43m3hew/43p3ge58D33stfO8D33sTfB9w4Hu/he8D4Ht/gu9DDnwftPB9CHwfTPB9hNcX3Yf4sIXvI2D5GK8letf9nywsHwPLR3kt0T2Rj/PmGd0T+QT4qa5UThrmY59/grluAZRJ+dI0+sTasa3a8uGYM4TlPuyBj9I+6tASxix6yHVcSvJhX36K1xcdwz9p4fsUWD7Dasn+H+r/bGH5DFg+zWrJHsP/hTfP6Bj+WfBTXamcNMzHPv8sc90CKJPypWn0iVWsYhWrWMUqVrGKVaxiFatYxSpWsYpVrGIVa75YteWTMWcIy33SAx+lfdqhJYxZ9JDrd/YkH/bl53l90T2Jz1n4Pg+WL7FasvckvmBh+RJYvshqyd6T+FfePKN7El8GP9WVyknDfOzzLzPXLYAyKV+aRp9YxSpWsYpVrGIVq1jFKlaxilWsYhWrWMUqVrHmi1VbPhdzhrDc5zzwUdoXHVrCmEUPuX5nT/JhX36V1xfdk/iKhe+rYHma1ZL9+xH/ZmF5GixfY7Vk70l8nTfP6J7EN8BPdaVy0jAf+/wbzHULoEzKl6bRJ1axilWsYhWrWMUq1o5t1ZavxJwhLPcVD3yU9jWHljBm0UOu65QkH/blt3h90TXdNy183wLLd1gt2Wu6f7ewfAcs32a1ZK/p/oM3z+ia7rvgp7pSOWmYj33+Xea6BVAm5UvT6BOrWMUqVrGKVaxiFWvHtmrLN2POEJb7pgc+Svu2Q0sYs+gh13VKkg/78vu8vuia7nsWvu+D5Yesluw13TMWlh+C5Qesluw13X/y5hld0/0I/M+YTyonDfOxz3/EXLcAyqR8aRp9YhWrWMUqVrGKVaxi7dhWbflezBnCct/zwEdpP3BoCWMWPeS6TknyYV/+hNcXXdP92ML3E7A8y2uJ/s7Af1lYngXLT3kt0TXdf/PmGV3T/Qz8VFcqJw3zsc9/xly3AMqkfGkafWLt2FZt+XHMGcJyP/bAR2k/dWgJYxY95DouJfmwL5/j9UXH8J9b+J4Dyy95LdEx/H8sLL8Eyy94LdEx/H9584yO4b8CP9WVyknDfOzzXzHXLYAyKV+aRp9YO7ZVW34ec4aw3M898FHaLxxawphFD7mOS0k+7Mtf8/qiY/jzFr5fg+W3Diz/Z2H5LVh+w2uJjuG/480zOob/HvxUVyonDfOxz3/PXLcAyqR8aRp9+WLVludjzhCWe94DH6X9xqEljFn0kGv/SfJhX/7Rge8PFr4/gu8PCb4/O/D9ycL3Z/D9KcH3Vwe+v1j4/gq+vyT4goDfFwfl8lH5aVgQfYUOfAUWvkLwFST4OjnwFVn4OoGvKMHX2YGv2MLXGXzFCb7Qga+LhS8EX5cEX9qBr8TClwZfSYKv1IGvq4WvFHxdE3zdHPjKLHzdwEfr3Qe+Hg583S18PcBH6z0Avl4OfD0tfL3A1zPB18eBr7eFrw/4eif4+jnw9bXw9QNf34T9Y4ADX38L3wDw9U/wDXLgG2jhGwS+gQm+IQ58gy18Q8A3OMFX7sA31MJXDr6hCb4KB76Mha8CfJkEX6UD3zALXyX4hiX4hjvwVVn4hoOvKsE30oFvhIVvJPhGJPhGO/CNsvCNBt+oBN9YB74xFr6x4BuT4BvvwDfOwjcefOMSfBMd+CZY+CaCb0KCr8aBr9rCVwO+6gTfJAe+WgvfJPDVJvimOPBNtvBNAd/kBN80Xl/0+/RUCx+Vry0zeC3R/c6LLCwzwDKdud90njN584x+K58FFaK6zoQ+n5XQ57OY6xZAmZQvTaNPrB3bqi10bCBnCMtNDdrfR2nTHVrCmEUPuY5LST7syzkOjuGzLXxzoK3msVqyf4dqroVlHljqHBzD5zs4hi+AClFd50OfL0jo8wUO9o/5sf2DptEnVrGKVaxiFatYxSpWsYpVrGIVq1jFKlaxilWs+WLVFvqtm5whLEfz2tP3t9+cHVrCmEUPsclWv7Mn+bAvF/L6onsSF1v4FkJbLWa1ZO9JXGJhWQyWRcz9pvNcwptndE9iKVSI6roE+nxpQp8vdbB/LIntHzSNPrGKVaxiFatYxSpWsYpVrGIVq1jFKlaxilWsYs0Xq7bQb93kDGE5mteePkpb5NASxix6iE22+p09yYd9uZzXF92TWGbhWw5ttZLVkv2bO5daWFaCZQVzv+k8V/HmGd2TWA0Vorqugj5fndDnqx3sH6ti+wdNo0+sYhWrWMUqVrGKVawd26otdK1AzhCWo3nt6aO0FQ4tYcyih9hkq+uUJB/25VpeX3RNt8bCtxbaaj2rJXtNd5mFZT1Y1jH3m85zA2+e0TXdRqgQ1XUD9PnGhD7f6GD/2BDbP2gafWIVq1jFKlaxilWsYu3YVm2hawVyhrAczWtPH6Wtc2gJYxY9xCZbXack+bAvN/H6omu6yy18m6CttrBastd0V1hYtoBlM3O/6Ty38uYZXdNtgwpRXbdCn29L6PNtDvaPrbH9g6bRJ1axilWsYhWrWMUq1o5t1Ra6ViBnCMvRvPb0Udpmh5YwZtFDbLLVdUqSD/uyntcXXdNtt/DVQ1s18FqivzOww8LSAJadzP2m82zkzTO6ptsFFaK6NkKf70ro810O9o/G2P5B0+gTa8e2agsdG3bAMZyW2x60v4/Sdjq0hDGLHnIdl5J82Jd7HBzDd1v49kBb7XNwDN9rYdkHlisdHMP3OziGH4AKUV33Q58fSOjzAw72j/2x/YOm0SfWjm3VFjo27IVjOC23O2h/H6Vd6dASxix6yHVcSvJhXzY5OIYftPA1QVsddmA5ZGE5DJarHBzDmx0cw1ugQlTXZujzloQ+b3GwfzTH9g+aRl++WLWFtuFDcKyh5Q4G7e+jtKscWsKYRQ+59p8kH/blUQe+Ixa+o+A7kuA77sB3zMJ3HHzHEnxXO/CdsPBdDb4TCb5rHfiusfBdC75rEnwnHfius/CdBN91Cb4bHPiut/DdAL7rE3w3OfDdaOG7CXw3JvhudXD+cLOF71Y4Ft/i4PzhFG+e1TrP25jbTOdxGhqJ2u8U9B3Nvw3a67SD79FTse9RmkZfW629U+1rdVBubVeVRxeoN+V/X6p1O+jhdjNeBOm4793poE3uMHkGJqiM26FN7nJQLpXTyZRLDiqrEJZ5Osx+lqay2wsNBY7bBoc6GL8Ttl0a+npk6eORZaFHlm4eWbp6ZAk9shR7ZCn0yHIq8MdS6lG7lHhk6eyRpcgjSz+PLAM8svT3yFLnkaW3R5YyjyxpjyxdPLJ08sgStLMlTF34+0kI80/BcgWxdXU7Pld2fv5Zk14A+ZyD67N43mch7zNm/Fxw4brYRmcdtBGWUwfTVFYJGM4F7W/p5JGli0eWtEeWMo8svT2y1Hlk6e+RZYBHln4eWYo8snT2yFLikaXUI8upwB9LoUftUuyRJfTI0tUjSzePLAs9svTxyNLXI0vBS2ShazPK90zM0p7l3s1bbvT83j1QLl2r3g3tTuXfA457mR1BzBFAuVRWISxzjTkh0OdLx0vOuy5O8br0sZvODylvXeZJB2U2XjS1fsfkXbvaUuZ83npm/5ZxqvUQxKbrYJzK15YFvJboOZN5vHlGz5nMZW4zncccaBNqP7KnYf5caK85zO0VQJmUL02jr63W3u1sddX/s3nz/NuzK9SWs2NtivWZyVwfnccsk1cRlDUTypzuoO9mmLwCE1TGLCj3IgflUjn0PAw5qKxCWOZBc5zM9TyMi7bBoQ7GqawXeh6mvS19PLIs9MjS0yNLN48sXT2yhB5Zij2yFHpkmeORpZdHlu4eWUo9spR4ZOnskaXII0s/jywDPLL098hS55Glh0eWMo8saY8sXTyydPLIErSz5YWeWaL5cyCtILZu/JmlqSa9ANaZYsYLE/KeCmnTzPiUhHWxjabG6lL94oaojbCcOpimsvCZpSkeWDp5ZOnikSXtkaXMI0sPjyx1Hln6e2QZ4JGln0eWIo8snT2ylHhkKfXI0t0jSy+PLHM8shR6ZCn2yBJ6ZOnqkaWbR5aeHlkWemTp45Glr0eWgpfIQtfPlO+0mKU9y53MW270fMIkKJd+T5gM7U7lTwJHLbMjiDkCKJfKKoRlVpkLVH1Oe2n6vMvFc2V0bYPPeK11UCY+V/b3ypzPW8/JL/fnynQec8Gf9FwVzcd7A8zPouV8rmquu3Kj+r8cn4ETa9utaSiPnGHqwn2tPX2UtgAszMeCGl0One/Ng3Jm8ZYTHVNx29BDrmMqPpvH/AxkjatnG2eAP/5sYxrm4zF1BnPdAiiT8qVp9LXVOlesL0sr/33BSdH5IZarh7bcK3TRBg6e6Y32cbwuobpSOWmYj/07jbluAZRJ+dI0+sQqVrGKVaxiFatYxSpWsYpVrGIVq1jFKlaxilWsYhWrWMUqVrGKVaxiFSu/lf9Z6dromQssVw+5nrmY6rANdJ5TePOMnrmYDH6qK5WThvnYv8zPhrd6Lp/ypWn0iVWsYhWrWMUqVrGKVaxiFatYxSpWsYpVrGIVa75YdbmTeMudHMbK1UOu36wnOWwDF/9/h86jBvxUVyonDfOxf2uY6xZAmZQvTaNPrB3bqsutZi23JrovheXqIdc+Xu2wDXSeE3nzjLgTwE91pXLSMB/7dwJz3QIok/KlafSJVaxiFatYxSpWsYq1Y1t1ueNZy82e82O5esh1zj/eYRvoPMfx5hmd848FP9WVyknDfOzfscx1C6BMypem0SdWsYpVrGIVq1jFKtaObdXljuEttzaMlauHXOf8Yxy2gc5zNG+e0Tn/KPBTXamcNMzH/h3FXLcAyqR8aRp9+WLV5Y7kLTfaFrFcPeTaFkc6bAOd5wjePKNtcTj4qa5UThrmY/8OZ65bAGVSvjSNvnyxhpBWAGk0H//GaJUZL4K0SjPeCdIugTpR2iIz3hnSFpvxLpC2xIz3hbSlZhz/buoyMz4b0pab8ZmQdqkZnwFpK8z4RZC20oxPg7RVZnwKpK0245MhbY0Zr4W0tWa8BtIuM+MTIW2dGZ8AaevN+DhI22DGx0LaRjM+GtIuN+OjIG2TGZ8LaVfAOH1uNuMlkLbFjKchbasZ7wpp28x4KaRtN+NlkFZvxrtB2o4EH22LIyCNtkXcdmlbrII02hYrIY22xUsgjbbFRZBG2+JiSKM2WgJp1EZLIY3aaBmkURsthzRqo0shjdpoBaRRG62ENPpbfKsgjf4W6WpIo7+ptQbS6G/nrYW03mb8MkjrY8bXQRrtj+shrZ8Z3wBp/c34Rkijv8N5OaQNNOObIG2QGcdtc7AZ3wxpQ8z4Fkgbasa3Qlq5Gd8GaRkzvh3SKsx4PaQNM+O0beptpRiWrTOf1S9uqMGyaMj1vU3lF0NdmCzVabBkoJyhrOXURn/jifqmwJRF29xQKHcIT7k1NKLLHQz5V4CDyiqEZb5hdtRSs/xg1nbIfj8PifUneQaDh5b5tvHoY951Za3XY3TV4j5BQ65tMgN1YOozolTjftwWC7Yn73abPa9l3gaqdZ6DmPPUeQyENolvU2mYPwjaayBze+H+RvnSNPrEKlaxilWsYhWrWMUqVrGKVaxiFatYxSpWsYo1X6zaUhFz4r2sCg98lIb3W7h/28Z7f5S3vnexD+5dlLOWmb23lIE6ZcBAZRXCMq8rO+9qMuMlMJ/6Cu8xYv/x3u/I9h+VQ/nSNJVVAnXB/uO+34H36Sjfl2+5tTv594Haan3/Xz9TkDH5xfc76lO890ppeJ9P9zltd/hcQ3ksrb36A/eZckij8WHg423jGhf30KLHdgZCP2TMOJVTCPNPwzHkjrLzfRM/Xuj5DyfMpyHXfU28b838nFg1PidWbPIdnlAu8zOLrZ5PC0xQGZReCOMP0UMysJweqH3JrLe7qoTlcHxobJ00zK9yXGd8NrAOpqksvZ2cgW3qYfi+5P6+wfpiu/SBdqH55dAu3Pubbhc8v8uAYRBYKmNOPK/CY2CVA98LnVdVgY/ShoCP6oHHk6fA6vIcKP58DfYh0/dEq+dr8PmLCnBQWfg8y1vMdq0fa4mf92Rg3QGQ50vxTFD8uxmfCXoHmB2cMyc+E0SepGeC3gPHiWf/zvnrkFiaaz/lOyTmx/OCIS+R5YXa0tU1GB2z9LOo6KCyCmGZj8W2Ke7nwPHZbRpynWsMh7YZwWxx8J16wXsq8e9+fPejN9TNxbsfI2NtStPoG5lgxfPoQbHl+N/tqa128D5UdC4x1uSlj0e0j1M5hTD/y3Dc+iqcE1OdM5DPMwnzaci1HY+G9uP9/x6y3xv4/0nUQRlYLvP/vVaD5dI5c/z/tyiE8e/DOTP+/xQZ80lmvd2NS1gOx0fG1kmnLnznz1Wdx4OjDqapLL2dPA3b1DNwzsy9n2N9sV0GQLvQfDx3rYgtr7dn2h/wO5l7vwxSrd/TrIPpMeCjtFHQps86+60u68qAK5O68Lc6/A0xAy78DbGQ2VWcOv++CFee+K4KDbmOXcXw2YnZon+PondVmluaDtfvblzTWN8QAKsoRiwAGo7j62H0Og2+Hkav0+DrYbQ+vgpG+XSBefHmYat/L6hcgSm8yCCLTeFdUuff89FtpX/H0+dnerPT7+Xo93D0ezf6PZteYDxjPvV5hr7m0u/N6Pdk9HsxejvW53/6mKDPP/U5of7e19t6JpU9BujfyfR1rD4v0Odh+vxLHy/0Pqm/V/T+qvdTfXzRx0B9nNfHQH0SpA9M+h00/X8G6/fT9Htr+m/e6Xfa9Ltu01PZ9+BmqpiVyr47p9+pm2vadp6K+SoWqLhYxcJU9n0p/X6Ufh9qSSr7vtOyVPZ9Jv3+kn5fSb+fpN9H0u8f6feN9PtF+n0i/f6Qfl9Ivx+k3wfS7/9sSmXf79mcyr6/o9/X2ZbKvo9Tn8q+b7NTRYOKRhW7VOxWsUfFXhVXqtinYr+KAyoOqmhScUjFVSoOq2hW0aLiiIqjKo6pOK7ihIqrVVyj4loV16k4qeJ6FTeouFHFTSpuVnGLiltVnFJxm4rTKm5XcYeKO1Xclcr29VkV51TcreIeFfequE/FK1Tcr+IBFQ+qeEjFwyoeUfFKFY+qeEzF4yqeUPFk6vw+jxv+18zLZ7PM9Nrs/ppp3t/UkqnOHFT/1u/f33SssWFCBuc1Zw4caW7JNLfUH27J7DrcdCBTMwHzfaDETb5fN++o0PdZfUtL44FDLZmWJrXi/pa9h/afyBzb27In03S08fAuVQCu/OayF7Hy283Kgy9cub6h4YXX+6hZj/biJQcbGo9nmo60ZJp2ZXY0HTnY0Pz/jfGPJsWVAgA=", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -450,36 +517,74 @@ "returnTypes": [ { "kind": "struct", - "path": "aztec::abi::PublicCircuitPublicInputs", + "path": "aztec::protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs", "fields": [ { "name": "call_context", "type": { "kind": "struct", - "path": "aztec::abi::CallContext", + "path": "aztec::protocol_types::abis::call_context::CallContext", "fields": [ { "name": "msg_sender", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "storage_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "portal_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::EthAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "function_selector", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::abis::function_selector::FunctionSelector", + "fields": [ + { + "name": "inner", + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 32 + } + } + ] } }, { @@ -526,7 +631,7 @@ "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageUpdateRequest", + "path": "aztec::protocol_types::contrakt::storage_update_request::StorageUpdateRequest", "fields": [ { "name": "storage_slot", @@ -551,13 +656,13 @@ } }, { - "name": "contract_storage_read", + "name": "contract_storage_reads", "type": { "kind": "array", "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageRead", + "path": "aztec::protocol_types::contrakt::storage_read::StorageRead", "fields": [ { "name": "storage_slot", @@ -566,7 +671,7 @@ } }, { - "name": "value", + "name": "current_value", "type": { "kind": "field" } @@ -576,7 +681,7 @@ } }, { - "name": "public_call_stack", + "name": "public_call_stack_hashes", "type": { "kind": "array", "length": 4, @@ -635,7 +740,7 @@ "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::BlockHeader", + "path": "aztec::protocol_types::abis::block_header::BlockHeader", "fields": [ { "name": "note_hash_tree_root", @@ -685,13 +790,22 @@ { "name": "prover_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } } ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } ], diff --git a/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json b/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json index 8a0d04a998d..116928067b9 100644 --- a/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json +++ b/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json @@ -48,7 +48,7 @@ } } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -72,7 +72,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -104,13 +104,33 @@ { "name": "function_selector", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::abis::function_selector::FunctionSelector", + "fields": [ + { + "name": "inner", + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 32 + } + } + ] } }, { "name": "target_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { @@ -135,7 +155,7 @@ } ], "returnTypes": [], - "bytecode": "H4sIAAAAAAAA/+19B5gUxfN23+1Fcs45Z3fujgsKemRQkgQBUeEiIkmSgIqYc8CAOWEGA+asoKiYc46YE+ac8Ks+qqWYW/Huv1Xz6/5m53ne592dne2pqq7qeWe2d6ZFDaWWZah/liTkQuRofIuXCm2kxmg3O5qbk1OWl1XmZXtF0ayC4vy+0Zy+xbn5Xr7XN79vaVZ+dnZZfk5+XkFxQV60wMvJLvPK+xZkl2PDqXw2RiX8ToM20gT8TrPc73RoI13A73TL/W4BbbQQ8LuF5X63gTbaCPjdxnK/O0AbHQT87mC5312gjS4Cfndh9tss3HZ2Y7RT26bHtXbYXlPAVkAz5ObILZBbIrdCbo3cBrktcjvk9sgdkDsid0LujNwFuStyt/8R9wJ0xz7TcamHcelugV09iF31LesvvX1PQARApFylpRA5Gt/iybWdmyPYdl/BtnMF284TbDtfsO0CwbaL0kmbvZB7I/dB3sXsC9kkbhZgU2Tb60xVuWYyEXpJIutq4Otksq4mvo6QdbXwdQpZVxtfp5J1dfB1GllXF1+n+z7TSyFyNM4l1nlJNM4lk8Qlg/hD42LYxKUGWWfiUpOsM77XIutMXGqTdWZ/dcg6sz8TT91+S/K5WWhfmphQm83nKTF8So3hU1oMn9Jj+ERt1utMLAqRo3EuaSRGXG3SfDdLku99IXldm8SkFq8tFefXdXjbrIhZPYGY1VFVj1k9ErO6AjGrz9tmRcwaCsSsvqp6zBqSmDUQiFkj3jYrYtZEIGaNVNVj1oTErLFAzJrythkVaLPCzmYCdrbkbTNf921zVfW+bUn6toVAzFrxtlkRs9bMbeo22pCYmPgZ22uSz1uTeLVhjlcS2adp17xvI7ffCv/b/of/bWPY0TZA/6l9CVsTtiZs/d/a2vp/bKvebzvW/Xp5mb796mVnx852gjHQbbbnbbNinO9A7De+mv3UJJ/TXOzA7FsS2adp17yn9iVsTdiasDVha8LWhK0JWxO2JmxN2JqwNWFrwtaEra7YSn8DTSa2MJ/bV9iifLaoGHExS6ZFtqRZZEvEIlvSLbIlxSJbMiyyJdUiW5L+x7bQeTGKrDOfJ5N1Znyk82c64ms6f6YTvqbzZzoTP826Lviazp/piq/pHKNu5LXh7viazjHqga/pHKOe+JrOMTLzyeh8IjO3rC5ZZ+aZ1SfrzJyzBmSdmX/WiKwzc9Eak3VZ+LopWZeNr5uRdWaSZHOyzkxubEHWmUmJrcg6M5mwLVln+pD2uenDDmSd6cOOZJ3pw05knenDzmSd6cMuZJ3pw65knelD2qemD7uTdaYPe5B1pg97knVmDlIvss70a2+yzvRrH7LOzMXZhawzfR0l60xfe2SdmZOSRdaZ/s8m60z/55B1Zm5GX7LO5EQuWWdywvSp7ouxSds/N9+nNWr2Q2s0L8b+cmPYZV7TMcl8pxA5Gt9SMSbR/RSS92ZfNYgNORbYkmqRLRkW2ZJikS3pFtkSsciWNItsybTIluQYtmTz2lJxCDHHB72YcTib2GFsyiJ2eMwxqWgjhh0escPsP0rs2IXXjopd9Ilhxy7EDrP/PsSO3rx2VIS/Vww7ehM7zP57ETt68tpRkXo9YtjRk9hh9t+D2NGd146KFOwWww6qsc3+uxE7uvLaUSFJusSwoyuxw+y/C7GjM68dFbvtFMOOzsQOs/9OxI6OvHZUjGX0XEq/N+OF2VeEbDMARZPWxPQ8jGpUo/epvjXnBVQbmz8OUV1t/vBDNfmu+Jrq+d3wNT0XMOMtPY/Y2TkIPVcx+iufrDPHtQKyzmiAXck6o5eMTen4XeY5rll6X2Zerll2dv5N52eZ79FzRTNXi871lZi72tpnn3nfhthn1tE55czzeStsqeWzxbxvLbzfOr791glov/V8+60X0H4b+PbbIKD9NvPtt5lvv/923V3CFuWzRe3EluYW2dLIIlvqWmRLPYtsqWGRLekW2ZJikS0tLbKlqUW2NLPIloYW2VLbIlvqWGRLpkW2pFlkS8QiW1pYZEtji2yRPp+pji31LbKlgUW21LTIlloW2ZJhkS2pFtmS9D+25d/mU5jP6W+15hoLncPQ1ueTXtcOX9M5DOb6GL1PirmORuc1mOuEdF6DuQZXj6wz1zbpXAdz/Y7OdTDXYhuSdebaH53/YK4d07kO5rohnetg4kHjZ46dbcg6c+5A5zWYvGtH1hkNQK8fmnMgep3R1A+d62C0DL1GafqGznUwfUOvb5q+oXMdTN/Qa6Omb+hcB9M3Jj7ar5vJ/YvM92numP3Q3/l7xNhf9xh2mde0Vsx3CpGj8S0VtUL3U0jem33R3/m7WmBLqkW2ZFhkSy2LbKlpkS0NLLKlvkW2NLHIlsYW2dLCIlsiFtmSZpEtmRbZUsciW2pbZEtDi2xpZpEtTS2ypaVFtqRYZEu6RbbUsMiWehbZUtciWxpZZEtzi2xJDsgWc/5s2u3us0XvtwvvfiumZnUm+zXn9V2I/2b/9H81nZjtSPLZ0Y7sV3Lem26jQwz/OxL/zf47EDs6MNuh/W9C7Cgk7+m1JFMXpn/08aZv8na7mOdJVthF82+FqlybEbLNoOTtdhUkb4+hmYNG75vcxrdOty9xr7A2vria92Zf2j7/XDRqH/3Pk//+ZvS6Iv1uxLePdCXSP1HaP3pppyr3Dx3n0tSOtWVqLkK2GU768OjI9u8x277DXOBkFXvMZ673iumppnYUaZ/GsD15HWs87ODbzsSU0U7Pb4fZfzuyrk0MO9sTO2PdN5D73qj++kpSlWvE/9r40pHYxTxHdqfH01Zkv8zz7LOqe4/AnsSWPry2ZNP/n1bFFsH/QXgC//GouNdvlLlN3QZ9KImJn7G9Jvmc/n+F+380SWSfpl3zntqXsJXfVm1LK5+d9P/YrSywz6yj/ztu4YufPn4vlNOG2bG0of+6M9WGx0e227WEaMNuvrjS34NprCX+80K1QKGqfGyqQXyh/wNiPg/b4VzUtGvTfpljX5GiVN90ixF3s39pndU2hh3tiB1m//Tewsw6qkKX9oxhR2tih9k/1Qy9mOOR6bNDLzvTDPQ/i8z6xaP3yqiKLVS/MOsCj47/VbGFHsOyBGzxqmEL/b9vjoAt2dWwhf4HOlfAlr7VsCWX2JIvYEteNWwx+9fHdlN/Xcg6UwftyTqTj3Qel8mLTmSd6Z8OZJ3/fh41ib10rpj5zyO9brObb52OXz+fT9H4lorjktmPade870fsM/+/3E3OlnzaPr1O0Y/ssz+z/2mkLS4/dJsDmO3UbQzEtlJIf5j9RMjnt5LrSrfja51Pu+PnBaSdjTE+N8vO6qiQ9MlgXl8rrnUMIe0XxtiHXj+Ud78e3W8SwuzDrI+Q1w+boibb6cXE19is62dQjO3o691936lJPh8k7PNgYkcheW/2pfPkLpJTG8m5zh7M9lB/aVx2I3Exn/cn2w0kr8227UjcBvHamS+Q9xW+DyExN7E1+6G59zTpj2dJDQ/wxU1//k6Mz82ysxqneTeM19eKGh9O2i8k+6D7HcG7X4/u19S42YdZHyGv3yY1PmL7y3/ia2zWNT40xnb09QDfd2qSz4cK+zyM2FFI3pt96Tx5geTUO6TGC5ntof7SuAwkcTGf0+sGQ8hrs207EjfmsTFfIO8rfB9OYm7aNfuhufcJ6Y/PSA0P9sVNf/5LjM/NsrMap3m3J6+vFTW+F2m/kOyD7nck7349ul9T42YfZn2EvP6Z1PjI7S//ia+xWdf4iBjb0deDfd+pST4fIezznsSOQvLe7EvnyZckp34hNc58fPSovzQuQ0hczOf0+tRw8tps247EjXlszBfI+wrf9yIxN7E1+6G5p8i12mTy/5Bhvrjpz+vH+NwsO6txmnejeH2tqPHRpP1Csg+63zG8+/Xofk2Nm32MJqE1r+uZiQJkO72Y+BqbdY2PjLEdfT3M952a5PORwj6PInYUkvdmXzpPUklO1SfzCrjPHai/NC7DSVzM5/Ta717ktdm2HYkb89iYL5D3Fb6PJjE3sTX7obnXgvRHK1LDe/ripj/vGeNzs+ysxmnejeX1taLG9ybtF5J90P2O492vR/dratzsw6yPkNc9SI2P2/7yn/gam3WNj4mxHX29p+87NcnnY4R9HkvsKCTvzb50nrQlOdWT1Dj3uQP1l8ZlLxIX83knst1o8tps247EjXlszBfI+wrf9yYxN7E1+6G5l0P6I5fU8Chf3PTnQ2J8bpad1TjNu/G8vlbU+ATSfiHZB93vRN79enS/psbNPsz6CHk9mNT4xO0v/4mvsVnX+LgY29HXo3zfqUk+Hyfs83hiRyF5b/ZVMa+T5NQQUuPc5w7UXxqX0SQu5vMOZLu9yWuzbTsSN+axMV8g7yt8n0BibmJr9kNzbzTpj7Gkhsf64qY/nxbjc7PsrMZp3u3D62tFjU8i7ReSfdD9Tubdr0f3a2rc7MOsj5DXB5Aan7z95T/xNTbrGp8YYzv6eqzvOzXJ5xOFfd6H2FFI3pt96TwZT3JqGqlx7nMH6i+Ny94kLuZzcjnkn9yn27YjcWMeG/MF8r7C90kk5ia2Zj809w4k/XEQqeHxvrjpz5fF+NwsO6txmndTeH2tqPF9SfuFZB90v1N59+vR/ZoaN/sw6yPk9VJS41O3v/wnvsZmXeOTY2xHX4/3facm+XyysM9TiB2F5L3Zl86TOSSnlpEa5z53oP7SuEwgcTGf03sBt/Rtr/PZ1AOde8Bdl/S4YNo17+l4bdbR8x/B/0tUxJH+T8H/fwn6/6BuxCbz/yAX51r6X5v5pfT/BPQ6baz/a3T0baf9Y/6fUbbAfwkq+tvMr0shsTH7iZDPzya1vIqM/8Znmg9XxfjcLDs7PtD5j8xz/aJ03rM5PvSJsV/ueX10v+b4YPZh1kfI6yvJ8YE+58LE19is8653jO3o6/a+79Qkn/cW9pk+G6OQvKdzx88nOXUVGdfaMdtD/aVxaUHiYj6n/xmSrDe6/57EDv+zROl/Aun4yf3/Gfq/KtOued+b2GfWtSP2GT/oWEL/F1BPwNa6PlvNe3rvbIn9pvr2mxrQftN9+00PaL+Zvv1mBrTfmr791gxov8HnlZen22zI3Kbup/pqx2Vnx156f+oGrLZEvQy1/R5wM8oWjZ63qGxhErHJ2Gnu+VKD2EXPySPkOymqsm9pMdZlxFhXQ1Ve6PM6apPX9cj36vjs1DE297Sg95o09+mi95o0ftD7Shp/zPbpqnIfsR58zJLsazs7mpuTU5aXVeZle0XRrILi/L7RnL7Fuflevtc3v29pVn52dll+Tn5eQXFBXrTAy8ku88r7FmSXY+PJjHbuwtcW1UL/BJbLTo8xfmaANwmhD6Rb1bYDr+Y+yBX7UjsuScx9maP4D1wm33LQj2ziT1/0u1LiC/RZlK+tKLVX/9HDDEixBqw0AV+Ubz/++NVRwoOJROfkCrSbp/iKQ8rvPP4+2mHw4x7wsxjbylf8A05VBtIC7MtYA1QB2W7XGNsl4+e7Iuvip/8mkog5Zx73+x/FvP9OYt6fbLf7TmK+O4n5HjG2i+LneyBHiK8SY8tuiv8gPCaDdxzg9tvkD7ffYzNkxr8Is50DGGPJ2NceZ/yCEmU9+dqK0rNK0+ZAtW0msp7xqmdWD1XbZsbpGZh6ZpOeQaNnaukZEPqXdj2jQ/9Sqn+R07/86l9f9C9E+tck/Uui/oVG/zKjf1HSv3rpX/b0r177AfYHHACYBpgOKAIUA0oApYAyQDlgBuBAwEzAQYBZgNmAOYC5gHmAgwHzAQsACwGLAIsBhwCWAJYClgEOBRwGOBywHHCE2nanjCMBR6kdz0ypONULPWMuZOoDAbEbpbYb1lfe0olvyvd5HfQvldWWnCg9czfLzq6s0CeKpLDasu3KirkqAVdWBixedOCkmYvmli3c4fqKf/RLihEt+rwJ+hwGE+EUsi6ZeGTWme+kExY7/YioyqlMHePaz0AlczhijYe37fqLWY5GPkZtT70kEi/dkX/HiFkSeZ2M2yTvZJukf2nn30pRLBmMc9rxn4mzOgD+q38R5n3TBPm/aoqycr1EvaMVnz45RskkbjJz/Dh9PnaHtmDboqyc3LK+0dyy/IL8soK88r550ZKi8vLSvGhOSXG0uDgnN5rtZZcX52VFi7MKYLcFZX1LvAq7gtI+x/K1tcMFqeNU4oIUS+ccJ9Du8cruC1La7+P5+yimrRwD3fEC7Z6geAtTF6Fu00ilINTLICVzEGDNC596ORH5JBUy9aIdp+pFB0BavdAEiVe9nKj4iu8k5YZ64fT5ZOWeejlZ8Q6SZjlFJdQLS+ecItDuqcpu9aL9PpW/j0TUy0loK3e7pynewtRFqNsMUr0MVjIHAda88KmX05HPUCFTL9pxql50AKTVC02QeNXL6Yqv+M5QbqgXTp9XKvfUy0rFO0ia5UyVUC8snXOmQLtnKbvVi/b7LP4+ElEvZ6Ct3O2erXgLUxehbjNI9TJEyRwEWPPCp17OQV6lQqZetONUvegASKsXmiDxqpdzFF/xrVJuqBdOn89V7qmXcxXvIGmW81RCvbB0znkC7Z6v7FYv2u/z+ftIRL2sQlu5271A8RamLkLdZpDqZaiSOQiw5oVPvVyIfJEKmXrRjlP1ogMgrV5ogsSrXi5UfMV3kXJDvXD6fLFyT71crHgHSbNcohLqhaVzLhFo91Jlt3rRfl/K30ci6uUitJW73csUb2HqItRtBqlehimZgwBrXvjUy+XIq1XI1Mvlakf1ogMgrV5ogsSrXi5XfMW3WrmhXjh9vkK5p16uULyDpFmuVAn1wtI5Vwq0e5WyW71ov6/i7yMR9bIabeVu92rFW5i6CHWbQaqX4UrmIMCaFz71cg3ytSpk6kU7TtWLDoC0eqEJEq96uUbxFd+1yg31wunzdco99XKd4h0kzbJGJdQLS+esEWh3rbJbvWi/1/L3kYh6uRZt5W73esVbmLoIdZtBqpcRSuYgwJoXPvVyA/KNKmTqRTtO1YsOgLR6oQkSr3q5QfEV343KDfXC6fNNyj31cpPiHSTNsk4l1AtL56wTaPdmZbd60X7fzN9HIurlRrSVu91bFG9h6iLUbQapXvZUMgcB1rzwqZdbkW9TIVMv2nGqXnQApNULTZB41cutiq/4blNuqBdOn29X7qmX2xXvIGmWO1RCvbB0zh0C7d6p7FYv2u87+ftIRL3chrZyt3uX4i1MXYS6zSDVy15K5iDAmhc+9XI38j0qZOpFO07Viw6AtHqhCRKverlb8RXfPcoN9cLp873KPfVyr+IdJM1yn0qoF5bOuU+g3fuV3epF+30/fx+JqJd70Fbudh9QvIWpi1C3GaR6GalkDgKseeFTLw8ir1chUy/acapedACk1QtNkHjVy4OKr/jWKzfUC6fPG5R76mWD4h0kzfKQSqgXls55SKDdh5Xd6kX7/TB/H4mol/VoK3e7GxVvYeoi1G0GqV5GKZmDAGte+NTLI8iPqpCpF+04VS86ANLqhSZIvOrlEcVXfI8qN9QLp8+PKffUy2OKd5A0yyaVUC8snbNJoN3Hld3qRfv9OH8fiaiXR9FW7nafULyFqYtQtxmkehmtZA4CrHnhUy9PIj+lQqZetONUvegASKsXmiDxqpcnFV/xPaXcUC+cPj+t3FMvTyveQdIsz6iEemHpnGcE2n1W2a1etN/P8veRiHp5Cm3lbvc5xVuYugh1m0GqlzFK5iDAmhc+9fI88gsqZOpFO07Viw6AtHqhCRKvenle8RXfC8oN9cLp84vKPfXyouIdJM3ykkqoF5bOeUmg3ZeV3epF+/0yfx+JqJcX0Fbudl9RvIWpi1C3GaR6GatkDgKseeFTL68iv6ZCpl6041S96ABIqxeaIPGql1cVX/G9ptxQL5w+v67cUy+vK95B0ixvqIR6YemcNwTafVPZrV6032/y95GIenkNbeVu9y3FW5i6CHWbQaqXvZXMQYA1L3zq5W3kd1TI1It2nKoXHQBp9UITJF718rbiK753lBvqhdPnd5V76uVdxTtImuU9lVAvLJ3znkC7m5Xd6kX7vZm/j0TUyztoK3e77yvewtRFqNsMUr2MUzIHAda88KmXD5A/VCFTL9pxql50AKTVC02QeNXLB4qv+D5UbqgXTp8/Uu6pl48U7yBplo9VQr2wdM7HAu1+ouxWL9rvT/j7SES9fIi2crf7qeItTF2Eus0g1ct4JXMQYM0Ln3r5DPlzFTL1oh2n6kUHQFq90ASJV718pviK73Plhnrh9PkL5Z56+ULxDpJm+VIl1AtL53wp0O4WZbd60X5v4e8jEfXyOdrK3e5XircwdRHqNoNULxOUzEGANS986uVr5G9UyNSLdpyqFx0AafVCEyRe9fK14iu+b5Qb6oXT52+Ve+rlW8U7SJrlO5VQLyyd851Au98ru9WL9vt7/j4SUS/foK3c7f6geAtTF6FuM0j1MlHJHARY88KnXn5E/kmFTL1ox6l60QGQVi80QeJVLz8qvuL7SbmhXjh9/lm5p15+VryDpFl+UQn1wtI5vwi0+6uyW71ov3/l7yMR9fIT2srd7m+KtzB1Eeo2g1Qv+yiZgwBrXvjUy+/If6iQqRftOFUvOgDS6oUmSLzq5XfFV3x/KDfUC6fPfyr31MufineQNMtfKqFeWDrnL4F2tyq71Yv2eyt/H4molz/QVu52/1a8hWmOqEGql0lK5iDAmhc+9WKCkJQUMvWi90DViw6AtHqhCRKvetGGx9uWKb6kJDfUC6fPyUnuqZfkJN5B8p88T0qoF5bO0YHkbjeFMeml/E5JYu8jEfWShLZyt5vKXJi6CHWbQaqXyUrmIMCaFz71koZBSA+beknzqZf0ANQLTZB41Usa46CW7oh64fQ5w0H1kiGkXjIT6oWnczIF1EsNy9WL9ruGI+olHW3lbremgHqpGbB6maJkDgKseeFTL7UwCLXDpl5q+dRL7QDUC02QeNVLLcZBrbYj6oXT5zoOqpc6QuqlbkK98HROXQH1Us9y9aL9rueIeqmNtnK3W19AvdQPWL3sq2QOAqx54VMvDTAIDcOmXhr41EvDANQLTZB41UsDxkGtoSPqhdPnRg6ql0ZC6qVxQr3wdE5jAfXSxHL1ov1u4oh6aYi2crfbVEC9NA1YvUxVMgcB1rzwqZdmGITmYVMvzXzqpXkA6oUmSLzqpRnjoNbcEfXC6XMLB9VLCyH10jKhXng6p6WAemlluXrRfrdyRL00R1u5220toF5aB6xe9lMyBwHWvPCplzYYhLZhUy9tfOqlbQDqhSZIvOqlDeOg1tYR9cLpczsH1Us7IfXSPqFeeDqnvYB66WC5etF+d3BEvbRFW7nb7SigXjoGrF72VzIHAda88KmXThiEzmFTL5186qVzAOqFJki86qUT46DW2RH1wulzFwfVSxch9dI1oV54OqergHrpZrl60X53c0S9dEZbudvtLqBeugesXg5QMgcB1rzwqZceGISeYVMvPXzqpWcA6oUmSLzqpQfjoNbTEfXC6XMvB9VLLyH10juhXng6p7eAeuljuXrRfvdxRL30RFu5291FQL3sErB6maZkDgKseeFTL2YU88KmXqI+9eIFoF5ogsSrXqKMg5rniHrh9DnLQfWSJaReshPqhadzsgXUS47l6kX7neOIevHQVu52+wqol74Bq5fpSuYgwJoXPvWSi0HIC5t6yfWpl7wA1Mt0xadechkHtTxH1Aunz/kOqpd8IfVSkFAvPJ1TIKBedrVcvWi/d3VEveShrdzt7iagXnYLWL0UKZmDAGte+NRLPwxC/7Cpl34+9dI/APVCEyRe9dKPcVDr74h64fR5dwfVy+5C6mWPhHrh6Zw9BNRLoeXqpSIpHVEv/dFW7nYHCKiXAQGrl2IlcxBgzQufehmIQRgUNvUy0KdeBgWgXmiCxKteBjIOaoMcUS+cPg92UL0MFlIvQxLqhadzhgiol6GWqxft91BH1MsgtJW73WEC6mVYwOqlRMkcBFjzwqdehmMQRoRNvQz3qZcRAagXmiDxqpfhjIPaCEfUC6fPezqoXvYUUi97JdQLT+fsJaBeRlquXrTfIx1RLyPQVu52Rwmol1EBq5dSJXMQYM0Ln3oZjUEYEzb1MtqnXsYEoF5ogsSrXkYzDmpjHFEvnD6PdVC9jBVSL3sn1AtP5+wtoF7GWa5etN/jHFEvY9BW7nbHC6iX8QGrlzIlcxBgzQufepmAQZgYNvUywadeJgagXmiCxKteJjAOahMdUS+cPu/joHrZR0i9TEqoF57OmSSgXiZbrl6035MdUS8T0VbudqcIqJcpAauXciVzEGDNC5962ReDMDVs6mVfn3qZGoB6oQkSr3rZl3FQm+qIeuH0eT8H1ct+Qupl/4R64emc/QXUywGWqxft9wGOqJepaCt3u9ME1Mu0gNXLDCVzEGDNC596mY5BKAqbepnuUy9FAagXmiDxqpfpjINakSPqhdPnYgfVS7GQeilJqBeezikRUC+llqsX7XepI+qlCG3lbrdMQL2UBaxeDlQyBwHWvPCpl3IMwoywqZdyn3qZEYB6oQkSr3opZxzUZjiiXjh9PtBB9XKgkHqZmVAvPJ0zU0C9HGS5etF+H+SIepmBtnK3O0tAvcwKWL3MVDIHAda88KmX2RiEOWFTL7N96mVOAOqFJki86mU246A2xxH1wunzXAfVy1wh9TIvoV54OmeegHo52HL1ov0+2BH1Mgdt5W53voB6mR+wejlIyRwEWPPCp14WYBAWhk29LPCpl4UBqBeaIPGqlwWMg9pCR9QLp8+LHFQvi4TUy+KEeuHpnMUC6uUQy9WL9vsQR9TLQrSVu90lAuplScDqZZaSOQiw5oVPvSzFICwLm3pZ6lMvywJQLzRB4lUvSxkHtWWOqBdOnw91UL0cKqReDkuoF57OOUxAvRxuuXrRfh/uiHpZhrZyt7tcQL0sD1i9zFYyBwHWvPCplyMwCCvCpl6O8KmXFQGoF5og8aqXIxgHtRWOqBdOn490UL0cKaRejkqoF57OOUpAvRxtuXrRfh/tiHpZgbZyt3uMgHo5JmD1MkfJHARY88KnXo7FIBwXNvVyrE+9HBeAeqEJEq96OZZxUDvOEfXC6fPxDqqX44XUywkJ9cLTOScIqJcTLVcv2u8THVEvx6Gt3O2eJKBeTgpYvcxVMgcB1rzwqZeTMQinhE29nOxTL6cEoF5ogsSrXk5mHNROcUS9cPp8qoPq5VQh9XJaQr3wdM5pAurldMvVi/b7dEfUyyloK3e7ZwiolzMCVi/zlMxBgDUvfOplJQbhzLCpl5U+9XJmAOqFJki86mUl46B2piPqhdPnsxxUL2cJqZezE+qFp3POFlAv51iuXrTf5ziiXs5EW7nbXSWgXlYFrF4OVjIHAda88KmXczEI54VNvZzrUy/nBaBeaILEq17OZRzUznNEvXD6fL6D6uV8IfVyQUK98HTOBQLq5ULL1Yv2+0JH1Mt5aCt3uxcJqJeLAlYv85XMQYA1L3zq5WIMwiVhUy8X+9TLJQGoF5og8aqXixkHtUscUS+cPl/qoHq5VEi9XJZQLzydc5mAernccvWi/b7cEfVyCdrK3e5qAfWyOmD1skDJHARY88KnXq7AIFwZNvVyhU+9XBmAeqEJEq96uYJxULvSEfXC6fNVDqqXq4TUy9UJ9cLTOVcLqJdrLFcv2u9rHFEvV6Kt3O1eK6Berg1YvSxUMgcB1rzwqZfrMAhrwqZervOplzUBqBeaIPGql+sYB7U1jqgXTp/XOqhe1gqpl+sT6oWnc64XUC83WK5etN83OKJe1qCt3O3eKKBebgxYvSxSMgcB1rzwqZebMAjrwqZebvKpl3UBqBeaIPGql5sYB7V1jqgXTp9vdlC93CykXm5JqBeezrlFQL3carl60X7f6oh6WYe2crd7m4B6uS1g9bJYyRwEWPPCp15uxyDcETb1crtPvdwRgHqhCRKvermdcVC7wxH1wunznQ6qlzuF1MtdCfXC0zl3CaiXuy1XL9rvux1RL3egrdzt3iOgXu4JWL0comQOAqx54VMv92IQ7gubernXp17uC0C90ASJV73cyzio3eeIeuH0+X4H1cv9QurlgYR64emcBwTUy4OWqxft94OOqJf70FbudtcLqJf1AauXJUrmIMCaFz71sgGD8FDY1MsGn3p5KAD1QhMkXvWygXFQe8gR9cLp88MOqpeHhdTLxoR64emcjQLq5RHL1Yv2+xFH1MtDaCt3u48KqJdHA1YvS5XMQYA1L3zq5TEMwqawqZfHfOplUwDqhSZIvOrlMcZBbZMj6oXT58cdVC+PC6mXJxLqhadznhBQL09arl603086ol42oa3c7T4loF6eCli9LFMyBwHWvPCpl6cxCM+ETb087VMvzwSgXmiCxKtenmYc1J5xRL1w+vysg+rlWSH18lxCvfB0znMC6uV5y9WL9vt5R9TLM2grd7svCKiXFwJWL4cqmYMAa1741MuLGISXwqZeXvSpl5cCUC80QeJVLy8yDmovOaJeOH1+2UH18rKQenkloV54OucVAfXyquXqRfv9qiPq5SW0lbvd1wTUy2sBq5fDlMxBgDUvfOrldQzCG2FTL6/71MsbAagXmiDxqpfXGQe1NxxRL5w+v+mgenlTSL28lVAvPJ3zloB6edty9aL9ftsR9fIG2srd7jsC6uWdgNXL4UrmIMCaFz718i4G4b2wqZd3ferlvQDUC02QeNXLu4yD2nuOqBdOnzc7qF42C6mX9xPqhadz3hdQLx9Yrl603x84ol7eQ1u52/1QQL18GLB6Wa5kDgKseeFTLx9hED4Om3r5yKdePg5AvdAEiVe9fMQ4qH3siHrh9PkTB9XLJ0Lq5dOEeuHpnE8F1MtnlqsX7fdnjqiXj9FW7nY/F1AvnwesXo5QMgcB1rzwqZcvMAhfhk29fOFTL18GoF5ogsSrXr5gHNS+dES9cPq8xUH1skVIvXyVUC88nfOVgHr52nL1ov3+2hH18iXayt3uNwLq5ZuA1csKJXMQYM0Ln3r5FoPwXdjUy7c+9fJdAOqFJki86uVbxkHtO0fUC6fP3zuoXr4XUi8/JNQLT+f8IKBefrRcvWi/f3REvXyHtnK3+5OAevkpYPVypJI5CLDmhU+9/IxB+CVs6uVnn3r5JQD1cqTiUy8/Mw5qvziiXjh9/tVB9fKrkHr5LaFeeDrnNwH18rvl6kX7/bsj6uUXtJW73T8E1MsfAauXo5TMQYA1L3zq5U8Mwl9hUy9/+tTLXwGoF5og8aqXPxkHtb8cUS+cPm91UL1sFVIvfyfUC0/n/C2gXnSPmLZsVC9b6eFC8Q4k3CrjL7SVu92kZH71otvMNK+3h5e9/3oy9lk7bCcZjI4AUgCpgDRAOiBD+wSoAagJqAWoDagDqAuoB6gPaABoCGgEaAxoAmgKaAZoDmgBaAloBWgNaANoC2gHaI8BM3HUtmSo7e8jvvcpvvepvvdpvvfpvvcZvveZvvc1fO9r+t7X8r2v7Xtfx/e+ru99Pd/7+r73DXzvG/reN/K9b+x738T3vqnvfTPf++a+9y1871v63rfyvW/te9/G976t73073/v2yfJCjtZMvGNHMuP4Pj5DRsj54xeveI0k87Sl+yKFMX4TrI9fRdNeavw+Z6HPXhpj/CbaHL+cf+z00uPzOUp89jIY47ePrfHL2sFOL/P/7nPU57NXgzF+kyyMX255JTu9mv83n/Nj+OzVYozfZNvilx/TTq929X3O+xefvTqM8ZtiU/zy/tVOr271fM7aic9ePcb47WtL/PJ2aqdXv+o+l/yHz14DxvhNtSF+ef9pp9ewaj5Hq+Cz14gxfvv9r+MXrZKdXuP/9rlvFX32mjDGb///Zfxyqmyn13SnPueUV8Nnrxlj/A74X8Uvr1p2es3/3ef8avrstWCM37T/QfwKyqttp9cyts/R/4PPXivG+E0POn7R/5OdXuvKPnv/R5+9NozxKwoyfqX/Zzu9tjv6nB2Hz147xvgVBxS/rPK47PTaJ/NdS6TX7OKNX0lA8YvGt3iM19m8iYzxK3UkfozXibxJjPErcyR+jNc5vCmM8St3JH6M5+neVMb4zXAkfoznmd7+jPE70JH4MZ4nedMY4zfTkfgx6nyviDF+BzkSP0ad6pUwxm+WI/Fj1FleGWP8ZjsSP0ad4M1gjN8cR+LHeJzzZjLGb64j8WMcp71ZjPGb50j8GMcZbw5j/A52JH6MdeIx5ozHGT89n03/I6MXYCugN7Jp/xi1bZ7bSchnIK9Cvgh5NfK1yDci34Z8D/J65EeRn0J+Afk15HeQP0T+HPkb5J+Q/0BOwj9WpCPXRm6I3By5LXJn5J7IHnIecn/kQcgjkMcgT0SeilyEPAN5DvJC5GXIK5CPQz4F+Uzk85AvQb4SeQ3yOuQ7kO9Dfgh5E7J5sLB5RJ952I25bby5Aau5lZm5KYj5e635o0o7zAMz37EdspkfaeZNmvmUZp6lmX9p5mWa+ZpmHqeZ32nmfZr5oGaeqJk/auaVmvmmZh6qmZ9q5q2a+axmnquZ/2rmxZr5smYerZlfa+bdmvm4Zp6umb9r5vV2SFY7LNzzozswXt8O6o8izRXvOGSWjsmJP4qwdI4OJHe7nRgTVcrvTsnsfbSD0Ej2tR1vHDhj2pnxR6OI2l50dLF5IJG0s5kjdjZV/AOz5tr4ugvkWFdAN0B3QA9AT0AvQG9AH8AuAP0fYA+QBWiM3zV/laaLXpfii4VeZ/4qbOotjXynkMk/gYNJNJPYHInhd0oMv1MJ1ySfK18M6mAc0nltLqXxVr6+8Mdckf2nqe39wmSLVyEYsa2yufMXly0uG7u4ePbMkqGL55Ysmjlv7qCi2bNpYhrDTYJGYgTOv552Qga+TiXrMomDZp1pK4Osox1sApPEXdF6VG9BjGdqNxrUTQu6JcuMnMzxyKKxyMY3Ockhu2mBdvwvnzFc+9DBzEnm/29sjlCCcV9T6sYg9bb9v628PDvZ/vglM8eP0+e+pC0vPzsrKy9bb5dfCmlaWpKVn5VVWpwTLYkWlWSVFeR4BeU5WTnZJaUlxdBmkVceLS8qKSjP32ZXUOfcfRn7idqbmzjn5umcXIFz7jzLz7m133lC59wSB4o8gQNQPnNh6nDqNpNVcLeW6u6gSivAN7uGTaUVCKo0HcxdBYpkV0dUWndGlVaQbH/8uFUap8+7OajSdhNSaf0SKo2nc/oJqLT+lqs07Xd/R1Tarmgrd7u7C6i03QNWaT0cVGl74JvCsKm0PQRVmg5moUCRFDqi0nowqrQ9ku2PH7dK4/R5gIMqbYCQShuYUGk8nTNQQKUNslylab8HOaLSCtFW7nYHC6i0wQGrtF0cVGlD8M3QsKm0IYIqTQdzqECRDHVEpe3CqNKGJNsfP26VxunzMAdV2jAhlTY8odJ4Ome4gEobYblK036PcESlDUVbudvdU0Cl7RmwSos6qNL2wjcjw6bS9hJUaTqYIwWKZKQjKi3KqNL2SrY/ftwqjdPnUQ6qtFFCKm10QqXxdM5oAZU2xnKVpv0e44hKG4m2crc7VkCljQ1YpXkOqrS98c24sKm0vQVVmg7mOIEiGeeISvMYVdreyfbHj1ulcfo83kGVNl5IpU1IqDSezpkgoNImWq7StN8THVFp49BW7nb3EVBp+yRXVg5cfab/i9pZIA6TkmX7PxrfUnGngkkCfp+RYXfe63/8S/i9MsMN4cDYP97KDLtzvJlQjp9teY53FcrxcxzJccb+8c6xPMebCuX4eZbneJZQjp/vSI4z9o93vuU5PhT7WvG2K2LrSIdsHRegrXE/9lnJ1PtFlud+T6Fx7mJHxjnG/vEutryvewn19WUB9bVF544ep8+6P/TNsMyFQa2v9a2Fc5B3RS5ErgGYjP2YrrbfYawnft4LuTdyH+ShyCORxyHXB0wh7ZmLkd3Uts/9rH8x2bea20+t5vb7VXP7/au5/QHV3H5aNbefXs3ti6q5fXE1ty+p5val1dy+rJrbl1dz+xnV3P7Aam4/k2yf/C/bZwAOquJ2s6q43ewqbjenitvNreJ286q43cFV3G5+FbdbUMXtFlZxu0VV3G5xFbc7pIrbLanidkuruN0yst0k3G4Kjs9ZybHz1s/74nZTkfdD3h/5AORpyNORi5CLkUuQS5HLkMuRZyAfiDwT+SDkWcizkecgz0Weh3ww8nzkBcgLkRchL0Y+BHkJ8lLkZVWMT4KD4Z6AQ2OMv12wnyYjH4rcAHCYKQ5cuLVfC8a2Dk/m05GJO0fvaGfY7xy9Gl8vhxw7ArACcCTgKMDRgGMAxwKOAxwPOAFwIuAkwMmAUwCnAk4DnA44A7AScCbgLMDZgHMAqwDnAs4DnA+4AHAh4CLAxYBLAJcCLgNcDlgNuAJwJeAqwNWAawDXAq4DrAGsBVwPuAFwI+AmwDrAzYBbALcCbgPcDrgDcCfgLsDdgHsA9wLuA9wPeADwIGA9YAPgIcDDgI2ARwCPAh4DbAI8DngC8CTgKcDTgGcAzwKeAzwPeAHwIuAlwMuAVwCvAl4DvA54A/Am4C3A24B3AO8C3gNsBrwP+ADwIeAjwMeATwCfAj4DfA74AvAlYAvgK8DXgG8A3wK+A3wP+AHwI+AnwM+AXwC/An4D/A74A/An4C/AVsDfydsGiCRAMiACSAGkAtIA6YAMQCagBqAmoBagNqAOoC6gHqA+oAGgIaARoDGgCaApoBmgOaAFoCWgFaB1JHEncrvvRF7k2XYn8obYVknR7NljF8w8pGhRmbkPOR3ijMlmqPv/8h7khxNPmNoN7B7k+pjDZXMMc7na3mEWcRvs2baRkM0i1o5LzSLWwdTgvmCs22SyUXQWMS2EeGcRt4nYH79k5vhx+tyOtOXKLOJ2jP1E7W0fScwiZumc9hH+djswJr2U3x0i7H0k8qt8W7SVu92OzIWpi1C3iSdrgai0Ix1UaZ0w7zqHTaV1ElRpOpidBYqksyMq7UhGldYpYn/8uFUap89dHFRpXYRUWteESuPpnK4CKq2b5SpN+93NEZXWGW3lbre7gErrHrBKO8pBldYD865n2FRaD0GVpoPZU6BIejqi0o5iVGk9IvbHj1ulcfrcy0GV1ktIpfVOqDSezuktoNL6WK7StN99HFFpPdFW7nZ3EVBpuwSs0o53UKVFMe+8sKm0qKBK08H0BIrEc0SlHc+o0qIR++PHrdI4fc5yUKVlCam07IRK4+mcbAGVlmO5StN+5zii0jy0lbvdvgIqrW/AKu0EB1VaLuZdXthUWq6gStPBzBMokjxHVNoJjCotN2J//LhVGqfP+Q6qtHwhlVaQUGk8nVMgoNJ2tVylab93dUSl5aGt3O3uJqDSdgtYpZ3ooErrh3nXP2wqrZ+gStPB7C9QJP0dUWknMqq0fhH748et0jh93t1Blba7kErbI6HSeDpnDwGVVmi5SqtISkdUWn+0lbvdAQIqbUDAKq210EGAOS92UGkDMe8GhU2lDRRUaTqYgwSKZJAjKq01w4BrVNrAiP3x41ZpnD4PdlClDRZSaUMSKo2nc4YIqLShlqs07fdQR1TaILSVu91hAiptWETuSTHmriHccRgeke3/aHxLxZ3Jhgv0/+oMu/Ne3+FLwu8rMtwQDoz9412RYXeONxPK8astz/EjhHL8GkdynLF/vGssz/GmQjm+xvIcP0kox9c6kuOM/eOttTzHtVYdHpCujsa3VExld8XWPIds7R+grRxPtZEYm260vE6PFhqTb3JkTGbsH+8my/v6GKG+viWgvrboPNfj9Fn3B32qjT4X0Hd71/f00twZuSeyfqrNCOxH+lSbo/F7xyAfi3wcsoffz0Puj6yfarMnac/cGrYxft4EuSlyM+TmyC2QawH2Iu2sxHb2xM9PQjtORj4F+VTk05BPRz4DeSXymchnIZ+NfA7yKuRzkc9DPh/5AuQLkS9Cvhj5EuRLkS9Dvhx5NfIVyFciX4V8NfI1yNciX4e8Bnkt8vXINyDfiHwT8jrkm5FvQb4V+Tbk25HvQL4T+S7ku5HvQb4X+T7k+5EfQH4QeT3yBuSHkB9G3oj8CPKjyI8hb0J+HPkJ5CeRn0J+GvkZ5GeRn0N+HvkF5BeRX0J+GfkV5FeRX0N+HfkN5DeR30J+G/kd5HeR30PejPw+8gfIHyJ/hPwx8ifInyJ/hvw58hfIXyJvQf4K+Wvkb5C/Rf4O+XvkH5B/RP4J+WfkX5B/Rf4N+XfkP5D/RP4LeSvy38gK6zcJORk5gpyCnIqchpyOnIGcacYv5Jpm3ECujVwHuS5yPTNOITdAbojcCHkv5JbIrZB7AEaScclI0uXo3wjcbqRpHzAKN+I+Buvr1qMEjsGjLb92rZ8qop9cwu33GEa/g/ohtLXi1Q5mGZv4IZSnc8YK/BC6t+U/hGq/9xY6WTdLsq/teOPAGdNxfANJYI8q4hxIJO1s5YidLRX/wKy5Nr4eD0kxATARsA9gEmAyYApgX8BUwH6A/QEHAKZFEo+WsfvRMtFS2x4t0xzbKps7f3HZ4rKxi4tnzywxD5cZVDR7Nk1MY7hJ0EiMwPnXO/WAGT2qtyHGM7Ub2ANmJkZkRk7meOww+Xg69mxR2CYfTxecfKyDWSRw3ljkyOTjiYyTj6dH7I9fMnP8OH0udnDycbHQ5OOSxDk3T+eUCJxzl1p+zq39LhU655Y4UJQKHIDKBCYfl0WC/YvYPg6qtHLMuxlhU2nlgipNB3OGQJHMcESl7cOo0soj9sePW6Vx+nyggyrtQCGVNjOh0ng6Z6aASjvIcpWm/T7IEZU2A23lbneWgEqbFbBKm+SgSpuNeTcnbCpttqBK08GcI1AkcxxRaZMYVdrsiP3x41ZpnD7PdVClzRVSafMSKo2nc+YJqLSDLVdp2u+DHVFpc9BW7nbnC6i0+QGrtP0cVGkLMO8Whk2lLRBUaTqYCwWKZKEjKm0/RpW2IGJ//LhVGqfPixxUaYuEVNrihErj6ZzFAirtEMtVmvb7EEdU2kK0lbvdJQIqbUnAKm1/B1XaUsy7ZWFTaUsFVZoO5jKBIlnmiErbn1GlLY3YHz9ulcbp86EOqrRDhVTaYQmVxtM5hwmotMMtV2na78MdUWnL0FbudpcLqLTlAau0AxxUaUdg3q0Im0o7QlCl6WCuECiSFY6otAMYVdoREfvjx63SOH0+0kGVdqSQSjsqodJ4OucoAZV2tOUqTft9tCMqbQXayt3uMQIq7ZiI3K3L9X9RxwnE4diIbP9H41sq7lRwrIDft1l+y1v9j38Jv2935PaKjP3j3W757RVbCeX4XZbn+AShHL/bkRxn7B/vbstzvKVQjt9neY5PE8rx+x3Jccb+8e63PMcXYl8r3nZFbF3mkK0rArSV43bgEvW+3vLcnyw0zm1wZJxj7B9vg+V9PUWorzc6cjtwznOTjYK3A9f6Wt+Wtgh5BvIcZH078OOwH+ntwCfj51OQ90WeirwQeRnyCmR9O/DjSXtmyO6mtn3uZ/2LyQnV3P7Eam5/UjW3P7ma259Sze1Preb2p1Vz+9Oruf0Z1dx+ZTW3P7Oa259Vze3Prub251Rz+1XV3P5csn3yv2yfATivitudX8XtLqjidhdWcbuLqrjdxVXc7pIqbndpFbe7rIrbXV7F7VZXcbsrqrjdlVXc7qoqbnd1Fbe7hmw3Cbc7HsfnaZHYeevnE3C7E5FPQj4Z+RTkU5FPQz4d+QzklchnIp+FfDbyOcirkM9FPg/5fOQLkC9Evgj5YuRLkC9Fvgz5cuTVyFcgX4l8FfLVyNdUMT4JDoZ7Aq6NMf6Ox346DvlaZH37/esilWfJcOtf/RjZFqR9pnY5Z8p4/hU0HmswkGsjIZspox1/kDi7lvz4xZ0kOkF0onCfJD2aEczMmWraGfXZ6a2J8Pm8lu9HSk8qftwXFDjjd/1O2srPKysuz8vJLormlBdDO7nlZdlFWQVeeX42NJ+d4xUXlUVLc4rzcnNy88vzAnvWxfV8fb7DzJkbIomZMyydc0OEv90bGZNeyu8bI+x9JHIlei3ayt3upoAOQNFqLpUeoMmYSzcxHoA442eEjLZvgApufng8B+TyHZeSGOaKqN51mGA370T1DowRM7/qHaj+W/XGauc/VS93J9k+tUt3yDqBAWpdhL/AbsYCo0u8A5Zv4ewv72bGwe8WvmIvN/G8hT+elYp/naXxvJW5Ls3CfQayltHn25gPGBLTYG8VGIueyLB7DNZ+3ybg95OOnGUz9o8XlM+cx8e4pxMzjrFS+X17RGa84OxriUvUYwT8voPRby3C9dUWczVGt60v/RtIxEXqquydlueDztc7BfLhLka/U9SODxxUvDH4Z0zlju1dEfttvFtIc7IfnI5lPDjd48DBSaIo73VgMLpOwO9nLBfbugjvEfD7WTt/Eqz8Xw3GemTsa48zfsIHsX9+SuLOzXsdOIjd58pBrA1jW/czFo0u6IiqvEj8aZeprcTjxaNyjxdfja8f0PNiAOsBGwAPAR4GbAQ8AngU8BhgE+BxwBOAJwFPAZ4GPAN4FvAc4HnAC4AXAS8BXga8AngV8BrgdcAbgDcBbwHeBrwDeBfwHmAz4H3AB4APAR8BPgZ8AvgU8Bngc8AXgC8BWwBfAb4GfAP4FvAd4HvAD4AfAT8Bfgb8AvgV8Bvgd8AfgD8BfwG2Av7WxQEjeBIgGRABpABSAWmAdEAGIBNQA1ATUAtQG1AHUBdQD1Af0ADQENAI0BjQBNAU0AzQHNAC0BLQCtAa0AbQFtAO0B7QAdAR0AnQGdAF0BXQDdAd0APQE9AL0BvQB7ALQB+BPEAWIBuQA+gLyAXkAfIBBYBdAbsB+gH6A3YH7AEoBAwADAQMAgwGDAEMBQwDDAeMAOwJ2AswEjAKMBowBjAWsDdgHGA8YAJgImAfwCTAZMAUwL6AqYD9APunJB5Xb/fj6os82x5X3xDbKimaPXvsgpmHFC0qMw+rp0OcMdkMdZEYIfOvd+5B9fcT65naDexB9eulRB2vnTvcau4AzJBpKSGbQKsdl7rVnA6mBvfZsW6TyUbRW82tZ7jyZW41d0CK/fHj/imP0+fppC1XbjU3nbGfqL1FKYkJsyydU5TC324xY9JL+V2cwt5HMrdqQVu52y1hLkxdhLrNZBXchM8NDqq0Usy7srCptFJBlaaDWSZQJGWOqLQNjCqtNMX++HGrNE6fyx1UaeVCKm1GQqXxdM4MAZV2oOUqTft9oCMqrQxt5W53poBKmxmwSnvIQZV2EObdrLCptIMEVZoO5iyBIpnliEp7iFGlHZRif/y4VRqnz7MdVGmzhVTanIRK4+mcOQIqba7lKk37PdcRlTYLbeVud56ASpsXsEp7zEGVdjDm3fywqbSDBVWaDuZ8gSKZ74hKe4xRpR2cYn/8uFUap88LHFRpC4RU2sKESuPpnIUCKm2R5SpN+73IEZU2H23lbnexgEpbHLBK2+SgSjsE825J2FTaIYIqTQdziUCRLHFEpW1iVGmHpNgfP26VxunzUgdV2lIhlbYsodJ4OmeZgEo71HKVpv0+1BGVtgRt5W73MAGVdljAKu1xB1Xa4Zh3y8Om0g4XVGk6mMsFimS5IyrtcUaVdniK/fHjVmmcPh/hoEo7QkilrUioNJ7OWSGg0o60XKVpv490RKUtR1u52z1KQKUdFbBK21/oIMCcFzuotKMx744Jm0o7WlCl6WAeI1Akxzii0vZnGHCNSjs6xf74cas0Tp+PdVClHSuk0o5LqDSezjlOQKUdb7lK034f74hKOwZt5W73BAGVdkJKZeXA1WfmriHccTgxRbb/o/EtFXcmO1Gg/1/IsDvv9R2+JPx+0ZH7vDP2j/ei5bcZbSWU469YnuMPCuX4q47kOGP/eK9anuMthXL8Dctz/AmhHH/TkRxn7B/vTctzXGvVEwPS1dH4loqp7K7YusQhW5cHaGu8Y4iudYmx6R3L6/RhoTH5XUfGZMb+8d61vK83CvX1+448O4rzPOp95geh6turmqFSnwtsVdtuKKm5DHkWcg3ASdiP6Wr73Wofxu9tRH4E+VHk+fj9JcjLkesDTibtmVvDTsTP90GehDwZeQryvsi1AKeQdlZiOyfj50+gHU8iP4X8NPIzyM8iP4f8PPILyC8iv4T8MvIryK8iv4b8OvIbyG8iv4X8NvI7yO8iv4e8Gfl95A+QP0T+CPlj5E+QP0X+DPlz5C+Qv0TegvwV8tfI3yB/i/wd8vfIPyD/iPwT8s/IvyD/ivwb8u/IfyD/ifwX8lbkv5EV9l8ScjJyBDkFORU5DTkdOQM50+Qvck2TN8i1kesg10WuZ/IUuQFyQ+RGyI2RmyA3RW6G3By5BXJL5FbIrZHbILdFbofcHrkDckfkTsidkbsgd0XuhtwduQdyT+ReyL2R+yDvghxF9pCzkLORc5D7Iuci5yHnIxcg74q8G3I/5P7IuyPvgVyIPAB5IPIg5MHIQ5CHIg9DHo48AnlP5L2QRyKPQh6NPAZ5LPLeyOOQxyNPQD4FeSryfibegFPJuGR+GHoA8/sk3O5Uk1+A01IqzzDgPh7rZ7kdTnbA1C7nLIOdPpT6dDxgnZESslkG2vEHibM6AIU+47j2aZKEW7R9aOdzl6I+O73TU/h8pv0UjW/xPnTkBIczfit30lZ+XllxeV5OdlE0p7wY2sktL8suyirwyvOzofnsHK+4qCxamlOcl5uTm1+eFw1q1sHKFF6hbpYzUxKzDlg658wU/nbPYkx6Kb/PSmHvI5ErY2egrdztfhzQAShazcVvJ2cunc14APqY+QqEHsS0fQNUcHNr4zkgl++4lMQwV0T1noN1u2onqndgjJj5Ve9A9d+qN1Y7/6l6uTvJ9mkxukPOERigzknhL7BVWGB04Z6ny9hf3irGwe9cvmIvN/E8lz+elYr/HEvjeR5zXZqF+wzkDEafz2c+YEhMITxPYCz61PKflrTf5wv4/ZkjZ9mM/eN95sjPaecw1vUFjGOsVH5fkCIzXnD2tcTVx9ECU60vZPRbi3D95EpzPq3b7qa2QyouEldlL7I8H3S+XiRQBxcz+p2itj/JlC6ccZWI7cUp9tt4iZDmZD84nch4cLrUgYOTRFFe5sBgdJqA319aLrZ1EV4q4PcWO38SrGTn5Yz1yNjXHmf8hA9i//yUxJ2blzlwELtc6iDGXZCrE6rIW+1AQl3BbaMrp3FXJhK04t/Ittt4VVCyPRrfkjUuwpecVyeS07vagdHzGkeSM5szOa9NJKd3rQPJeZ0jyeldxHjBYw3zBY9/65x47VzLXERpqvLC1b5Ugq51oIiud0EfjxHQxzckEtQJfXxjGPXxTYnk9G5yYPRcF0Z9fHMiOb2bHUjOW1zRx3cyJuetlv8g2AbauFLgB6JvLP9hTN8U8AoBv7915Iex2xjzkrGvvW8dyJurBPLmdst/QNd+XyPg9x0O+H2dgN93Wu63Pi5ITBT5wYH6XiPg94+OHBfuYjwuMPa196PleaPr5XqBvPnFgXq5QcDvXx2pl7sZ64Wxr71fHaiXGwXy5h4HjqvrBPy+1wG/bxHw+z4H/L5VwO8/LK/vO4VuvP+nI8eF+xmPC4x97XHGL6j7srTna2uH+7I8kLgvC0/nPCBwX5YHGScpSPn9YAp7H4n+DZMzpusZB7iI2l50dLF5IJG0s50jdrZV/AOz5tr4egPk2EOAhwEbAY8AHgU8BtgEeBzwBOBJwFOApwGN8buZMXJKr0vxxUKvM/dmMfVGfwEsZPJP4GASzSQ2R2L4nRLD71TCNcnnyheDOhiHdF6bS2m8la8v/DFXZP9panu/MNni6ZmQzbGtsrnzF5ctLhu7uHj2zJKhi+eWLJo5b+6gotmzaWIaw02CRmIEzr+edoKZeplK1mUSB80601YGWUc72AQmibui9ajegRjP1G40qLtEPSz1GzOvnTs8gfUZzJBnU0J2b1TtuNQTWHUwnxU4735WKMG47+z0MIPUM09gfSbF/vhxzwHh9Pk50pYrT2B9jrGfqL3PJ865eTrneYFz7hcsP+fWfr8gdM4tcaB4QeAA9CJzYeoi1G0mq+Du5bnRQZX2Eubdy2FTaS8JqjQdzJcFiuRlR1TaRkaV9lKK/fHjVmmcPr/ioEp7RUilvZpQaTyd86qASnvNcpWm/X7NEZX2MtrK3e7rAirt9YBV2iMOqrQ3MO/eDJtKe0NQpelgvilQJG86otIeYVRpb6TYHz9ulcbp81sOqrS3hFTa2wmVxtM5bwuotHcsV2na73ccUWlvoq3c7b4roNLeDVilPeGgSnsP825z2FTae4IqTQdzs0CRbHZEpT3BqNLeS7E/ftwqjdPn9x1Uae8LqbQPEiqNp3M+EFBpH1qu0rTfHzqi0jajrdztfiSg0j4KWKU96aBK+xjz7pOwqbSPBVWaDuYnAkXyiSMq7UlGlfZxiv3x41ZpnD5/6qBK+1RIpX2WUGk8nfOZgEr73HKVpv3+3BGV9gnayt3uFwIq7YuAVdpTDqq0LzHvtoRNpX0pqNJ0MLcIFMkWR1TaU4wq7csU++PHrdI4ff7KQZX2lZBK+zqh0ng652sBlfaN5SpN+/2NIyptC9rK3e63Airt25TKyoGrzzpAG+sF4vBdimz/R+NbKu5U8J2A339n2J33+h//En5rmcrpt1m4hQNj/3jcPnPneDuhHI9k2p3jDwnleIojOc7YP16K5TneVijH0y3P8aeFcjzDkRxn7B8vw/Ic34x9rXjbFbH1E4ds3RKgrfHWpa4fiXqvaXnuPyo0ztVyZJxj7B+vluV9/ZhQX9cNqK8tOnf0OH3W/aFvhmWGSq2vt6ptt//R/DLym8g1AN9jP6ar7XcYexQ/fwx5E/LjyJuRP0Heglwf8ANpz1yM7Ka2fe5n/YvJj9Xc/qdqbv9zNbf/pZrb/1rN7X+r5va/V3P7P6q5/Z/V3P6vam6/tZrb/13N7fVPfdXZPqma2ydXc/sI2T75X7bPAKRUcbvUKm6XVsXt0qu4XUYVt8us4nY1qrhdzSpuV6uK29Wu4nZ1qrhd3SpuV6+K29Wv4nYNqrhdQ7LdJNzuBxyfn06Jnbd+/hG3+wn5Z+RfkH9F/g35d+Q/kP9E/gt5K/LfyLpmNSchJyNHkFOQU5HTkNORM5AzkWsg10SuhVwbuQ5yXeR6yPWRGyA3TK1afBIcDPcENIox/m7APPoeuZHpR0Dj1MqzZLi1/t6wgzv5ntBb8bTf+4XOb/3L/7Ftz7+CxrcJTrdpmhqymTfa8QeJszoAhT7juPZpko77pKu+5Sebpji4/W4gdLIZ5/Mzoj47vSapfD43ZWyrYUDxi8a3eIz57THmjNfQkQtbnPnXbCdt5eeVFZfn5WQXRXPKi6Gd3PKy7KKsAq88Pxuaz87xiovKoqU5xXm5Obn55XmBPXOF2hyNc6H2Nk9NzOBi6ZzmqfzttmBMeim/W6Sy95HILyJN0Vb2di09APnt5MyllnyDkdeU+cqzHsS0fQNUcP9TaBpHPMp3XEpimCtyttQK67b1Ts6WBsaImf9saaD677OlWO3859kSdyfZPsVQd0grgQGqVSp/gbXGAqMLt2Jm7C+vNePg14av2MtNPNvwx7NS8TPmAWs826by1qVZuM9AOM9a2zEfMCSmY7cVGIuaW36VR/vdTsDvFo6cZTP2j9fCkWkUrRjruj3jGCuV3+1TZcYLzr6WuGp9g8DV29YOXLW+W8DvNnZeta5kZwdOzcM4NrZxIG/uEcibjqn2+32vgN+dHPD7PgG/OzP6rS9S6KmC5mq1rm2dTzq2nclFSL1wjyNdGMcRS38JEtPTXQT0RlfGvErBvPIvnHGViG3XVPtt7CZ0bs9+EvAd43/luztwEiBRlD0sP8hpvxsL+N3e8kFYF2F3Ab87OHIS0JOxHhn72uOMn/BB7J+f7Llzs4cDB7GerhzEOjC21YuxaHRBR1Tlhbuj2iuZjuK2s50jdrZltJP+HLwaX/eGHOsD2AWgT+88QBYgG5AD6AvIBeQB8gEFgF0BuwH6AfoDdgfsoXNV/4IGGAgYBBgMGAIYChgGGA4YAdgTsBdgJGAUYDRgDGAsYG/AOMB4wATARMA+gEmAyYApgH0BUwH7AfYHHACYBpgOKAIUA0oApYAyQDlgBuBAwEzAQYBZgNmAOYC5gHmAgwHzAQsACwGLAIsBhwCWAJYClgEOBRwGOBywHHAEYAXgSMBRgKMBxwCOBRwHOB5wAuBEwEmAkwGnAE4FnAY4HXAGYCXgTMBZgLMB5wBWAc4FnAc4H3AB4ELARYCLAZcALgVcBrgcsBpwBeBKwFWAqwHXAK4FXAdYA1gLuB5wA+BGwE2AdYCbAbcAbgXcBrgdcAfgTsBdgLsB9wDuBdwHuB/wAOBBwHrABsBDgIcBGwGPAB4FPAbYBHgc8ATgScBTgKcBzwAaYy5W/GlK7bjodSm+2tLrUvG1Gb/TyHcKmepFYN5dNJPYHInhd0oMv1MJ1ySfK18M6mAc0lltLvJovJWvL/wxV2T/aWp7v/DYEvUyoI2G2FZJ0ezZYxfMPKRoUdnQxXNLFs2cN5cOccZkM9RFYoTMv56GPwNfp5J1mcQ1s860lUHW0a41IUniPjbom4D1Ih3D1G40qClb+pjDZXMMc7na3uHWss9ivJ9LDdkfXLTjUreW1cHU4D47fk4owbinWdFCiPfWss+m2h8/7ikTnD4/T9py5dayzzP2E7X3hdTEHxNYOueFVP52X2RMeim/XxRQJ7Fs5RjoXhQ4AL3EXJi6CHWbySq4ifVRB1Xay5h3r4RNpb0sqNJ0MF8RKJJXHFFpUUaV9nKq/fHjVmmcPr/qoEp7VUilvZZQaTyd85qASnvdcpWm/X7dEZX2CtrK3e4bAirtjYBVmuegSnsT8+6tsKm0NwVVmg7mWwJF8pYjKs1jVGlvptofP26Vxunz2w6qtLeFVNo7CZXG0znvCKi0dy1Xadrvdx1RaW+hrdztvieg0t4LWKXlOqjSNmPevR82lbZZUKXpYL4vUCTvO6LSchlV2uZU++PHrdI4ff7AQZX2gZBK+zCh0ng650MBlfaR5SpN+/2RIyrtfbSVu92PBVTaxwGrtDwHVdonmHefhk2lfSKo0nQwPxUokk8dUWl5jCrtk1T748et0jh9/sxBlfaZkEr7PKHSeDrncwGV9oXlKk37/YUjKu1TtJW73S8FVNqXAau0fAdV2hbMu6/CptK2CKo0HcyvBIrkK0dUWj6jStuSan/8uFUap89fO6jSvhZSad8kVBpP53wjoNK+tVylab+/dUSlfYW2crf7nYBK+y5glfaMgyrte8y7H8Km0r4XVGk6mD8IFMkPjqi0ZxhV2vep9sePW6Vx+vyjgyrtRyGV9lNCpfF0zk8CKu1ny1Wa9vtnR1TaD2grd7u/CKi0X1IrKweuPjN3DeGOw6+psv0fjW+puDPZrwJ+d860O+/1Hb4k/O7iyPM0GPvH62L5bUbbCeV4d8tzvI9QjvdwJMcZ+8frYXmOtxXK8d6W53iBUI73cSTHGfvH62N5jv+Afa142xWx9X2HbP3UIVu/CtDWeMcQXesSY5NneZ1mCY3JWY6MyYz942VZ3tfZQn3d15Fn9HGeR3H6rPtD317VXMTU5wJb1bYbSmp+BfktZH2L/t+wH9PV9rvVZuHn2cg5yH2R30f+FPkr5PqA30l75tawj+LnjyFvQn4c+QnkJ5FrAf4g7azEdn7HzwuQd0XeDbkfcn/k3ZH3QC5EHoA8EHkQ8mDkIchDkYchD0cegbwn8l7II5FHIY9GHoM8Fnlv5HHI45EnIE9E3gd5EvJk5CnI+yJPRd4PeX/kA5CnIU9HLkIuRi5BLkUuQy5HnoF8IPJM5IOQZyHPRp6DPBd5HvLByPORFyAvRF6EvBj5EOQlyEuRlyEfinwY8uHIy5GPQF6BfCTyUchHIx+DfCzyccjHI5+AfCLyScgnI5+CfCryacinI5+BvBL5TOSzkM9GPgd5FfK5yOchn498AfKFyBchX4x8CfKlyJchX468GvkK5CuRr0K+Gvka5GuRr0Neg7wW+XrkG5BvRL4JeR3yzci3IN+KfBvy7ch3IN+JfBfy3cj3IN+LfB/y/cgPID+IvB55A/JDyA8jb0R+BPkP5KeQn0buAfgzdfu4ZH4Y6o2f/4b8J3IDwF+plWcYcGsP/TzRixifT66fv3dXynZ7mdrlnLVQ6XniNL5bU7fx36khm7WgHX+QOKsDUOgzjmufJum4RWCeAw8jvUvA73w7n18V9dnpbU3l8/lvxrYKAopfNL7FY8xvjzFnvAJHTrQ580+fofxbW/l5ZcXleTnZRdGc8mJoJ7e8LLsoq8Arz8+G5rNzvOKismhpTnFebk5ufnleNKjZL9TmaJwLtTcpLTH7haVzdCC5201OY0x6Ib+T09j7SOQKrT7oJKfxt9vf0gNQpSvUjLkU4RuMvP7MV8L0IKbtG6CCm+NNBU20mkv5jktJDHNFzpZSsG5T0/79bGmg2r7829nSQPXfZ0ux2vnPsyXuTrJ9epbukBSBASoljb/AUrHA6MKtmBn7y0tlHPzS0tiKvdzEM40/npWKnzEPWOOZnsZbl2bhPgPhPGvNSOM9YEhMZU0XGIv2sPwqj/Y7Q8DvQkfOshn7xyt05GfdFMaxLJNxjJXK78w0mfGCs68lrlpfKXD1dpADV61vE/B7sJ1XrSvZWYOxHhn72hvsQN7cLpA3NdPs9/sOAb9rOeD3nQJ+12b0W1+k0FOEzNVqXds6n3Rsa9Onnyv+caQO4zhi6S9BYnq6joDeqMuYVymYV/6FM64Ssa2bZr+N9YTO7dlPAn5lPLmv78BJgERRNrD8IKf9/iuV3+9hlg/CugjrC/T3cEdOAhoy1iNjX3uc8RM+iP3zkz13bjZw4CDWUOogxl2QjRKqyGvkQEI1lkoo7pGzSQgun7ia6OtT7LexKXeiu3Kdq5kbv2lm0SSK1+fmiaOP19yBo08LF4pS4iJsSzeKMpuzKFslitJr5UBRtnahKCV+IWjjyOyfOoyzBNoyXyD8t6SM1852zINHDVV54Wr/32IQjW/x2jkweLR35XyyA2Pit2Y8n2yTmUh0F84nO7pwlLxH4CjZKYTnk50TRx+vswNHny4uFOW9AkXZNYTnk90SRel1c6Aou7tQlPcJFGUPR84nuzBOOOlp+YSTDtBGE4EJCHtZPvFC32S+sYDfIx2ZeNGLMS8Z+9obaXne6HppJpA3Yxyol6YCfo91pF56M9YLY197Yx2ol5YCeTPegXppIeD3BEfqpQ9jvTD2tTfBgXppI5A3kxyol9YCfk92pF52YawXxr72JjtQLxIT5qc6UC9tBfzez5F6iTLWC2Nfe/s5UC/tBfJmmgP10kHA7+mO1IvHWC+Mfe1Nd6BeOgrkTYkD9dJJwO9SR+oli7FeGPvaK3WgXroI5M0MB+qlq4DfBzpSL9mM9cLY196BDtRLd4G8meVAvfQQ8Hu2I/WSw1gvjH3tzXagXnoK5M08y/3Wv0lLPBj7YEfqpS9jvTD2tccZv6DuV9+Zr60d7lefm7hfPU/n5Arcrz6P8U8SUn7nCd2v3iz+iUJxPxiHMab5jANcRG0vOrrYPJBI2tnJETs7Kv6BWXNtfF0AObYrYDdAP0B/wO6APXTu6dtcAwYCBgEGA4YAGuN3M2PklF6X4ouFXmfuWW/qjd4BrpDJP4GDSTST2ByJ4XdKDL9TCdcknytfDOpgHNJ5bS6l8Va+vvDHXJH9p6nt/cJki5cBbTTHtsrmzl9ctrhs7OLi2TNLhi6eW7Jo5ry5g4pmz6aJaQw3CRqJETj/etoJGfg6lazLJA6adaatDLKOdrAJTBJ3RetRvQsxnqndaFBPz9hN6u9rvHZm0VgMxZ4flhayZw1qx//yGcO1Dx3MYQLn3cOEEoz7iRe7MUi9MnwswNA0++OXzBw/Tp+Hk7a8/OysrLxsvV1+adTLKS3Jys/KKi3OiZZEi0qyygpyvILynKyc7JLSkmJos8grj5YXlRSU52+zK6hz7uGM/UTtHZE45+bpnBEC59x7Wn7Orf3eU+icW+JAsafEH1WYC1MXoW4zWQX3jLN+Dqq0kZh3o8Km0kYKqjQdzFECRTLKEZXWj1GljUyzP37cKo3T59EOqrTRQiptTEKl8XTOGAGVNtZylab9HuuIShuFtnK3u7eASts7YJXW30GVNg7zbnzYVNo4QZWmgzle4j+Rjqi0/owqbVya/fHjVmmcPk9wUKVNEFJpExMqjadzJgqotH0sV2na730cUWnj0Vb2PxkLqLRJAau0gQ6qtMmYd1PCptImC6o0HcwpAkUyxRGVNpBRpU1Osz9+3CqN0+d9HVRp+wqptKkJlcbTOVMFVNp+lqs07fd+jqi0KWgrd7v7C6i0/QNWaYMcVGkHYN5NC5tKO0BQpelgThMokmmOqLRBjCrtgDT748et0jh9nu6gSpsupNKKEiqNp3OKBFRaseUqTftd7IhKm4a2crdbIqDSSgJWaYMdVGmlmHdlYVNppYIqTQezTKBIyhxRaYMZVVppmv3x41ZpnD6XO6jSyoVU2oyESuPpnBkCKu1Ay1Wa9vtAR1RaGdrK3e5MAZU2M62ycuDqsy7QRr5AHA5Kk+3/aHxLxZ0KDhLwe2Gm3Xmv//Ev4feiTDeEA2P/eIssv0VUJ6EcX2J5ju8qlONLHclxxv7xllqe4x2Fcvwwy3N8iFCOH+5IjjP2j3e45Tk+Bfta8bYrYus0h2wtC9DWeOtS149Eva+wPPd3FxrnjnRknGPsH+9Iy/t6D6G+Piagvrbo3NHj9Fn3h74ZlrkwqPX1VrXt9j+aRyGPR9bPCZ6F/Ziutt9hbHf8fA/kQuQByFOQpyGXIdcHzCbtmYuR3dS2z/2sfzGZU83t51Zz+3nV3P7gam4/v5rbL6jm9guruf2iam6/uJrbH1LN7ZdUc/ul1dx+WTW3P7Sa2x9Wze0PJ9sn/8v2GYDlVdzuiCput6KK2x1Zxe2OquJ2R1dxu2OquN2xVdzuuCpud3wVtzuhitudWMXtTqrididXcbtTqrjdqWS7SbjdbByfh6TFzls/z8Ht5iLPQz4YeT7yAuSFyIuQFyMfgrwEeSnyMuRDkQ9DPhx5OfIRyCuQj0Q+Cvlo5GOQj0U+Dvl45BOQT0Q+Cflk5FOQT61ifBIcDPcEnBZj/C3AfpqFfBpyA8DpaZVnyXBr/QdBYNFHzUfjW7z10F5fofNb//J/bNvzr6DxPQNtX5kWspk32vEHibMryY9p3CddJum4T7qOs/xk0xQHt9/H2/n8jKjPTu8MxskEKxnbOiGg+EXjWzzG/PYYc8Y7wZELW5z5d+ZO2srPKysuz8vJLormlBdDO7nlZdlFWQVeeX42NJ+d4xUXlUVLc4rzcnNy88vzAnvmypnME0XMclZaYgYXS+eclcbf7tmMSS/l99mO/CKyEm3lbvcUSw9Afjs5c+kcvsHIO4X5yrMexLR9A1Rw/1NYGUc8yndcSmKYK3K2tArr9tydnC0NjBEz/9nSQPXfZ0ux2vnPsyXuTrJ9iqHukFUCA9SqNP4COxcLjC7cipmxv7xzGQe/8/iKvdzE8zz+eFYq/lWWxvN85ro0C/cZCOdZ6wXMBwyJ6djnC4xFp1l+lUf7fYGA36c7cpbN2D/e6Y5Mo1jFWNcXMo6xUvl9YZrMeMHZ1xJXrTsI+H2mA1etPQG/z3Lkqc8XMdYjY197Z1meN7peOkmcizhQL1kCfp/rSL1czFgvjH3tnetAvXQVyJsLHKiXbAG/L3SkXi5hrBfGvvYudKBeegjkzSUO1EuOgN+XOlIvlzLWC2Nfe5zx0xfT9YVs86uq1qD6uKrHikvTlJKM72WM8bV0xoLYdZ/LBOrycsbz4hTMK//CGVeJ2F6eZr+Nq4WuQbNfrDqI8WLVFQ5crJIoyistv1il/T5dwO/Vlg/CugivEPD7CkfE0VWM9cjY1x5n/IQPYv9MLePOzSsdOIhd5cpBrAtjW1czFo0u6IiqvHB3VGcl01HcdnZyxM6OjHbSaUur8fU1kGPXAq4DrAGsBVwPuAFwI+AmwDrAzYBbALcCbgPcDrgDcCfgLsDdgHsA9wLuA9wPeED/dwOwHrAB8BDgYcBGwCOARwGPATYBHgc8AXgS8BTgacAzgGcBzwGeB7wAeBHwEuBlwCuAVwGvAV4HvAF4E/AW4G3AO4B3Ae8BNgPeB3wA+BDwEeBjwCeATwGfAT4HfAH4ErAF8BXga8A3gG8B3wG+B/wA+BHwE+BnwC+AXwG/AX4H/AH4E/AXYCvgb31mnA5xByQDIoAUQCogDZAOyABkAmoAagJqAWoD6gDqAuoB6gMaABoCGgEaA5oAmgKaAZoDWgBaAloBWgPaANoC2gHaAzoAOgI6AToDugC6AroBugN6AHoCegF6A/oAdgFEAR4gC5ANyAH0BeQC8gD5gALAroDdAP0A/QG7A/YAFAIGAAYCBgEGA4YAhmo/MBczY4xRel2Kr7b0OjOtz4zf9OJDIVO9pPHXczST2ByJ4XdKDL9TCdcknytfDOpgHNJZbS7yaLyVry/8MVdk/2lqe7/w2BL1MqCNhthWSdHs2WMXzDykaFHZ0MVzSxbNnDeXDnHGZDPURWKEzL+ehj8DX6eSdZnENbPOtJVB1tGuNSFJ4j426JtVXk0Sn6ndaFBTi6+TEnW8du5wC/RhmNzD00P2R0ztuNQt0HUwNbjPjnWbTDaK/oHuOoYrX+YW6MPS7Y9fMnP8OH0eQdpy5RboIxj7idq7Z3riD3QsnbNnOn+7ezEmvZTfe6Wz95HIH+iGo63c7Y5kLkxdhLrNZBXcH8DWOKjSRmHejQ6bShslqNJ0MEcLFMloR1TaGkaVNird/vhxqzROn8c4qNLGCKm0sQmVxtM5YwVU2t6WqzTt996OqLTRaCt3u+MEVNq4gFXaWgdV2njMuwlhU2njBVWaDuYEgSKZ4IhKW8uo0san2x8/bpXG6fNEB1XaRCGVtk9CpfF0zj4CKm2S5SpN+z3JEZU2AW3lbneygEqbHLBKW+egSpuCebdv2FTaFEGVpoO5r0CR7OuISlvHqNKmpNsfP26VxunzVAdV2lQhlbZfQqXxdM5+Aiptf8tVmvZ7f0dU2r5oK3e7BwiotAMCVmk3O6jSpmHeTQ+bSpsmqNJ0MKcLFMl0R1TazYwqbVq6/fHjVmmcPhc5qNKKhFRacUKl8XROsYBKK7FcpWm/SxxRadPRVu52SwVUWmnAKu0WB1VaGeZdedhUWpmgStPBLBcoknJHVNotjCqtLN3++HGrNE6fZzio0mYIqbQDEyqNp3MOFFBpMy1XadrvmY6otHK0lbvdgwRU2kEBq7ShQgcB5rzYQaXNwrybHTaVNktQpelgzhYoktmOqLShDAOuUWmz0u2PH7dK4/R5joMqbY6QSpubUGk8nTNXQKXNs1ylab/nOaLSZqOt3O0eLKDSDk6vrBy4+szcNYQ7DvPTZfs/Gt9ScWey+QL9f3Wm3Xmv7/Al4fc1jjz3ibF/vGssv81oJ6EcX2N5jl8rlONrHclxxv7x1lqe4x2FcvxGy3P8VqEcv8mRHGfsH+8my3Nca9X5AenqaHxLxVR2V2yd7pCt5QHaGu8YomtdYmy6xfI6vV5oTL7VkTGZsX+8Wy3v6xuE+voOR54ly3kexemz7g89TJqLmPpcYKvadkNJzaORJyDXACzAfkxX2+9Wez1+7wbkG5FvQt4Xvz8duRy5PmAhac/ckHV3/HwP5ELkAcgDkQch1wIsIu2sxHYW4ue3oh23Id+OfAfynch3Id+NfA/yvcj3Id+P/ADyg8jrkTcgP4T8MPJG5EeQH0V+DHkT8uPITyA/ifwU8tPIzyA/i/wc8vPILyC/iPwS8svIryC/ivwa8uvIbyC/ifwW8tvI7yC/i/we8mbk95E/QP4Q+SPkj5E/Qf4U+TPkz5G/QP4SeQvyV8hfI3+D/C3yd8jfI/+A/CPyT8g/I/+C/Cvyb8i/I/+B/CfyX8hbkf9GVph3ScjJyBHkFORU5DTkdOQM5ExTd8g1Tb4j10aug1wXuZ6pL+QGyA2RGyE3Rm6C3BS5GXJz5BbILZFbIbdGboPcFrkdcnvkDsgdkTshd0bugtwVuRtyd+QeyD2ReyH3Ru6DvAtyFNlDzkLORs5B7ouci5yHnI9cgLwr8m7I/ZD7Iy9CHow8xNgNWEzGJfPD0DWYJwtwu8WmnwCHpFeeYcCtPfRzFuvwzQGteH5hxS3fee3knLXg+VfQ+C7BA9nS9JDNWtCOP0icXUp+iOAWgSbpuEXgXQ483DMq4Pfddj6/Kuqz01vC+EPsUsa27gkoftH4Fo8xvz3GnPHuceREmzP/lu2krfy8suLyvJzsomhOeTG0k1tell2UVeCV52dD89k5XnFRWbQ0pzgvNyc3vzwvGtTsl2VCs18OTU/MfmHpnEPT+ds9jDHppfw+zJErtEvRVu52H7D0AOS3kzOXDucbjLwHmK+E6UFM2zdABTfHe2kc8SjfcSmJYa7I2dJyrNsjdnK2NDBGzPxnSwPVf58txWrnP8+WuDvJ9ulZukOWCwxQy9P5C+wILDC6cCtmxv7yjmAc/FbwFXu5iecK/nhWKv7llsbzSOa6NAv3GQjnWetRzAcMiamsRwqMRestv8qj/T5KwO8NjpxlM/aPt8GRn3WXM9b10YxjrFR+H50uM15w9rXEVesmAldvNzpw1bqXgN+P2HnVupKdxzDWI2Nfe49Ynje6XpoJ5M0mB+qlt4DfjztSL8cy1gtjX3uPO1AvLQXy5ikH6qWPgN9PO1IvxzHWC2Nfe087UC9tBPLmOQfqZRcBv593pF6OZ6wXxr72OOOnL6bXU9t/VdUaVB9X9VhxfLpSkvE9gTG+ls5YELvuc4LAefGJjOfFKZhX/oUzrhKxPTHdfhtPEroGzX6xaj7jxaqTHbhYJVGUp1h+sUr7fYiA3y9ZPgjrIjxZwO+XHRFHpzLWI2Nfe5zxEz6I/TO1jDs3T3HgIHaq1EGMuyBPS6gi7zQHEup0qYTiHjnPCMFlflcTPT/NfhtXupLoZ4bk+rxZmOc3ZOWn8fXFWYmjmHeWA0exs10p7nNC8mOCWZiLO5uzuFclittb5UBxn+tKcZ8Xgl8+aPy4zxnPZy7IOqrywh0H7mQ/34GCvMCVgryQsSDPZCzIszITie7COeNFriT6xYyJvoox0c8N4TnjJYmjmHeJA0exS10p7ssYi/sCxuK+MITnjJcnitu73IHiXu1KcV/BWNyXMBb3pZZPJOgCbZwhMJHgNcv91g81OV3A79cdmUBxJWO9MPa197oD9XKmQN685UC9rBTw+21H6uUqxnph7GvvbQfq5RyBvHnPgXo5W8DvzY7Uy9WM9cLY195mB+rlPIG8+dCBejlXwO+PHKmXaxjrhbGvvY8cqJcLBPLmUwfq5UIBvz9zpF6uZawXxr72PnOgXi4SyJsvHaiXiwX83uJIvVzHWC+Mfe1tcaBeLhXIm28cqJfLBPz+1pF6WcNYL4x97X3rQL2sFsibHxyolysE/P7RkXpZy1gvjH3t/Wh53mRBG30Vf978Yrnf+WrbXVy5/f7VkXq5nrFeGPva+9XyvMlLk/m98g/b6wX8vlLA7z8dqZcbGOuFsa+9Px2oF4nfK/92oF6uEvBbPxGU02+permRsV4Y+9rjjp9EvUj8Xhmx3G9dL1cL+J3iSL3cxFgvjH3tpThQLxK/V6Y7UC/XCPid4Ui9rGOsF8a+9jIcqBeJ3+1qOlAv1wr4XcuRermZsV4Y+9qr5UC9SPxuV9eBerlOwO96jtTLLYz1wtjXXj0H6kXid7uGDtTLGgG/GzlSL7cy1gtjX3uNHKgXid/tmjpQL2sF/G7mSL3cxlgvjH3tScUvmTl/khj74nZHnmqYzOjzHY74HGH0+U5HfE5h9PkuR3xOZfT5bkd8TmP0+R5HfE5n9PleR3zuwejzfY743I3R5/tD6PMDIfT5wRD6vN4Rn69nfJjJhhD280Mh9PnhEPq8MYQ+PxJCnx8Noc+PhdDnTSH0+fEQ+vxECH1+MoQ+PxVCn58Ooc/PhNDnZ0Po83Mh9Pn5EPr8Qgh9fjGEPr8UQp9fDqHPr4TQ51dD6PNrIfT59RD6/EYIfX4zhD6/FUKf3w6hz++E0Od3Q+jzeyH0eXMIfX4/hD5/EEKfPwyhzx+F0OePQ+jzJyH0+dMQ+vxZCH3+PIQ+fxFCn78Moc9bQujzVyH0+esQ+vxNCH3+NoQ+fxdCn78Poc8/hNDnH0Po808h9PnnEPr8Swh9/jWEPv8WQp9/D6HPf4TQ5z9D6PNfIfR5awh9/juEPquM8PmcFEKfk0PocySEPqeE0OfUEPqcFkKf00Poc0YIfc4Moc81QuhzzRD6XCuEPtcOoc91Quhz3RD6XC+EPtcPoc8NQuhzwxD63CiEPjcOoc9NQuhz0xD63CyEPjcPoc8tQuhzyxD63CqEPrcOoc9tQuhz2xD63C6EPrcPoc8dQuhzxxD63CmEPncOoc9dQuhz1xD63C2EPncPoc89QuhzzxD63CuEPvcOoc99QujzLo74fAPj86uijvh8I6PPniM+38Toc5YjPq9j9DnbEZ9vZvQ5xxGfb2H0ua8jPt/K6HOuIz7fxuhzXgg1SX4IfS4Ioc+7htDn3ULoc78Q+tw/hD7vHkKf93DE5wxGnwsd8TmT0ecBjvhcg9HngY74XJPR50GO+FyL0efBjvhcm9HnIY74XIfR56GO+FyX0edhjvhcj9Hn4Y74XJ/R5xGO+NyA0ec9HfG5IaPPeznicyNGn0c64nNjRp9HOeJzE0afRzP63ATbSUKfI4AUQCogDQCXqPVtrJQ+R9LnDFpDa02pNZbWHPoYrI9JeozWY5auYZ3Tuo+b4Hq9NAU0AzQHtAC0BLQCtAa0AbQFtAO0B3QAdAR0AnQGdAF0BVyEbd0ORt0BuBNwF+BuwD2AewH3Ae4HPAB4ELAesAHwEOBhwEbAI4BHAY8BNgEeBzwBeBKgnxuvn6Ounyuun7Otnzutn8Osn0usn9Orn1urn+Oqn2uqn/Opn3upnwOpn4uonxOon5unnyOnn6umnzOmn7uln0Oln8ukn1Okn9ujn2Ojn+uin3Oin/uhn4Ohnwuhn5Ognxug76Ov7yuv77Ou7zuu78Ot70ut79Os71us7+Or72ur7/Oq73uq7wOq74up7xOp75uo7yOo76un7zP3N3agvi+Xvk+Vvm+Tvo+Rvq+Pvs+Nvu+Lvg+Kvi+Ivk+Gvm+Evo+Cvq+A/p+9/t+5/h+2/l+y/p+u/t+q/h+n/l+j/p+f/t+b/h+Y/l+U/p+Q/t+M/h+J/l+F/p+Bnnev56Hredl6nrKet6vnsep5nXqeo573p+fB6Xlhep6Unjek59HoeSV6noWed6B/h9cXJvTvtPp3S/07nv5dS//Oo3/30L8D6Ovi+jqxvm6qryPq62r6OlPFdReAPi/X56n6vE2fx2hdr3Wu1n1aB2ldoI+T+rihx1E9rug6M8v/A0F8Bp3TYwgA", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -152,7 +172,7 @@ } ], "returnTypes": [], - "bytecode": "H4sIAAAAAAAA/+2dBZwcRfbHa2dWkmyy2Qhx2biHmfUlyIS4EiEQnMiGAEew4G6Bw53gFpzDDjvssMPdDrcDjgPuDnfCv9/kveSlMuw/uXmvqfp09+fTW93VM6/e75X0t3ure54vNKZjsVm5FGCawTSV35IuCmwU5bBblaqtrm6sq2xMV6XnpCob5tbXpKpr5tbWp+vTNfU18yvrq6oa66vr6xrmNtSlGtLVVY3pBTUNVQvQcJGcjykN3RDSYgXdxY7rLglslCjoLhHW/VvtPV8/Own6WYCxrEB7HYN1ebB2img6NFg7Y51BXMoxLp0d8KtLsCaDtZn57SWDaSq/Ja1nuyqlaFvT70pF21WKtqsVbdco2q4tYTa7YtoN0+6Y9sC0J6YVmPYK1keTK7abmzX7THNcYSlgeS1wO8HySnE7yfJa4nYhy2uF20Usrwy3i1lea9wusY7BksE0leeSiwtSeS7NWVyaMT08LpRSXFqwPIpLKcsj7S1ZHsWlFcuj8spYHpVH8QT7XdlxWnhdUky4z3S8MIemohyainNoKsmhifsMeRSLDKapPJdiFiMpm7y901Jg7WfYdisWk5ayvmT5tkzWZjZm5QoxKzNrH7NyFrPWCjFrI2szG7N2CjFrY9Y+Zu1YzNoqxKy9rM1szDooxKy9WfuYdWAxW08hZh1lbaYUbGb97KTgZ1dZm/VQt53N2tdtV1a3XRRi1k3WZjZm3YVtgo0eLCYUP/K9lB3vzuLVQzheBaxMskv7PfTKzerv+f/o75nDj54h6uf+xb7Gvsa+/r6+dv+dfYVyK0TLTdc1t8qFpalzZ4ViDMBmL1mb2XG+N/OftFI5pew4b4u9hbUVsDLJLu1z/2JfY19jX2NfY19jX2NfY19jX2NfY19jX2NfY1998ZX/DzTBfBG+ts/6YixfTI640NLcIV+KHfIl6ZAvJQ75UuiQL80c8qXIIV8Kfmdf+LwYw/LoeILl0fjI58/0wW0+f6YvbvP5M/2YTsrrj9t8/swA3OZzjAaybUoH4TafYzQYt/kcoyG4zecYDcVtPp9oGG63ZnnDcbsNy1sft9uyPJrU2J7l0WTE9VgeTSLsyPJo8l8nlkeT9jqzPJps14Xl1eJ2N5ZXh9s9WR7VIa9zqsPeLI/qsA/Lozrsy/KoDvuxPKrD/iyP6nAAy6M65HVKdTiI5VEdDmZ5VIdDWB7NQRrK8qheh7E8qtfhLI/m4qzP8qiuUyyP6jrN8mhOSiXLo/qvYnlU/9Usj+Zm1LA8ahO1LI/aBNUp1MW0glXH6fu8j1I5vI/W5SivNodftM3HJPpOBtNUfkt2TOLlZNg+ldWC+VDtgC9FDvnSzCFfCh3ypcQhX5IO+VLskC/NHfIlkcOXKllfsqcQ/uAAjcNVzA/yqZL5kRaOSdZGDj/SzA8qP8X8WF/Wj2wRw3P4sT7zg8ofzvwYJutHNvxDc/gxjPlB5Q9lfgyR9SPb9Abn8GMI84PKH8z8GCTrR7YJDszhB2dsKn8g82OArB9ZJOmfw48BzA8qvz/zo5+sH9li++bwox/zg8rvy/zoI+tHdizj11KwT+MFlZVknxmJ0ARMzK/DOKMS73O+pesCzsb1uM25ugG3OZNvgNuc50fgNr8WoPGWX0c0dQ3Cr1WIv+pZHp3XGlgeMcAGLI94iXwqwe8Kz3GthLJoXi4tTV1/8/lZ9D1+rUhztfhcX425q90t/+xnq0pZHp9TLjyfN+tLS8sX2u+uXG6ZVW5ZSOWWW+WWh1RuW6vctiGV28kqt5NV7m/dd9fwxVi+mCZ86eyQL+0d8qW1Q76UO+RLC4d8KXHIl0KHfOnqkC8dHfKlk0O+tHPIl1YO+VLmkC/NHfKl2CFfkg750sUhX9ZzyBft65l18aWNQ760dciXUod8aemQL80c8qXIIV8Kfmdffms+BR3n/6uleyx8DkNPSxPkVeA2n8NA98f4e1LoPhqf10D3Cfm8BroHV87y6N4mn+tA9+/4XAe6F9uO5dG9Pz7/ge4d87kOdN+Qz3WgePD40bmzB8ujawc+r4HaXQXLIwbg9w/pGojfZ6T+w+c6EMvwe5RUN3yuA9UNv79JdcPnOlDd8HujVDd8rgPVDcUHdN3E3l9E3+dth8rh/+cfnKO8QTn8om3eV+g7GUxT+S3ZvsLLybB9Kov/n3+AA74UOeRLM4d8aemQL6UO+dLWIV/aOORLB4d8Wc8hX7o45EvSIV+KHfKluUO+lDnkSyuHfGnnkC+dHPKlo0O+dHXIl0KHfClxyJcWDvlS7pAvrR3ypb1DvnR2yJdESL7Q9TPZHWT5AuX2ly03OzWrHyuXruv7M/1UPn+upq+wHwWWHxWsXM15b2Cjdw79fZh+Kr8386O3sB+gvwPzI8P2+b0k6hdUP3C+qUms8kt4nmTWL97+DjNr9s0k+8yoxCq/GhKrYkhz0Ph7k3tYeWBf411hPay42u/yBv/suWjcP/7Mk/1+M35fkX83aZVRYlTqJ8XrB5YKs2b98HGu2Kzet6jPJdlnxrM6PDK56nvCvq82Fzhhco/5wv09Oz2V+o5h9nkMe7HtXONhb+tzFFNBP9O2H1R+BcvrkcPPXszPXO8NlH43qt2/CsyafcTeJi19mF/Cc2SbPJ92Y+UKz7OvXNd3BA5hvgyX9aWKP3+6Nr4oPgeRVnjGI/uu35SwTbDBf9yD4ke+l7Lj/PkV6edoCliZZJf2uX+xr/K+gi/dLD/589jdHPCP8vhzx12s+MH5e289NqzKxYb2fWfOhkuSq/zaj7HhQCuu/P/BPNYaz7xwFsiYNc9NLZgW/hyQ8HXYateiZNelcoVjn22inG8G5og7la/NWT1z+FHB/KDy+buFhTkqy6VDcvjRnflB5XNmGCocj+aWH7A0xQz8mUVhfknzd2WsjS+cX4S5IM3H/7XxhZ/DKhV8Sa+DL/x532oFX6rWwRf+DHStgi816+BLLfOlXsGXunXwhcqHczv1v/4sj/pBL5ZH7ZHP46J20ZflUf30Znn2+zxKmb98rhg988jv24yw8iB+G1qaUvkt2fMSlUN2aX9D5h89fzlCz5d6bp/fp9iQlbmRsP5iZktKB9gcKewn2NgUbRWy+qBykuz4Ley+0q24De1pYzzewOw8lOM4LU31owyrk9GyWrP3OsYw+5kcZUD+WNly07zcAlypDMpPsu0HqVOzz8FC8SWfof+MyvE5vr2x9Z1SdnyUsubRzI8M26eyoJ3cwdrUQ+xaZxNhf7heHpcRLC50fCP2uU3ZNn22gsVtlKyf9QrtPqt9DIs5xZbK4W3vKVYfz7A+PNKKGxx/K8dxWprq47zdjZPVmu3j45n9DCuDlztBttw0L5f6OJVB+Um2/Sbr4xNWba6ML/kMfXxsjs/x7ZHWd0rZ8bHKmscxPzJsn8qCdvI8a1NvsT6eEfaH6+Vx2ZTFhY7z+wZj2DZ9toLFTXhsrFdo91nt41nMyS6Vw9veR6w+PmZ9eLQVNzj+XY7jtDTVx3m7myirNdvHJzH7GVYGL3eybLlpXi71cSqD8pNs+1vWxyev2lwZX/IZ+viEHJ/j26Ot75Sy4xOUNU9kfmTYPpUF7eRT1qa+Y31c+PyY5np5XMawuNBxfn9qPNumz1awuAmPjfUK7T6rfRKLOcWWyuFtz7B7tQn2fMg4K25wvE2O47Q01cd5u5siqzXbx6cy+xlWBi93M9ly07xc6uNUxlQWWtoup4kC7HOwUHzJZ+jjk3N8jm+Ps75Tyo5PVtY8hfmRYftUFrSTItam2rB5BdLXDlwvj8t4Fhc6zu/9TmLb9NkKFjfhsbFeod1ntU9lMafYUjm87XVh9dGN9eGJVtzg+JAcx2lpqo/zdjdNVmu2j09n9jOsDF7uDNly07xc6uNUBuUn2fZg1sdnrNpcGV/yGfr4Zjk+x7cnWt8pZcc3U9Y8jfmRYftUFrSTnqxNDWF9XPragevlcZnE4kLH+7LPTWXb9NkKFjfhsbFeod1ntU9nMafYUjm87VWz+qhlfXiKFTc4PibHcVqa6uO83c2U1Zrt45sz+xlWBi93lmy5aV4u9XEqg/KTbHs06+OzVm2ujC/5DH18Ro7P8e0p1ndK2fEZyppnMj8ybJ/Kys7rZG1qDOvj0tcOXC+Py1QWFzrem31uOtumz1awuAmPjfUK7T6rfXMWc4otlcPb3lRWH9NYH55mxQ2O75DjOC1N9XHe7raQ1Zrt41sy+xlWBi93tmy5aV4u9XEqg/KTbHt71sdnr9pcGV/yGfr4rByf49vTrO+UsuOzlDVvwfzIsH0qC9rJTNamdmB9XPragevlcZnO4kLH2e2QlW2ff7aCxU14bKxXaPdZ7VuymFNsqRze9hay+tiF9eGZVtzg+AE5jtPSVB/n7W4rWa3ZPr41s59hZfByt5EtN83LpT5OZVB+km3vz/r4Nqs2V8aXfIY+PjvH5/j2TOs7pez4bGXNWzE/MmyfyoJ2shtrUwewPi597cD18rhszuJCx/m7gLtan4f2TP2Bzz2Q7pf8vEB2aZ+P15THr38Un5fIxpE/p2A/L8GfDxrIfKLng3yca2lv0/xS/jwBv0+b63mNPtbnQJ/wc0ZVCs8SZOub5tcVsthQOUl2/AzWl89i4z9p5u1hWY7jtDR1fuDzH4Xn+qX4vGc6PwzPUa70vD5eLp0fqAzKT7Lty9n5gf/OBcWXfIZ2NyzH5/h2L+s7pez4MGXN/LcxMmyfzx1fytrUMjauVQj7w/XyuHRhcaHj/Jkhzf7Gyx/C/LB/S5Q/E8jHT+nnZ/hzVWSX9ocx/yivgvlHOvhYwp8LKFfwtbXlK+3zd2drlFtklVsUUrklVrklIZXb3Cq3eUjlllrlloZUbvjtKl0HNtsJ24R6amNWX5o69/L3U7cV9SWVbmZWvQNup8bFU3df3Lh3AfOJ/KR3vrRgfvFr8iT7TqFZU1txjrxmOfJamDUX/nsdrdh2OftemeUnxJjeacHfNUnv6eLvmiQd/L2SpIc+X2LWrCPRkw8tCct2Vaq2urqxrrIxXZWek6psmFtfk6qumVtbn65P19TXzK+sr6pqrK+ur2uY21CXakhXVzWmF9Q0VC1A4wlBP3vI2eIstDKwUn5WCMaPBnhqEHDxudysOOFD2h1TWPiN6Fy68vWlj5E/cVF764M6ejM9fVH3Gg1foc56ytlKcX/hJQc0IOUasIoVtBirHDt+ZUZ5MNGonH4Kdvsbuc6hpbu/fB2tNvhJD/i9BG0NMPIDztoMpAOxLnMNUAPZ5wbl+FwCjw/CFDr/YLP6Ih1zyXY85HeK+dAmYj6UfW5YEzEfxmI+PMfneuLx4ZjyuysaY8tgI38SXlIoOw5I6x6CMZXWfWyhzviXFPYzJRhLwbpOS8YvLCjrKGcrxa8qySbACjyhDE+pwtPB8GQqPJkLT6PCo5fw1Bo8VQhPT8ETl/B0FTzlsgnaGGlWPHUxyqyYNQuzs8eaFbPrYBYnzI6CWTgw2wtmUcB/62FWCPy3Ff6rB/89hv/gwH+Z4D9S8N9I+C8P/HcH/isF/zmD/w7Cf862DdbtgnX7YN0hWHcM1jnBOjdY5wXr/GBtDNYFwbpTsC4M1p2DdZdg3TVY/xCsuwXromDdPVj3MKtfmXI4hYVfMWeE6kABdlPcd0rhzlsJ02as42Wor0jUl+oUv3Knpak7K/wXRQpFfVlxZ4XuSgR3Vkbus3jhljsvXtS492r3V+zRryBHtPjvTfDfYaAIF7K8BFNEefSdEpaqXX4kzZpNmQuTKidtdE5HovFIr7j/QsuemO5lVjW9AhYvqMhfc8SsgG0n8DOJJj5T8Bt2fqsrqjUGEgfCv2ViIQD23b+kcNm8gfyvTNG4AJZUek8BW8QnexmdhpsQjp+k5r1XsxV8dk5ldW1jTaq2sb6hvrGhbkFNXWrenAUL5telqufNTc2dW12bqkpXLZhbV5maW9kQFNvQWDMvnfUrLPbZW87WajekFpv4hpRI5SxWsLuPcfuGFOjeR76OcvoqMdDto2B3XyPbMaETgk1CpTDopdLonARE24VFL/thur+JGL2AcE4vEABteuENJF962c/Idb79jR/0Iqn5AOMfvRxgZAdJWg40Mb2IVM6BCnYPMm7TC+g+SL6OVOhlf/RV2u7BRrZjQicEm2HSS5XROQmItguLXg7B9FATMXoB4ZxeIADa9MIbSL70coiR63yHGj/oRVLzYcY/ejnMyA6StBxuYnoRqZzDFeweYdymF9B9hHwdqdDLoeirtN0jjWzHhE4INsOkl2qjcxIQbRcWvRyF6dEmYvQCwjm9QAC06YU3kHzp5Sgj1/mONn7Qi6TmY4x/9HKMkR0kaVliYnoRqZwlCnaPNW7TC+g+Vr6OVOjlaPRV2u5xRrZjQicEm2HSS43ROQmItguLXv6I6fEmYvQCwjm9QAC06YU3kHzp5Y9GrvMdb/ygF0nNJxj/6OUEIztI0nKiielFpHJOVLB7knGbXkD3SfJ1pEIvx6Ov0nZPNrIdEzoh2AyTXmqNzklAtF1Y9HIKpqeaiNELCOf0AgHQphfeQPKll1OMXOc71fhBL5KaTzP+0ctpRnaQpOV0E9OLSOWcrmD3DOM2vYDuM+TrSIVeTkVfpe2eaWQ7JnRCsBkmvdQZnZOAaLuw6OUsTM82EaMXEM7pBQKgTS+8geRLL2cZuc53tvGDXiQ1n2P8o5dzjOwgSctSE9OLSOUsVbB7rnGbXkD3ufJ1pEIvZ6Ov0nbPM7IdEzoh2AyTXuqNzklAtF1Y9HI+pheYiNELCOf0AgHQphfeQPKll/ONXOe7wPhBL5KaLzT+0cuFRnaQpOUiE9OLSOVcpGD3YuM2vYDui+XrSIVeLkBfpe1eYmQ7JnRCsBkmvTQYnZOAaLuw6OVSTC8zEaMXEM7pBQKgTS+8geRLL5cauc53mfGDXiQ1X278o5fLjewgScsyE9OLSOUsU7B7hXGbXkD3FfJ1pEIvl6Gv0navNLIdEzoh2AyTXjYwOicB0XZh0ctVmF5tIkYvIJzTCwRAm154A8mXXq4ycp3vauMHvUhqvsb4Ry/XGNlBkpZrTUwvIpVzrYLd64zb9AK6r5OvIxV6uRp9lbZ7vZHtmNAJwWaY9DLC6JwERNuFRS9/wvQGEzF6AeGcXiAA2vTCG0i+9PInI9f5bjB+0Iuk5huNf/Ryo5EdJGm5ycT0IlI5NynYvdm4TS+g+2b5OlKhlxvQV2m7txjZjgmdEGyGSS8bGp2TgGi7sOjlz5jeaiJGLyCc0wsEQJteeAPJl17+bOQ6363GD3qR1Hyb8Y9ebjOygyQtt5uYXkQq53YFu3cYt+kFdN8hX0cq9HIr+ipt904j2zGhE4LNMOllI6NzEhBtFxa9/AXTu0zE6AWEc3qBAGjTC28g+dLLX4xc57vL+EEvkprvNv7Ry91GdpCk5R4T04tI5dyjYPde4za9gO575etIhV7uQl+l7d5nZDsmdEKwGSa9bGx0TgKi7cKil79ier+JGL2AcE4v9xt9euENJF96+auR63z3Gz/oRVLzA8Y/ennAyA6StDxoYnoRqZwHFew+ZNymF9D9kHwdqdDL/eirtN2HjWzHhE4INsOkl02MzklAtF1Y9PI3TB8xEaMXEM7pBQKgTS+8geRLL38zcp3vEeMHvUhqftT4Ry+PGtlBkpbHTEwvIpXzmILdx43b9AK6H5evIxV6eQR9lbb7hJHtmNAJwWaY9JIxOicB0XZh0cuTmD5lIkYvIJzTCwRAm14yRo5enjRyne8p4we9SGp+2vhHL08b2UGSlmdMTC8ilfOMgt1njdv0Arqfla8jFXp5Cn2Vtvucke2Y0AnBZpj0MtLonARE24VFL89j+oKJGL2AcE4vEABteuENJF96ed7Idb4XjB/0Iqn5ReMfvbxoZAdJWl4yMb2IVM5LCnZfNm7TC+h+Wb6OVOjlBfRV2u4rRrZjQicEm2HSy6ZG5yQg2i4sevk7pq+aiNELCOf0AgHQphfeQPKll78buc73qvGDXiQ1v2b8o5fXjOwgScvrJqYXkcp5XcHuG8ZtegHdb8jXkQq9vIq+Stt908h2TOiEYDNMehlldE4Cou3Cope3MH3bRIxeQDinFwiANr3wBpIvvbxl5Drf28YPepHU/I7xj17eMbKDJC3vmpheRCrnXQW77xm36QV0vydfRyr08jb6Km33fSPbMaETgs0w6WW00TkJiLYLi17+gekHJmL0AsI5vUAAtOmFN5B86eUfRq7zfWD8oBdJzR8a/+jlQyM7SNLykYnpRaRyPlKw+0/jNr2A7n/K15EKvXyAvkrb/djIdkzohGAzTHoZY3ROAqLtwqKXf2H6iYkYvYBwTi8QAG164Q0kX3r5l5HrfJ8YP+hFUvOnxj96+dTIDpK0fGZiehGpnM8U7P7buE0voPvf8nWkQi+foK/Sdv9jZDsmdEKwGSa9jDU6JwHRdmHRy38x/dxEjF5AOKcXCIA2vfAGki+9/NfIdb7PjR/0Iqn5C+MfvXxhZAdJWr40Mb2IVM6XCna/Mm7TC+j+Sr6OVOjlc/RV2u7XRrZjQicEm2HSyzijcxIQbRcWvXyDKZzII0Uv35jV6QW2temFN5B86eUbI9f5vjV+0Iuk5u+Mf/TynZEdJGn53sT0IlI53yvY/cG4TS+g+wf5OlKhl2/RV2m7PxrZjgmdEGyGSS/jjc5JQLRdWPTyE6Y/m4jRCwjn9AIB0KYX3kDypZefjFzn+9n4QS+Smn8x/tHLL0Z2kKRluYnpRaRylivY/dW4TS+g+1f5OlKhl5/RV2m7YFBK98qzb0G49DLB6JwERNuFRS8FGIREQcToBYRzeoEAaNMLbyD50ktBgVznSxToNFxpepHUnCzwj16SwoMkLYUFMb2IVA4EUtpukWCj19JdVCBeRyr0kkBfpe0WK9BLccj0MtHonARE24VFLyUYhGZRo5cSi16ahUAvvIHkSy8lgoNaM0/oRVJzcw/ppbkSvbSI6UWmcloo0Eup4/QCuks9oZdm6Ku03ZYK9NIyZHqZZHROAqLtwqKXVhiEsqjRSyuLXspCoBfeQPKll1aCg1qZJ/Qiqbm1h/TSWoleymN6kamccgV6aeM4vYDuNp7QSxn6Km23rQK9tA2ZXiYbnZOAaLuw6KUdBqF91OilnUUv7UOgF95A8qWXdoKDWntP6EVS83oe0st6SvTSIaYXmcrpoEAvHR2nF9Dd0RN6aY++StvtpEAvnUKmlylG5yQg2i4seumMQegSNXrpbNFLlxDohTeQfOmls+Cg1sUTepHU3NVDeumqRC/dYnqRqZxuCvTS3XF6Ad3dPaGXLuirtN0eCvTSI2R6mWp0TgKi7cKil54YhIqo0UtPi14qQqAX3kDypZeegoNahSf0Iqm5l4f00kuJXnrH9CJTOb0V6KWP4/QCuvt4Qi8V6Ku03b4K9NI3ZHrZzOicBETbhUUv/TAI/aNGL/0seukfAr3wBpIvvfQTHNT6e0IvkpoHeEgvA5ToZWBMLzKVM1CBXgY5Ti+ge5An9NIffZW2O1iBXgaHTC/TjM5JQLRdWPQyBIMwNGr0MsSil6Eh0AtvIPnSyxDBQW2oJ/QiqXmYh/QyTIlehsf0IlM5wxXoZX3H6QV0r+8JvQxFX6XtphToJRUyvUw3OicB0XZh0Usag1AZNXpJW/RSGQK98AaSL72kBQe1Sk/oRVJzlYf0UqVEL9UxvchUTrUCvdQ4Ti+gu8YTeqlEX6Xt1irQS23I9DLD6JwERNuFRS91GIT6qNFLnUUv9SHQC28g+dJLneCgVu8JvUhqbvCQXhqU6GWDmF5kKmcDBXoZ4Ti9gO4RntBLPfoqbXdDBXrZMGR6mWl0TgKi7cKil40wCBtHjV42suhl4xDohTeQfOllI8FBbWNP6EVS8yYe0ssmSvSSielFqHIU6GWk4/QCukd6Qi8bo6/SdjdVoJdNQ6aXzY3OSUC0XVj0MgqDMDpq9DLKopfRIdALbyD50ssowUFttCf0Iql5jIf0MkaJXsbG9CJTOWMV6GWc4/QCusd5Qi+j0Vdpu+MV6GV8yPQyy+icBETbhUUvEzAIE6NGLxMsepkYAr3wBpIvvUwQHNQmekIvkponeUgvk5ToZXJMLzKVM1mBXqY4Ti+ge4on9DIRfZW2O1WBXqaGTC9bGJ2TgGi7sOhlMwzCtKjRy2YWvUwLgV54A8mXXjYTHNSmeUIvkpqne0gv05XoZUZMLzKVM0OBXmY6Ti+ge6Yn9DINfZW2u7kCvWweMr1saXROAqLtwqKXWRiELaJGL7MsetkiBHrhDSRfepklOKht4Qm9SGre0kN62VKJXmbH9CJTObMV6GUrx+kFdG/lCb1sgb5K291agV62DpleZhudk4Bou7DoZRsMwrZRo5dtLHrZNgR64Q0kX3rZRnBQ29YTepHUvJ2H9LKdEr1sH9OLTOVsr0AvOzhOL6B7B0/oZVv0Vdrujgr0smPI9LKV0TkJiLYLi17mYBDmRo1e5lj0MjcEeuENJF96mSM4qM31hF4kNc/zkF7mKdHL/JheZCpnvgK9NDpOL6C70RN6mYu+SttdoEAvC0Kml62NzklAtF1Y9LITBmFh1OhlJ4teFoZAL7yB5EsvOwkOags9oRdJzTt7SC87K9HLLjG9yFTOLgr0sqvj9AK6d/WEXhair9J2/6BAL38ImV62MTonAdF2YdHLbhiERVGjl90selkUAr3wBpIvvewmOKgt8oReJDXv7iG97K5EL3vE9CJTOXso0MuejtML6N7TE3pZhL5K291LgV72CpletjU6JwHRdmHRy94YhMVRo5e9LXpZHAK98AaSL73sLTioLfaEXiQ17+MhveyjRC/7xvQiUzn7KtDLfo7TC+jezxN6WYy+StvdX4Fe9g+ZXrYzOicB0XZh0csBGIQDo0YvB1j0cmAI9MIbSL70coDgoHagJ/QiqfkgD+nlICV6OTimF5nKOViBXg5xnF5A9yGe0MuB6Ku03UMV6OXQkOlle6NzEhBtFxa9HIZBODxq9HKYRS+Hh0AvvIHkSy+HCQ5qh3tCL5Kaj/CQXo5QopcjY3qRqZwjFejlKMfpBXQf5Qm9HI6+Sts9WoFejg6ZXnYwOicB0XZh0csxGIQlUaOXYyx6WRICvfAGki+9HCM4qC3xhF4kNR/rIb0cq0Qvx8X0IlM5xynQyx8dpxfQ/UdP6GUJ+ipt93gFejk+ZHrZ0eicBETbhUUvJ2AQTowavZxg0cuJIdDLjkaOXk4QHNRO9IReJDWf5CG9nKRELyfH9CJTOScr0MspjtML6D7FE3o5EX2VtnuqAr2cGjK9zDE6JwHRdmHRy2kYhNOjRi+nWfRyegj0whtIvvRymuCgdron9CKp+QwP6eUMJXo5M6YXmco5U4FeznKcXkD3WZ7Qy+noq7TdsxXo5eyQ6WWu0TkJiLYLi17OwSAsjRq9nGPRy9IQ6IU3kHzp5RzBQW2pJ/QiqflcD+nlXCV6OS+mF5nKOU+BXs53nF5A9/me0MtS9FXa7gUK9HJByPQyz+icBETbhUUvF2IQLooavVxo0ctFIdALbyD50suFgoPaRZ7Qi6Tmiz2kl4uV6OWSmF5kKucSBXq51HF6Ad2XekIvF6Gv0nYvU6CXy0Kml/lG5yQg2i4serkcg7AsavRyuUUvy0KgF95A8qWXywUHtWWe0Iuk5is8pJcrlOjlypheZCrnSgV6ucpxegHdV3lCL8vQV2m7VyvQy9Uh00uj0TkJiLYLi16uwSBcGzV6ucail2tDoBfeQPKll2sEB7VrPaEXSc3XeUgv1ynRy/UxvchUzvUK9PInx+kFdP/JE3q5Fn2VtnuDAr3cEDK9LDA6JwHRdmHRy40YhJuiRi83WvRyUwj0whtIvvRyo+CgdpMn9CKp+WYP6eVmJXq5JaYXmcq5RYFe/uw4vYDuP3tCLzehr9J2b1Wgl1tDppedjM5JQLRdWPRyGwbh9qjRy20WvdweAr3wBpIvvdwmOKjd7gm9SGq+w0N6uUOJXu6M6UWmcu5UoJe/OE4voPsvntDL7eirtN27FOjlrpDpZaHROQmItguLXu7GINwTNXq526KXe0KgF95A8qWXuwUHtXs8oRdJzfd6SC/3KtHLfTG9yFTOfQr08lfH6QV0/9UTerkHfZW2e78CvdwfMr3sbHROAqLtwqKXBzAID0aNXh6w6OXBEOiFN5B86eUBwUHtQU/oRVLzQx7Sy0NK9PJwTC8ylfOwAr38zXF6Ad1/84ReHkRfpe0+okAvj4RML7sYnZOAaLuw6OVRDMJjUaOXRy16eSwEeuENJF96eVRwUHvME3qR1Py4h/TyuBK9PBHTi0zlPKFAL086Ti+g+0lP6OUx9FXa7lMK9PJUyPSyq9E5CYi2C4tensYgPBM1ennaopdnQqAX3kDypZenBQe1ZzyhF0nNz3pIL88q0ctzMb3IVM5zCvTyvOP0Arqf94RenkFfpe2+oEAvL4RML38wOicB0XZh0cuLGISXokYvL1r08lII9MIbSL708qLgoPaSJ/QiqfllD+nlZSV6eSWmF5nKeUWBXv7uOL2A7r97Qi8voa/Sdl9VoJdXQ6aX3YzOSUC0XVj08hoG4fWo0ctrFr28HgK98AaSL728Jjiove4JvUhqfsNDenlDiV7ejOlFpnLeVKCXtxynF9D9lif08jr6Km33bQV6eTtkellkdE4Cou3Copd3MAjvRo1e3rHo5d0Q6IU3kHzp5R3BQe1dT+hFUvN7HtLLe0r08n5MLzKV874CvfzDcXoB3f/whF7eRV+l7X6gQC8fhEwvuxudk4Bou7Do5UMMwkdRo5cPLXr5KAR64Q0kX3r5UHBQ+8gTepHU/E8P6eWfSvTycUwvMpXzsQK9/MtxegHd//KEXj5CX6XtfqJAL5+ETC97GJ2TgGi7sOjlUwzCZ1Gjl08tevksBHrhDSRfevlUcFD7zBN6kdT8bw/p5d9K9PKfmF5kKuc/CvTyX8fpBXT/1xN6+Qx9lbb7uQK9fI70kjCrdwTp+usoWGcVaOeLwMkvg/WrYP06WL+Bk22wfhes3wfrD8H6Y7D+FKw/B+svwbo8WH9F8QXBmgjWZLAWBmtRsBYHa0mwNgvW5sHaIlhLg7VlsLYK1rJgbR2s5RgwiuMXeGKn/S+t/a+s/a+t/W+s/W+t/e+s/e+t/R+s/R+t/Z+s/Z+t/V+s/eXW/q/WPvzh+wXWfsLaT1r7hdZ+kbVfbO2XWPvNrP3m1n4La7/U2m9p7bey9sus/dbWfnlCH+R4n8l37PhCcHw/vlAH5Oz45QuvXxbI2IK6+Eowfic4H7+s6fTX+WuuRM3pbwTjd6LL8ate6Wf62/w0p5jm9HeC8TvJ1fhVruZn+vv/XXPK0pz+QTB+JzsYv9oFa/iZ/vF/01yfQ3P6J8H4neJa/Opz+pn+ed011/2G5vQvgvE71aX41f2mn+nl66a5sgnN6V8F43eaK/Gra9LPNIDmWtqa9/9oThck5OJ3ugvxq/t//Uwn1k5zai00p5OC8Tvj945faq38TBf+/5pr1lJzukgwfmf+nvGrXms/08VNaq5esA6a0yWC8Tvr94pf3Tr5mW7225rr11Fzurlg/M7+HeLXsGCd/Uy3yK059T9oTpcKxu+csOOX+p/8TLdcU3P6f9ScbiUYv6Vhxm/+/+xnumx1zVV5aE63FozfuSHFr3JBXn6myxNy9xL5Pbt843deSPFL5bekBe+zpU8UjN/5nsRP8D5R+mTB+F3gSfwE73OkTxWM34WexE/wOj19umD8LvIkfoLXmekzBeN3sSfxE7xOSp8tGL9LPImfIOenlwrG71JP4ifIqenzBON3mSfxE+Ss9AWC8bvck/gJckL6IsH4LfMkfoLnufQlgvG7wpP4CY7T6csE43elJ/ETHGfSywTjd5Un8RPsJ2nBNpOWjB/MZ4MnMroG6/Jg7YYp2d/LrJjntj+mh2J6NKbHY3oqpmdjegGml2F6NaY3YHorpndhej+mj2D6FKYvYPoqpm9j+gGmn2D6OabfYvozpgmct9gM0zJM22PaBdMKTPtjOhTTSkzrMd0Y09GYTsR0GqZbYLotpnMxXYjpIkwXY3ogpodjugTTEzE9HdOlmF6E6TJMr8X0Jkxvx5R+WJh+oo9+7IZeG08vYKVXmb2LKT1eSw+qVGA7oPmONA+S5kfSvEmaT0nzLGn+Jc3LpPmaNI+T5nfSvE+aD0rzRFfOH8XUYErzUGl+Ks1bpfmsNM+V5r/SvFiaL0vzaGl+Lc27pfm4NE+X5u/SvN42CbPaUoBpBtNUfku6jeD97aRZc24qX6R81rNdlVK0rel3paLtKkXb1Yq2axRt15Ywm22xj7bDtD2m62HaAdOOmHYK0kcRGuAZCLvPNDernhwsYHktcDvB8kpxO8nyWuJ2IctrhdtFLK8Mt4tZXmvcLrGOwZLBNJXnovDAVYqeJTEsnvR0LG1TSnFpwfIoLqUsj7S3ZHkUl1Ysj8orY3lUHsWTWMeY3E+FNmcx4T7T8cIcmopyaCrOoakkhybuM+RRLDKYpvJcilmMpGzy9k5LgbWfYdutWExayvqSLjar6lvIZjZm5QoxKzNrH7NyFrPWCjFrI2szG7N2CjFrY9Y+Zu1YzNoqxKy9rM1szDooxKy9WfuYdWAxW08hZh1lbaYUbGb97KTgZ1dZm/VQt53N2tdtV1a3XRRi1k3WZjZm3YVtgo0eLCYUP/K9lB3vzuLVQzheBaxMskv7PfTKzerv+f/o75nDj54h6uf+xb7Gvsa+/r6+dv+dfYVyK0TLTdc1t8qFpalzZ4ViDMBmL1mb2XG+N/OftFI5pew4b4u9hbUVsDLJLu1z/2JfY19jX2NfY19jX2NfY19jX2NfY19jX2NfY1998ZX/DzTBfBG+ts/6YixfTI640NLcIV+KHfIl6ZAvJQ75UuiQL80c8qXIIV8Kfmdf+LwYw/LoeILl0fjI58/0wW0+f6YvbvP5M/2YTsrrj9t8/swA3OZzjAaybUoH4TafYzQYt/kcoyG4zecYDcVtPp9oGG63ZnnDcbsNy1sft9uyPJrU2J7l0WTE9VgeTSLsyPJo8l8nlkeT9jqzPJps14Xl1eJ2N5ZXh9s9WR7VIa9zqsPeLI/qsA/Lozrsy/KoDvuxPKrD/iyP6nAAy6M65HVKdTiI5VEdDmZ5VIdDWB7NQRrK8qheh7E8qtfhLI/m4qzP8qiuUyyP6jrN8mhOSiXLo/qvYnlU/9Usj+Zm1LA8ahO1LI/aBNUp1MW0glXH6fu8j1I5vI/W5SivNodftM3HJPpOBtNUfkt2TOLlZNg+ldWC+VDtgC9FDvnSzCFfCh3ypcQhX5IO+VLskC/NHfIlkcOXKllfsqcQ/uAAjcNVzA/yqZL5kRaOSdZGDj/SzA8qP8X8WF/Wj2wRw3P4sT7zg8ofzvwYJutHNvxDc/gxjPlB5Q9lfgyR9SPb9Abn8GMI84PKH8z8GCTrR7YJDszhB2dsKn8g82OArB9ZJOmfw48BzA8qvz/zo5+sH9li++bwox/zg8rvy/zoI+tHdizj11KwT+MFlZVknxmJ0ARMzK/DOKMS73O+pesCzsb1uM25ugG3OZNvgNuc50fgNr8WoPGWX0c0dQ3Cr1WIv+pZHp3XGlgeMcAGLI94iXwqwe8Kz3GthLJoXi4tTV1/8/lZ9D1+rUhztfhcX425q90t/2i/B/OP8viccuH5vFlfWlq+0H535XLLrHLLQiq33Cq3PKRy21rltg2p3E5WuZ2scn/rvruGL8byxTThS2eHfGnvkC+tHfKl3CFfWjjkS4lDvhQ65EtXh3zp6JAvnRzypZ1DvrRyyJcyh3xp7pAvxQ75knTIly4O+bKeQ75oX8+siy9tHPKlrUO+lDrkS0uHfGnmkC9FDvlS8Dv78lvzKeg4/18t3WPhcxh6WpogrwK3+RwGuj/G35NC99H4vAa6T8jnNdA9uHKWR/c2+VwHun/H5zrQvdh2LI/u/fH5D3TvmM91oPuGfK4DxYPHj86dPVgeXTvweQ3U7ipYHjEAv39I10D8PiP1Hz7XgViG36OkuuFzHahu+P1Nqhs+14Hqht8bpbrhcx2obig+oOsm9v4i+j5vO1QO/z//4BzlDcrhF23zvkLfyWCaym/J9hVeTobtU1n8//wDHPClyCFfmjnkS0uHfCl1yJe2DvnSxiFfOjjky3oO+dLFIV+SDvlS7JAvzR3ypcwhX1o55Es7h3zp5JAvHR3ypatDvhQ65EuJQ760cMiXcod8ae2QL+0d8qWzQ74kQvKFrp/J7iDLFyi3v2y52alZ/Vi5dF3fn+mn8vlzNX2F/Siw/Khg5WrOewMbvXPo78P0U/m9mR+9hf0A/R2YHxm2z+8lUb+g+oHzTU1ilV/C8ySzfvH2d5hZs28m2WdGJVb51ZBYFUOag8bfm9zDygP7Gu8K62HFlfapLPDPnovG/ePPPNnvN+P3Ffl3k1YZJUalflK8fmCpMGvWDx/nis3qfYv6XJJ9ZjyrwyOTq74n7Ptqc4ETJveYL9zfs9NTqe8YZp/HsBfbzjUe9rY+RzEV9DNt+0HlV7C8Hjn87MX8zPXeQOl3o9r9q8Cs2UfsbdLSh/klPEe2yfNpN1au8Dz7ynV9R+AQ5stwWV+q+POna+OL4nMQaYVnPLLv+k0J2wQb/Mc9KH7keyk7zp9fkX6OpoCVSXZpn/sX+yrvK/jSzfKTP4/dzQH/KI8/d9zFih+cv/fWY8OqXGxo33fmbLgkucqv/RgbDrTiyv8fzGOt8cwLZ4GMWfPc1IJp4c8BCV+HrXYtSnZdKlc49tkmyvlmYI64U/nanNUzhx8VzA8qn79bWJijslw6JIcf3ZkfVD5nhqHC8Whu+QFLU8zAn1kU5pc0f1fG2vjC+UWYC9J8/F8bX/g5rFLBl/Q6+MKf961W8KVqHXzhz0DXKvhSsw6+1DJf6hV8qVsHX6h8OLdT/+vP8qgf9GJ51B75PC5qF31ZHtVPb5Znv8+jlPnL54rRM4/8vs0IKw/it6GlKZXfkj0vUTlkl/Y3ZP7R85cj9Hyp5/b5fYoNWZkbCesvZrakdIDNkcJ+go1N0VYhqw8qJ8mO38LuK92K29CeNsbjDczOQzmO09JUP8qwOhktqzV7r2MMs5/JUQbkj5UtN83LLcCVyqD8JNt+kDo1+xwsFF/yGfrPqByf49sbW98pZcdHKWsezfzIsH0qC9rJHaxNPcSudTYR9ofr5XEZweJCxzdin9uUbdNnK1jcRsn6Wa/Q7rPax7CYU2ypHN72nmL18QzrwyOtuMHxt3Icp6WpPs7b3ThZrdk+Pp7Zz7AyeLkTZMtN83Kpj1MZlJ9k22+yPj5h1ebK+JLP0MfH5vgc3x5pfaeUHR+rrHkc8yPD9qksaCfPszb1FuvjGWF/uF4el01ZXOg4v28whm3TZytY3ITHxnqFdp/VPp7FnOxSObztfcTq42PWh0dbcYPj3+U4TktTfZy3u4myWrN9fBKzn2Fl8HIny5ab5uVSH6cyKD/Jtr9lfXzyqs2V8SWfoY9PyPE5vj3a+k4pOz5BWfNE5keG7VNZ0E4+ZW3qO9bHhc+Paa6Xx2UMiwsd5/enxrNt+mwFi5vw2Fiv0O6z2iexmFNsqRze9gy7V5tgz4eMs+IGx9vkOE5LU32ct7spslqzfXwqs59hZfByN5MtN83LpT5OZUxloaXtcpoowD4HC8WXfIY+PjnH5/j2OOs7pez4ZGXNU5gfGbZPZUE7KWJtqg2bVyB97cD18riMZ3Gh4/ze7yS2TZ+tYHETHhvrFdp9VvtUFnOKLZXD214XVh/dWB+eaMUNjg/JcZyWpvo4b3fTZLVm+/h0Zj/DyuDlzpAtN83LpT5OZVB+km0PZn18xqrNlfEln6GPb5bjc3x7ovWdUnZ8M2XN05gfGbZPZUE76cna1BDWx6WvHbheHpdJLC50vC/73FS2TZ+tYHETHhvrFdp9Vvt0FnOKLZXD2141q49a1oenWHGD42NyHKelqT7O291MWa3ZPr45s59hZfByZ8mWm+blUh+nMig/ybZHsz4+a9XmyviSz9DHZ+T4HN+eYn2nlB2foax5JvMjw/aprOy8TtamxrA+Ln3twPXyuExlcaHjvdnnprNt+mwFi5vw2Fiv0O6z2jdnMafYUjm87U1l9TGN9eFpVtzg+A45jtPSVB/n7W4LWa3ZPr4ls59hZfByZ8uWm+blUh+nMig/yba3Z3189qrNlfEln6GPz8rxOb49zfpOKTs+S1nzFsyPDNunsqCdzGRtagfWx6WvHbheHpfpLC50nN0OWdn2+WcrWNyEx8Z6hXaf1b4liznFlsrhbW8hq49dWB+eacUNjh+Q4zgtTfVx3u62ktWa7eNbM/sZVgYvdxvZctO8XOrjVAblJ9n2/qyPb7Nqc2V8yWfo47NzfI5vz7S+U8qOz1bWvBXzI8P2qSxoJ7uxNnUA6+PS1w5cL4/L5iwudJy/C7ir9Xloz9Qf+NwD6X7Jzwtkl/b5eE15/PpH8XmJbBz5cwr28xL8+aCBzCd6PsjHuZb2Ns0v5c8T8Pu0uZ7X6GN9DvQJP2dUpfAsQba+aX5dIYsNlZNkx89gffksNv6TZt4eluU4TktT5wc+/1F4rl+Kz3um88PwHOVKz+vj5dL5gcqg/CTbvpydH/jvXFB8yWdod8NyfI5v97K+U8qOD1PWzH8bI8P2+dzxpaxNLWPjWoWwP1wvj0sXFhc6zp8Z0uxvvPwhzA/7t0T5M4F8/JR+foY/V0V2aX8Y84/yKph/pIOPJfy5gHIFX1tbvtI+f3e2RrlFVrlFIZVbYpVbElK5za1ym4dUbqlVbmlI5YbfrtJ1YLOdsE2opzZm9aWpcy9/P3VbUV9S6WZm1TvgdmpcPHX3xY17FzCfyE9650sL5he/Jk+y7xSaNbUV58hrliOvhVlz4b/X0Yptl7PvlVl+QozpnRb8XZP0ni7+rknSwd8rSXro8yVmzToSPfnQkrBsV6Vqq6sb6yob01XpOanKhrn1Nanqmrm19en6dE19zfzK+qqqxvrq+rqGuQ11qYZ0dVVjekFNQ9UCNJ4Q9HO9hBz0cc0FwvHsmJCLHw3w1CDaBraXB2k7TNtjCkvnxAotJaweAVqW4zH6XJfECntrNCiFWHQQrDPub9fEqo6eayAoVtBirHLs+JUZ5U6qUTldE/J2uwl2AC3d3RLidbTaoCI9kHYSjGn3hCwZre0A1aOJAaoH+1zPHJ9L4Od64ueg81fwnq8Qc8l23Ot3innvJmLem32uTxMx78Ni3jfH5zrg8b6Ygl/98KDG2FKRY8zKt34eKZQdB6R1Q/vpp6D70UKd8S8p7Gd/wf4jWNdpyfiFBWUd5Wyl+NUa2RwQ1NXAYB0UrIODdUiwDg3WYcE6PFjXD1a4MkgHa2WwVgVrdWLFfwtqg7UuWOsTK97itUGwjgjWDYN1o2DdOFg3gbYQrCODddPEijd/jQ7WMcE6NljHJVa8SWpCsE4M1knBOjlYpwTr1GDdLFinBev0YJ0RrDODdfNgnRWsWwTrlsE6O1i3Ctatg3WbYN02WLcL1u2DdYdg3TFY5wTr3GCdF6zzg7UxWBckVr/iS1h1ya9EpepAAXZT3HdK4Y5WCdNmrONlqK9I1JfqFL8iNqy9mRyxNGb1X+ooFPVlxR0LutoP7liM3Gfxwi13Xryoce/V7lvYo19Bjmjx33Hgv29AES5keQmmiPLoOyUsVbv8SJo1mzIXJlXOgITO6Ug0HukV9zVo2Ql3FiZWNb0CFi+oyF9zxKyAbSfwM4kmPlPwG3Z+qyuqNQYSB8K/ZWIhAPZdtaRw2byB/K9M0bgAllR6JwFbxCcLlRpuQjh+kpp3Xs1W8Nk5ldW1jTWp2sb6hvrGhroFNXWpeXMWLJhfl6qeNzc1d251baoqXbVgbl1lam5lQ1BsQ2PNvHTWr7DYZ2fBeuL+7pKIb0iJVM4uCXm7uwo2ei3duybE6yinrxID3a4Jebt/EO6YEE6wSagUBr0M9JBedsOdRVGjl90selkUAr0MFKSX3QQHtUWe0Iuk5t09pJfdlehlj5heZCpnDwV62dNxegHde3pCL4vQV2m7eynQy14h08sgD+mFJhMujhq97G3Ry+IQ6GWQIL3sLTioLfaEXiQ17+MhveyjRC/7xvQiUzn7KtDLfo7TC+jezxN6WYy+StvdX4Fe9g+ZXgZ7SC8H4M6BUaOXAyx6OTAEehksSC8HCA5qB3pCL5KaD/KQXg5SopeDY3qRqZyDFejlEMfpBXQf4gm9HIi+Sts9VIFeDg2ZXoZ4SC+H4c7hUaOXwyx6OTwEehkiSC+HCQ5qh3tCL5Kaj/CQXo5QopcjY3qRqZwjFejlKMfpBXQf5Qm9HI6+Sts9WoFejg6ZXoZ6SC/H4M6SqNHLMRa9LAmBXoYK0ssxgoPaEk/oRVLzsR7Sy7FK9HJcTC8ylXOcAr380XF6Ad1/9IRelqCv0naPV6CX40Oml2Ee0ssJuHNi1OjlBIteTgyBXoYJ0ssJgoPaiZ7Qi6Tmkzykl5OU6OXkmF5kKudkBXo5xXF6Ad2neEIvJ6Kv0nZPVaCXU0Oml+Ee0stpuHN61OjlNIteTg+BXoYL0stpgoPa6Z7Qi6TmMzyklzOU6OXMmF5kKudMBXo5y3F6Ad1neUIvp6Ov0nbPVqCXs0Oml/U9pJdzcGdp1OjlHIteloZAL+sL0ss5goPaUk/oRVLzuR7Sy7lK9HJeTC8ylXOeAr2c7zi9gO7zPaGXpeirtN0LFOjlgpDpJeUhvVyIOxdFjV4utOjlohDoJSVILxcKDmoXeUIvkpov9pBeLlail0tiepGpnEsU6OVSx+kFdF/qCb1chL5K271MgV4uC5le0h7Sy+W4syxq9HK5RS/LQqCXtCC9XC44qC3zhF4kNV/hIb1coUQvV8b0IlM5VyrQy1WO0wvovsoTelmGvkrbvVqBXq4OmV4qPaSXa3Dn2qjRyzUWvVwbAr1UCtLLNYKD2rWe0Iuk5us8pJfrlOjl+pheZCrnegV6+ZPj9AK6/+QJvVyLvkrbvUGBXm4ImV6qPKSXG3HnpqjRy40WvdwUAr1UCdLLjYKD2k2e0Iuk5ps9pJeblejllpheZCrnFgV6+bPj9AK6/+wJvdyEvkrbvVWBXm4NmV6qPaSX23Dn9qjRy20WvdweAr1UC9LLbYKD2u2e0Iuk5js8pJc7lOjlzpheZCrnTgV6+Yvj9AK6/+IJvdyOvkrbvUuBXu4KmV5qPKSXu3HnnqjRy90WvdwTAr3UCNLL3YKD2j2e0Iuk5ns9pJd7lejlvpheZCrnPgV6+avj9AK6/+oJvdyDvkrbvV+BXu4PmV5qPaSXB3DnwajRywMWvTwYAr3UCtLLA4KD2oOe0Iuk5oc8pJeHlOjl4ZheZCrnYQV6+Zvj9AK6/+YJvTyIvkrbfUSBXh4JmV7qPKSXR3HnsajRy6MWvTwWAr3UCdLLo4KD2mOe0Iuk5sc9pJfHlejliZheZCrnCQV6edJxegHdT3pCL4+hr9J2n1Kgl6dCppd6D+nladx5Jmr08rRFL8+EQC/1gvTytOCg9own9CKp+VkP6eVZJXp5LqYXmcp5ToFennecXkD3857QyzPoq7TdFxTo5YWQ6aXBQ3p5EXdeihq9vGjRy0sh0EuDIL28KDioveQJvUhqftlDenlZiV5eielFpnJeUaCXvztOL6D7757Qy0voq7TdVxXo5dWQ6WUDD+nlNdx5PWr08ppFL6+HQC8bCNLLa4KD2uue0Iuk5jc8pJc3lOjlzZheZCrnTQV6ectxegHdb3lCL6+jr9J231agl7dDppcRHtLLO7jzbtTo5R2LXt4NgV5GCNLLO4KD2rue0Iuk5vc8pJf3lOjl/ZheZCrnfQV6+Yfj9AK6/+EJvbyLvkrb/UCBXj4ImV429JBePsSdj6JGLx9a9PJRCPSyoSC9fCg4qH3kCb1Iav6nh/TyTyV6+TimF5nK+ViBXv7lOL2A7n95Qi8foa/Sdj9RoJdPQqaXjTykl09x57Oo0cunFr18FgK9bCRIL58KDmqfeUIvkpr/7SG9/FuJXv4T04tM5fxHgV7+6zi9gO7/ekIvn6Gv0nY/V6CXz0Oml409pJcvcOfLqNHLFxa9fBkCvWwsSC9fCA5qX3pCL5Kav/KQXr5SopevY3qRqZyvFejlG8fpBXR/4wm9fIm+Stv9VoFevg2ZXjbxkF6+w53vo0Yv31n08n0I9LKJIL18Jziofe8JvUhq/sFDevlBiV5+jOlFpnJ+VKCXnxynF9D9kyf08j36Km33ZwV6+Tlkesl4SC+/4M7yqNHLLxa9LA+BXjKC9PKL4KC23BN6kdT8q4f08qsSvUBDj+klT5tQOaBE2m5B0m16Ad0FSfE6UqGX5eirtN1EUp5ewGaY9DLSQ3pJYrsrTEaMXkA4pxcIgDa9jBSkl6TgoFaY1Gm40vQiqbko6R+9FAkPkrQUx/QiUznFCvRS4ji9gO4ST+ilEH2VtttMgV6ahUwvm3pIL82x3bWIGr00t+ilRQj0sqkgvTQXHNRaeEIvkppLPaSXUiV6aRnTi0zltFSgl1aO0wvobuUJvbRAX6XtlinQS1nI9DLKQ3ppje2uPGr00tqil/IQ6GWUIL20FhzUyj2hF0nNbTyklzZK9NI2pheZymmrQC/tHKcX0N3OE3opR1+l7bZXoJf2IdPLaA/pZT1sdx2iRi/rWfTSIQR6GS1IL+sJDmodPKEXSc0dPaSXjkr00immF5nK6aRAL50dpxfQ3dkTeumAvkrb7aJAL11CppcxHtJLV2x33aJGL10teukWAr2MEaSXroKDWjdP6EVSc3cP6aW7Er30iOlFpnJ6KNBLT8fpBXT39IReuqGv0nYrFOilImR6GeshvfTCdtc7avTSy6KX3iHQy1hBeuklOKj19oReJDX38ZBe+ijRS9+YXmQqp68CvfRznF5Adz9P6KU3+iptt78CvfQPmV7GeUgvA7DdDYwavQyw6GVgCPQyTpBeBggOagM9oRdJzYM8pJdBSvQyOKYXmcoZrEAvQxynF9A9xBN6GYi+StsdqkAvQ0Oml/Ee0sswbHfDo0Yvwyx6GR4CvYwXpJdhgoPacE/oRVLz+h7Sy/pK9JKK6UWmclIK9JJ2nF5Ad9oTehmOvkrbrVSgl8qQ6WWCh/RShe2uOmr0UmXRS3UI9DJBkF6qBAe1ak/oRVJzjYf0UqNEL7UxvchUTq0CvdQ5Ti+gu84TeqlGX6Xt1ivQS33I9DLRQ3ppwHa3QdTopcGilw1CoJeJgvTSIDiobeAJvUhqHuEhvYxQopcNY3qRqZwNFehlI8fpBXRv5Am9bIC+StvdWIFeNg6ZXiZ5SC+bYLvLRI1eNrHoJRMCvUwSpJdNBAe1jCf0Iql5pIf0MlKJXjaN6UWmcjZVoJdRjtML6B7lCb1k0Fdpu6MV6GV0yPQy2UN6GYPtbmzU6GWMRS9jQ6CXyYL0MkZwUBvrCb1Iah7nIb2MU6KX8TG9yFTOeAV6meA4vYDuCZ7Qy1j0VdruRAV6mRgyvUzxkF4mYbubHDV6mWTRy+QQ6GWKIL1MEhzUJntCL5Kap3hIL1OU6GVqTC8ylTNVgV42c5xeQPdmntDLZPRV2u40BXqZFjK9TPWQXqZju5sRNXqZbtHLjBDoZaogvUwXHNRmeEIvkppnekgvM5XoZfOYXmQqZ3MFepnlOL2A7lme0MsM9FXa7hYK9LJFyPSymYf0siW2u9lRo5ctLXqZHQK9bCZIL1sKDmqzPaEXSc1beUgvWynRy9YxvchUztYK9LKN4/QCurfxhF5mo6/SdrdVoJdtQ6aXaR7Sy3bY7raPGr1sZ9HL9iHQyzRBetlOcFDb3hN6kdS8g4f0soMSvewY04tM5eyoQC9zHKcX0D3HE3rZHn2VtjtXgV7mhkwv0z2kl3nY7uZHjV7mWfQyPwR6mS5IL/MEB7X5ntCLpOZGD+mlUYleFsT0IlM5CxToZSfH6QV07+QJvcxHX6XtLlSgl4Uh08sMD+llZ2x3u0SNXna26GWXEOhlhiC97Cw4qO3iCb1Iat7VQ3rZVYle/hDTi0zl/EGBXnZznF5A926e0Msu6Ku03UUK9LIoZHqZ6SG97I7tbo+o0cvuFr3sEQK9zBSkl90FB7U9PKEXSc17ekgveyrRy14xvchUzl4K9LK34/QCuvf2hF72QF+l7S5WoJfFIdPL5h7Syz7Y7vaNGr3sY9HLviHQy+aC9LKP4KC2ryf0Iql5Pw/pZT8letk/pheZytlfgV4OcJxeQPcBntDLvuirtN0DFejlwJDpZZaH9HIQtruDo0YvB1n0cnAI9DJLkF4OEhzUDvaEXiQ1H+IhvRyiRC+HxvQiUzmHKtDLYY7TC+g+zBN6ORh9lbZ7uAK9HB4yvWzhIb0cge3uyKjRyxEWvRwZAr1sIUgvRwgOakd6Qi+Smo/ykF6OUqKXo2N6kamcoxXo5RjH6QV0H+MJvRyJvkrbXaJAL0tCppctPaSXY7HdHRc1ejnWopfjQqCXLQXp5VjBQe04T+hFUvMfPaSXPyrRy/ExvchUzvEK9HKC4/QCuk/whF6OQ1+l7Z6oQC8nhkwvsz2kl5Ow3Z0cNXo5yaKXk0Ogl9mC9HKS4KB2sif0Iqn5FA/p5RQlejk1pheZyjlVgV5Oc5xeQPdpntDLyeirtN3TFejl9JDpZSsP6eUMbHdnRo1ezrDo5cwQ6GUrQXo5Q3BQO9MTepHUfJaH9HKWEr2cHdOLTOWcrUAv5zhOL6D7HE/o5Uz0VdruUgV6WRoyvWztIb2ci+3uvKjRy7kWvZwXAr1sLUgv5woOaud5Qi+Sms/3kF7OV6KXC2J6kamcCxTo5ULH6QV0X+gJvZyHvkrbvUiBXi4KmV628ZBeLsZ2d0nU6OVii14uCYFethGkl4sFB7VLPKEXSc2XekgvlyrRy2UxvchUzmUK9HK54/QCui/3hF4uQV+l7S5ToJdlIdPLth7SyxXY7q6MGr1cYdHLlSHQy7aC9HKF4KB2pSf0Iqn5Kg/p5Solerk6pheZyrlagV6ucZxeQPc1ntDLleirtN1rFejl2pDpZTsP6eU6bHfXR41errPo5foQ6GU7QXq5TnBQu94TepHU/CcP6eVPSvRyQ0wvMpVzgwK93Og4vYDuGz2hl+vRV2m7NynQy00h08v2HtLLzdjubokavdxs0cstIdDL9oL0crPgoHaLJ/QiqfnPHtLLn5Xo5daYXmQq51YFernNcXoB3bd5Qi+3oK/Sdm9XoJfbQ6aXHTyklzuw3d0ZNXq5w6KXO0Oglx0E6eUOwUHtTk/oRVLzXzykl78o0ctdMb3IVM5dCvRyt+P0Arrv9oRe7kRfpe3eo0Av94RMLzt6SC/3Yru7L2r0cq9FL/eFQC87CtLLvYKD2n2e0Iuk5r96SC9/VaKX+2N6kamc+xXo5QHH6QV0P+AJvdyHvkrbfVCBXh4MmV7meEgvD2G7ezhq9PKQRS8Ph0AvcwTp5SHBQe1hT+hFUvPfPKSXvynRyyMxvchUziMK9PKo4/QCuh/1hF4eRl+l7T6mQC+PhUwvcz2kl8ex3T0RNXp53KKXJ0Kgl7mC9PK44KD2hCf0Iqn5SQ/p5UklenkqpheZynlKgV6edpxeQPfTntDLE+irtN1nFOjlmZDpZZ6H9PIstrvnokYvz1r08lwI9DJPkF6eFRzUnvOEXiQ1P+8hvTyvRC8vxPQiUzkvKNDLi47TC+h+0RN6eQ59lbb7kgK9vBQyvcz3kF5exnb3StTo5WWLXl4JgV7mC9LLy4KD2iue0Iuk5r97SC9/V6KXV2N6kamcVxXo5TXH6QV0v+YJvbyCvkrbfV2BXl4PmV4aPaSXN7DdvRk1ennDopc3Q6CXRkF6eUNwUHvTE3qR1PyWh/TylhK9vB3Ti0zlvK1AL+84Ti+g+x1P6OVN9FXa7rsK9PJuyPSywEN6eQ/b3ftRo5f3LHp5PwR6WSBIL+8JDmrve0Ivkpr/4SG9/EOJXj6I6UWmcj5QoJcPHacX0P2hJ/TyPvoqbfcjBXr5COkF9uHM3DbIXB6k7TCl8hYmVpy4FmG6GNMDMT0c0yWYnojp6ZguxfQiTJdhei2mN2F6O6b3YPogpo9h+gymL2H6OqbvYvoRpp9h+iWm32O6HNNCPBG3wLQc0w6YdsO0N6YDMR2OaTWmG2CawXQsppMxnYHpbEy3x3Q+prtgugem+2J6MKZHYnocpidjSj/3TD+ceAmm9DJ/ei0uvWCOXtVCDz3T40M0EZemtNA/h+g2CwFLBbaDcoxfa0zLMG2FaUtMSzFtgWlzTJthWoJpMaZFVC+YJjFNYFqAqcH01wKsT0x/wfRnTH/C9EdMf8D0e0y/w/RbTL/B9GtMv8L0S0y/wPSfbAwyRn6c+6fwOPxbfuZr+2OBsaixvnbO3OoFCzTi2Cuw0VdB9xOFuueeVH5LegDYUND9pLBuWpLCfv5L7hyZFqzr9JOOt5tOwbjaJaEwV9dx3d0Dzf0VdD/rSX/5RLC/CNZ1Wit+CeH2UyBYF596coMkIaj5M080JwU1/9sTzYWCmv/jieYiQc3/9URzsaDmzz3RXCKo+QtPNHcR1PylJ5o/Frye/soTzZ0E6/nrCGr+JoKav/VE878E+/N3nmj+RFDz9xFs2z9EUPOPEdT8UwQ1/xxBzb9EUPPyCGr+NYKajSf3PSU1F0RQcyKCmpMR1FwYQc1FEdRcHEHNJRHU3CyCmptHUHOLCGoujaDmlhHU3CqCmssiqLl1BDWXR1BzmwhqbhtBze0iqLl9BDWvF0HNHSKouWMENXeKoObOEdTcJYKau0ZQc7cIau4eQc09Iqi5ZwQ1V0RQc68Iau4dQc19Iqi5bwQ194ug5v4R1DwggpoHRlDzoAhqHhxBzUMiqHloBDUPi6Dm4RHUvH4ENaciqDkdQc2VEdRcFUHN1RHUXBNBzbUR1FwXQc31EdTcEEHNG0RQ84gIat4wgpo3iqDmjSOoeZMIas5EUPPICGreNIKaR0VQ8+gIah4TQc1jI6h5XAQ1j4+g5gkR1DwxgponRVDz5AhqnhJBzVMjqHmzCGqeFkHN0yOoeUYENc+MoObNI6h5VgQ1bxFBzVtGUPPsCGreKoKat46g5m0iqHnbCGreLoKat4+g5h0iqHnHCGqeE0HNcyOoeV4ENc+PoObGCGpeEEHNO0VQ88IIat45gpp3iaDmXSOo+Q8R1LxbBDUviqDm3SOoeY8Iat4zgpr3iqDmvSOoeXEENe8TQc37eqK5maDm/TzR3FxQ8/6eaG4hqPkATzSXCmo+0BPNLQU1H+SJ5laCmg/2RHOZoOZDPNHcWlDzoZ5oLhfUfJgnmtsIaj7cE81tBTUf4YnmdoKaj/REc3tBzUd5onk9Qc1He6K5g6DmYwQ1d0Q7Bag5GayBeVMUrMXBWhKscE0I10hwzQAMDUwJjAXMAedgOCfBGA1jFvRhaNNQx6C5I4vp+Zh+GhTyWbD+O1j/E6z/DdbPg/WLYP0yWL8K1q+D9Ztg/TZYvwvW74P1h2D9MVh/Ctafg/WXYF0erL+i0/A79/C77/A76PC74PA72fC70fA7yvC7wvA7u/C7s/A7rPC7pPA7nfC7lfA7jvC7hvA7f/C7d/A7cPC7aPA7YfC7WfA7UvC7SvA7Q/C7O/A7NPC7LPA7JfC7HfA7FvC7DvA7B/Def3gPPrwXHt6TDu8Nh/dow3ul4T3L8N5heA8vvJcW3tMK7y2F93jCey3hPY/w3kN4DyC8Fw/eEwfvTYP3iMF7teA9U/DeJXgPEbyXB95TA+9tyb7HJFjhPRfw3gd4DwK8FwCek4fnxuE5aniuGJ6zhedO4TlMeC4RntOD59bgOS54rgme84HnXuA5EHguAp4TgHnzMI8c5lXDPGOYdwvzUGFeJsxThHl7MI8N5nXBPCeY9wPzYGBeCMyTgHkD8H90+L8y/J8V/u8I/4eD/0vB/2ng/xZwHx/ua8N9XrjvCfcB4b4Y3CeC+yZwHwGuq+E6E6674DoEuBw4FbgNOAbO63Ceg3EfxkEYF6Cf0PJ/jk3BomqPBgA=", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -171,36 +191,74 @@ "returnTypes": [ { "kind": "struct", - "path": "aztec::abi::PublicCircuitPublicInputs", + "path": "aztec::protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs", "fields": [ { "name": "call_context", "type": { "kind": "struct", - "path": "aztec::abi::CallContext", + "path": "aztec::protocol_types::abis::call_context::CallContext", "fields": [ { "name": "msg_sender", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "storage_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "portal_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::EthAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "function_selector", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::abis::function_selector::FunctionSelector", + "fields": [ + { + "name": "inner", + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 32 + } + } + ] } }, { @@ -247,7 +305,7 @@ "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageUpdateRequest", + "path": "aztec::protocol_types::contrakt::storage_update_request::StorageUpdateRequest", "fields": [ { "name": "storage_slot", @@ -272,13 +330,13 @@ } }, { - "name": "contract_storage_read", + "name": "contract_storage_reads", "type": { "kind": "array", "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageRead", + "path": "aztec::protocol_types::contrakt::storage_read::StorageRead", "fields": [ { "name": "storage_slot", @@ -287,7 +345,7 @@ } }, { - "name": "value", + "name": "current_value", "type": { "kind": "field" } @@ -297,7 +355,7 @@ } }, { - "name": "public_call_stack", + "name": "public_call_stack_hashes", "type": { "kind": "array", "length": 4, @@ -356,7 +414,7 @@ "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::BlockHeader", + "path": "aztec::protocol_types::abis::block_header::BlockHeader", "fields": [ { "name": "note_hash_tree_root", @@ -406,13 +464,22 @@ { "name": "prover_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } } ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -438,36 +505,74 @@ "returnTypes": [ { "kind": "struct", - "path": "aztec::abi::PublicCircuitPublicInputs", + "path": "aztec::protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs", "fields": [ { "name": "call_context", "type": { "kind": "struct", - "path": "aztec::abi::CallContext", + "path": "aztec::protocol_types::abis::call_context::CallContext", "fields": [ { "name": "msg_sender", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "storage_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "portal_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::EthAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "function_selector", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::abis::function_selector::FunctionSelector", + "fields": [ + { + "name": "inner", + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 32 + } + } + ] } }, { @@ -514,7 +619,7 @@ "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageUpdateRequest", + "path": "aztec::protocol_types::contrakt::storage_update_request::StorageUpdateRequest", "fields": [ { "name": "storage_slot", @@ -539,13 +644,13 @@ } }, { - "name": "contract_storage_read", + "name": "contract_storage_reads", "type": { "kind": "array", "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageRead", + "path": "aztec::protocol_types::contrakt::storage_read::StorageRead", "fields": [ { "name": "storage_slot", @@ -554,7 +659,7 @@ } }, { - "name": "value", + "name": "current_value", "type": { "kind": "field" } @@ -564,7 +669,7 @@ } }, { - "name": "public_call_stack", + "name": "public_call_stack_hashes", "type": { "kind": "array", "length": 4, @@ -623,7 +728,7 @@ "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::BlockHeader", + "path": "aztec::protocol_types::abis::block_header::BlockHeader", "fields": [ { "name": "note_hash_tree_root", @@ -673,13 +778,22 @@ { "name": "prover_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } } ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } ], diff --git a/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json b/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json index 5496e442409..63c310b171a 100644 --- a/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json +++ b/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json @@ -7,7 +7,7 @@ "isInternal": false, "parameters": [], "returnTypes": [], - "bytecode": "H4sIAAAAAAAA/+XdZZOTZxSH8V0gSd27uLu1ySbZJFVK3alSL6Rk6y1V6qXU3XB390/IuWbCwAt4xb0z3HNl5j9590x+m+yj5z7nZE9Pz7aeM6/e7vuC7nv5wl6VQmyjcI7tVssDtVqn0d+pVCtLy/2tdrNertXbA81Ks1Jv1pf1N6vVTrPWbLTarUa5ValVO5XBeqs62N1wId1nLA+FuxjbKA6Bu3iRu0uxjdIQuEuJ3ef7vV/o5xw5RJ9zWOLvqTeheVQm5mEJzaMzMQ9PaB6TiXlEQvPYTMyFhOZxmZiLCc3jMzGXEponZGIemdA8UWieJDRPFpqnCM1TheZpQvN0oXmG0DxTaJ4lNM8WmucIzXOF5nlC83yh+Sah+WahuSw0V4TmfqG5KjTXhOa60DwgNDeE5qbQ3BKabxGabxWabxOabxea7xCa7xSaFwjNdwnNC4Xmu4Xme4Tme4Xm+4Tm+4XmB4TmB4Xmh4Tmh4XmR4TmR4Xmx4Tmx4XmRULzE0Lzk0LzU0Lz00LzM0Lzs0LzYqH5OaH5eaH5BaH5RaH5JaH5ZaH5FaH5VaF5idC8VGhuC82vCc3LhOaO0DwoNL8uNL8hNL8pNL8lNL8tNL8jNL8rNL8nNL8vNC8Xmj8Qmj8Umj8Smj8Wmj8Rmj8VmlcIzZ8JzZ8LzV8IzV8KzV8JzV8Lzd8Izd8KzSuF5u+E5lVC8/dC8w9C849C809C889C8y9C869C829C8+9C8x9C859C819C899C8z9C879C839C8/9C82qheY3QvFZoXic0rxeaNwjNG4XmTULzZqF5i9C8VWjeJjRvF5p3CM07heZdmZgvSWjenYn50oTmPZmYL0to3puJ+fKE5n2ZmK9IaN6fifnKhOYDmZivSmg+mIn56oTmQ5mYr0loPpyJ+dqE5iOZmK9LaD6aifn6hOZjmZhvSGg+non5xoTmE5mY+xKaTyY093W309s1D4+MiBQixUgpwjUh10hcM3AOzTkl51icc3AM5pjEPpp9Fv/D/Kb5jvvO+ntu6r6PioyOjImMjYyLjI9MiEyMTIpMjkyJTI1Mi0yPzIjMjMyKzI7MicyNzIvMjzDjnpnvfInMBGdGNjOjmaHMTGFm7DYizGBlJikzOplZyQxHZhoy4+/0zDtmoi2MMDOLGVLMVGLGEDN3mEHDTBZmlDCzgxkWzHRgxgE9/xdF6AlPj3R6htNDm57S9FheHKEHLz1p6dFKz1J6eNLTkh6P9DxcEqEnXjtCzzR6iNFTix5T9FyiBxE9eehRQ88WepjQ04MeF/R8WB6hJwBr5Fkzzhpq1hSzxnZFhDWYrElkjR5r1ljDxZom1viw5mVlhDURqyLUzFNDTk01NcbU3FKDSk0mNYrU7FHDRk0XNU7U/FADQ00INRLUDPAMnWfKPGPlmSPP4HgmxTMafhPcw+eeNvd4uee5PcI9Me4Rcc+EewhcU3ONyTUX1yCck3OOyjkb5zAc0znGsc9nH8g+gf+R069TXMw0LzyaAAA=", + "bytecode": "H4sIAAAAAAAA/+XdZ2+TZxSHcSfEdvdu2BD2bu3Yju1OSvemk+6Ci9Pd0kl3Kd17TzpS9l6fkHMJI/ECXnFH4tZl6S9LefHIv9h+/Ixzn3O4UCiMFY4++iL9kYHI0HF/47G891w5tUe1GNsonmC7tcpIvd5tDnerteqaynC702pU6o3OSKvaqjZajbXDrVqt26q3mu1Ou1lpV+u1bnW00a6N9jZcTPcaK+PhLsU2SuPgLp3m7nJsozwO7nJid+Ekn/dTfZ0Tx+l19id+n/oSmidlYu5PaJ6ciXlCQvOUTMwDCc1TMzEXE5qnZWIuJTRPz8RcTmiekYl5YkLzTKF5SGieJTTPFprnCM1zheZ5QvN8oXmB0LxQaF4kNC8WmpcIzUuF5mVC82VC8+VCc0VorgrNw0JzTWiuC80NoXlEaG4KzS2huS00XyE0Xyk0XyU0Xy00XyM0Xys0LxearxOaVwjN1wvNNwjNNwrNNwnNNwvNtwjNtwrNtwnNtwvNdwjNdwrNdwnNdwvNK4Xme4Tme4Xm+4Tm+4XmB4TmB4XmVULzQ0Lzw0LzI0Lzo0LzY0Lz40LzE0Lzk0LzaqF5jdDcEZqfEprXCs1doXlUaH5aaH5GaH5WaH5OaH5eaH5BaH5RaH5JaH5ZaF4nNL8iNL8qNL8mNL8uNL8hNL8pNK8Xmt8Smt8Wmt8Rmt8Vmt8Tmt8Xmj8Qmj8UmjcIzR8JzRuF5o+F5k+E5k+F5s+E5s+F5i+E5i+F5q+E5q+F5m+E5m+F5u+E5u+F5h+E5h+F5p+E5p+F5l+E5l+F5t+E5t+F5j+E5j+F5r+E5k1C899C8z9C879C839C85jQ/L/QvFlo3pKJ+YyE5q2ZmM9MaN6WifmshObtmZjPTmjekYn5nITmnZmYz01o3pWJ+byE5t2ZmM9PaN6TifmChOa9mZgvTGjel4n5ooTm/ZmYL05oPpCJ+ZKE5oOZmC9NaD6UiXkwoflwQvNgbzt9PfOEyECkGClFyhHOCTlH4pyBY2iOKTnG4piD32B+k9hHs8/iO8xnmvd48Lj/56be86TI5MiUyNTItMj0yIzIzMhQZFZkdmROZG5kXmR+ZEFkYWRRZHFkSWRpZFmEGffMfOdNZCY4M7KZGc0MZWYKM2O3GWEGKzNJmdHJzEpmODLTkBl/x2beMRNtRYSZWcyQYqYSM4aYucMMGmayMKOEmR3MsGCmAzMO6Pm/MkJPeHqk0zOcHtr0lKbH8qoIPXjpSUuPVnqW0sOTnpb0eKTn4eoIPfE6EXqm0UOMnlr0mKLnEj2I6MlDjxp6ttDDhJ4e9Lig58O6CD0BWCPPmnHWULOmmDW26yOswWRNImv0WLPGGi7WNLHGhzUvGyKsidgYoWaeGnJqqqkxpuaWGlRqMqlRpGaPGjZquqhxouaHGhhqQqiRoGaAe+jcU+YeK/ccuQfHPSnu0fCZ4Bo+17S5xss1z7EI18S4RsQ1E64hcE7NOSbnXJyDcEzOMSrHbBzD8JvObxz7fPaB7BP4jhx7HAEN+DJJTJoAAA==", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -39,13 +39,33 @@ { "name": "function_selector", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::abis::function_selector::FunctionSelector", + "fields": [ + { + "name": "inner", + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 32 + } + } + ] } }, { "name": "target_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { @@ -70,7 +90,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -87,7 +107,7 @@ } ], "returnTypes": [], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -106,36 +126,74 @@ "returnTypes": [ { "kind": "struct", - "path": "aztec::abi::PublicCircuitPublicInputs", + "path": "aztec::protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs", "fields": [ { "name": "call_context", "type": { "kind": "struct", - "path": "aztec::abi::CallContext", + "path": "aztec::protocol_types::abis::call_context::CallContext", "fields": [ { "name": "msg_sender", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "storage_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "portal_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::EthAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "function_selector", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::abis::function_selector::FunctionSelector", + "fields": [ + { + "name": "inner", + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 32 + } + } + ] } }, { @@ -182,7 +240,7 @@ "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageUpdateRequest", + "path": "aztec::protocol_types::contrakt::storage_update_request::StorageUpdateRequest", "fields": [ { "name": "storage_slot", @@ -207,13 +265,13 @@ } }, { - "name": "contract_storage_read", + "name": "contract_storage_reads", "type": { "kind": "array", "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageRead", + "path": "aztec::protocol_types::contrakt::storage_read::StorageRead", "fields": [ { "name": "storage_slot", @@ -222,7 +280,7 @@ } }, { - "name": "value", + "name": "current_value", "type": { "kind": "field" } @@ -232,7 +290,7 @@ } }, { - "name": "public_call_stack", + "name": "public_call_stack_hashes", "type": { "kind": "array", "length": 4, @@ -291,7 +349,7 @@ "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::BlockHeader", + "path": "aztec::protocol_types::abis::block_header::BlockHeader", "fields": [ { "name": "note_hash_tree_root", @@ -341,13 +399,22 @@ { "name": "prover_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } } ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -373,36 +440,74 @@ "returnTypes": [ { "kind": "struct", - "path": "aztec::abi::PublicCircuitPublicInputs", + "path": "aztec::protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs", "fields": [ { "name": "call_context", "type": { "kind": "struct", - "path": "aztec::abi::CallContext", + "path": "aztec::protocol_types::abis::call_context::CallContext", "fields": [ { "name": "msg_sender", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "storage_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "portal_contract_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::EthAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } }, { "name": "function_selector", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::abis::function_selector::FunctionSelector", + "fields": [ + { + "name": "inner", + "type": { + "kind": "integer", + "sign": "unsigned", + "width": 32 + } + } + ] } }, { @@ -449,7 +554,7 @@ "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageUpdateRequest", + "path": "aztec::protocol_types::contrakt::storage_update_request::StorageUpdateRequest", "fields": [ { "name": "storage_slot", @@ -474,13 +579,13 @@ } }, { - "name": "contract_storage_read", + "name": "contract_storage_reads", "type": { "kind": "array", "length": 16, "type": { "kind": "struct", - "path": "aztec::abi::ContractStorageRead", + "path": "aztec::protocol_types::contrakt::storage_read::StorageRead", "fields": [ { "name": "storage_slot", @@ -489,7 +594,7 @@ } }, { - "name": "value", + "name": "current_value", "type": { "kind": "field" } @@ -499,7 +604,7 @@ } }, { - "name": "public_call_stack", + "name": "public_call_stack_hashes", "type": { "kind": "array", "length": 4, @@ -558,7 +663,7 @@ "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::BlockHeader", + "path": "aztec::protocol_types::abis::block_header::BlockHeader", "fields": [ { "name": "note_hash_tree_root", @@ -608,13 +713,22 @@ { "name": "prover_address", "type": { - "kind": "field" + "kind": "struct", + "path": "aztec::protocol_types::address::AztecAddress", + "fields": [ + { + "name": "inner", + "type": { + "kind": "field" + } + } + ] } } ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" } ], diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index 353457cd6f5..bf7610adc41 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -38,6 +38,7 @@ export { computeMessageSecretHash, CheatCodes, AztecAddressLike, + FunctionSelectorLike, isContractDeployed, EthCheatCodes, computeAuthWitMessageHash, diff --git a/yarn-project/aztec.js/src/utils/abi_types.ts b/yarn-project/aztec.js/src/utils/abi_types.ts index eb637142f20..dbe82ddcf20 100644 --- a/yarn-project/aztec.js/src/utils/abi_types.ts +++ b/yarn-project/aztec.js/src/utils/abi_types.ts @@ -1,10 +1,13 @@ -import { AztecAddress, EthAddress, Fr } from '@aztec/circuits.js'; +import { AztecAddress, EthAddress, Fr, FunctionSelector } from '@aztec/circuits.js'; /** Any type that can be converted into a field for a contract call. */ export type FieldLike = Fr | Buffer | bigint | number | { /** Converts to field */ toField: () => Fr }; -/** Any type that can be converted into an EthereumAddress Aztec.nr struct. */ +/** Any type that can be converted into an EthAddress Aztec.nr struct. */ export type EthAddressLike = { /** Wrapped address */ address: FieldLike } | EthAddress; -/** Any type that can be converted into an EthereumAddress Aztec.nr struct. */ +/** Any type that can be converted into an AztecAddress Aztec.nr struct. */ export type AztecAddressLike = { /** Wrapped address */ address: FieldLike } | AztecAddress; + +/** Any type that can be converted into an FunctionSelector Aztec.nr struct. */ +export type FunctionSelectorLike = FieldLike | FunctionSelector; diff --git a/yarn-project/boxes/token/src/contracts/src/main.nr b/yarn-project/boxes/token/src/contracts/src/main.nr index d697c9ec9f4..d19b1da706b 100644 --- a/yarn-project/boxes/token/src/contracts/src/main.nr +++ b/yarn-project/boxes/token/src/contracts/src/main.nr @@ -27,7 +27,7 @@ contract Token { types::type_serialization::{ field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, - aztec_address_serialization::{AztecAddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, + address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, }, types::address::{AztecAddress}, selector::compute_selector, @@ -77,7 +77,7 @@ contract Token { admin: PublicState::new( context, 1, - AztecAddressSerializationMethods, + AddressSerializationMethods, ), // docs:end:storage_admin_init // docs:start:storage_minters_init diff --git a/yarn-project/end-to-end/src/e2e_card_game.test.ts b/yarn-project/end-to-end/src/e2e_card_game.test.ts index 2b13e560420..3ba6082f7bc 100644 --- a/yarn-project/end-to-end/src/e2e_card_game.test.ts +++ b/yarn-project/end-to-end/src/e2e_card_game.test.ts @@ -25,7 +25,9 @@ const cardToField = (card: Card): bigint => { }; interface PlayerGameEntry { - address: bigint; + address: { + inner: bigint; + }; deck_strength: bigint; points: bigint; } @@ -160,12 +162,16 @@ describe('e2e_card_game', () => { expect((await contract.methods.view_game(GAME_ID).view({ from: firstPlayer })) as Game).toMatchObject({ players: [ { - address: firstPlayer.toBigInt(), + address: { + inner: firstPlayer.toBigInt(), + }, deck_strength: expect.anything(), points: 0n, }, { - address: 0n, + address: { + inner: 0n, + }, deck_strength: 0n, points: 0n, }, @@ -200,12 +206,16 @@ describe('e2e_card_game', () => { expect((await contract.methods.view_game(GAME_ID).view({ from: firstPlayer })) as Game).toMatchObject({ players: expect.arrayContaining([ { - address: firstPlayer.toBigInt(), + address: { + inner: firstPlayer.toBigInt(), + }, deck_strength: expect.anything(), points: 0n, }, { - address: secondPlayer.toBigInt(), + address: { + inner: secondPlayer.toBigInt(), + }, deck_strength: expect.anything(), points: 0n, }, @@ -249,7 +259,7 @@ describe('e2e_card_game', () => { async function playGame(playerDecks: { address: AztecAddress; deck: Card[] }[], id = GAME_ID) { const initialGameState = (await contract.methods.view_game(id).view({ from: firstPlayer })) as Game; - const players = initialGameState.players.map(player => player.address); + const players = initialGameState.players.map(player => player.address.inner); const cards = players.map( player => playerDecks.find(playerDeckEntry => playerDeckEntry.address.toBigInt() === player)!.deck, ); @@ -283,8 +293,8 @@ describe('e2e_card_game', () => { ]); const sortedByPoints = game.players.sort((a, b) => Number(b.points - a.points)); - const winner = AztecAddress.fromBigInt(sortedByPoints[0].address); - const loser = AztecAddress.fromBigInt(sortedByPoints[1].address); + const winner = AztecAddress.fromBigInt(sortedByPoints[0].address.inner); + const loser = AztecAddress.fromBigInt(sortedByPoints[1].address.inner); await expect( contractFor(loser).methods.claim_cards(GAME_ID, game.rounds_cards.map(cardToField)).send().wait(), diff --git a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts index e390a85a4f7..4d2b9c7209d 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts @@ -31,7 +31,7 @@ describe('e2e_nested_contract', () => { it('performs nested calls', async () => { await parentContract.methods - .entryPoint(childContract.address, childContract.methods.value.selector.toField()) + .entryPoint(childContract.address, childContract.methods.value.selector) .send() .wait(); @@ -48,21 +48,21 @@ describe('e2e_nested_contract', () => { it('fails simulation if calling a function not allowed to be called externally', async () => { await expect( parentContract.methods - .entryPoint(childContract.address, childContract.methods.valueInternal.selector.toField()) + .entryPoint(childContract.address, childContract.methods.valueInternal.selector) .simulate(), ).rejects.toThrowError('Assertion failed: Sender must be this contract'); }, 100_000); it('performs public nested calls', async () => { await parentContract.methods - .pubEntryPoint(childContract.address, childContract.methods.pubGetValue.selector.toField(), 42n) + .pubEntryPoint(childContract.address, childContract.methods.pubGetValue.selector, 42n) .send() .wait(); }, 100_000); it('enqueues a single public call', async () => { await parentContract.methods - .enqueueCallToChild(childContract.address, childContract.methods.pubIncValue.selector.toField(), 42n) + .enqueueCallToChild(childContract.address, childContract.methods.pubIncValue.selector, 42n) .send() .wait(); expect(await getChildStoredValue(childContract)).toEqual(new Fr(42n)); @@ -71,14 +71,14 @@ describe('e2e_nested_contract', () => { it('fails simulation if calling a public function not allowed to be called externally', async () => { await expect( parentContract.methods - .enqueueCallToChild(childContract.address, childContract.methods.pubIncValueInternal.selector.toField(), 42n) + .enqueueCallToChild(childContract.address, childContract.methods.pubIncValueInternal.selector, 42n) .simulate(), ).rejects.toThrowError('Assertion failed: Sender must be this contract'); }, 100_000); it('enqueues multiple public calls', async () => { await parentContract.methods - .enqueueCallToChildTwice(childContract.address, childContract.methods.pubIncValue.selector.value, 42n) + .enqueueCallToChildTwice(childContract.address, childContract.methods.pubIncValue.selector, 42n) .send() .wait(); expect(await getChildStoredValue(childContract)).toEqual(new Fr(85n)); @@ -86,7 +86,7 @@ describe('e2e_nested_contract', () => { it('enqueues a public call with nested public calls', async () => { await parentContract.methods - .enqueueCallToPubEntryPoint(childContract.address, childContract.methods.pubIncValue.selector.toField(), 42n) + .enqueueCallToPubEntryPoint(childContract.address, childContract.methods.pubIncValue.selector, 42n) .send() .wait(); expect(await getChildStoredValue(childContract)).toEqual(new Fr(42n)); @@ -94,7 +94,7 @@ describe('e2e_nested_contract', () => { it('enqueues multiple public calls with nested public calls', async () => { await parentContract.methods - .enqueueCallsToPubEntryPoint(childContract.address, childContract.methods.pubIncValue.selector.toField(), 42n) + .enqueueCallsToPubEntryPoint(childContract.address, childContract.methods.pubIncValue.selector, 42n) .send() .wait(); expect(await getChildStoredValue(childContract)).toEqual(new Fr(85n)); @@ -103,7 +103,7 @@ describe('e2e_nested_contract', () => { // Regression for https://github.com/AztecProtocol/aztec-packages/issues/640 it('reads fresh value after write within the same tx', async () => { await parentContract.methods - .pubEntryPointTwice(childContract.address, childContract.methods.pubIncValue.selector.value, 42n) + .pubEntryPointTwice(childContract.address, childContract.methods.pubIncValue.selector, 42n) .send() .wait(); expect(await getChildStoredValue(childContract)).toEqual(new Fr(84n)); @@ -114,7 +114,7 @@ describe('e2e_nested_contract', () => { // through the account contract, if the account entrypoint behaves properly, it will honor // this order and not run the private call first which results in the public calls being inverted. it('executes public calls in expected order', async () => { - const pubSetValueSelector = childContract.methods.pubSetValue.selector.toField(); + const pubSetValueSelector = childContract.methods.pubSetValue.selector; const actions = [ childContract.methods.pubSetValue(20n).request(), parentContract.methods.enqueueCallToChild(childContract.address, pubSetValueSelector, 40n).request(), diff --git a/yarn-project/end-to-end/src/e2e_pending_commitments_contract.test.ts b/yarn-project/end-to-end/src/e2e_pending_commitments_contract.test.ts index 509ce526bc4..980ed63fb10 100644 --- a/yarn-project/end-to-end/src/e2e_pending_commitments_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_pending_commitments_contract.test.ts @@ -77,9 +77,9 @@ describe('e2e_pending_commitments_contract', () => { .test_insert_then_get_then_nullify_all_in_nested_calls( mintAmount, owner, - deployedContract.methods.insert_note.selector.toField(), - deployedContract.methods.get_then_nullify_note.selector.toField(), - deployedContract.methods.get_note_zero_balance.selector.toField(), + deployedContract.methods.insert_note.selector, + deployedContract.methods.get_then_nullify_note.selector, + deployedContract.methods.get_note_zero_balance.selector, ) .send() .wait(); @@ -101,8 +101,8 @@ describe('e2e_pending_commitments_contract', () => { .test_insert2_then_get2_then_nullify2_all_in_nested_calls( mintAmount, owner, - deployedContract.methods.insert_note.selector.toField(), - deployedContract.methods.get_then_nullify_note.selector.toField(), + deployedContract.methods.insert_note.selector, + deployedContract.methods.get_then_nullify_note.selector, ) .send() .wait(); @@ -125,8 +125,8 @@ describe('e2e_pending_commitments_contract', () => { .test_insert2_then_get2_then_nullify1_all_in_nested_calls( mintAmount, owner, - deployedContract.methods.insert_note.selector.toField(), - deployedContract.methods.get_then_nullify_note.selector.toField(), + deployedContract.methods.insert_note.selector, + deployedContract.methods.get_then_nullify_note.selector, ) .send() .wait(); @@ -159,9 +159,9 @@ describe('e2e_pending_commitments_contract', () => { .test_insert1_then_get2_then_nullify2_all_in_nested_calls( mintAmount, owner, - deployedContract.methods.insert_note.selector.toField(), - deployedContract.methods.get_then_nullify_note.selector.toField(), - deployedContract.methods.get_note_zero_balance.selector.toField(), + deployedContract.methods.insert_note.selector, + deployedContract.methods.get_then_nullify_note.selector, + deployedContract.methods.get_note_zero_balance.selector, ) .send() .wait(); @@ -195,9 +195,9 @@ describe('e2e_pending_commitments_contract', () => { .test_insert_then_get_then_nullify_all_in_nested_calls( mintAmount, owner, - deployedContract.methods.dummy.selector.toField(), - deployedContract.methods.get_then_nullify_note.selector.toField(), - deployedContract.methods.get_note_zero_balance.selector.toField(), + deployedContract.methods.dummy.selector, + deployedContract.methods.get_then_nullify_note.selector, + deployedContract.methods.get_note_zero_balance.selector, ) .send() .wait(); diff --git a/yarn-project/end-to-end/src/guides/up_quick_start.sh b/yarn-project/end-to-end/src/guides/up_quick_start.sh index 9181b8d6aa7..418952234bf 100755 --- a/yarn-project/end-to-end/src/guides/up_quick_start.sh +++ b/yarn-project/end-to-end/src/guides/up_quick_start.sh @@ -6,8 +6,8 @@ set -eux # The following accounts and pks must match the ones exposed by the sandbox. # docs:start:declare-accounts -ALICE="0x06357cc85cb8fc561adbf741f63cd75efa26ffba1c80d431ec77d036d8edf022" -BOB="0x1b18a972d54db0283a04abaace5f7b03c3fca5a4b2c0cf113b457de6ea4991e7" +ALICE="0x26fc40ccf8622e4ac4bb1132762cb3917933b1b556155b1964bbbfdd3071ff5c" +BOB="0x2a0f32c34c5b948a7f9766f0c1aad70a86c0ee649f56208e936be4324d49b0b9" ALICE_PRIVATE_KEY="0x2153536ff6628eee01cf4024889ff977a18d9fa61d0e414422f7681cf085c281" # docs:end:declare-accounts diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 92e70e281c3..9bd5e60c296 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -103,7 +103,8 @@ export async function deployAndInitializeTokenAndBridgeContracts( throw new Error(`Token admin is not ${owner}`); } - if ((await bridge.methods.token().view()) !== token.address.toBigInt()) { + // TODO(#3641) - Fix deserialization and compare AztecAddress directly + if ((await bridge.methods.token().view()).inner !== token.address.toBigInt()) { throw new Error(`Bridge token is not ${token.address}`); } diff --git a/yarn-project/foundation/src/abi/encoder.test.ts b/yarn-project/foundation/src/abi/encoder.test.ts index bfe0d63ebf2..faeac04f45d 100644 --- a/yarn-project/foundation/src/abi/encoder.test.ts +++ b/yarn-project/foundation/src/abi/encoder.test.ts @@ -25,7 +25,7 @@ describe('abi/encoder', () => { expect(encodeArguments(abi, [field])).toEqual([field]); }); - it.each(['AztecAddress', 'EthereumAddress'])('accepts address instance for %s structs', (structType: string) => { + it.each(['AztecAddress', 'EthAddress'])('accepts address instance for %s structs', (structType: string) => { const abi: FunctionAbi = { name: 'constructor', functionType: FunctionType.SECRET, @@ -35,7 +35,7 @@ describe('abi/encoder', () => { name: 'owner', type: { kind: 'struct', - path: `aztec::types::address::${structType}`, + path: `types::address::${structType}`, fields: [ { name: 'address', diff --git a/yarn-project/foundation/src/abi/encoder.ts b/yarn-project/foundation/src/abi/encoder.ts index a4db8e24230..6aece06f6c0 100644 --- a/yarn-project/foundation/src/abi/encoder.ts +++ b/yarn-project/foundation/src/abi/encoder.ts @@ -1,6 +1,6 @@ import { Fr } from '../fields/index.js'; import { ABIType, FunctionAbi } from './abi.js'; -import { isAddressStruct } from './utils.js'; +import { isAddressStruct, isFunctionSelectorStruct } from './utils.js'; /** * Encodes arguments for a function call. @@ -68,17 +68,32 @@ class ArgumentEncoder { this.encodeArgument(abiType.type, arg[i], `${name}[${i}]`); } break; - case 'struct': + case 'struct': { // If the abi expects a struct like { address: Field } and the supplied arg does not have // an address field in it, we try to encode it as if it were a field directly. - if (isAddressStruct(abiType) && typeof arg.address === 'undefined') { - this.encodeArgument({ kind: 'field' }, arg, `${name}.address`); + const isAddress = isAddressStruct(abiType); + if (isAddress && typeof arg.address === 'undefined' && typeof arg.inner === 'undefined') { + this.encodeArgument({ kind: 'field' }, arg, `${name}.inner`); + break; + } + if (isFunctionSelectorStruct(abiType)) { + if (typeof arg.value === 'undefined') { + this.encodeArgument({ kind: 'integer', sign: 'unsigned', width: 32 }, arg, `${name}.inner`); + } else { + this.encodeArgument({ kind: 'integer', sign: 'unsigned', width: 32 }, arg.value, `${name}.inner`); + } break; } for (const field of abiType.fields) { - this.encodeArgument(field.type, arg[field.name], `${name}.${field.name}`); + // The ugly check bellow is here because of a `CompleteAddress`. Since it has `address` property but in ABI + // it's called inner we set `field.name` here to `address` instead of using `field.name`. I know it's hacky + // but using address.address in Noir looks stupid and renaming `address` param of `CompleteAddress` + // to `inner` doesn't make sense. + const fieldName = isAddress && arg.address !== undefined ? 'address' : field.name; + this.encodeArgument(field.type, arg[fieldName], `${name}.${field.name}`); } break; + } case 'integer': this.flattened.push(new Fr(arg)); break; diff --git a/yarn-project/foundation/src/abi/utils.ts b/yarn-project/foundation/src/abi/utils.ts index d7d15a4d94a..8d645f92833 100644 --- a/yarn-project/foundation/src/abi/utils.ts +++ b/yarn-project/foundation/src/abi/utils.ts @@ -6,7 +6,7 @@ import { type ABIType } from './abi.js'; * @returns Boolean. */ export function isAddressStruct(abiType: ABIType) { - return isEthereumAddressStruct(abiType) || isAztecAddressStruct(abiType); + return isEthAddressStruct(abiType) || isAztecAddressStruct(abiType); } /** @@ -14,8 +14,8 @@ export function isAddressStruct(abiType: ABIType) { * @param abiType - Type to check. * @returns Boolean. */ -export function isEthereumAddressStruct(abiType: ABIType) { - return abiType.kind === 'struct' && abiType.path.endsWith('::types::address::EthereumAddress'); +export function isEthAddressStruct(abiType: ABIType) { + return abiType.kind === 'struct' && abiType.path.endsWith('types::address::EthAddress'); } /** @@ -24,5 +24,14 @@ export function isEthereumAddressStruct(abiType: ABIType) { * @returns Boolean. */ export function isAztecAddressStruct(abiType: ABIType) { - return abiType.kind === 'struct' && abiType.path.endsWith('::types::address::AztecAddress'); + return abiType.kind === 'struct' && abiType.path.endsWith('types::address::AztecAddress'); +} + +/** + * Returns whether the ABI type is an Function Selector defined in Aztec.nr. + * @param abiType - Type to check. + * @returns Boolean. + */ +export function isFunctionSelectorStruct(abiType: ABIType) { + return abiType.kind === 'struct' && abiType.path.endsWith('types::abis::function_selector::FunctionSelector'); } diff --git a/yarn-project/noir-compiler/src/__snapshots__/index.test.ts.snap b/yarn-project/noir-compiler/src/__snapshots__/index.test.ts.snap index b9e79a46077..5d3f916dc63 100644 --- a/yarn-project/noir-compiler/src/__snapshots__/index.test.ts.snap +++ b/yarn-project/noir-compiler/src/__snapshots__/index.test.ts.snap @@ -240,17 +240,21 @@ exports[`noir-compiler using wasm binary generates Aztec.nr external interface 1 use dep::std; use dep::aztec::context::{ PrivateContext, PublicContext }; -use dep::protocol_types::constants::RETURN_VALUES_LENGTH; +use dep::protocol_types::{ + address::AztecAddress, + abis::function_selector::FunctionSelector, + constants::RETURN_VALUES_LENGTH, +}; // Interface for calling TestContract functions from a private context struct TestContractPrivateContextInterface { - address: Field, + address: AztecAddress, } impl TestContractPrivateContextInterface { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address, } @@ -262,7 +266,7 @@ impl TestContractPrivateContextInterface { ) { let mut serialized_args = [0; 0]; - context.call_public_function(self.address, 0x46be982e, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x46be982e), serialized_args) } } @@ -272,11 +276,11 @@ impl TestContractPrivateContextInterface { // Interface for calling TestContract functions from a public context struct TestContractPublicContextInterface { - address: Field, + address: AztecAddress, } impl TestContractPublicContextInterface { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address, } @@ -288,7 +292,7 @@ impl TestContractPublicContextInterface { ) -> [Field; RETURN_VALUES_LENGTH] { let mut serialized_args = [0; 0]; - context.call_public_function(self.address, 0x46be982e, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x46be982e), serialized_args) } } @@ -316,6 +320,7 @@ import { EthAddressLike, FieldLike, Fr, + FunctionSelectorLike, Point, PublicKey, Wallet, diff --git a/yarn-project/noir-compiler/src/contract-interface-gen/contractTypescript.ts b/yarn-project/noir-compiler/src/contract-interface-gen/contractTypescript.ts index 68c00af09ad..6afa902c1d5 100644 --- a/yarn-project/noir-compiler/src/contract-interface-gen/contractTypescript.ts +++ b/yarn-project/noir-compiler/src/contract-interface-gen/contractTypescript.ts @@ -3,7 +3,8 @@ import { ContractArtifact, FunctionArtifact, isAztecAddressStruct, - isEthereumAddressStruct, + isEthAddressStruct, + isFunctionSelectorStruct, } from '@aztec/foundation/abi'; import compact from 'lodash.compact'; @@ -26,12 +27,15 @@ function abiTypeToTypescript(type: ABIParameter['type']): string { case 'array': return `${abiTypeToTypescript(type.type)}[]`; case 'struct': - if (isEthereumAddressStruct(type)) { + if (isEthAddressStruct(type)) { return 'EthAddressLike'; } if (isAztecAddressStruct(type)) { return 'AztecAddressLike'; } + if (isFunctionSelectorStruct(type)) { + return 'FunctionSelectorLike'; + } return `{ ${type.fields.map(f => `${f.name}: ${abiTypeToTypescript(f.type)}`).join(', ')} }`; default: throw new Error(`Unknown type ${type}`); @@ -189,6 +193,7 @@ import { EthAddressLike, FieldLike, Fr, + FunctionSelectorLike, Point, PublicKey, Wallet, diff --git a/yarn-project/noir-compiler/src/contract-interface-gen/noir.ts b/yarn-project/noir-compiler/src/contract-interface-gen/noir.ts index ecc5ffb771d..ec7049b9c3e 100644 --- a/yarn-project/noir-compiler/src/contract-interface-gen/noir.ts +++ b/yarn-project/noir-compiler/src/contract-interface-gen/noir.ts @@ -32,7 +32,7 @@ function isPrivateCall(functionType: FunctionType) { function generateCallStatement(selector: FunctionSelector, functionType: FunctionType) { const callMethod = isPrivateCall(functionType) ? 'call_private_function' : 'call_public_function'; return ` - context.${callMethod}(self.address, 0x${selector.toString()}, serialized_args)`; + context.${callMethod}(self.address, FunctionSelector::from_field(0x${selector.toString()}), serialized_args)`; } /** @@ -167,7 +167,11 @@ ${callStatement} function generateStaticImports() { return `use dep::std; use dep::aztec::context::{ PrivateContext, PublicContext }; -use dep::protocol_types::constants::RETURN_VALUES_LENGTH;`; +use dep::protocol_types::{ + address::AztecAddress, + abis::function_selector::FunctionSelector, + constants::RETURN_VALUES_LENGTH, +};`; } /** @@ -189,7 +193,7 @@ function generateContractStructName(contractName: string, kind: 'private' | 'pub function generateContractInterfaceStruct(contractName: string, kind: 'private' | 'public') { return `// Interface for calling ${contractName} functions from a ${kind} context struct ${generateContractStructName(contractName, kind)} { - address: Field, + address: AztecAddress, } `; } @@ -203,7 +207,7 @@ struct ${generateContractStructName(contractName, kind)} { */ function generateContractInterfaceImpl(contractName: string, kind: 'private' | 'public', functions: string[]) { return `impl ${generateContractStructName(contractName, kind)} { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address, } diff --git a/yarn-project/noir-contracts/src/contracts/benchmarking_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/benchmarking_contract/Nargo.toml index 18720278402..79a4fd9b875 100644 --- a/yarn-project/noir-contracts/src/contracts/benchmarking_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/benchmarking_contract/Nargo.toml @@ -7,3 +7,4 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } value_note = { path = "../../../../aztec-nr/value-note" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file 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 27683d5a52d..e128c7d7b15 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 @@ -17,9 +17,10 @@ contract Benchmarking { log::emit_unencrypted_log, state_vars::{map::Map, public_state::PublicState, set::Set}, types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - types::address::{AztecAddress}, }; + use dep::protocol_types::address::AztecAddress; + struct Storage { notes: Map>, balances: Map>, @@ -39,8 +40,8 @@ contract Benchmarking { // Creates a new value note for the target owner. Use this method to seed an initial set of notes. #[aztec(private)] - fn create_note(owner: Field, value: Field) { - increment(storage.notes.at(owner), value, owner); + fn create_note(owner: AztecAddress, value: Field) { + increment(storage.notes.at(owner.to_field()), value, owner); } // Deletes a note at a specific index in the set and creates a new one with the same value. @@ -49,8 +50,8 @@ contract Benchmarking { // See https://discourse.aztec.network/t/utxo-concurrency-issues-for-private-state/635 // by @rahul-kothari for a full explanation on why this is needed. #[aztec(private)] - fn recreate_note(owner: Field, index: u32) { - let owner_notes = storage.notes.at(owner); + fn recreate_note(owner: AztecAddress, index: u32) { + let owner_notes = storage.notes.at(owner.to_field()); let getter_options = NoteGetterOptions::new().set_limit(1).set_offset(index); let notes = owner_notes.get_notes(getter_options); let note = notes[0].unwrap_unchecked(); @@ -60,22 +61,23 @@ contract Benchmarking { // Reads and writes to public storage and enqueues a call to another public function. #[aztec(public)] - fn increment_balance(owner: Field, value: Field) { - let current = storage.balances.at(owner).read(); - storage.balances.at(owner).write(current + value); + fn increment_balance(owner: AztecAddress, value: Field) { + let current = storage.balances.at(owner.to_field()).read(); + storage.balances.at(owner.to_field()).write(current + value); let _callStackItem1 = context.call_public_function(context.this_address(), - compute_selector("broadcast(Field)"), - [owner]); + compute_selector("broadcast((Field))"), + [owner.to_field()]); } // Emits a public log. #[aztec(public)] - fn broadcast(owner: Field) { - emit_unencrypted_log(&mut context, storage.balances.at(owner).read()); + fn broadcast(owner: AztecAddress) { + emit_unencrypted_log(&mut context, storage.balances.at(owner.to_field()).read()); } unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/cards.nr b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/cards.nr index 560dc4fb8e9..4f524ef95c0 100644 --- a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/cards.nr +++ b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/cards.nr @@ -1,4 +1,5 @@ use dep::protocol_types::constants::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL}; +use dep::protocol_types::address::AztecAddress; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, note::{ @@ -59,7 +60,7 @@ impl CardNote { fn new( strength: u16, points: u16, - owner: Field, + owner: AztecAddress, ) -> Self { let card = Card { strength, @@ -68,7 +69,7 @@ impl CardNote { CardNote::from_card(card, owner) } - pub fn from_card(card: Card, owner: Field) -> CardNote { + pub fn from_card(card: Card, owner: AztecAddress) -> CardNote { CardNote { card, note: ValueNote::new(card.to_field(), owner), @@ -125,7 +126,7 @@ impl Deck { } } - pub fn add_cards(&mut self, cards: [Card; N], owner: Field) -> [CardNote]{ + pub fn add_cards(&mut self, cards: [Card; N], owner: AztecAddress) -> [CardNote]{ let context = self.set.context.private.unwrap(); let mut inserted_cards = []; @@ -138,7 +139,7 @@ impl Deck { inserted_cards } - pub fn get_cards(&mut self, cards: [Card; N], owner: Field) -> [CardNote; N] { + pub fn get_cards(&mut self, cards: [Card; N], owner: AztecAddress) -> [CardNote; N] { let options = NoteGetterOptions::with_filter(filter_cards, cards); let maybe_notes = self.set.get_notes(options); let mut found_cards = [Option::none(); N]; @@ -149,7 +150,7 @@ impl Deck { ); // Ensure the notes are actually owned by the owner (to prevent user from generating a valid proof while // spending someone else's notes). - assert(card_note.note.owner == owner); + assert(card_note.note.owner.eq(owner)); for j in 0..cards.len() { if found_cards[j].is_none() & (cards[j].strength == card_note.card.strength) & (cards[j].points == card_note.card.points) { @@ -165,7 +166,7 @@ impl Deck { }) } - pub fn remove_cards(&mut self, cards: [Card; N], owner: Field) { + pub fn remove_cards(&mut self, cards: [Card; N], owner: AztecAddress) { let card_notes = self.get_cards(cards, owner); for card_note in card_notes { self.set.remove(card_note.note); @@ -188,9 +189,9 @@ impl Deck { global PACK_CARDS = 3; // Limited by number of write requests (max 4) -pub fn get_pack_cards(seed: Field, owner_address: Field) -> [Card; PACK_CARDS] { +pub fn get_pack_cards(seed: Field, owner: AztecAddress) -> [Card; PACK_CARDS] { // generate pseudo randomness deterministically from 'seed' and user secret - let secret = get_secret_key(owner_address); + let secret = get_secret_key(owner); let mix = secret.high + secret.low + seed; let random_bytes = std::hash::sha256(mix.to_le_bytes(32)); diff --git a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/game.nr b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/game.nr index 7b6255e907c..c3aba855f4b 100644 --- a/yarn-project/noir-contracts/src/contracts/card_game_contract/src/game.nr +++ b/yarn-project/noir-contracts/src/contracts/card_game_contract/src/game.nr @@ -1,3 +1,4 @@ +use dep::protocol_types::address::AztecAddress; use dep::aztec::types::type_serialization::TypeSerializationInterface; use crate::cards::Card; @@ -5,14 +6,14 @@ global NUMBER_OF_PLAYERS = 2; global NUMBER_OF_CARDS_DECK = 2; struct PlayerEntry { - address: Field, + address: AztecAddress, deck_strength: u32, points: u120, } impl PlayerEntry { pub fn is_initialized(self) -> bool { - self.address != 0 + !self.address.is_zero() } } @@ -32,8 +33,8 @@ global GAME_SERIALIZED_LEN: Field = 15; fn deserializeGame(fields: [Field; GAME_SERIALIZED_LEN]) -> Game { let players = [ - PlayerEntry { address: fields[0], deck_strength: fields[1] as u32, points: fields[2] as u120 }, - PlayerEntry { address: fields[3], deck_strength: fields[4] as u32, points: fields[5] as u120 } + PlayerEntry { address: AztecAddress::from_field(fields[0]), deck_strength: fields[1] as u32, points: fields[2] as u120 }, + PlayerEntry { address: AztecAddress::from_field(fields[3]), deck_strength: fields[4] as u32, points: fields[5] as u120 } ]; let rounds_cards = [ Card::from_field(fields[6]), Card::from_field(fields[7]), @@ -52,10 +53,10 @@ fn deserializeGame(fields: [Field; GAME_SERIALIZED_LEN]) -> Game { fn serializeGame(game: Game) -> [Field; GAME_SERIALIZED_LEN] { [ - game.players[0].address, + game.players[0].address.to_field(), game.players[0].deck_strength as Field, game.players[0].points as Field, - game.players[1].address, + game.players[1].address.to_field(), game.players[1].deck_strength as Field, game.players[1].points as Field, game.rounds_cards[0].to_field(), @@ -81,7 +82,7 @@ impl Game { for i in 0..NUMBER_OF_PLAYERS { let entry = self.players[i]; if entry.is_initialized() { - assert(entry.address != player_entry.address, "Player already in game"); + assert(!entry.address.eq(player_entry.address), "Player already in game"); } else if !added { self.players[i] = player_entry; added = true; 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 9edea67a00c..088f75d9ace 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 @@ -2,7 +2,10 @@ mod cards; mod game; contract CardGame { - use dep::protocol_types::constants::MAX_NOTES_PER_PAGE; + use dep::protocol_types::{ + address::AztecAddress, + constants::MAX_NOTES_PER_PAGE, + }; use dep::aztec::{ context::Context, hash::pedersen_hash, @@ -59,7 +62,7 @@ contract CardGame { impl Storage { fn init( context: Context, - ) -> pub Self { + ) -> Self { Storage { collections: Map::new( context, @@ -111,7 +114,7 @@ contract CardGame { let buyer = context.msg_sender(); let mut cards = get_pack_cards(seed, buyer); - let mut collection = storage.collections.at(buyer); + let mut collection = storage.collections.at(buyer.to_field()); let _inserted_cards = collection.add_cards(cards, buyer); } @@ -121,19 +124,19 @@ contract CardGame { let player = context.msg_sender(); - let mut collection = storage.collections.at(player); + let mut collection = storage.collections.at(player.to_field()); collection.remove_cards(cards, player); - let mut game_deck = storage.game_decks.at(game as Field).at(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 = compute_selector("on_game_joined(u32,(Field),u32)"); let strength = compute_deck_strength(cards); context.call_public_function(context.this_address(), selector, - [game as Field, player, strength]); + [game as Field, player.to_field(), strength]); } #[aztec(public)] - internal fn on_game_joined(game: u32, player: Field, deck_strength: u32) { + internal fn on_game_joined(game: u32, player: AztecAddress, deck_strength: u32) { let game_storage = storage.games.at(game as Field); let mut game_data = game_storage.read(); @@ -155,26 +158,26 @@ contract CardGame { fn play_card(game: u32, card: Card) { let player = context.msg_sender(); - let mut game_deck = storage.game_decks.at(game as Field).at(player); + 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 = compute_selector("on_card_played(u32,(Field),Field)"); // docs:start:call_public_function context.call_public_function(context.this_address(), selector, - [game as Field, player, card.to_field()]); + [game as Field, player.to_field(), card.to_field()]); // docs:end:call_public_function } #[aztec(public)] - internal fn on_card_played(game: u32, player: Field, card_as_field: Field) { + internal fn on_card_played(game: u32, player: AztecAddress, card_as_field: Field) { let game_storage = storage.games.at(game as Field); let mut game_data = game_storage.read(); let card = Card::from_field(card_as_field); let current_player = game_data.current_player(); - assert(current_player.address == player, "Not your turn"); + assert(current_player.address.eq(player), "Not your turn"); game_data.play_card(card); game_storage.write(game_data); @@ -185,17 +188,17 @@ contract CardGame { let player = context.msg_sender(); let cards = cards_fields.map(|card_field| Card::from_field(card_field)); - let mut collection = storage.collections.at(player); + 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 = compute_selector("on_cards_claimed(u32,(Field),Field)"); context.call_public_function(context.this_address(), selector, - [game as Field, player, pedersen_hash(cards_fields, 0)]); + [game as Field, player.to_field(), pedersen_hash(cards_fields, 0)]); } #[aztec(public)] - internal fn on_cards_claimed(game: u32, player: Field, cards_hash: Field) { + internal fn on_cards_claimed(game: u32, player: AztecAddress, cards_hash: Field) { let game_storage = storage.games.at(game as Field); let mut game_data = game_storage.read(); @@ -205,19 +208,19 @@ contract CardGame { assert_eq(cards_hash, pedersen_hash(game_data.rounds_cards.map(|card: Card| card.to_field()), 0)); let winner = game_data.winner(); - assert_eq(player, winner.address, "Not the winner"); + assert(player.eq(winner.address), "Not the winner"); game_storage.write(game_data); } - unconstrained fn view_collection_cards(owner: Field, offset: u32) -> [Option; MAX_NOTES_PER_PAGE] { - let collection = storage.collections.at(owner); + unconstrained fn view_collection_cards(owner: AztecAddress, offset: u32) -> [Option; MAX_NOTES_PER_PAGE] { + let collection = storage.collections.at(owner.to_field()); collection.view_cards(offset) } - unconstrained fn view_game_cards(game: u32, player: Field, offset: u32) -> [Option; MAX_NOTES_PER_PAGE] { - let game_deck = storage.game_decks.at(game as Field).at(player); + unconstrained fn view_game_cards(game: u32, player: AztecAddress, offset: u32) -> [Option; MAX_NOTES_PER_PAGE] { + let game_deck = storage.game_decks.at(game as Field).at(player.to_field()); game_deck.view_cards(offset) } @@ -230,7 +233,8 @@ contract CardGame { // Note 1: Needs to be defined by every contract producing logs. // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) } } 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 c884aece908..9bb20c9fd20 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 @@ -16,7 +16,7 @@ contract Child { } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { current_value: PublicState::new( context, @@ -37,7 +37,7 @@ contract Child { } fn check_sender(call_context: CallContext) { - assert_eq(call_context.msg_sender, call_context.storage_contract_address, "Sender must be this contract"); + assert(call_context.msg_sender.eq(call_context.storage_contract_address), "Sender must be this contract"); } // Returns a sum of the input and the chain id and version of the contract in private circuit public input's return_values. diff --git a/yarn-project/noir-contracts/src/contracts/counter_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/counter_contract/Nargo.toml index 9c973675fe1..23cb537fb80 100644 --- a/yarn-project/noir-contracts/src/contracts/counter_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/counter_contract/Nargo.toml @@ -7,4 +7,5 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } value_note = { path = "../../../../aztec-nr/value-note" } -easy_private_state = { path = "../../../../aztec-nr/easy-private-state"} \ No newline at end of file +easy_private_state = { path = "../../../../aztec-nr/easy-private-state"} +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/counter_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/counter_contract/src/main.nr index e332d692bd8..a01a6ce0971 100644 --- a/yarn-project/noir-contracts/src/contracts/counter_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/counter_contract/src/main.nr @@ -1,5 +1,6 @@ contract Counter { // docs:start:imports + use dep::protocol_types::address::AztecAddress; use dep::aztec::{ context::{PrivateContext, Context}, note::{ @@ -28,7 +29,7 @@ contract Counter { // docs:start:storage_init impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { counters: Map::new( context, @@ -44,31 +45,32 @@ contract Counter { // docs:start:constructor #[aztec(private)] - fn constructor(headstart: u120, owner: Field) { + fn constructor(headstart: u120, owner: AztecAddress) { let counters = storage.counters; - counters.at(owner).add(headstart, owner); + counters.at(owner.to_field()).add(headstart, owner); } // docs:end:constructor // docs:start:increment #[aztec(private)] - fn increment(owner: Field) { + fn increment(owner: AztecAddress) { let counters = storage.counters; - counters.at(owner).add(1, owner); + counters.at(owner.to_field()).add(1, owner); } // docs:end:increment // docs:start:get_counter - unconstrained fn get_counter(owner: Field) -> Field { + unconstrained fn get_counter(owner: AztecAddress) -> Field { let counters = storage.counters; - balance_utils::get_balance(counters.at(owner).set) + balance_utils::get_balance(counters.at(owner.to_field()).set) } // docs:end:get_counter // docs:start:nullifier - unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); - note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, preimage) + unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); + note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) } // docs:end:nullifier } diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/actions.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/actions.nr index 9e3234812f9..a542a422838 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/actions.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/actions.nr @@ -1,4 +1,7 @@ -use dep::protocol_types::constants::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL}; +use dep::protocol_types::{ + address::AztecAddress, + constants::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL}, +}; use dep::aztec::note::{ note_getter_options::NoteGetterOptions, note_viewer_options::NoteViewerOptions, }; @@ -115,8 +118,8 @@ unconstrained pub fn view_cards(state_var: Set, options } // docs:end:state_vars-SetView -unconstrained pub fn get_total_points(state_var: Set, account: Field, offset: u32) -> u8 { - let options = NoteViewerOptions::new().select(2, account).set_offset(offset); +unconstrained pub fn get_total_points(state_var: Set, account: AztecAddress, offset: u32) -> u8 { + let options = NoteViewerOptions::new().select(2, account.to_field()).set_offset(offset); let mut total_points = 0; let notes = view_cards(state_var, options); for i in 0..notes.len() { @@ -131,13 +134,13 @@ unconstrained pub fn get_total_points(state_var: Set, a } // docs:start:state_vars-MapAtSingletonInit -pub fn add_new_profile(state_var: Map>, account: Field, profile: &mut ProfileNote) { - state_var.at(account).initialize(profile, Option::some(account), true); +pub fn add_new_profile(state_var: Map>, account: AztecAddress, profile: &mut ProfileNote) { + state_var.at(account.to_field()).initialize(profile, Option::some(account), true); } // docs:end:state_vars-MapAtSingletonInit // docs:start:state_vars-MapAtSingletonGet -pub fn get_profile(state_var: Map>, account: Field) -> ProfileNote { - state_var.at(account).get_note(true) +pub fn get_profile(state_var: Map>, account: AztecAddress) -> ProfileNote { + state_var.at(account.to_field()).get_note(true) } // docs:end:state_vars-MapAtSingletonGet diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr index 95eb42363cb..ee74e34c7ad 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/main.nr @@ -4,6 +4,10 @@ mod options; mod types; contract DocsExample { + use dep::protocol_types::{ + address::AztecAddress, + abis::function_selector::FunctionSelector, + }; use dep::std::option::Option; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, @@ -50,7 +54,7 @@ contract DocsExample { // docs:start:state_vars-Set // docs:start:state_vars-MapSingleton impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { // highlight-next-line:state_vars-PublicState locked: PublicState::new(context, 1, BoolSerializationMethods), @@ -92,10 +96,10 @@ contract DocsExample { #[aztec(private)] fn constructor(min_points: u8, max_points: u8, legendary_card_secret: Field) { - let mut game_rules = RulesNote::new(min_points, max_points, Option::some(0)); + let mut game_rules = RulesNote::new(min_points, max_points, Option::some(AztecAddress::zero())); actions::init_game_rules(storage.game_rules, &mut game_rules); - let mut legendary_card = CardNote::new(0, legendary_card_secret, 0); + let mut legendary_card = CardNote::new(0, legendary_card_secret, AztecAddress::zero()); actions::init_legendary_card(storage.legendary_card, &mut legendary_card); } @@ -116,7 +120,7 @@ contract DocsExample { // docs:end:functions-OpenFunction #[aztec(public)] - fn replace_queen(account: Field, points: u8) { + fn replace_queen(account: AztecAddress, points: u8) { let new_queen = Queen { account, points }; assert(actions::can_replace_queen(storage.queen, new_queen)); @@ -131,10 +135,10 @@ contract DocsExample { let points = actions::get_total_points(storage.cards, account, 0); let current_queen = storage.queen.read(); - assert(account != current_queen.account); + assert(!account.eq(current_queen.account)); assert(points > current_queen.points); - AccountContractInterface::at(account).send_rewards(current_queen.points); + AccountContractInterface::at(account.to_field()).send_rewards(current_queen.points); let new_queen = Queen { account, points }; storage.queen.write(new_queen); @@ -145,7 +149,7 @@ contract DocsExample { #[aztec(private)] fn add_common_cards(secrets: [Field; 4]) { for i in 0..secrets.len() as u8 { - let mut card = CardNote::new(0, secrets[i], 0); + let mut card = CardNote::new(0, secrets[i], AztecAddress::zero()); actions::add_new_card(storage.cards, &mut card); } } @@ -167,24 +171,24 @@ contract DocsExample { let owner = legendary_card.owner; let result = context.call_private_function(inputs.call_context.storage_contract_address, - GET_POINTS_OF_COMMON_CARD_FUNCTION_SELECTOR, - [owner, 0]); + FunctionSelector::from_field(GET_POINTS_OF_COMMON_CARD_FUNCTION_SELECTOR), + [owner.to_field(), 0]); let total_points = legendary_card.points + result[0] as u8; context.call_public_function(inputs.call_context.storage_contract_address, - REPLACE_QUEEN_FUNCTION_SELECTOR, - [owner, total_points as Field]); + FunctionSelector::from_field(REPLACE_QUEEN_FUNCTION_SELECTOR), + [owner.to_field(), total_points as Field]); } #[aztec(private)] - fn get_points_of_common_cards(account: Field, offset: u32) { + fn get_points_of_common_cards(account: AztecAddress, offset: u32) { let mut total_points = 0; let options = create_account_card_getter_options(account, offset); let cards = actions::get_cards(storage.cards, options); for i in 0..cards.len() { if (cards[i].is_some()) { let card = cards[i].unwrap_unchecked(); - assert(card.owner == account); + assert(card.owner.eq(account)); total_points += card.points; } } @@ -193,7 +197,7 @@ contract DocsExample { } // docs:start:functions-UnconstrainedFunction - unconstrained fn get_total_points(account: Field) -> u8 { + unconstrained fn get_total_points(account: AztecAddress) -> u8 { actions::get_total_points(storage.cards, account, 0) } // docs:end:functions-UnconstrainedFunction diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/options.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/options.nr index 6ac7442ea2f..3a93fc918db 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/options.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/options.nr @@ -1,17 +1,20 @@ use crate::types::card_note::{CardNote, CARD_NOTE_LEN}; -use dep::protocol_types::constants::MAX_READ_REQUESTS_PER_CALL; +use dep::protocol_types::{ + address::AztecAddress, + constants::MAX_READ_REQUESTS_PER_CALL, +}; use dep::aztec::note::note_getter_options::{NoteGetterOptions, Sort, SortOrder}; use dep::std::option::Option; // docs:start:state_vars-NoteGetterOptionsSelectSortOffset -pub fn create_account_card_getter_options(account_address: Field, offset: u32) -> NoteGetterOptions { - NoteGetterOptions::new().select(2, account_address).sort(0, SortOrder.DESC).set_offset(offset) +pub fn create_account_card_getter_options(account: AztecAddress, offset: u32) -> NoteGetterOptions { + NoteGetterOptions::new().select(2, account.to_field()).sort(0, SortOrder.DESC).set_offset(offset) } // docs:end:state_vars-NoteGetterOptionsSelectSortOffset // docs:start:state_vars-NoteGetterOptionsMultiSelects -pub fn create_exact_card_getter_options(points: u8, secret: Field, account_address: Field) -> NoteGetterOptions { - NoteGetterOptions::new().select(0, points as Field).select(1, secret).select(2, account_address) +pub fn create_exact_card_getter_options(points: u8, secret: Field, account: AztecAddress) -> NoteGetterOptions { + NoteGetterOptions::new().select(0, points as Field).select(1, secret).select(2, account.to_field()) } // docs:end:state_vars-NoteGetterOptionsMultiSelects @@ -30,13 +33,13 @@ pub fn filter_min_points(cards: [Option; MAX_READ_REQUESTS_PER_CALL], // docs:end:state_vars-OptionFilter // docs:start:state_vars-NoteGetterOptionsFilter -pub fn create_account_cards_with_min_points_getter_options(account_address: Field, min_points: u8) -> NoteGetterOptions { - NoteGetterOptions::with_filter(filter_min_points, min_points).select(2, account_address).sort(0, SortOrder.ASC) +pub fn create_account_cards_with_min_points_getter_options(account: AztecAddress, min_points: u8) -> NoteGetterOptions { + NoteGetterOptions::with_filter(filter_min_points, min_points).select(2, account.to_field()).sort(0, SortOrder.ASC) } // docs:end:state_vars-NoteGetterOptionsFilter // docs:start:state_vars-NoteGetterOptionsPickOne -pub fn create_largest_account_card_getter_options(account_address: Field) -> NoteGetterOptions { - NoteGetterOptions::new().select(2, account_address).sort(0, SortOrder.DESC).set_limit(1) +pub fn create_largest_account_card_getter_options(account: AztecAddress) -> NoteGetterOptions { + NoteGetterOptions::new().select(2, account.to_field()).sort(0, SortOrder.DESC).set_limit(1) } // docs:end:state_vars-NoteGetterOptionsPickOne diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/card_note.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/card_note.nr index 01269b00954..03ecfa5545f 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/card_note.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/card_note.nr @@ -1,3 +1,4 @@ +use dep::protocol_types::address::AztecAddress; use dep::aztec::{ note::{ note_header::NoteHeader, @@ -19,13 +20,13 @@ global CARD_NOTE_LEN: Field = 3; struct CardNote { points: u8, secret: Field, - owner: Field, + owner: AztecAddress, header: NoteHeader, } // docs:end:state_vars-CardNote impl CardNote { - pub fn new(points: u8, secret: Field, owner: Field) -> Self { + pub fn new(points: u8, secret: Field, owner: AztecAddress) -> Self { CardNote { points, secret, @@ -35,14 +36,14 @@ impl CardNote { } pub fn serialize(self) -> [Field; CARD_NOTE_LEN] { - [self.points as Field, self.secret, self.owner] + [self.points as Field, self.secret, self.owner.to_field()] } pub fn deserialize(serialized_note: [Field; CARD_NOTE_LEN]) -> Self { CardNote { points: serialized_note[0] as u8, secret: serialized_note[1], - owner: serialized_note[2], + owner: AztecAddress::from_field(serialized_note[2]), header: NoteHeader::empty(), } } @@ -51,7 +52,7 @@ impl CardNote { pedersen_hash([ self.points as Field, self.secret, - self.owner, + self.owner.to_field(), ],0) } diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/profile_note.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/profile_note.nr index a0058066167..9d4eea39b09 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/profile_note.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/profile_note.nr @@ -1,3 +1,4 @@ +use dep::protocol_types::address::AztecAddress; use dep::std::option::Option; use dep::aztec::{ note::{ @@ -15,12 +16,12 @@ global PROFILE_NOTE_LEN: Field = 2; struct ProfileNote { avatar: Field, xp: Field, - maybe_owner: Option, + maybe_owner: Option, header: NoteHeader, } impl ProfileNote { - pub fn new(avatar: Field, xp: Field, maybe_owner: Option) -> Self { + pub fn new(avatar: Field, xp: Field, maybe_owner: Option) -> Self { ProfileNote { avatar, xp, @@ -58,7 +59,7 @@ impl ProfileNote { self.header = header; } - pub fn set_owner(&mut self, owner: Field) { + pub fn set_owner(&mut self, owner: AztecAddress) { self.maybe_owner = Option::some(owner); } diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/queen.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/queen.nr index 488ee5f52bc..645d39f8924 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/queen.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/queen.nr @@ -1,8 +1,9 @@ +use dep::protocol_types::address::AztecAddress; use dep::aztec::types::type_serialization::TypeSerializationInterface; // docs:start:state_vars-CustomStruct struct Queen { - account: Field, + account: AztecAddress, points: u8, } // docs:end:state_vars-CustomStruct @@ -11,11 +12,11 @@ struct Queen { global QUEEN_SERIALIZED_LEN: Field = 2; fn deserialize(fields: [Field; QUEEN_SERIALIZED_LEN]) -> Queen { - Queen { account: fields[0], points: fields[1] as u8 } + Queen { account: AztecAddress::from_field(fields[0]), points: fields[1] as u8 } } fn serialize(queen: Queen) -> [Field; QUEEN_SERIALIZED_LEN] { - [queen.account, queen.points as Field] + [queen.account.to_field(), queen.points as Field] } global QueenSerializationMethods = TypeSerializationInterface { diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/rules_note.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/rules_note.nr index f1ce9166efd..aae5dba13fe 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/rules_note.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/rules_note.nr @@ -1,3 +1,4 @@ +use dep::protocol_types::address::AztecAddress; use dep::std::option::Option; use dep::aztec::{ note::{ @@ -15,12 +16,12 @@ global RULES_NOTE_LEN: Field = 2; struct RulesNote { min_points: u8, max_points: u8, - maybe_owner: Option, + maybe_owner: Option, header: NoteHeader, } impl RulesNote { - pub fn new(min_points: u8, max_points: u8, maybe_owner: Option) -> Self { + pub fn new(min_points: u8, max_points: u8, maybe_owner: Option) -> Self { RulesNote { min_points, max_points, @@ -58,7 +59,7 @@ impl RulesNote { self.header = header; } - pub fn set_owner(&mut self, owner: Field) { + pub fn set_owner(&mut self, owner: AztecAddress) { self.maybe_owner = Option::some(owner); } diff --git a/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/Nargo.toml index 8f0625c3b46..5feca12855d 100644 --- a/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/Nargo.toml @@ -7,4 +7,5 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } value_note = { path = "../../../../aztec-nr/value-note"} -easy_private_state = { path = "../../../../aztec-nr/easy-private-state"} \ No newline at end of file +easy_private_state = { path = "../../../../aztec-nr/easy-private-state"} +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr index 859d6859bf7..8af766921bb 100644 --- a/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/easy_private_token_contract/src/main.nr @@ -1,5 +1,6 @@ // docs:start:easy_private_token_contract contract EasyPrivateToken { + use dep::protocol_types::address::AztecAddress; use dep::std::option::Option; use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, @@ -40,42 +41,43 @@ contract EasyPrivateToken { * initialize the contract's initial state variables. */ #[aztec(private)] - fn constructor(initial_supply: u120, owner: Field) { + fn constructor(initial_supply: u120, owner: AztecAddress) { let balances = storage.balances; - balances.at(owner).add(initial_supply, owner); + balances.at(owner.to_field()).add(initial_supply, owner); } // Mints `amount` of tokens to `owner`. #[aztec(private)] - fn mint(amount: u120, owner: Field) { + fn mint(amount: u120, owner: AztecAddress) { let balances = storage.balances; - balances.at(owner).add(amount, owner); + balances.at(owner.to_field()).add(amount, owner); } // Transfers `amount` of tokens from `sender` to a `recipient`. #[aztec(private)] - fn transfer(amount: u120, sender: Field, recipient: Field) { + fn transfer(amount: u120, sender: AztecAddress, recipient: AztecAddress) { let balances = storage.balances; - balances.at(sender).sub(amount, sender); - balances.at(recipient).add(amount, recipient); + balances.at(sender.to_field()).sub(amount, sender); + balances.at(recipient.to_field()).add(amount, recipient); } // Helper function to get the balance of a user ("unconstrained" is a Noir alternative of Solidity's "view" function). - unconstrained fn getBalance(owner: Field) -> Field { + unconstrained fn getBalance(owner: AztecAddress) -> Field { let balances = storage.balances; // Return the sum of all notes in the set. - balance_utils::get_balance(balances.at(owner).set) + balance_utils::get_balance(balances.at(owner.to_field()).set) } // Computes note hash and nullifier. // Note 1: Needs to be defined by every contract producing logs. // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) } } 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 f428fc88426..f9685507a90 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,25 +1,27 @@ contract EasyPrivateVoting { // docs:start:imports - use dep::protocol_types::constants::EMPTY_NULLIFIED_COMMITMENT; + use dep::protocol_types::{ + 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}, - aztec_address_serialization::{AztecAddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, - field_serialization::{ FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - }, - types::address::{AztecAddress}, + 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}, + address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, + field_serialization::{ FieldSerializationMethods, FIELD_SERIALIZED_LEN}, + }, }; // docs:end:imports // docs:start:storage_struct struct Storage { - admin: PublicState, // admin can end vote - tally: Map>, // we will store candidate as key and number of votes as value - voteEnded: PublicState, // voteEnded is boolean -} + admin: PublicState, // admin can end vote + tally: Map>, // we will store candidate as key and number of votes as value + voteEnded: PublicState, // voteEnded is boolean + } // docs:end:storage_struct // docs:start:storage_impl impl Storage { @@ -28,7 +30,7 @@ contract EasyPrivateVoting { admin: PublicState::new( context, 1, // storage slot. this can be anything except 0. it is hashed, and hash on 0 = 0 - AztecAddressSerializationMethods, + AddressSerializationMethods, ), tally: Map::new( context, @@ -56,7 +58,7 @@ contract EasyPrivateVoting { // 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 - [admin.address] // parameters + [admin.to_field()] // parameters ); } // docs:end:constructor @@ -71,7 +73,7 @@ contract EasyPrivateVoting { #[aztec(private)] // annotation to mark function as private and expose private context fn cast_vote(candidate: Field) { let secret = get_secret_key(context.msg_sender()); // get secret key of caller of function - let nullifier = dep::std::hash::pedersen_hash([context.msg_sender(), secret.low, secret.high]); // compute nullifier with this secret key so others can't descrypt it + let nullifier = dep::std::hash::pedersen_hash([context.msg_sender().to_field(), secret.low, secret.high]); // compute nullifier with this secret key so others can't descrypt it context.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT); // push nullifier context.call_public_function( context.this_address(), @@ -92,7 +94,7 @@ contract EasyPrivateVoting { // docs:start:end_vote #[aztec(public)] fn end_vote() { - assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), "Only admin can end votes"); // assert that caller is admin + assert(storage.admin.read().eq(context.msg_sender()), "Only admin can end votes"); // assert that caller is admin storage.voteEnded.write(true); } // docs:end:end_vote diff --git a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/Nargo.toml index dd89fa41284..51ec4df865c 100644 --- a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/Nargo.toml @@ -6,4 +6,5 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } -authwit = { path = "../../../../aztec-nr/authwit" } \ No newline at end of file +authwit = { path = "../../../../aztec-nr/authwit" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr index 436199240ad..da1c72d8f6f 100644 --- a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr +++ b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr @@ -1,3 +1,4 @@ +use dep::protocol_types::address::AztecAddress; use dep::aztec::{ note::{ note_header::NoteHeader, @@ -20,12 +21,12 @@ global ECDSA_PUBLIC_KEY_NOTE_LEN: Field = 5; struct EcdsaPublicKeyNote { x: [u8; 32], y: [u8; 32], - owner: Field, // We store the owner address only to get the secret key to compute the nullifier + owner: AztecAddress, // We store the owner address only to get the secret key to compute the nullifier header: NoteHeader, } impl EcdsaPublicKeyNote { - pub fn new(x: [u8; 32], y: [u8; 32], owner: Field) -> Self { + pub fn new(x: [u8; 32], y: [u8; 32], owner: AztecAddress) -> Self { EcdsaPublicKeyNote { x, y, @@ -56,8 +57,7 @@ impl EcdsaPublicKeyNote { let last_x = self.x[31] as Field; let last_y = self.y[31] as Field; - let res: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] = [x, last_x, y, last_y, self.owner]; - res + [x, last_x, y, last_y, self.owner.to_field()] } pub fn compute_nullifier(self) -> Field { @@ -104,7 +104,7 @@ fn deserialize(serialized_note: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN]) -> EcdsaPubl } y[31] = serialized_note[3].to_be_bytes(32)[31]; - EcdsaPublicKeyNote { x, y, owner: serialized_note[4], header: NoteHeader::empty() } + EcdsaPublicKeyNote { x, y, owner: AztecAddress::from_field(serialized_note[4]), header: NoteHeader::empty() } } fn serialize(note: EcdsaPublicKeyNote) -> [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] { diff --git a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr index 7706217e639..a4604621e7c 100644 --- a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr @@ -3,6 +3,7 @@ mod ecdsa_public_key_note; // Account contract that uses ECDSA signatures for authentication on the same curve as Ethereum. // The signing key is stored in an immutable private note and should be different from the signing key. contract EcdsaAccount { + use dep::protocol_types::address::AztecAddress; use dep::std; use dep::std::option::Option; use dep::aztec::{ @@ -30,7 +31,7 @@ contract EcdsaAccount { } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { public_key: ImmutableSingleton::new(context, 1, EcdsaPublicKeyNoteInterface), } @@ -47,6 +48,7 @@ contract EcdsaAccount { storage.public_key.initialize(&mut pub_key_note, Option::none(), true); } + // Note: If you globally change the entrypoint signature don't forget to update default_entrypoint.ts #[aztec(private)] fn entrypoint(payload: pub EntrypointPayload) { let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl); @@ -103,7 +105,8 @@ contract EcdsaAccount { serialized_note: [Field; ECDSA_PUBLIC_KEY_NOTE_LEN] ) -> [Field; 4] { assert(storage_slot == 1); - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(EcdsaPublicKeyNoteInterface, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/src/contracts/escrow_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/escrow_contract/Nargo.toml index 75ddeb0cb48..a78a27d1949 100644 --- a/yarn-project/noir-contracts/src/contracts/escrow_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/escrow_contract/Nargo.toml @@ -7,3 +7,4 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } address_note = { path = "../../../../aztec-nr/address-note"} +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file 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 befda626373..d90955cd2be 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,6 +2,8 @@ contract Escrow { use dep::std::option::Option; + use dep::protocol_types::address::AztecAddress; + use dep::aztec::{ context::{PrivateContext, PublicContext, Context}, note::{ @@ -25,7 +27,7 @@ contract Escrow { } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { owners: Set::new(context, 1, AddressNoteMethods), } @@ -35,7 +37,7 @@ contract Escrow { // Creates a new instance // docs:start:constructor #[aztec(private)] - fn constructor(owner: pub Field) { + fn constructor(owner: pub AztecAddress) { let this = context.this_address(); // Create a new note and add it to the owners set. @@ -48,21 +50,22 @@ contract Escrow { // Withdraws balance. Requires that msg.sender is registered as an owner. #[aztec(private)] - fn withdraw(token: Field, amount: Field, recipient: Field) { + fn withdraw(token: AztecAddress, amount: Field, recipient: AztecAddress) { let this = context.this_address(); let sender = context.msg_sender(); // We don't remove note from the owners set. If a note exists, the owner and recipient are legit. - let options = NoteGetterOptions::new().select(0, sender).select(1, this).set_limit(1); + let options = NoteGetterOptions::new().select(0, sender.to_field()).select(1, this.to_field()).set_limit(1); 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 _callStackItem = context.call_private_function(token, selector, [this, recipient, amount, 0]); + let _callStackItem = context.call_private_function(token, selector, [this.to_field(), recipient.to_field(), amount, 0]); } unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; ADDRESS_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); assert(storage_slot == 1); note_utils::compute_note_hash_and_nullifier(AddressNoteMethods, note_header, serialized_note) } diff --git a/yarn-project/noir-contracts/src/contracts/import_test_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/import_test_contract/src/main.nr index abf55cd9ba6..bbaff182363 100644 --- a/yarn-project/noir-contracts/src/contracts/import_test_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/import_test_contract/src/main.nr @@ -3,6 +3,7 @@ mod test_contract_interface; // Contract that uses the autogenerated interface of the Test contract for calling its functions. // Used for testing calling into other contracts via autogenerated interfaces. contract ImportTest { + use dep::protocol_types::address::AztecAddress; use crate::test_contract_interface::{ TestPrivateContextInterface, TestPublicContextInterface, @@ -21,7 +22,7 @@ contract ImportTest { // See yarn-project/acir-simulator/src/client/private_execution.ts // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[aztec(private)] - fn main(target: Field) -> Field { + fn main(target: AztecAddress) -> Field { let test_contract_instance = TestPrivateContextInterface::at(target); let return_values = test_contract_instance.test_code_gen(&mut context, 1, @@ -47,7 +48,7 @@ contract ImportTest { // Used for testing calling a function with no arguments // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[aztec(private)] - fn callNoArgs(target: Field) -> Field { + fn callNoArgs(target: AztecAddress) -> Field { let test_contract_instance = TestPrivateContextInterface::at(target); let return_values = test_contract_instance.get_this_address(&mut context); @@ -58,7 +59,7 @@ contract ImportTest { // Used for testing calling an open function // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[aztec(private)] - fn callOpenFn(target: Field) { + fn callOpenFn(target: AztecAddress) { let test_contract_instance = TestPrivateContextInterface::at(target); test_contract_instance.create_nullifier_public(&mut context, 1, 2); } @@ -67,7 +68,7 @@ contract ImportTest { // Used for testing calling an open function from another open function // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[aztec(public)] - fn pubCallOpenFn(target: Field) -> Field { + fn pubCallOpenFn(target: AztecAddress) -> Field { let test_contract_instance = TestPublicContextInterface::at(target); let ret = test_contract_instance.create_nullifier_public(context, 1, 2); 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 3509134e7cf..c0516b90468 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,5 +1,6 @@ // A demonstration of inclusion and non-inclusion proofs. contract InclusionProofs { + use dep::protocol_types::address::AztecAddress; use dep::aztec::{ state_vars::{ map::Map, @@ -8,7 +9,6 @@ contract InclusionProofs { }, selector::compute_selector, types::{ - address::AztecAddress, type_serialization::field_serialization::FieldSerializationMethods, }, context::Context, @@ -81,8 +81,8 @@ contract InclusionProofs { owner: AztecAddress, value: Field, ) { - let owner_private_values = storage.private_values.at(owner.address); - let mut note = ValueNote::new(value, owner.address); + let owner_private_values = storage.private_values.at(owner.to_field()); + let mut note = ValueNote::new(value, owner); owner_private_values.insert(&mut note, true); } @@ -95,8 +95,8 @@ contract InclusionProofs { spare_commitment: Field, // This is only used when the note is not found --> used to test the failure case ) { // 1) Get the note from PXE. - let private_values = storage.private_values.at(owner.address); - let options = NoteGetterOptions::new().select(1, owner.address).set_limit(1); + let private_values = storage.private_values.at(owner.to_field()); + let options = NoteGetterOptions::new().select(1, owner.to_field()).set_limit(1); let notes = private_values.get_notes(options); let maybe_note = notes[0]; @@ -117,8 +117,8 @@ contract InclusionProofs { spare_nullifier: Field, // This is only used when the note is not found --> used to test the failure case ) { // 2) Get the note from PXE - let private_values = storage.private_values.at(owner.address); - let options = NoteGetterOptions::new().select(1, owner.address).set_limit(1); + let private_values = storage.private_values.at(owner.to_field()); + let options = NoteGetterOptions::new().select(1, owner.to_field()).set_limit(1); let notes = private_values.get_notes(options); let maybe_note = notes[0]; @@ -137,8 +137,8 @@ contract InclusionProofs { block_number: u32, // The block at which we'll prove that the note exists and is not nullified ) { // 1) Get the note from PXE. - let private_values = storage.private_values.at(owner.address); - let options = NoteGetterOptions::new().select(1, owner.address).set_limit(1); + let private_values = storage.private_values.at(owner.to_field()); + let options = NoteGetterOptions::new().select(1, owner.to_field()).set_limit(1); let notes = private_values.get_notes(options); let note = notes[0].unwrap(); @@ -150,8 +150,8 @@ contract InclusionProofs { fn nullify_note( owner: AztecAddress, ) { - let private_values = storage.private_values.at(owner.address); - let options = NoteGetterOptions::new().select(1, owner.address).set_limit(1); + let private_values = storage.private_values.at(owner.to_field()); + let options = NoteGetterOptions::new().select(1, owner.to_field()).set_limit(1); let notes = private_values.get_notes(options); let note = notes[0].unwrap(); @@ -181,7 +181,8 @@ contract InclusionProofs { // Note 1: Needs to be defined by every contract producing logs. // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) } } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/lending_contract/src/asset.nr b/yarn-project/noir-contracts/src/contracts/lending_contract/src/asset.nr index e4158fda7f2..5a33ff26332 100644 --- a/yarn-project/noir-contracts/src/contracts/lending_contract/src/asset.nr +++ b/yarn-project/noir-contracts/src/contracts/lending_contract/src/asset.nr @@ -1,3 +1,4 @@ +use dep::protocol_types::address::AztecAddress; use dep::aztec::types::type_serialization::TypeSerializationInterface; // Struct to be used to represent "totals". Generally, there should be one per asset. @@ -9,7 +10,7 @@ struct Asset { interest_accumulator: u120, last_updated_ts: u120, loan_to_value: u120, - oracle_address: Field, + oracle: AztecAddress, } global ASSET_SERIALIZED_LEN: Field = 4; @@ -21,7 +22,7 @@ fn deserializeAsset(fields: [Field; ASSET_SERIALIZED_LEN]) -> Asset { interest_accumulator: fields[0] as u120, last_updated_ts: fields[1] as u120, loan_to_value: fields[2] as u120, - oracle_address: fields[3] + oracle: AztecAddress::from_field(fields[3]) } } @@ -30,7 +31,7 @@ fn serializeAsset(asset: Asset) -> [Field; ASSET_SERIALIZED_LEN] { asset.interest_accumulator as Field, asset.last_updated_ts as Field, asset.loan_to_value as Field, - asset.oracle_address + asset.oracle.to_field() ] } 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 6b2cfa5c629..773ff12bea6 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 @@ -5,14 +5,15 @@ 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; struct PriceFeed { - address: Field, + address: AztecAddress, } impl PriceFeed { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address } } @@ -28,62 +29,62 @@ impl PriceFeed { } struct Token { - address: Field, + address: AztecAddress, } impl Token { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address } } - pub fn transfer_public(self: Self, context: PublicContext, from: Field, to: Field, amount: Field, nonce: Field) { + 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)"), - [from, to, amount, nonce] + [from.to_field(), to.to_field(), amount, nonce] ); } - pub fn mint_public(self: Self, context: PublicContext, to: Field, amount: Field) { + pub fn mint_public(self: Self, context: PublicContext, to: AztecAddress, amount: Field) { context.call_public_function( self.address, compute_selector("mint_public((Field),Field)"), - [to, amount] + [to.to_field(), amount] ); } - pub fn burn_public(self: Self, context: PublicContext, from: Field, amount: Field, nonce: Field) { + 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)"), - [from, amount, nonce] + [from.to_field(), amount, nonce] ); } // Private - pub fn unshield(self: Self, context: &mut PrivateContext, from: Field, to: Field, amount: Field, nonce: Field) -> [Field; RETURN_VALUES_LENGTH] { + 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)"), - [from, to, amount, nonce] + [from.to_field(), to.to_field(), amount, nonce] ) } - pub fn burn(self: Self, context: &mut PrivateContext, from: Field, amount: Field, nonce: Field) -> [Field; RETURN_VALUES_LENGTH] { + 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)"), - [from, amount, nonce] + [from.to_field(), amount, nonce] ) } } struct Lending { - address: Field, + address: AztecAddress, } impl Lending { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address } } @@ -97,7 +98,7 @@ impl Lending { interest_accumulator: return_values[0] as u120, last_updated_ts: return_values[1] as u120, loan_to_value: return_values[2] as u120, - oracle_address: return_values[3], + oracle: AztecAddress::from_field(return_values[3]), } } } 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 f34b9119cb2..0f79bd4383a 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,6 +11,7 @@ mod interfaces; // - A way to repay all debt at once // - Liquidations contract Lending { + use dep::protocol_types::address::AztecAddress; use dep::safe_math::SafeU120; use dep::std::option::Option; use dep::aztec::{ @@ -23,6 +24,7 @@ contract Lending { types::type_serialization::{ field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, TypeSerializationInterface, + address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, }, }; use crate::asset::{ASSET_SERIALIZED_LEN, Asset, AssetSerializationMethods}; @@ -32,25 +34,25 @@ contract Lending { // Storage structure, containing all storage, and specifying what slots they use. struct Storage { - collateral_asset: PublicState, - stable_coin: PublicState, + collateral_asset: PublicState, + stable_coin: PublicState, assets: Map>, collateral: Map>, static_debt: Map>, // abusing keys very heavily } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { collateral_asset: PublicState::new( context, 1, - FieldSerializationMethods, + AddressSerializationMethods, ), stable_coin: PublicState::new( context, 2, - FieldSerializationMethods, + AddressSerializationMethods, ), assets: Map::new( context, @@ -101,7 +103,7 @@ contract Lending { ) {} #[aztec(public)] - fn init(oracle_address: Field, loan_to_value: Field, collateral_asset: Field, stable_coin: Field) { + fn init(oracle: AztecAddress, loan_to_value: Field, collateral_asset: AztecAddress, stable_coin: AztecAddress) { let asset_loc = storage.assets.at(0); let asset = asset_loc.read(); @@ -113,7 +115,7 @@ contract Lending { interest_accumulator: 1000000000, last_updated_ts: context.timestamp() as u120, loan_to_value: loan_to_value as u120, - oracle_address + oracle }); storage.collateral_asset.write(collateral_asset); @@ -146,65 +148,65 @@ contract Lending { } #[aztec(private)] - fn deposit_private(from: Field, amount: Field, nonce: Field, secret: Field, on_behalf_of: Field, collateral_asset: Field) { - let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender()); + fn deposit_private(from: AztecAddress, amount: Field, nonce: Field, secret: Field, on_behalf_of: Field, collateral_asset: AztecAddress) { + 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 = compute_selector("_deposit((Field),Field,(Field))"); context.call_public_function(context.this_address(), selector, - [on_behalf_of, amount, collateral_asset]); + [on_behalf_of, amount, collateral_asset.to_field()]); } #[aztec(public)] - fn deposit_public(amount: Field, nonce: Field, on_behalf_of: Field, collateral_asset: Field) { + fn deposit_public(amount: Field, nonce: Field, on_behalf_of: Field, collateral_asset: AztecAddress) { Token::at(collateral_asset).transfer_public(context, context.msg_sender(), context.this_address(), amount, nonce); - let selector = compute_selector("_deposit(Field,Field,Field)"); + let selector = compute_selector("_deposit((Field),Field,(Field))"); context.call_public_function(context.this_address(), selector, - [on_behalf_of, amount, collateral_asset]); + [on_behalf_of, amount, collateral_asset.to_field()]); } #[aztec(public)] - internal fn _deposit(owner: Field, amount: Field, collateral_asset: Field) { + internal fn _deposit(owner: AztecAddress, amount: Field, collateral_asset: AztecAddress) { let _asset = Lending::at(context.this_address()).update_accumulator(context); let coll_asset = storage.collateral_asset.read(); - assert(coll_asset == collateral_asset); + assert(coll_asset.eq(collateral_asset)); - let coll_loc = storage.collateral.at(owner); + let coll_loc = storage.collateral.at(owner.to_field()); let collateral = coll_loc.read(); coll_loc.write(collateral + amount); } #[aztec(private)] - fn withdraw_private(secret: Field, to: Field, amount: Field) { - let on_behalf_of = compute_identifier(secret, 0, context.msg_sender()); - let selector = compute_selector("_withdraw(Field,Field,Field)"); - context.call_public_function(context.this_address(), selector, [on_behalf_of, to, amount]); + 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)"); + context.call_public_function(context.this_address(), selector, [on_behalf_of, to.to_field(), amount]); } #[aztec(public)] - fn withdraw_public(to: Field, amount: Field) { - let selector = compute_selector("_withdraw(Field,Field,Field)"); + fn withdraw_public(to: AztecAddress, amount: Field) { + let selector = compute_selector("_withdraw((Field),(Field),Field)"); context.call_public_function(context.this_address(), selector, - [context.msg_sender(), to, amount]); + [context.msg_sender().to_field(), to.to_field(), amount]); } #[aztec(public)] - internal fn _withdraw(owner: Field, recipient: Field, amount: Field) { + internal fn _withdraw(owner: AztecAddress, recipient: AztecAddress, amount: Field) { let asset = Lending::at(context.this_address()).update_accumulator(context); - let price = PriceFeed::at(asset.oracle_address).get_price(context); + let price = PriceFeed::at(asset.oracle).get_price(context); - let coll_loc = storage.collateral.at(owner); + let coll_loc = storage.collateral.at(owner.to_field()); let collateral: Field = coll_loc.read(); - let debt_loc = storage.static_debt.at(owner); + let debt_loc = storage.static_debt.at(owner.to_field()); let static_debt: Field = debt_loc.read(); // debt_covered will revert if decrease would leave insufficient collateral to cover debt. @@ -226,35 +228,35 @@ contract Lending { } #[aztec(private)] - fn borrow_private(secret: Field, to: Field, amount: Field) { - let on_behalf_of = compute_identifier(secret, 0, context.msg_sender()); - let selector = compute_selector("_borrow(Field,Field,Field)"); - context.call_public_function(context.this_address(), selector, [on_behalf_of, to, amount]); + 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)"); + context.call_public_function(context.this_address(), selector, [on_behalf_of, to.to_field(), amount]); } #[aztec(public)] - fn borrow_public(to: Field, amount: Field) { - let selector = compute_selector("_borrow(Field,Field,Field)"); + fn borrow_public(to: AztecAddress, amount: Field) { + let selector = compute_selector("_borrow((Field),(Field),Field)"); context.call_public_function(context.this_address(), selector, - [context.msg_sender(), to, amount]); + [context.msg_sender().to_field(), to.to_field(), amount]); } #[aztec(public)] - internal fn _borrow(owner: Field, to: Field, amount: Field) { + internal fn _borrow(owner: AztecAddress, to: AztecAddress, amount: Field) { let asset = Lending::at(context.this_address()).update_accumulator(context); - let price = PriceFeed::at(asset.oracle_address).get_price(context); + let price = PriceFeed::at(asset.oracle).get_price(context); // Fetch collateral and static_debt, compute health of current position - let collateral = storage.collateral.at(owner).read() as u120; - let static_debt = storage.static_debt.at(owner).read() as u120; + let collateral = storage.collateral.at(owner.to_field()).read() as u120; + let static_debt = storage.static_debt.at(owner.to_field()).read() as u120; let debt_covered = covered_by_collateral(price, asset.loan_to_value, collateral, 0, 0); let debt_returns = debt_updates(asset.interest_accumulator, static_debt, amount as u120, 0); assert(debt_returns.debt_value < debt_covered); - storage.static_debt.at(owner).write(debt_returns.static_debt as Field); + storage.static_debt.at(owner.to_field()).write(debt_returns.static_debt as Field); // @todo @LHerskind Need to support both private and public minting. let stable_coin = storage.stable_coin.read(); @@ -262,48 +264,48 @@ contract Lending { } #[aztec(private)] - fn repay_private(from: Field, amount: Field, nonce: Field, secret: Field, on_behalf_of: Field, stable_coin: Field) { - let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender()); + fn repay_private(from: AztecAddress, amount: Field, nonce: Field, secret: Field, on_behalf_of: Field, stable_coin: AztecAddress) { + 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 = compute_selector("_repay((Field),Field,(Field))"); context.call_public_function(context.this_address(), selector, - [on_behalf_of, amount, stable_coin]); + [on_behalf_of, amount, stable_coin.to_field()]); } #[aztec(public)] - fn repay_public(amount: Field, nonce: Field, owner: Field, stable_coin: Field) { + 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)"); - context.call_public_function(context.this_address(), selector, [owner, amount, stable_coin]); + let selector = compute_selector("_repay((Field),Field,(Field))"); + context.call_public_function(context.this_address(), selector, [owner.to_field(), amount, stable_coin.to_field()]); } #[aztec(public)] - internal fn _repay(owner: Field, amount: Field, stable_coin: Field) { + internal fn _repay(owner: AztecAddress, amount: Field, stable_coin: AztecAddress) { let asset = Lending::at(context.this_address()).update_accumulator(context); // To ensure that private is using the correct token. - assert(stable_coin == storage.stable_coin.read()); + assert(stable_coin.eq(storage.stable_coin.read())); - let static_debt = storage.static_debt.at(owner).read() as u120; + let static_debt = storage.static_debt.at(owner.to_field()).read() as u120; let debt_returns = debt_updates(asset.interest_accumulator, static_debt, 0, amount as u120); - storage.static_debt.at(owner).write(debt_returns.static_debt as Field); + storage.static_debt.at(owner.to_field()).write(debt_returns.static_debt as Field); } unconstrained fn get_asset(assetId: Field) -> Asset { storage.assets.at(assetId).read() } - unconstrained fn get_position(owner: Field) -> Position { - let collateral = storage.collateral.at(owner).read(); - let static_debt = storage.static_debt.at(owner).read(); + unconstrained fn get_position(owner: AztecAddress) -> Position { + let collateral = storage.collateral.at(owner.to_field()).read(); + let static_debt = storage.static_debt.at(owner.to_field()).read(); let asset = storage.assets.at(0).read(); let debt = debt_value(static_debt as u120, asset.interest_accumulator as u120) as Field; Position { collateral, static_debt, debt } } - unconstrained fn get_assets() -> [Field; 2] { + unconstrained fn get_assets() -> [AztecAddress; 2] { [storage.collateral_asset.read(), storage.stable_coin.read()] } diff --git a/yarn-project/noir-contracts/src/contracts/parent_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/parent_contract/Nargo.toml index 6b845f1f512..a17390a872f 100644 --- a/yarn-project/noir-contracts/src/contracts/parent_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/parent_contract/Nargo.toml @@ -6,3 +6,4 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } 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 9560223aff5..38b9c3fcfe1 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,13 +1,17 @@ // 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, + }; #[aztec(private)] fn constructor() {} // Private function to call another private function in the targetContract using the provided selector #[aztec(private)] - fn entryPoint(targetContract: Field, targetSelector: Field) -> Field { + fn entryPoint(targetContract: AztecAddress, targetSelector: FunctionSelector) -> Field { // Call the target private function let return_values = context.call_private_function(targetContract, targetSelector, [0]); @@ -17,7 +21,7 @@ contract Parent { // Public function to directly call another public function to the targetContract using the selector and value provided #[aztec(public)] - fn pubEntryPoint(targetContract: Field, targetSelector: Field, initValue: Field) -> Field { + fn pubEntryPoint(targetContract: AztecAddress, targetSelector: FunctionSelector, initValue: Field) -> Field { let return_values = context.call_public_function(targetContract, targetSelector, [initValue]); return_values[0] @@ -25,7 +29,7 @@ contract Parent { // Same as pubEntryPoint, but calls the target contract twice, using the return value from the first invocation as the argument for the second. #[aztec(public)] - fn pubEntryPointTwice(targetContract: Field, targetSelector: Field, initValue: Field) -> Field { + fn pubEntryPointTwice(targetContract: AztecAddress, targetSelector: FunctionSelector, initValue: Field) -> Field { let returnValue = context.call_public_function(targetContract, targetSelector, [initValue])[0]; let return_values = context.call_public_function(targetContract, targetSelector, [returnValue]); @@ -34,7 +38,7 @@ contract Parent { // Private function to enqueue a call to the targetContract address using the selector and argument provided #[aztec(private)] - fn enqueueCallToChild(targetContract: Field, targetSelector: Field, targetValue: Field) { + fn enqueueCallToChild(targetContract: AztecAddress, targetSelector: FunctionSelector, targetValue: Field) { context.call_public_function(targetContract, targetSelector, [targetValue]); } @@ -42,11 +46,11 @@ 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: Field, targetSelector: Field) { - let enqueueCallToChildSelector = compute_selector("enqueueCallToChild(Field,Field,Field)"); + fn enqueueCallsToChildWithNestedFirst(targetContract: AztecAddress, targetSelector: FunctionSelector) { + let enqueueCallToChildSelector = compute_selector("enqueueCallToChild((Field),(u32),Field)"); let _ret = context.call_private_function(context.this_address(), enqueueCallToChildSelector, - [targetContract, targetSelector, 10]); + [targetContract.to_field(), targetSelector.to_field(), 10]); context.call_public_function(targetContract, targetSelector, [20]); } @@ -54,17 +58,17 @@ contract Parent { // - one issued directly from this function with value 20, // - followed by one through a nested call to enqueueCallToChild with value 10. #[aztec(private)] - fn enqueueCallsToChildWithNestedLast(targetContract: Field, targetSelector: Field) { + fn enqueueCallsToChildWithNestedLast(targetContract: AztecAddress, targetSelector: FunctionSelector) { context.call_public_function(targetContract, targetSelector, [20]); - let enqueueCallToChildSelector = compute_selector("enqueueCallToChild(Field,Field,Field)"); + let enqueueCallToChildSelector = compute_selector("enqueueCallToChild((Field),(u32),Field)"); let _ret = context.call_private_function(context.this_address(), enqueueCallToChildSelector, - [targetContract, targetSelector, 10]); + [targetContract.to_field(), targetSelector.to_field(), 10]); } // Private function to enqueue a call to the targetContract address using the selector and argument provided #[aztec(private)] - fn enqueueCallToChildTwice(targetContract: Field, targetSelector: Field, targetValue: Field) { + fn enqueueCallToChildTwice(targetContract: AztecAddress, targetSelector: FunctionSelector, targetValue: Field) { // Enqueue the first public call context.call_public_function(targetContract, targetSelector, [targetValue]); // Enqueue the second public call @@ -72,27 +76,27 @@ 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: Field, targetSelector: Field, targetValue: Field) { - let pubEntryPointSelector = compute_selector("pubEntryPoint(Field,Field,Field)"); + #[aztec(private)] + fn enqueueCallToPubEntryPoint(targetContract: AztecAddress, targetSelector: FunctionSelector, targetValue: Field) { + let pubEntryPointSelector = compute_selector("pubEntryPoint((Field),(u32),Field)"); let thisAddress = context.this_address(); let _void = context.call_public_function(thisAddress, pubEntryPointSelector, - [targetContract, targetSelector, targetValue]); + [targetContract.to_field(), targetSelector.to_field(), targetValue]); } // Private function to enqueue two calls to the pubEntryPoint function of this same contract, passing the target arguments provided - #[aztec(private)] - fn enqueueCallsToPubEntryPoint(targetContract: Field, targetSelector: Field, targetValue: Field) { - let pubEntryPointSelector = compute_selector("pubEntryPoint(Field,Field,Field)"); + #[aztec(private)] + fn enqueueCallsToPubEntryPoint(targetContract: AztecAddress, targetSelector: FunctionSelector, targetValue: Field) { + let pubEntryPointSelector = compute_selector("pubEntryPoint((Field),(u32),Field)"); let thisAddress = context.this_address(); context.call_public_function(thisAddress, pubEntryPointSelector, - [targetContract, targetSelector, targetValue]); + [targetContract.to_field(), targetSelector.to_field(), targetValue]); context.call_public_function(thisAddress, pubEntryPointSelector, - [targetContract, targetSelector, targetValue + 1]); + [targetContract.to_field(), targetSelector.to_field(), targetValue + 1]); } } diff --git a/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/Nargo.toml index 5e2af8dd90e..0cec95291e7 100644 --- a/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/Nargo.toml @@ -7,3 +7,4 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } value_note = { path = "../../../../aztec-nr/value-note"} +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } diff --git a/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/src/main.nr index c07f02136d1..c0780c4d4c1 100644 --- a/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/pending_commitments_contract/src/main.nr @@ -20,13 +20,17 @@ contract PendingCommitments { }, state_vars::{map::Map, set::Set}, }; + use dep::protocol_types::{ + address::AztecAddress, + abis::function_selector::FunctionSelector, + }; struct Storage { balances: Map>, } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { balances: Map::new( context, @@ -49,8 +53,8 @@ contract PendingCommitments { // getting / reading that note all in the same contract function // Realistic way to describe this test is "Mint note A, then burn note A in the same transaction" #[aztec(private)] - fn test_insert_then_get_then_nullify_flat(amount: Field, owner: Field) -> Field { - let owner_balance = storage.balances.at(owner); + fn test_insert_then_get_then_nullify_flat(amount: Field, owner: AztecAddress) -> Field { + let owner_balance = storage.balances.at(owner.to_field()); let mut note = ValueNote::new(amount, owner); // Insert note @@ -71,8 +75,8 @@ contract PendingCommitments { // Confirm cannot access commitments inserted later in same function #[aztec(private)] - fn test_bad_get_then_insert_flat(amount: Field, owner: Field) -> Field { - let owner_balance = storage.balances.at(owner); + fn test_bad_get_then_insert_flat(amount: Field, owner: AztecAddress) -> Field { + let owner_balance = storage.balances.at(owner.to_field()); let options = NoteGetterOptions::with_filter(filter_notes_min_sum, amount); // get note (note inserted at bottom of function shouldn't exist yet) @@ -90,12 +94,12 @@ contract PendingCommitments { // Dummy nested/inner function (to pass a function which does nothing) #[aztec(private)] - fn dummy(amount: Field, owner: Field) {} + fn dummy(amount: Field, owner: AztecAddress) {} // Nested/inner function to create and insert a note #[aztec(private)] - fn insert_note(amount: Field, owner: Field) { - let owner_balance = storage.balances.at(owner); + fn insert_note(amount: Field, owner: AztecAddress) { + let owner_balance = storage.balances.at(owner.to_field()); let mut note = ValueNote::new(amount, owner); // Insert note @@ -104,8 +108,8 @@ contract PendingCommitments { // Nested/inner function to get a note and confirm it matches the expected value #[aztec(private)] - fn get_then_nullify_note(expected_value: Field, owner: Field) -> Field { - let owner_balance = storage.balances.at(owner); + fn get_then_nullify_note(expected_value: Field, owner: AztecAddress) -> Field { + let owner_balance = storage.balances.at(owner.to_field()); let options = NoteGetterOptions::new().set_limit(1); let note = owner_balance.get_notes(options)[0].unwrap(); @@ -119,8 +123,8 @@ contract PendingCommitments { // Nested/inner function to get a note and confirms that none is returned #[aztec(private)] - fn get_note_zero_balance(owner: Field) { - let owner_balance = storage.balances.at(owner); + fn get_note_zero_balance(owner: AztecAddress) { + let owner_balance = storage.balances.at(owner.to_field()); let options = NoteGetterOptions::new(); let maybe_notes = owner_balance.get_notes(options); @@ -135,30 +139,30 @@ contract PendingCommitments { #[aztec(private)] fn test_insert_then_get_then_nullify_all_in_nested_calls( amount: Field, - owner: Field, - insert_fn_selector: Field, - get_then_nullify_fn_selector: Field, - get_note_zero_fn_selector: Field + owner: AztecAddress, + insert_fn_selector: FunctionSelector, + get_then_nullify_fn_selector: FunctionSelector, + get_note_zero_fn_selector: FunctionSelector ) { // nested call to create/insert note let _callStackItem1 = context.call_private_function(inputs.call_context.storage_contract_address, insert_fn_selector, - [amount, owner]); + [amount, owner.to_field()]); // nested call to read and nullify that note let _callStackItem2 = context.call_private_function(inputs.call_context.storage_contract_address, get_then_nullify_fn_selector, - [amount, owner]); + [amount, owner.to_field()]); // nested call to confirm that balance is zero let _callStackItem3 = context.call_private_function(inputs.call_context.storage_contract_address, get_note_zero_fn_selector, - [owner]); + [owner.to_field()]); } // same test as above, but insert 2, get 2, nullify 2 #[aztec(private)] - fn test_insert2_then_get2_then_nullify2_all_in_nested_calls(amount: Field, owner: Field, insert_fn_selector: Field, get_then_nullify_fn_selector: Field) { + fn test_insert2_then_get2_then_nullify2_all_in_nested_calls(amount: Field, owner: AztecAddress, insert_fn_selector: FunctionSelector, get_then_nullify_fn_selector: FunctionSelector) { // args for nested calls - let args = [amount, owner]; + let args = [amount, owner.to_field()]; // nested call to create/insert note let _callStackItem1 = context.call_private_function(inputs.call_context.storage_contract_address, @@ -181,9 +185,9 @@ contract PendingCommitments { // same test as above, but insert 2, get 1, nullify 1 #[aztec(private)] - fn test_insert2_then_get2_then_nullify1_all_in_nested_calls(amount: Field, owner: Field, insert_fn_selector: Field, get_then_nullify_fn_selector: Field) { + fn test_insert2_then_get2_then_nullify1_all_in_nested_calls(amount: Field, owner: AztecAddress, insert_fn_selector: FunctionSelector, get_then_nullify_fn_selector: FunctionSelector) { // args for nested calls - let args = [amount, owner]; + let args = [amount, owner.to_field()]; // nested call to create/insert note let _callStackItem1 = context.call_private_function(inputs.call_context.storage_contract_address, @@ -204,13 +208,13 @@ contract PendingCommitments { #[aztec(private)] fn test_insert1_then_get2_then_nullify2_all_in_nested_calls( amount: Field, - owner: Field, - insert_fn_selector: Field, - get_then_nullify_fn_selector: Field, - get_note_zero_fn_selector: Field + owner: AztecAddress, + insert_fn_selector: FunctionSelector, + get_then_nullify_fn_selector: FunctionSelector, + get_note_zero_fn_selector: FunctionSelector ) { // args for nested calls - let args = [amount, owner]; + let args = [amount, owner.to_field()]; // nested call to create/insert note let _callStackItem1 = context.call_private_function(inputs.call_context.storage_contract_address, @@ -226,7 +230,7 @@ contract PendingCommitments { let _callStackItem4 = context.call_private_function(inputs.call_context.storage_contract_address, get_note_zero_fn_selector, - [owner]); + [owner.to_field()]); } // Confirm cannot get/read a pending commitment in a nested call @@ -239,8 +243,8 @@ contract PendingCommitments { // #[aztec(private)] //fn test_bad_get_in_nested_call_then_insert( // amount: Field, - // owner: Field, - // get_then_nullify_fn_selector: Field, + // owner: AztecAddress, + // get_then_nullify_fn_selector: FunctionSelector, //) { //} @@ -248,7 +252,8 @@ contract PendingCommitments { // Note 1: Needs to be defined by every contract producing logs. // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/Nargo.toml index 13577bbd263..456836c53b3 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/Nargo.toml @@ -6,4 +6,5 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } -authwit = { path = "../../../../aztec-nr/authwit" } \ No newline at end of file +authwit = { path = "../../../../aztec-nr/authwit" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr index 34513072247..4210bf8e8ba 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/main.nr @@ -6,6 +6,8 @@ contract SchnorrAccount { use dep::std; use dep::std::option::Option; + use dep::protocol_types::address::AztecAddress; + use dep::aztec::{ context::{PrivateContext, Context}, note::{ note_header::NoteHeader, utils as note_utils }, @@ -27,7 +29,7 @@ contract SchnorrAccount { } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { // docs:start:storage_init signing_public_key: ImmutableSingleton::new(context, 1, PublicKeyNoteMethods), @@ -48,6 +50,7 @@ contract SchnorrAccount { // docs:end:initialize } + // Note: If you globally change the entrypoint signature don't forget to update default_entrypoint.ts file #[aztec(private)] fn entrypoint(payload: pub EntrypointPayload) { let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl); @@ -107,7 +110,8 @@ contract SchnorrAccount { serialized_note: [Field; PUBLIC_KEY_NOTE_LEN] ) -> [Field; 4] { assert(storage_slot == 1); - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(PublicKeyNoteMethods, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/public_key_note.nr b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/public_key_note.nr index 5547b887f5b..579dceff555 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/public_key_note.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/public_key_note.nr @@ -12,6 +12,7 @@ use dep::aztec::{ log::emit_encrypted_log, context::PrivateContext, }; +use dep::protocol_types::address::AztecAddress; global PUBLIC_KEY_NOTE_LEN: Field = 3; @@ -20,12 +21,12 @@ global PUBLIC_KEY_NOTE_LEN: Field = 3; struct PublicKeyNote { x: Field, y: Field, - owner: Field, // We store the owner address only to get the secret key to compute the nullifier and to broadcast + owner: AztecAddress, // We store the owner address only to get the secret key to compute the nullifier and to broadcast header: NoteHeader, } impl PublicKeyNote { - pub fn new(x: Field, y: Field, owner: Field) -> Self { + pub fn new(x: Field, y: Field, owner: AztecAddress) -> Self { PublicKeyNote { x, y, @@ -36,7 +37,7 @@ impl PublicKeyNote { // serialize the note as 3 fields pub fn serialize(self) -> [Field; PUBLIC_KEY_NOTE_LEN] { - [self.x, self.y, self.owner] + [self.x, self.y, self.owner.to_field()] } pub fn compute_nullifier(self) -> Field { @@ -68,7 +69,7 @@ impl PublicKeyNote { } fn deserialize(serialized_note: [Field; PUBLIC_KEY_NOTE_LEN]) -> PublicKeyNote { - PublicKeyNote { x: serialized_note[0], y: serialized_note[1], owner: serialized_note[2], header: NoteHeader::empty() } + PublicKeyNote { x: serialized_note[0], y: serialized_note[1], owner: AztecAddress::from_field(serialized_note[2]), header: NoteHeader::empty() } } fn serialize(note: PublicKeyNote) -> [Field; PUBLIC_KEY_NOTE_LEN] { diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr index 69b6ef6b5b6..70af212ca67 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr @@ -22,6 +22,7 @@ contract SchnorrHardcodedAccount { #[aztec(private)] fn constructor() {} + // Note: If you globally change the entrypoint signature don't forget to update default_entrypoint.ts #[aztec(private)] fn entrypoint(payload: pub EntrypointPayload) { let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl); diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/Nargo.toml index a83a9e626dc..b821d34c282 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/Nargo.toml @@ -6,4 +6,5 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } -authwit = { path = "../../../../aztec-nr/authwit" } \ No newline at end of file +authwit = { path = "../../../../aztec-nr/authwit" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr index 6ddcff3a22e..0b20f873917 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/main.nr @@ -19,6 +19,7 @@ contract SchnorrSingleKeyAccount { #[aztec(private)] fn constructor() {} + // Note: If you globally change the entrypoint signature don't forget to update default_entrypoint.ts #[aztec(private)] fn entrypoint(payload: pub EntrypointPayload) { let actions = AccountActions::private(&mut context, ACCOUNT_ACTIONS_STORAGE_SLOT, is_valid_impl); @@ -46,7 +47,7 @@ contract SchnorrSingleKeyAccount { #[contract_library_method] fn is_valid_impl(context: &mut PrivateContext, message_hash: Field) -> pub bool { let witness = get_auth_witness(message_hash); - assert(recover_address(message_hash, witness) == context.this_address()); + assert(recover_address(message_hash, witness).eq(context.this_address())); true } } diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/util.nr b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/util.nr index db5384cb7c5..cf8db726439 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/util.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_single_key_account_contract/src/util.nr @@ -1,8 +1,9 @@ +use dep::protocol_types::address::AztecAddress; use dep::std::{schnorr::verify_signature}; use dep::aztec::address::compute_address; use crate::auth_oracle::{AuthWitness}; -pub fn recover_address(message_hash: Field, witness: AuthWitness) -> Field { +pub fn recover_address(message_hash: Field, witness: AuthWitness) -> AztecAddress { let message_bytes = message_hash.to_be_bytes(32); let verification = verify_signature(witness.owner.x, witness.owner.y, @@ -10,6 +11,5 @@ pub fn recover_address(message_hash: Field, witness: AuthWitness) -> Field { message_bytes); assert(verification == true); - let reproduced_address = compute_address(witness.owner.x, witness.owner.y, witness.partial_address); - reproduced_address + compute_address(witness.owner.x, witness.owner.y, witness.partial_address) } diff --git a/yarn-project/noir-contracts/src/contracts/slow_tree_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/slow_tree_contract/Nargo.toml index 81fd493ee4a..c211d2ac2c3 100644 --- a/yarn-project/noir-contracts/src/contracts/slow_tree_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/slow_tree_contract/Nargo.toml @@ -7,4 +7,5 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } value_note = { path = "../../../../aztec-nr/value-note"} -slow_updates_tree = { path = "../../../../aztec-nr/slow-updates-tree"} \ No newline at end of file +slow_updates_tree = { path = "../../../../aztec-nr/slow-updates-tree"} +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file 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 f745e9acac0..149e53966ef 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,6 +6,7 @@ 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::std::option::Option; use dep::value_note::{ balance_utils, @@ -44,7 +45,7 @@ contract SlowTree { // docs:end:constants_and_storage impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { trees: Map::new( context, @@ -65,18 +66,18 @@ contract SlowTree { // docs:start:initialize #[aztec(public)] fn initialize() { - storage.trees.at(context.msg_sender()).initialize(EMPTY_ROOT); + storage.trees.at(context.msg_sender().to_field()).initialize(EMPTY_ROOT); } // docs:end:initialize // docs:start:read_at_pub #[aztec(public)] fn read_at_pub(key: Field) -> Field { - storage.trees.at(context.msg_sender()).read_at(key) + storage.trees.at(context.msg_sender().to_field()).read_at(key) } // docs:end:read_at_pub #[aztec(public)] fn read_leaf_at_pub(key: Field) -> Leaf { - storage.trees.at(context.msg_sender()).read_leaf_at(key) + storage.trees.at(context.msg_sender().to_field()).read_leaf_at(key) } // docs:start:read_at_private #[aztec(private)] @@ -89,7 +90,7 @@ contract SlowTree { let selector = compute_selector("_assert_current_root(Field,Field)"); context.call_public_function(context.this_address(), selector, - [context.msg_sender(), expected_root]); + [context.msg_sender().to_field(), expected_root]); p.value } @@ -105,7 +106,7 @@ contract SlowTree { // docs:start:update_at_pub #[aztec(public)] fn update_at_public(p: SlowUpdateProof) { - storage.trees.at(context.msg_sender()).update_at(p); + storage.trees.at(context.msg_sender().to_field()).update_at(p); } // docs:end:update_at_pub // docs:start:update_at_private @@ -125,7 +126,7 @@ contract SlowTree { context.call_public_function(context.this_address(), selector, [ - context.msg_sender(), + context.msg_sender().to_field(), p.index, p.new_value, before_root, @@ -146,15 +147,15 @@ contract SlowTree { storage.trees.at(caller).update_unsafe_at(index, new_value, new_root); } // docs:end:_update - unconstrained fn un_read_leaf_at(address: Field, key: Field) -> Leaf { - storage.trees.at(address).read_leaf_at(key) + unconstrained fn un_read_leaf_at(address: AztecAddress, key: Field) -> Leaf { + storage.trees.at(address.to_field()).read_leaf_at(key) } - unconstrained fn un_read_root(address: Field) -> Leaf { - storage.trees.at(address).read_root() + unconstrained fn un_read_root(address: AztecAddress) -> Leaf { + storage.trees.at(address.to_field()).read_root() } - unconstrained fn compute_note_hash_and_nullifier(_contract_address: Field, _nonce: Field, _storage_slot: Field, _preimage: [Field; 4]) -> [Field; 4] { + unconstrained fn compute_note_hash_and_nullifier(_contract_address: Field, _nonce: Field, _storage_slot: Field, _serialized_note: [Field; 4]) -> [Field; 4] { [0x0d, 0x0e, 0x0a, 0x0d] } } diff --git a/yarn-project/noir-contracts/src/contracts/stateful_test_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/stateful_test_contract/Nargo.toml index b09a51ccd44..20f806b0511 100644 --- a/yarn-project/noir-contracts/src/contracts/stateful_test_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/stateful_test_contract/Nargo.toml @@ -6,4 +6,5 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } -value_note = { path = "../../../../aztec-nr/value-note"} \ No newline at end of file +value_note = { path = "../../../../aztec-nr/value-note"} +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/stateful_test_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/stateful_test_contract/src/main.nr index 491f8ff494a..abf3e95a075 100644 --- a/yarn-project/noir-contracts/src/contracts/stateful_test_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/stateful_test_contract/src/main.nr @@ -1,5 +1,6 @@ // A contract used for testing a random hodgepodge of small features from simulator and end-to-end tests. contract StatefulTest { + use dep::protocol_types::address::AztecAddress; use dep::std::option::Option; use dep::value_note::{ balance_utils, @@ -24,7 +25,7 @@ contract StatefulTest { } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { notes: Map::new( context, @@ -49,39 +50,40 @@ contract StatefulTest { } #[aztec(private)] - fn constructor(owner: Field, value: Field) { - let loc = storage.notes.at(owner); + fn constructor(owner: AztecAddress, value: Field) { + let loc = storage.notes.at(owner.to_field()); increment(loc, value, owner); } #[aztec(private)] - fn create_note(owner: Field, value: Field) { + fn create_note(owner: AztecAddress, value: Field) { if (value != 0) { - let loc = storage.notes.at(owner); + let loc = storage.notes.at(owner.to_field()); increment(loc, value, owner); } } #[aztec(private)] - fn destroy_and_create(recipient: Field, amount: Field) { + fn destroy_and_create(recipient: AztecAddress, amount: Field) { let sender = context.msg_sender(); - let sender_notes = storage.notes.at(sender); + let sender_notes = storage.notes.at(sender.to_field()); decrement(sender_notes, amount, sender); - let recipient_notes = storage.notes.at(recipient); + let recipient_notes = storage.notes.at(recipient.to_field()); increment(recipient_notes, amount, recipient); } - unconstrained fn summed_values(owner: Field) -> Field { - let owner_balance = storage.notes.at(owner); + unconstrained fn summed_values(owner: AztecAddress) -> Field { + let owner_balance = storage.notes.at(owner.to_field()); // Return the sum of all notes in the set. balance_utils::get_balance(owner_balance) } unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; VALUE_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) } } diff --git a/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr b/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr index 51bd95002ae..9ff10a75a23 100644 --- a/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr +++ b/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr @@ -2,7 +2,31 @@ use dep::std; use dep::aztec::context::{ PrivateContext, PublicContext }; -use dep::protocol_types::constants::RETURN_VALUES_LENGTH; +use dep::protocol_types::{ + address::AztecAddress, + abis::function_selector::FunctionSelector, + constants::RETURN_VALUES_LENGTH, +}; + +struct CancellerConsumeMintPrivateMessageStruct { + inner: Field, +} + +struct ToConsumeMintPublicMessageStruct { + inner: Field, +} + +struct CancellerConsumeMintPublicMessageStruct { + inner: Field, +} + +struct AztecAddressGetPortalContractAddressStruct { + inner: Field, +} + +struct AddressGetPublicKeyStruct { + inner: Field, +} struct AStructTestCodeGenStruct { amount: Field, @@ -29,11 +53,11 @@ struct ManyNotesADeepStructTestCodeGenStruct { // Interface for calling Test functions from a private context struct TestPrivateContextInterface { - address: Field, + address: AztecAddress, } impl TestPrivateContextInterface { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address, } @@ -44,38 +68,38 @@ impl TestPrivateContextInterface { context: &mut PrivateContext, secret_hash_for_redeeming_minted_notes: Field, amount: Field, - canceller: Field, + canceller: CancellerConsumeMintPrivateMessageStruct, msg_key: Field, secret_for_L1_to_L2_message_consumption: Field ) -> [Field; RETURN_VALUES_LENGTH] { let mut serialized_args = [0; 5]; serialized_args[0] = secret_hash_for_redeeming_minted_notes; serialized_args[1] = amount; - serialized_args[2] = canceller; + serialized_args[2] = canceller.inner; serialized_args[3] = msg_key; serialized_args[4] = secret_for_L1_to_L2_message_consumption; - context.call_private_function(self.address, 0x8999306a, serialized_args) + context.call_private_function(self.address, FunctionSelector::from_field(0x260712c7), serialized_args) } pub fn consume_mint_public_message( self, context: &mut PrivateContext, - to: Field, + to: ToConsumeMintPublicMessageStruct, amount: Field, - canceller: Field, + canceller: CancellerConsumeMintPublicMessageStruct, msg_key: Field, secret: Field ) { let mut serialized_args = [0; 5]; - serialized_args[0] = to; + serialized_args[0] = to.inner; serialized_args[1] = amount; - serialized_args[2] = canceller; + serialized_args[2] = canceller.inner; serialized_args[3] = msg_key; serialized_args[4] = secret; - context.call_public_function(self.address, 0x1c60863d, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x04ee3bb0), serialized_args) } @@ -89,7 +113,7 @@ impl TestPrivateContextInterface { serialized_args[0] = amount; serialized_args[1] = secret_hash; - context.call_public_function(self.address, 0x9749ca06, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x9749ca06), serialized_args) } @@ -103,7 +127,7 @@ impl TestPrivateContextInterface { serialized_args[0] = amount; serialized_args[1] = secret_hash; - context.call_public_function(self.address, 0xdf02db8d, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0xdf02db8d), serialized_args) } @@ -113,7 +137,7 @@ impl TestPrivateContextInterface { ) -> [Field; RETURN_VALUES_LENGTH] { let mut serialized_args = [0; 0]; - context.call_private_function(self.address, 0x11fb5d45, serialized_args) + context.call_private_function(self.address, FunctionSelector::from_field(0x11fb5d45), serialized_args) } @@ -125,7 +149,7 @@ impl TestPrivateContextInterface { let mut serialized_args = [0; 1]; serialized_args[0] = nullifier; - context.call_private_function(self.address, 0x82a8b183, serialized_args) + context.call_private_function(self.address, FunctionSelector::from_field(0x82a8b183), serialized_args) } @@ -137,31 +161,31 @@ impl TestPrivateContextInterface { let mut serialized_args = [0; 1]; serialized_args[0] = value; - context.call_public_function(self.address, 0x817a64cb, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x817a64cb), serialized_args) } pub fn get_portal_contract_address( self, context: &mut PrivateContext, - aztec_address: Field + aztec_address: AztecAddressGetPortalContractAddressStruct ) -> [Field; RETURN_VALUES_LENGTH] { let mut serialized_args = [0; 1]; - serialized_args[0] = aztec_address; + serialized_args[0] = aztec_address.inner; - context.call_private_function(self.address, 0x98ff64fd, serialized_args) + context.call_private_function(self.address, FunctionSelector::from_field(0x30e5344b), serialized_args) } pub fn get_public_key( self, context: &mut PrivateContext, - address: Field + address: AddressGetPublicKeyStruct ) -> [Field; RETURN_VALUES_LENGTH] { let mut serialized_args = [0; 1]; - serialized_args[0] = address; + serialized_args[0] = address.inner; - context.call_private_function(self.address, 0x5ccf578f, serialized_args) + context.call_private_function(self.address, FunctionSelector::from_field(0x501e4f48), serialized_args) } @@ -171,7 +195,7 @@ impl TestPrivateContextInterface { ) -> [Field; RETURN_VALUES_LENGTH] { let mut serialized_args = [0; 0]; - context.call_private_function(self.address, 0x95a7b2ae, serialized_args) + context.call_private_function(self.address, FunctionSelector::from_field(0x95a7b2ae), serialized_args) } @@ -181,7 +205,7 @@ impl TestPrivateContextInterface { ) -> [Field; RETURN_VALUES_LENGTH] { let mut serialized_args = [0; 0]; - context.call_private_function(self.address, 0xc71384f5, serialized_args) + context.call_private_function(self.address, FunctionSelector::from_field(0xc71384f5), serialized_args) } @@ -193,7 +217,7 @@ impl TestPrivateContextInterface { let mut serialized_args = [0; 1]; serialized_args[0] = time; - context.call_public_function(self.address, 0x61fa2bda, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x61fa2bda), serialized_args) } @@ -205,7 +229,7 @@ impl TestPrivateContextInterface { let mut serialized_args = [0; 1]; serialized_args[0] = value; - context.call_private_function(self.address, 0x1b3b9e18, serialized_args) + context.call_private_function(self.address, FunctionSelector::from_field(0x1b3b9e18), serialized_args) } @@ -238,7 +262,7 @@ impl TestPrivateContextInterface { serialized_args[15] = a_deep_struct.many_notes[2].amount; serialized_args[16] = a_deep_struct.many_notes[2].secret_hash; - context.call_private_function(self.address, 0x0f054f9b, serialized_args) + context.call_private_function(self.address, FunctionSelector::from_field(0x0f054f9b), serialized_args) } } @@ -248,11 +272,11 @@ impl TestPrivateContextInterface { // Interface for calling Test functions from a public context struct TestPublicContextInterface { - address: Field, + address: AztecAddress, } impl TestPublicContextInterface { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address, } @@ -261,20 +285,20 @@ impl TestPublicContextInterface { pub fn consume_mint_public_message( self, context: PublicContext, - to: Field, + to: ToConsumeMintPublicMessageStruct, amount: Field, - canceller: Field, + canceller: CancellerConsumeMintPublicMessageStruct, msg_key: Field, secret: Field ) -> [Field; RETURN_VALUES_LENGTH] { let mut serialized_args = [0; 5]; - serialized_args[0] = to; + serialized_args[0] = to.inner; serialized_args[1] = amount; - serialized_args[2] = canceller; + serialized_args[2] = canceller.inner; serialized_args[3] = msg_key; serialized_args[4] = secret; - context.call_public_function(self.address, 0x1c60863d, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x04ee3bb0), serialized_args) } @@ -288,7 +312,7 @@ impl TestPublicContextInterface { serialized_args[0] = amount; serialized_args[1] = secret_hash; - context.call_public_function(self.address, 0x9749ca06, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x9749ca06), serialized_args) } @@ -302,7 +326,7 @@ impl TestPublicContextInterface { serialized_args[0] = amount; serialized_args[1] = secret_hash; - context.call_public_function(self.address, 0xdf02db8d, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0xdf02db8d), serialized_args) } @@ -314,7 +338,7 @@ impl TestPublicContextInterface { let mut serialized_args = [0; 1]; serialized_args[0] = value; - context.call_public_function(self.address, 0x817a64cb, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x817a64cb), serialized_args) } @@ -326,7 +350,7 @@ impl TestPublicContextInterface { let mut serialized_args = [0; 1]; serialized_args[0] = time; - context.call_public_function(self.address, 0x61fa2bda, serialized_args) + context.call_public_function(self.address, FunctionSelector::from_field(0x61fa2bda), serialized_args) } } diff --git a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr index 1515b39d8a1..d5fefddd004 100644 --- a/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/test_contract/src/main.nr @@ -2,6 +2,10 @@ contract Test { use dep::std::option::Option; use dep::protocol_types::constants::EMPTY_NULLIFIED_COMMITMENT; + use dep::protocol_types::address::{ + AztecAddress, + EthAddress, + }; // docs:start:unencrypted_import use dep::aztec::log::emit_unencrypted_log; // docs:end:unencrypted_import @@ -28,10 +32,11 @@ contract Test { use dep::token_portal_content_hash_lib::{get_mint_private_content_hash, get_mint_public_content_hash}; use dep::field_note::field_note::{FieldNote, FieldNoteMethods, FIELD_NOTE_LEN}; - #[event] - struct ExampleEvent { - value: Field, - } + // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3655 + // #[event] + // struct ExampleEvent { + // value: Field, + // } struct Storage { example_constant: ImmutableSingleton, @@ -51,7 +56,7 @@ contract Test { // docs:end:empty-constructor #[aztec(private)] - fn get_public_key(address: Field) -> [Field; 2] { + fn get_public_key(address: AztecAddress) -> [Field; 2] { let pub_key = get_public_key_oracle(address); [pub_key.x, pub_key.y] @@ -59,19 +64,19 @@ contract Test { // Get the portal contract address through an oracle call #[aztec(private)] - fn get_portal_contract_address(aztec_address: Field) -> Field { + fn get_portal_contract_address(aztec_address: AztecAddress) -> EthAddress { get_portal_address(aztec_address) } // Get the address of the l1 portal for this contract (taken from the input context) #[aztec(private)] - fn get_this_portal_address() -> Field { + fn get_this_portal_address() -> EthAddress { context.this_portal_address() } // Get the address of this contract (taken from the input context) #[aztec(private)] - fn get_this_address() -> Field { + fn get_this_address() -> AztecAddress { context.this_address() } @@ -157,7 +162,7 @@ contract Test { } #[aztec(public)] - fn consume_mint_public_message(to: Field, amount: Field, canceller: Field, msg_key: Field, secret: Field) { + fn consume_mint_public_message(to: AztecAddress, amount: Field, canceller: EthAddress, msg_key: Field, secret: Field) { let content_hash = get_mint_public_content_hash(to, amount, canceller); // Consume message and emit nullifier context.consume_l1_to_l2_message(msg_key, content_hash, secret); @@ -167,7 +172,7 @@ contract Test { fn consume_mint_private_message( secret_hash_for_redeeming_minted_notes: Field, amount: Field, - canceller: Field, + canceller: EthAddress, msg_key: Field, secret_for_L1_to_L2_message_consumption: Field ) { @@ -198,14 +203,14 @@ contract Test { } impl DummyNote { - fn new(amount: Field, secret_hash: Field) -> pub Self { + fn new(amount: Field, secret_hash: Field) -> Self { Self { amount: amount, secret_hash: secret_hash } } - fn get_commitment(self) -> pub Field { + fn get_commitment(self) -> Field { pedersen_hash([self.amount, self.secret_hash],0) } } @@ -222,7 +227,8 @@ contract Test { // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; FIELD_NOTE_LEN]) -> [Field; 4] { assert(storage_slot == 1); - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(FieldNoteMethods, note_header, serialized_note) } } 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 9fb08061031..a9011819126 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,16 +1,16 @@ +use dep::protocol_types::address::AztecAddress; use dep::aztec::{ context::{ PrivateContext, PublicContext, Context }, selector::compute_selector, - types::address::AztecAddress, }; struct SlowMap { - address: Field, + address: AztecAddress, } impl SlowMap { pub fn at(address: AztecAddress) -> Self { - Self { address: address.address } + Self { address: address } } pub fn initialize(self: Self, context: PublicContext) { 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 73b14c9cf43..cdfafc51418 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,7 @@ contract TokenBlacklist { use dep::std::option::Option; use dep::safe_math::SafeU120; - + use dep::protocol_types::address::AztecAddress; use dep::aztec::{ note::{ note_getter_options::NoteGetterOptions, @@ -30,9 +30,8 @@ contract TokenBlacklist { types::type_serialization::{ field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, - aztec_address_serialization::{AztecAddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, + address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, }, - types::address::{AztecAddress}, selector::compute_selector, }; @@ -72,7 +71,7 @@ contract TokenBlacklist { admin: PublicState::new( context, 1, - AztecAddressSerializationMethods, + AddressSerializationMethods, ), balances: BalancesMap::new(context, 3), total_supply: PublicState::new( @@ -98,7 +97,7 @@ contract TokenBlacklist { public_slow_update: PublicState::new( context, 8, - AztecAddressSerializationMethods, + AddressSerializationMethods, ), // docs:end:slow_updates_storage @@ -108,16 +107,16 @@ contract TokenBlacklist { // docs:start:constructor #[aztec(private)] fn constructor(admin: AztecAddress, slow_updates_contract: AztecAddress) { - let mut slow_note = FieldNote::new(slow_updates_contract.address); + 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))"); context.call_public_function(context.this_address(), selector, - [admin.address, slow_updates_contract.address]); + [admin.to_field(), slow_updates_contract.to_field()]); // We cannot do the following atm // let roles = UserFlags{is_admin: true, is_minter: false, is_blacklisted: false}.get_value() as Field; - // SlowMap::at(slow_updates_contract).update_at_private(&mut context, admin.address, roles); + // SlowMap::at(slow_updates_contract).update_at_private(&mut context, admin.to_field(), roles); } //////// @@ -127,12 +126,12 @@ contract TokenBlacklist { fn init_slow_tree(user: AztecAddress) { let roles = UserFlags { is_admin: true, is_minter: false, is_blacklisted: false }.get_value() as Field; // docs:start:get_and_update_private - let slow = SlowMap::at(AztecAddress::new(storage.slow_update.get_note().value)); - slow.update_at_private(&mut context, user.address, roles); + let slow = SlowMap::at(AztecAddress::from_field(storage.slow_update.get_note().value)); + slow.update_at_private(&mut context, user.to_field(), roles); // docs:end:get_and_update_private context.call_public_function(context.this_address(), compute_selector("_init_slow_tree((Field))"), - [context.msg_sender()]); + [context.msg_sender().to_field()]); } #[aztec(public)] @@ -143,7 +142,7 @@ contract TokenBlacklist { /////// #[aztec(public)] internal fn _initialize(new_admin: AztecAddress, slow_updates_contract: AztecAddress) { - assert(new_admin.address != 0, "invalid admin"); + assert(!new_admin.is_zero(), "invalid admin"); storage.admin.write(new_admin); // docs:start:write_slow_update_public storage.public_slow_update.write(slow_updates_contract); @@ -157,12 +156,12 @@ contract TokenBlacklist { #[aztec(private)] fn update_roles(user: AztecAddress, roles: Field) { // docs:start:slowmap_at - let slow = SlowMap::at(AztecAddress::new(storage.slow_update.get_note().value)); + let slow = SlowMap::at(AztecAddress::from_field(storage.slow_update.get_note().value)); // docs:end:slowmap_at - let caller_roles = UserFlags::new(slow.read_at(&mut context, context.msg_sender()) as u120); + let caller_roles = UserFlags::new(slow.read_at(&mut context, context.msg_sender().to_field()) as u120); assert(caller_roles.is_admin, "caller is not admin"); - slow.update_at_private(&mut context, user.address, roles); + slow.update_at_private(&mut context, user.to_field(), roles); } #[aztec(public)] @@ -171,25 +170,25 @@ contract TokenBlacklist { let slow = SlowMap::at(storage.public_slow_update.read()); // docs:end:get_public // docs:start:read_at_pub - let to_roles = UserFlags::new(slow.read_at_pub(context, to.address) as u120); + let to_roles = UserFlags::new(slow.read_at_pub(context, to.to_field()) as u120); // docs:end:read_at_pub assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); - let caller_roles = UserFlags::new(slow.read_at_pub(context, context.msg_sender()) as u120); + let caller_roles = UserFlags::new(slow.read_at_pub(context, context.msg_sender().to_field()) as u120); assert(caller_roles.is_minter, "caller is not minter"); let amount = SafeU120::new(amount); - let new_balance = storage.public_balances.at(to.address).read().add(amount); + let new_balance = storage.public_balances.at(to.to_field()).read().add(amount); let supply = storage.total_supply.read().add(amount); - storage.public_balances.at(to.address).write(new_balance); + storage.public_balances.at(to.to_field()).write(new_balance); storage.total_supply.write(supply); } #[aztec(public)] fn mint_private(amount: Field, secret_hash: Field) { let slow = SlowMap::at(storage.public_slow_update.read()); - let caller_roles = UserFlags::new(slow.read_at_pub(context, context.msg_sender()) as u120); + let caller_roles = UserFlags::new(slow.read_at_pub(context, context.msg_sender().to_field()) as u120); assert(caller_roles.is_minter, "caller is not minter"); let pending_shields = storage.pending_shields; @@ -203,10 +202,10 @@ contract TokenBlacklist { #[aztec(public)] fn shield(from: AztecAddress, amount: Field, secret_hash: Field, nonce: Field) { let slow = SlowMap::at(storage.public_slow_update.read()); - let from_roles = UserFlags::new(slow.read_at_pub(context, from.address) as u120); + let from_roles = UserFlags::new(slow.read_at_pub(context, from.to_field()) as u120); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { // The redeem is only spendable once, so we need to ensure that you cannot insert multiple shields from the same message. assert_current_call_valid_authwit_public(&mut context, from); } else { @@ -214,52 +213,52 @@ contract TokenBlacklist { } let amount = SafeU120::new(amount); - let from_balance = storage.public_balances.at(from.address).read().sub(amount); + let from_balance = storage.public_balances.at(from.to_field()).read().sub(amount); let pending_shields = storage.pending_shields; let mut note = TransparentNote::new(amount.value as Field, secret_hash); - storage.public_balances.at(from.address).write(from_balance); + storage.public_balances.at(from.to_field()).write(from_balance); pending_shields.insert_from_public(&mut note); } #[aztec(public)] fn transfer_public(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { let slow = SlowMap::at(storage.public_slow_update.read()); - let from_roles = UserFlags::new(slow.read_at_pub(context, from.address) as u120); + let from_roles = UserFlags::new(slow.read_at_pub(context, from.to_field()) as u120); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let to_roles = UserFlags::new(slow.read_at_pub(context, to.address) as u120); + let to_roles = UserFlags::new(slow.read_at_pub(context, to.to_field()) as u120); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit_public(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); } let amount = SafeU120::new(amount); - let from_balance = storage.public_balances.at(from.address).read().sub(amount); - storage.public_balances.at(from.address).write(from_balance); + let from_balance = storage.public_balances.at(from.to_field()).read().sub(amount); + storage.public_balances.at(from.to_field()).write(from_balance); - let to_balance = storage.public_balances.at(to.address).read().add(amount); - storage.public_balances.at(to.address).write(to_balance); + let to_balance = storage.public_balances.at(to.to_field()).read().add(amount); + storage.public_balances.at(to.to_field()).write(to_balance); } #[aztec(public)] fn burn_public(from: AztecAddress, amount: Field, nonce: Field) { let slow = SlowMap::at(storage.public_slow_update.read()); - let from_roles = UserFlags::new(slow.read_at_pub(context, from.address) as u120); + let from_roles = UserFlags::new(slow.read_at_pub(context, from.to_field()) as u120); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit_public(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); } let amount = SafeU120::new(amount); - let from_balance = storage.public_balances.at(from.address).read().sub(amount); - storage.public_balances.at(from.address).write(from_balance); + let from_balance = storage.public_balances.at(from.to_field()).read().sub(amount); + storage.public_balances.at(from.to_field()).write(from_balance); let new_supply = storage.total_supply.read().sub(amount); storage.total_supply.write(new_supply); @@ -267,9 +266,9 @@ contract TokenBlacklist { #[aztec(private)] fn redeem_shield(to: AztecAddress, amount: Field, secret: Field) { - let slow = SlowMap::at(AztecAddress::new(storage.slow_update.get_note().value)); + let slow = SlowMap::at(AztecAddress::from_field(storage.slow_update.get_note().value)); // docs:start:slowmap_read_at - let to_roles = UserFlags::new(slow.read_at(&mut context, to.address) as u120); + let to_roles = UserFlags::new(slow.read_at(&mut context, to.to_field()) as u120); // docs:end:slowmap_read_at assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); @@ -289,13 +288,13 @@ contract TokenBlacklist { #[aztec(private)] fn unshield(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { - let slow = SlowMap::at(AztecAddress::new(storage.slow_update.get_note().value)); - let from_roles = UserFlags::new(slow.read_at(&mut context, from.address) as u120); + let slow = SlowMap::at(AztecAddress::from_field(storage.slow_update.get_note().value)); + let from_roles = UserFlags::new(slow.read_at(&mut context, from.to_field()) as u120); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let to_roles = UserFlags::new(slow.read_at(&mut context, to.address) as u120); + let to_roles = UserFlags::new(slow.read_at(&mut context, to.to_field()) as u120); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); @@ -304,20 +303,20 @@ contract TokenBlacklist { storage.balances.at(from).sub(SafeU120::new(amount)); let selector = compute_selector("_increase_public_balance((Field),Field)"); - context.call_public_function(context.this_address(), selector, [to.address, amount]); + context.call_public_function(context.this_address(), selector, [to.to_field(), amount]); } // docs:start:transfer_private #[aztec(private)] fn transfer(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { - let slow = SlowMap::at(AztecAddress::new(storage.slow_update.get_note().value)); - let from_roles = UserFlags::new(slow.read_at(&mut context, from.address) as u120); + let slow = SlowMap::at(AztecAddress::from_field(storage.slow_update.get_note().value)); + let from_roles = UserFlags::new(slow.read_at(&mut context, from.to_field()) as u120); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - let to_roles = UserFlags::new(slow.read_at(&mut context, to.address) as u120); + let to_roles = UserFlags::new(slow.read_at(&mut context, to.to_field()) as u120); assert(!to_roles.is_blacklisted, "Blacklisted: Recipient"); // docs:end:transfer_private - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); @@ -330,11 +329,11 @@ contract TokenBlacklist { #[aztec(private)] fn burn(from: AztecAddress, amount: Field, nonce: Field) { - let slow = SlowMap::at(AztecAddress::new(storage.slow_update.get_note().value)); - let from_roles = UserFlags::new(slow.read_at(&mut context, from.address) as u120); + let slow = SlowMap::at(AztecAddress::from_field(storage.slow_update.get_note().value)); + let from_roles = UserFlags::new(slow.read_at(&mut context, from.to_field()) as u120); assert(!from_roles.is_blacklisted, "Blacklisted: Sender"); - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); @@ -351,8 +350,8 @@ contract TokenBlacklist { #[aztec(public)] internal fn _increase_public_balance(to: AztecAddress, amount: Field) { - let new_balance = storage.public_balances.at(to.address).read().add(SafeU120::new(amount)); - storage.public_balances.at(to.address).write(new_balance); + let new_balance = storage.public_balances.at(to.to_field()).read().add(SafeU120::new(amount)); + storage.public_balances.at(to.to_field()).write(new_balance); } #[aztec(public)] @@ -373,7 +372,7 @@ contract TokenBlacklist { } unconstrained fn balance_of_public(owner: AztecAddress) -> u120 { - storage.public_balances.at(owner.address).read().value + storage.public_balances.at(owner.to_field()).read().value } // Below this point is the stuff of nightmares. @@ -383,7 +382,8 @@ contract TokenBlacklist { // Note 1: Needs to be defined by every contract producing logs. // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; TOKEN_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); if (storage_slot == 5) { note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, preimage) } else if (storage_slot == 7) { diff --git a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/balance_set.nr b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/balance_set.nr index ae54a03ea76..38ca7bb8400 100644 --- a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/balance_set.nr +++ b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/balance_set.nr @@ -1,10 +1,10 @@ use dep::std::option::Option; use dep::safe_math::SafeU120; use dep::protocol_types::constants::MAX_READ_REQUESTS_PER_CALL; +use dep::protocol_types::address::AztecAddress; use dep::aztec::{ context::Context, state_vars::set::Set, - types::address::AztecAddress, }; use dep::aztec::note::{ note_getter::view_notes, diff --git a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/balances_map.nr b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/balances_map.nr index 2afaf784966..946be841221 100644 --- a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/balances_map.nr +++ b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/balances_map.nr @@ -1,5 +1,5 @@ +use dep::protocol_types::address::AztecAddress; use dep::aztec::context::{PrivateContext, PublicContext, Context}; -use dep::aztec::types::address::AztecAddress; use dep::std::option::Option; use crate::types::balance_set::BalanceSet; use dep::aztec::hash::pedersen_hash; @@ -22,7 +22,7 @@ impl BalancesMap { } pub fn at(self, owner: AztecAddress) -> BalanceSet { - let derived_storage_slot = pedersen_hash([self.storage_slot, owner.address],0); + let derived_storage_slot = pedersen_hash([self.storage_slot, owner.to_field()],0); BalanceSet::new(self.context, owner, derived_storage_slot) } } diff --git a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/token_note.nr b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/token_note.nr index 55ef7ff36e9..88c086c4be3 100644 --- a/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/token_note.nr +++ b/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/types/token_note.nr @@ -1,4 +1,5 @@ use dep::protocol_types::constants::MAX_READ_REQUESTS_PER_CALL; +use dep::protocol_types::address::AztecAddress; use dep::aztec::{ note::{ note_header::NoteHeader, @@ -10,7 +11,6 @@ use dep::aztec::{ log::emit_encrypted_log, hash::pedersen_hash, }; -use dep::aztec::types::address::AztecAddress; use dep::aztec::oracle::{ rand::rand, get_secret_key::get_secret_key, @@ -46,13 +46,13 @@ impl TokenNote { } pub fn serialize(self) -> [Field; TOKEN_NOTE_LEN] { - [self.amount.value as Field, self.owner.address, self.randomness] + [self.amount.value as Field, self.owner.to_field(), self.randomness] } pub fn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> Self { Self { amount: SafeU120::new(preimage[0]), - owner: AztecAddress::new(preimage[1]), + owner: AztecAddress::from_field(preimage[1]), randomness: preimage[2], header: NoteHeader::empty(), } @@ -62,7 +62,7 @@ impl TokenNote { // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ self.amount.value as Field, - self.owner.address as Field, + self.owner.to_field(), self.randomness, ],0) } @@ -70,7 +70,7 @@ impl TokenNote { // docs:start:nullifier pub fn compute_nullifier(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(TokenNoteMethods, self); - let secret = get_secret_key(self.owner.address); + let secret = get_secret_key(self.owner); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ note_hash_for_nullify, @@ -88,7 +88,7 @@ impl TokenNote { pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !self.amount.is_zero() { - let encryption_pub_key = get_public_key(self.owner.address); + let encryption_pub_key = get_public_key(self.owner); emit_encrypted_log( context, (*context).this_address(), diff --git a/yarn-project/noir-contracts/src/contracts/token_bridge_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/token_bridge_contract/Nargo.toml index 9a028741f8d..5c2f4106919 100644 --- a/yarn-project/noir-contracts/src/contracts/token_bridge_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/token_bridge_contract/Nargo.toml @@ -6,4 +6,5 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } -token_portal_content_hash_lib = { path = "../token_portal_content_hash_lib" } \ No newline at end of file +token_portal_content_hash_lib = { path = "../token_portal_content_hash_lib" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file 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 c06c1468966..78a15f3918a 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,12 +7,16 @@ 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::aztec::{ context::{Context}, hash::{compute_secret_hash}, state_vars::{public_state::PublicState}, - types::type_serialization::field_serialization::FieldSerializationMethods, - types::address::{AztecAddress, EthereumAddress}, + types::type_serialization::address_serialization::AddressSerializationMethods, selector::compute_selector, }; // docs:end:token_bridge_imports @@ -24,7 +28,7 @@ contract TokenBridge { // docs:start:token_bridge_storage_and_constructor // Storage structure, containing all storage, and specifying what slots they use. struct Storage { - token: PublicState, + token: PublicState, } impl Storage { @@ -33,7 +37,7 @@ contract TokenBridge { token: PublicState::new( context, 1, - FieldSerializationMethods, + AddressSerializationMethods, ), } } @@ -43,21 +47,21 @@ contract TokenBridge { #[aztec(private)] fn constructor(token: AztecAddress) { let selector = compute_selector("_initialize((Field))"); - context.call_public_function(context.this_address(), selector, [token.address]); + context.call_public_function(context.this_address(), selector, [token.to_field()]); } // docs:end:token_bridge_storage_and_constructor // docs:start:claim_public // Consumes a L1->L2 message and calls the token contract to mint the appropriate amount publicly #[aztec(public)] - fn claim_public(to: AztecAddress, amount: Field, canceller: EthereumAddress, msg_key: Field, secret: Field) { - let content_hash = get_mint_public_content_hash(to.address, amount, canceller.address); + fn claim_public(to: AztecAddress, amount: Field, canceller: EthAddress, msg_key: Field, secret: Field) { + let content_hash = get_mint_public_content_hash(to, amount, canceller); // Consume message and emit nullifier context.consume_l1_to_l2_message(msg_key, content_hash, secret); // Mint tokens - Token::at(storage.token.read()).mint_public(context, to.address, amount); + Token::at(storage.token.read()).mint_public(context, to, amount); } // docs:end:claim_public @@ -66,13 +70,13 @@ contract TokenBridge { // Requires `msg.sender` to give approval to the bridge to burn tokens on their behalf using witness signatures #[aztec(public)] fn exit_to_l1_public( - recipient: EthereumAddress, // ethereum address to withdraw to + recipient: EthAddress, // ethereum address to withdraw to amount: Field, - callerOnL1: EthereumAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) + callerOnL1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) nonce: Field // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 ) { // Send an L2 to L1 message - let content = get_withdraw_content_hash(recipient.address, amount, callerOnL1.address); + let content = get_withdraw_content_hash(recipient, amount, callerOnL1); context.message_portal(content); // Burn tokens @@ -86,14 +90,14 @@ contract TokenBridge { fn claim_private( secret_hash_for_redeeming_minted_notes: Field, // secret hash used to redeem minted notes at a later time. This enables anyone to call this function and mint tokens to a user on their behalf amount: Field, - canceller: EthereumAddress, + canceller: EthAddress, msg_key: Field, // L1 to L2 message key as derived from the inbox contract secret_for_L1_to_L2_message_consumption: Field // secret used to consume the L1 to L2 message ) { // Consume L1 to L2 message and emit nullifier let content_hash = get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes, amount, - canceller.address); + canceller); context.consume_l1_to_l2_message(msg_key, content_hash, secret_for_L1_to_L2_message_consumption); // Mint tokens on L2 @@ -112,43 +116,43 @@ contract TokenBridge { #[aztec(private)] fn exit_to_l1_private( token: AztecAddress, - recipient: EthereumAddress, // ethereum address to withdraw to + recipient: EthAddress, // ethereum address to withdraw to amount: Field, - callerOnL1: EthereumAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) + callerOnL1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) nonce: Field // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 ) { // Send an L2 to L1 message - let content = get_withdraw_content_hash(recipient.address, amount, callerOnL1.address); + let content = get_withdraw_content_hash(recipient, amount, callerOnL1); context.message_portal(content); // docs:start:call_assert_token_is_same // 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)"), - [token.address]); + compute_selector("_assert_token_is_same((Field))"), + [token.to_field()]); // docs:end:call_assert_token_is_same // Burn tokens - Token::at(token.address).burn(&mut context, context.msg_sender(), amount, nonce); + Token::at(token).burn(&mut context, context.msg_sender(), amount, nonce); } /// docs:end:exit_to_l1_private // View function that is callable by other contracts. // Unconstrained can't be called by others since it isn't safe. #[aztec(public)] - fn get_token() -> Field { + fn get_token() -> AztecAddress { storage.token.read() } // /// Unconstrained /// - unconstrained fn token() -> Field { + unconstrained fn token() -> AztecAddress { storage.token.read() } #[aztec(public)] internal fn _initialize(token: AztecAddress) { - storage.token.write(token.address); + storage.token.write(token); } // docs:start:call_mint_on_token @@ -163,8 +167,8 @@ contract TokenBridge { // docs:start:assert_token_is_same #[aztec(public)] - internal fn _assert_token_is_same(token: Field) { - assert(storage.token.read() == token, "Token address is not the same as seen in storage"); + internal fn _assert_token_is_same(token: AztecAddress) { + assert(storage.token.read().eq(token), "Token address is not the same as seen in storage"); } // docs:end: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 6e467647059..88e2fc7639d 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,32 +1,36 @@ // docs:start:token_bridge_token_interface +use dep::protocol_types::address::{ + AztecAddress, + EthAddress, +}; use dep::aztec::{ context::{ PrivateContext, PublicContext, Context }, selector::compute_selector, }; struct Token { - address: Field, + address: AztecAddress, } impl Token { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address } } - pub fn mint_public(self: Self, context: PublicContext, to: Field, amount: Field) { + 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)"), - [to, amount] + [to.to_field(), amount] ); } // docs:start:public_burn_interface - pub fn burn_public(self: Self, context: PublicContext, from: Field, amount: Field, nonce: Field) { + 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)"), - [from, amount, nonce] + [from.to_field(), amount, nonce] ); } // docs:end:public_burn_interface @@ -41,11 +45,11 @@ impl Token { // docs:start:private_burn_interface - pub fn burn(self: Self, context: &mut PrivateContext, from: Field, amount: Field, nonce: Field) { + 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)"), - [from, amount, nonce] + [from.to_field(), amount, nonce] ); } // docs:end:private_burn_interface 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 c530f0bf66d..80d8ff96505 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 @@ -25,13 +25,13 @@ contract Token { hash::{compute_secret_hash}, state_vars::{map::Map, public_state::PublicState, set::Set}, types::type_serialization::{ - field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, - aztec_address_serialization::{AztecAddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, + field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, + bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN}, + address_serialization::{AddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN}, }, - types::address::{AztecAddress}, selector::compute_selector, }; + use dep::protocol_types::address::AztecAddress; // docs:start:import_authwit use dep::authwit::{ @@ -71,13 +71,13 @@ contract Token { // docs:start:storage_init impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { // docs:start:storage_admin_init admin: PublicState::new( context, 1, - AztecAddressSerializationMethods, + AddressSerializationMethods, ), // docs:end:storage_admin_init // docs:start:storage_minters_init @@ -124,14 +124,14 @@ contract Token { #[aztec(private)] fn constructor(admin: AztecAddress) { let selector = compute_selector("_initialize((Field))"); - context.call_public_function(context.this_address(), selector, [admin.address]); + context.call_public_function(context.this_address(), selector, [admin.to_field()]); } // docs:end:constructor // docs:start:set_admin #[aztec(public)] fn set_admin(new_admin: AztecAddress) { - assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), "caller is not admin"); + assert(storage.admin.read().eq(context.msg_sender()), "caller is not admin"); // docs:start:write_admin storage.admin.write(new_admin); // docs:end:write_admin @@ -142,10 +142,10 @@ contract Token { #[aztec(public)] fn set_minter(minter: AztecAddress, approve: bool) { // docs:start:read_admin - assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), "caller is not admin"); + assert(storage.admin.read().eq(context.msg_sender()), "caller is not admin"); // docs:end:read_admin // docs:start:write_minter - storage.minters.at(minter.address).write(approve); + storage.minters.at(minter.to_field()).write(approve); // docs:end:write_minter } // docs:end:set_minter @@ -154,13 +154,13 @@ contract Token { #[aztec(public)] fn mint_public(to: AztecAddress, amount: Field) { // docs:start:read_minter - assert(storage.minters.at(context.msg_sender()).read(), "caller is not minter"); + assert(storage.minters.at(context.msg_sender().to_field()).read(), "caller is not minter"); // docs:end:read_minter let amount = SafeU120::new(amount); - let new_balance = storage.public_balances.at(to.address).read().add(amount); + let new_balance = storage.public_balances.at(to.to_field()).read().add(amount); let supply = storage.total_supply.read().add(amount); - storage.public_balances.at(to.address).write(new_balance); + storage.public_balances.at(to.to_field()).write(new_balance); storage.total_supply.write(supply); } // docs:end:mint_public @@ -168,7 +168,7 @@ contract Token { // docs:start:mint_private #[aztec(public)] fn mint_private(amount: Field, secret_hash: Field) { - assert(storage.minters.at(context.msg_sender()).read(), "caller is not minter"); + assert(storage.minters.at(context.msg_sender().to_field()).read(), "caller is not minter"); let pending_shields = storage.pending_shields; let mut note = TransparentNote::new(amount, secret_hash); let supply = storage.total_supply.read().add(SafeU120::new(amount)); @@ -183,7 +183,7 @@ contract Token { // docs:start:shield #[aztec(public)] fn shield(from: AztecAddress, amount: Field, secret_hash: Field, nonce: Field) { - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { // The redeem is only spendable once, so we need to ensure that you cannot insert multiple shields from the same message. assert_current_call_valid_authwit_public(&mut context, from); } else { @@ -191,12 +191,12 @@ contract Token { } let amount = SafeU120::new(amount); - let from_balance = storage.public_balances.at(from.address).read().sub(amount); + let from_balance = storage.public_balances.at(from.to_field()).read().sub(amount); let pending_shields = storage.pending_shields; let mut note = TransparentNote::new(amount.value as Field, secret_hash); - storage.public_balances.at(from.address).write(from_balance); + storage.public_balances.at(from.to_field()).write(from_balance); pending_shields.insert_from_public(&mut note); } // docs:end:shield @@ -204,18 +204,18 @@ contract Token { // docs:start:transfer_public #[aztec(public)] fn transfer_public(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit_public(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); } let amount = SafeU120::new(amount); - let from_balance = storage.public_balances.at(from.address).read().sub(amount); - storage.public_balances.at(from.address).write(from_balance); + let from_balance = storage.public_balances.at(from.to_field()).read().sub(amount); + storage.public_balances.at(from.to_field()).write(from_balance); - let to_balance = storage.public_balances.at(to.address).read().add(amount); - storage.public_balances.at(to.address).write(to_balance); + let to_balance = storage.public_balances.at(to.to_field()).read().add(amount); + storage.public_balances.at(to.to_field()).write(to_balance); } // docs:end:transfer_public @@ -223,7 +223,7 @@ contract Token { #[aztec(public)] fn burn_public(from: AztecAddress, amount: Field, nonce: Field) { // docs:start:assert_current_call_valid_authwit_public - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit_public(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); @@ -231,8 +231,8 @@ contract Token { // docs:end:assert_current_call_valid_authwit_public let amount = SafeU120::new(amount); - let from_balance = storage.public_balances.at(from.address).read().sub(amount); - storage.public_balances.at(from.address).write(from_balance); + let from_balance = storage.public_balances.at(from.to_field()).read().sub(amount); + storage.public_balances.at(from.to_field()).write(from_balance); let new_supply = storage.total_supply.read().sub(amount); storage.total_supply.write(new_supply); @@ -260,7 +260,7 @@ contract Token { // docs:start:unshield #[aztec(private)] fn unshield(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); @@ -269,7 +269,7 @@ contract Token { storage.balances.at(from).sub(SafeU120::new(amount)); let selector = compute_selector("_increase_public_balance((Field),Field)"); - let _void = context.call_public_function(context.this_address(), selector, [to.address, amount]); + let _void = context.call_public_function(context.this_address(), selector, [to.to_field(), amount]); } // docs:end:unshield @@ -277,7 +277,7 @@ contract Token { #[aztec(private)] fn transfer(from: AztecAddress, to: AztecAddress, amount: Field, nonce: Field) { // docs:start:assert_current_call_valid_authwit - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); @@ -295,7 +295,7 @@ contract Token { // docs:start:burn #[aztec(private)] fn burn(from: AztecAddress, amount: Field, nonce: Field) { - if (from.address != context.msg_sender()) { + if (!from.eq(context.msg_sender())) { assert_current_call_valid_authwit(&mut context, from); } else { assert(nonce == 0, "invalid nonce"); @@ -311,9 +311,9 @@ contract Token { // docs:start:initialize #[aztec(public)] internal fn _initialize(new_admin: AztecAddress) { - assert(new_admin.address != 0, "invalid admin"); + assert(!new_admin.is_zero(), "invalid admin"); storage.admin.write(new_admin); - storage.minters.at(new_admin.address).write(true); + storage.minters.at(new_admin.to_field()).write(true); } // docs:end:initialize @@ -322,8 +322,8 @@ contract Token { // docs:start:increase_public_balance #[aztec(public)] internal fn _increase_public_balance(to: AztecAddress, amount: Field) { - let new_balance = storage.public_balances.at(to.address).read().add(SafeU120::new(amount)); - storage.public_balances.at(to.address).write(new_balance); + let new_balance = storage.public_balances.at(to.to_field()).read().add(SafeU120::new(amount)); + storage.public_balances.at(to.to_field()).write(new_balance); } // docs:end:increase_public_balance @@ -340,13 +340,13 @@ contract Token { // docs:start:admin unconstrained fn admin() -> Field { - storage.admin.read().address + storage.admin.read().to_field() } // docs:end:admin // docs:start:is_minter unconstrained fn is_minter(minter: AztecAddress) -> bool { - storage.minters.at(minter.address).read() + storage.minters.at(minter.to_field()).read() } // docs:end:is_minter @@ -364,7 +364,7 @@ contract Token { // docs:start:balance_of_public unconstrained fn balance_of_public(owner: AztecAddress) -> u120 { - storage.public_balances.at(owner.address).read().value + storage.public_balances.at(owner.to_field()).read().value } // docs:end:balance_of_public @@ -376,7 +376,8 @@ contract Token { // Note 1: Needs to be defined by every contract producing logs. // Note 2: Having it in all the contracts gives us the ability to compute the note hash and nullifier differently for different kind of notes. unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, serialized_note: [Field; TOKEN_NOTE_LEN]) -> [Field; 4] { - let note_header = NoteHeader::new(contract_address, nonce, storage_slot); + let _address = AztecAddress::from_field(contract_address); // TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/3669 + let note_header = NoteHeader::new(_address, nonce, storage_slot); if (storage_slot == 5) { note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, serialized_note) } else { diff --git a/yarn-project/noir-contracts/src/contracts/token_contract/src/types/balance_set.nr b/yarn-project/noir-contracts/src/contracts/token_contract/src/types/balance_set.nr index ae54a03ea76..a5c00d81967 100644 --- a/yarn-project/noir-contracts/src/contracts/token_contract/src/types/balance_set.nr +++ b/yarn-project/noir-contracts/src/contracts/token_contract/src/types/balance_set.nr @@ -1,10 +1,12 @@ use dep::std::option::Option; use dep::safe_math::SafeU120; -use dep::protocol_types::constants::MAX_READ_REQUESTS_PER_CALL; +use dep::protocol_types::{ + constants::MAX_READ_REQUESTS_PER_CALL, + address::AztecAddress, +}; use dep::aztec::{ context::Context, state_vars::set::Set, - types::address::AztecAddress, }; use dep::aztec::note::{ note_getter::view_notes, diff --git a/yarn-project/noir-contracts/src/contracts/token_contract/src/types/balances_map.nr b/yarn-project/noir-contracts/src/contracts/token_contract/src/types/balances_map.nr index 2afaf784966..04a595e9a8f 100644 --- a/yarn-project/noir-contracts/src/contracts/token_contract/src/types/balances_map.nr +++ b/yarn-project/noir-contracts/src/contracts/token_contract/src/types/balances_map.nr @@ -1,8 +1,8 @@ use dep::aztec::context::{PrivateContext, PublicContext, Context}; -use dep::aztec::types::address::AztecAddress; use dep::std::option::Option; use crate::types::balance_set::BalanceSet; use dep::aztec::hash::pedersen_hash; +use dep::protocol_types::address::AztecAddress; struct BalancesMap { context: Context, @@ -22,7 +22,7 @@ impl BalancesMap { } pub fn at(self, owner: AztecAddress) -> BalanceSet { - let derived_storage_slot = pedersen_hash([self.storage_slot, owner.address],0); + let derived_storage_slot = pedersen_hash([self.storage_slot, owner.to_field()], 0); BalanceSet::new(self.context, owner, derived_storage_slot) } } diff --git a/yarn-project/noir-contracts/src/contracts/token_contract/src/types/token_note.nr b/yarn-project/noir-contracts/src/contracts/token_contract/src/types/token_note.nr index 8c4f1721cf9..b55ebdd76b7 100644 --- a/yarn-project/noir-contracts/src/contracts/token_contract/src/types/token_note.nr +++ b/yarn-project/noir-contracts/src/contracts/token_contract/src/types/token_note.nr @@ -1,4 +1,9 @@ -use dep::protocol_types::constants::MAX_READ_REQUESTS_PER_CALL; +use dep::protocol_types::{ + address::AztecAddress, + constants::{ + MAX_READ_REQUESTS_PER_CALL + }, +}; use dep::aztec::{ note::{ note_header::NoteHeader, @@ -10,7 +15,6 @@ use dep::aztec::{ log::emit_encrypted_log, hash::pedersen_hash, }; -use dep::aztec::types::address::AztecAddress; use dep::aztec::oracle::{ rand::rand, get_secret_key::get_secret_key, @@ -46,13 +50,13 @@ impl TokenNote { } pub fn serialize(self) -> [Field; TOKEN_NOTE_LEN] { - [self.amount.value as Field, self.owner.address, self.randomness] + [self.amount.value as Field, self.owner.to_field(), self.randomness] } pub fn deserialize(serialized_note: [Field; TOKEN_NOTE_LEN]) -> Self { Self { amount: SafeU120::new(serialized_note[0]), - owner: AztecAddress::new(serialized_note[1]), + owner: AztecAddress::from_field(serialized_note[1]), randomness: serialized_note[2], header: NoteHeader::empty(), } @@ -62,7 +66,7 @@ impl TokenNote { // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ self.amount.value as Field, - self.owner.address as Field, + self.owner.to_field(), self.randomness, ],0) } @@ -70,7 +74,7 @@ impl TokenNote { // docs:start:nullifier pub fn compute_nullifier(self) -> Field { let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(TokenNoteMethods, self); - let secret = get_secret_key(self.owner.address); + let secret = get_secret_key(self.owner); // TODO(#1205) Should use a non-zero generator index. pedersen_hash([ note_hash_for_nullify, @@ -88,7 +92,7 @@ impl TokenNote { pub fn broadcast(self, context: &mut PrivateContext, slot: Field) { // We only bother inserting the note if non-empty to save funds on gas. if !self.amount.is_zero() { - let encryption_pub_key = get_public_key(self.owner.address); + let encryption_pub_key = get_public_key(self.owner); emit_encrypted_log( context, (*context).this_address(), diff --git a/yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/Nargo.toml b/yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/Nargo.toml index 767c52abb0e..f3aa0548013 100644 --- a/yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/Nargo.toml @@ -5,4 +5,5 @@ compiler_version = ">=0.18.0" type = "lib" [dependencies] -aztec = { path = "../../../../aztec-nr/aztec" } \ No newline at end of file +aztec = { path = "../../../../aztec-nr/aztec" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/src/lib.nr b/yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/src/lib.nr index 635257ac643..e76dd8b5ad8 100644 --- a/yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/src/lib.nr +++ b/yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/src/lib.nr @@ -1,14 +1,20 @@ // docs:start:mint_public_content_hash_nr -use dep::aztec::hash::{sha256_to_field}; +use dep::protocol_types::{ + address::{ + AztecAddress, + EthAddress, + }, + hash::sha256_to_field, +}; // Computes a content hash of a deposit/mint_public message. // Refer TokenPortal.sol for reference on L1. -pub fn get_mint_public_content_hash(owner_address: Field, amount: Field, canceller: Field) -> Field { +pub fn get_mint_public_content_hash(owner: AztecAddress, amount: Field, canceller: EthAddress) -> Field { let mut hash_bytes: [u8; 100] = [0; 100]; - let recipient_bytes = owner_address.to_be_bytes(32); + let recipient_bytes = owner.to_field().to_be_bytes(32); let amount_bytes = amount.to_be_bytes(32); - let canceller_bytes = canceller.to_be_bytes(32); + let canceller_bytes = canceller.to_field().to_be_bytes(32); for i in 0..32 { hash_bytes[i + 4] = recipient_bytes[i]; @@ -30,11 +36,11 @@ pub fn get_mint_public_content_hash(owner_address: Field, amount: Field, cancell // docs:start:get_mint_private_content_hash // Computes a content hash of a deposit/mint_private message. // Refer TokenPortal.sol for reference on L1. -pub fn get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes: Field, amount: Field, canceller: Field) -> Field { +pub fn get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes: Field, amount: Field, canceller: EthAddress) -> Field { let mut hash_bytes: [u8; 100] = [0; 100]; let secret_hash_bytes = secret_hash_for_redeeming_minted_notes.to_be_bytes(32); let amount_bytes = amount.to_be_bytes(32); - let canceller_bytes = canceller.to_be_bytes(32); + let canceller_bytes = canceller.to_field().to_be_bytes(32); for i in 0..32 { hash_bytes[i + 4] = secret_hash_bytes[i]; @@ -55,15 +61,15 @@ pub fn get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes: Fie // docs:start:get_withdraw_content_hash // Computes a content hash of a withdraw message. -pub fn get_withdraw_content_hash(recipient: Field, amount: Field, callerOnL1: Field) -> Field { +pub fn get_withdraw_content_hash(recipient: EthAddress, amount: Field, callerOnL1: EthAddress) -> Field { // Compute the content hash // Compute sha256(selector || amount || recipient) // then convert to a single field element // add that to the l2 to l1 messages let mut hash_bytes: [u8; 100] = [0; 100]; - let recipient_bytes = recipient.to_be_bytes(32); + let recipient_bytes = recipient.to_field().to_be_bytes(32); let amount_bytes = amount.to_be_bytes(32); - let callerOnL1_bytes = callerOnL1.to_be_bytes(32); + let callerOnL1_bytes = callerOnL1.to_field().to_be_bytes(32); // 0x69328dec, selector for "withdraw(address,uint256,address)" hash_bytes[0] = 0x69; diff --git a/yarn-project/noir-contracts/src/contracts/uniswap_contract/Nargo.toml b/yarn-project/noir-contracts/src/contracts/uniswap_contract/Nargo.toml index 919f3c6b7e2..46728c85fd4 100644 --- a/yarn-project/noir-contracts/src/contracts/uniswap_contract/Nargo.toml +++ b/yarn-project/noir-contracts/src/contracts/uniswap_contract/Nargo.toml @@ -6,4 +6,5 @@ type = "contract" [dependencies] aztec = { path = "../../../../aztec-nr/aztec" } -authwit = { path = "../../../../aztec-nr/authwit" } \ No newline at end of file +authwit = { path = "../../../../aztec-nr/authwit" } +protocol_types = { path = "../../../../noir-protocol-circuits/src/crates/types" } 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 a319d7135ba..22f3e286b98 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,55 +1,58 @@ // docs:start:interfaces +use dep::protocol_types::address::{ + AztecAddress, + EthAddress, +}; use dep::aztec::{ context::{ PrivateContext, PublicContext, Context }, selector::compute_selector, - types::address::AztecAddress, }; struct Token { - address: Field, + address: AztecAddress, } impl Token { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address } } - pub fn transfer_public(self: Self, context: PublicContext, from: Field, to: Field, amount: Field, nonce: Field) { + 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)"), - [from, to, amount, nonce] + [from.to_field(), to.to_field(), amount, nonce] ); } - pub fn unshield(self: Self, context: &mut PrivateContext, from: Field, to: Field, amount: Field, nonce: Field) { + 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)"), - [from, to, amount, nonce] + [from.to_field(), to.to_field(), amount, nonce] ); } } struct TokenBridge { - address: Field, + address: AztecAddress, } impl TokenBridge { - pub fn at(address: Field) -> Self { + pub fn at(address: AztecAddress) -> Self { Self { address } } pub fn token(self: Self, context: PublicContext) -> AztecAddress { let return_values = context.call_public_function(self.address, compute_selector("get_token()"), []); - AztecAddress::new(return_values[0]) + AztecAddress::from_field(return_values[0]) } - pub fn exit_to_l1_public(self: Self, context: PublicContext, recipient: Field, amount: Field, callerOnL1: Field, nonce: Field) { + 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)"), - [recipient, amount, callerOnL1, nonce] + [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 97d8a5f10e0..a40e4f12194 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,11 +6,14 @@ 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::aztec::{ context::{PrivateContext, PublicContext, Context}, oracle::{context::get_portal_address}, state_vars::{map::Map, public_state::PublicState}, - types::address::{AztecAddress, EthereumAddress}, types::type_serialization::bool_serialization::{ BoolSerializationMethods, BOOL_SERIALIZED_LEN, }, @@ -34,7 +37,7 @@ contract Uniswap { } impl Storage { - fn init(context: Context) -> pub Self { + fn init(context: Context) -> Self { Storage { approved_action: Map::new( context, @@ -68,20 +71,20 @@ contract Uniswap { recipient: AztecAddress, secret_hash_for_L1_to_l2_message: Field, deadline_for_L1_to_l2_message: Field, - canceller_for_L1_to_L2_message: EthereumAddress, - caller_on_L1: EthereumAddress, + canceller_for_L1_to_L2_message: EthAddress, + caller_on_L1: EthAddress, // nonce for someone to call swap on sender's behalf nonce_for_swap_approval: Field ) { - if (sender.address != context.msg_sender()) { + if (!sender.eq(context.msg_sender())) { assert_current_call_valid_authwit_public(&mut context, sender); } - let input_asset = TokenBridge::at(input_asset_bridge.address).token(context); + let input_asset = TokenBridge::at(input_asset_bridge).token(context); // Transfer funds to this contract - Token::at(input_asset.address).transfer_public(context, - sender.address, + Token::at(input_asset).transfer_public(context, + sender, context.this_address(), input_amount, nonce_for_transfer_approval); @@ -89,26 +92,26 @@ 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)"), - [input_asset.address, input_asset_bridge.address, input_amount]); + [input_asset.to_field(), input_asset_bridge.to_field(), input_amount]); // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. - let input_asset_bridge_portal_address = get_portal_address(input_asset_bridge.address); - let output_asset_bridge_portal_address = get_portal_address(output_asset_bridge.address); + let input_asset_bridge_portal_address = get_portal_address(input_asset_bridge); + let output_asset_bridge_portal_address = get_portal_address(output_asset_bridge); // ensure portal exists - else funds might be lost - assert(input_asset_bridge_portal_address != 0, "L1 portal address of input_asset's bridge is 0"); - assert(output_asset_bridge_portal_address != 0, "L1 portal address of output_asset's bridge is 0"); + assert(!input_asset_bridge_portal_address.is_zero(), "L1 portal address of input_asset's bridge is 0"); + assert(!output_asset_bridge_portal_address.is_zero(), "L1 portal address of output_asset's bridge is 0"); let content_hash = compute_swap_public_content_hash(input_asset_bridge_portal_address, input_amount, uniswap_fee_tier, output_asset_bridge_portal_address, minimum_output_amount, - recipient.address, + recipient, secret_hash_for_L1_to_l2_message, deadline_for_L1_to_l2_message, - canceller_for_L1_to_L2_message.address, - caller_on_L1.address); + canceller_for_L1_to_L2_message, + caller_on_L1); context.message_portal(content_hash); } // docs:end:swap_public @@ -129,17 +132,17 @@ contract Uniswap { secret_hash_for_redeeming_minted_notes: Field,// secret hash used to redeem minted notes at a later time. This enables anyone to call this function and mint tokens to a user on their behalf secret_hash_for_L1_to_l2_message: Field, // for when l1 uniswap portal inserts the message to consume output assets on L2 deadline_for_L1_to_l2_message: Field, // for when l1 uniswap portal inserts the message to consume output assets on L2 - canceller_for_L1_to_L2_message: EthereumAddress, // L1 address of who can cancel the message to consume assets on L2. - caller_on_L1: EthereumAddress // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) + canceller_for_L1_to_L2_message: EthAddress, // L1 address of who can cancel the message to consume assets on L2. + caller_on_L1: EthAddress // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { // Assert that user provided token address is same as expected by token bridge. // we can't directly use `input_asset_bridge.token` because that is a public method and public can't return data to private context.call_public_function(context.this_address(), compute_selector("_assert_token_is_same((Field),(Field))"), - [input_asset.address, input_asset_bridge.address]); + [input_asset.to_field(), input_asset_bridge.to_field()]); // Transfer funds to this contract - Token::at(input_asset.address).unshield(&mut context, + Token::at(input_asset).unshield(&mut context, context.msg_sender(), context.this_address(), input_amount, @@ -148,15 +151,15 @@ 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)"), - [input_asset.address, input_asset_bridge.address, input_amount]); + [input_asset.to_field(), input_asset_bridge.to_field(), input_amount]); // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. - let input_asset_bridge_portal_address = get_portal_address(input_asset_bridge.address); - let output_asset_bridge_portal_address = get_portal_address(output_asset_bridge.address); + let input_asset_bridge_portal_address = get_portal_address(input_asset_bridge); + let output_asset_bridge_portal_address = get_portal_address(output_asset_bridge); // ensure portal exists - else funds might be lost - assert(input_asset_bridge_portal_address != 0, "L1 portal address of input_asset's bridge is 0"); - assert(output_asset_bridge_portal_address != 0, "L1 portal address of output_asset's bridge is 0"); + assert(!input_asset_bridge_portal_address.is_zero(), "L1 portal address of input_asset's bridge is 0"); + assert(!output_asset_bridge_portal_address.is_zero(), "L1 portal address of output_asset's bridge is 0"); let content_hash = compute_swap_private_content_hash(input_asset_bridge_portal_address, input_amount, @@ -166,8 +169,8 @@ contract Uniswap { secret_hash_for_redeeming_minted_notes, secret_hash_for_L1_to_l2_message, deadline_for_L1_to_l2_message, - canceller_for_L1_to_L2_message.address, - caller_on_L1.address); + canceller_for_L1_to_L2_message, + caller_on_L1); context.message_portal(content_hash); } // docs:end:swap_private @@ -197,14 +200,14 @@ contract Uniswap { let message_hash = compute_authwit_message_hash(token_bridge, token, selector, - [context.this_address(), amount, nonce_for_burn_approval]); + [context.this_address().to_field(), amount, nonce_for_burn_approval]); storage.approved_action.at(message_hash).write(true); // increment nonce_for_burn_approval so it won't be used again storage.nonce_for_burn_approval.write(nonce_for_burn_approval + 1); // Exit to L1 Uniswap Portal ! - TokenBridge::at(token_bridge.address).exit_to_l1_public(context, + TokenBridge::at(token_bridge).exit_to_l1_public(context, context.this_portal_address(), amount, context.this_portal_address(), @@ -215,7 +218,7 @@ contract Uniswap { // docs:start:assert_token_is_same #[aztec(public)] internal fn _assert_token_is_same(token: AztecAddress, token_bridge: AztecAddress) { - assert(token.eq(TokenBridge::at(token_bridge.address).token(context)), "input_asset address is not the same as seen in the bridge contract"); + assert(token.eq(TokenBridge::at(token_bridge).token(context)), "input_asset address is not the same as seen in the bridge contract"); } // docs:end:assert_token_is_same diff --git a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/util.nr b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/util.nr index 163f8056a10..7e19a7173ae 100644 --- a/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/util.nr +++ b/yarn-project/noir-contracts/src/contracts/uniswap_contract/src/util.nr @@ -1,32 +1,38 @@ // docs:start:uniswap_public_content_hash -use dep::aztec::hash::sha256_to_field; +use dep::protocol_types::{ + address::{ + AztecAddress, + EthAddress, + }, + hash::sha256_to_field, +}; // This method computes the L2 to L1 message content hash for the public // refer `l1-contracts/test/portals/UniswapPortal.sol` on how L2 to L1 message is expected pub fn compute_swap_public_content_hash( - input_asset_bridge_portal_address: Field, + input_asset_bridge_portal_address: EthAddress, input_amount: Field, uniswap_fee_tier: Field, - output_asset_bridge_portal_address: Field, + output_asset_bridge_portal_address: EthAddress, minimum_output_amount: Field, - aztec_recipient: Field, + aztec_recipient: AztecAddress, secret_hash_for_L1_to_l2_message: Field, deadline_for_L1_to_l2_message: Field, - canceller_for_L1_to_L2_message: Field, - caller_on_L1: Field + canceller_for_L1_to_L2_message: EthAddress, + caller_on_L1: EthAddress ) -> Field { let mut hash_bytes: [u8; 324] = [0; 324]; // 10 fields of 32 bytes each + 4 bytes fn selector - let input_token_portal_bytes = input_asset_bridge_portal_address.to_be_bytes(32); + let input_token_portal_bytes = input_asset_bridge_portal_address.to_field().to_be_bytes(32); let in_amount_bytes = input_amount.to_be_bytes(32); let uniswap_fee_tier_bytes = uniswap_fee_tier.to_be_bytes(32); - let output_token_portal_bytes = output_asset_bridge_portal_address.to_be_bytes(32); + let output_token_portal_bytes = output_asset_bridge_portal_address.to_field().to_be_bytes(32); let amount_out_min_bytes = minimum_output_amount.to_be_bytes(32); - let aztec_recipient_bytes = aztec_recipient.to_be_bytes(32); + let aztec_recipient_bytes = aztec_recipient.to_field().to_be_bytes(32); let secret_hash_for_L1_to_l2_message_bytes = secret_hash_for_L1_to_l2_message.to_be_bytes(32); let deadline_for_L1_to_l2_message_bytes = deadline_for_L1_to_l2_message.to_be_bytes(32); - let canceller_bytes = canceller_for_L1_to_L2_message.to_be_bytes(32); - let caller_on_L1_bytes = caller_on_L1.to_be_bytes(32); + let canceller_bytes = canceller_for_L1_to_L2_message.to_field().to_be_bytes(32); + let caller_on_L1_bytes = caller_on_L1.to_field().to_be_bytes(32); // function selector: 0xf3068cac keccak256("swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,uint32,address,address)") hash_bytes[0] = 0xf3; @@ -56,29 +62,29 @@ pub fn compute_swap_public_content_hash( // This method computes the L2 to L1 message content hash for the private // refer `l1-contracts/test/portals/UniswapPortal.sol` on how L2 to L1 message is expected pub fn compute_swap_private_content_hash( - input_asset_bridge_portal_address: Field, + input_asset_bridge_portal_address: EthAddress, input_amount: Field, uniswap_fee_tier: Field, - output_asset_bridge_portal_address: Field, + output_asset_bridge_portal_address: EthAddress, minimum_output_amount: Field, secret_hash_for_redeeming_minted_notes: Field, secret_hash_for_L1_to_l2_message: Field, deadline_for_L1_to_l2_message: Field, - canceller_for_L1_to_L2_message: Field, - caller_on_L1: Field + canceller_for_L1_to_L2_message: EthAddress, + caller_on_L1: EthAddress ) -> Field { let mut hash_bytes: [u8; 324] = [0; 324]; // 10 fields of 32 bytes each + 4 bytes fn selector - let input_token_portal_bytes = input_asset_bridge_portal_address.to_be_bytes(32); + let input_token_portal_bytes = input_asset_bridge_portal_address.to_field().to_be_bytes(32); let in_amount_bytes = input_amount.to_be_bytes(32); let uniswap_fee_tier_bytes = uniswap_fee_tier.to_be_bytes(32); - let output_token_portal_bytes = output_asset_bridge_portal_address.to_be_bytes(32); + let output_token_portal_bytes = output_asset_bridge_portal_address.to_field().to_be_bytes(32); let amount_out_min_bytes = minimum_output_amount.to_be_bytes(32); let secret_hash_for_redeeming_minted_notes_bytes = secret_hash_for_redeeming_minted_notes.to_be_bytes(32); let secret_hash_for_L1_to_l2_message_bytes = secret_hash_for_L1_to_l2_message.to_be_bytes(32); let deadline_for_L1_to_l2_message_bytes = deadline_for_L1_to_l2_message.to_be_bytes(32); - let canceller_bytes = canceller_for_L1_to_L2_message.to_be_bytes(32); - let caller_on_L1_bytes = caller_on_L1.to_be_bytes(32); + let canceller_bytes = canceller_for_L1_to_L2_message.to_field().to_be_bytes(32); + let caller_on_L1_bytes = caller_on_L1.to_field().to_be_bytes(32); // function selector: 0xbd87d14b keccak256("swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,uint32,address,address)") hash_bytes[0] = 0xbd; diff --git a/yarn-project/noir-protocol-circuits/src/crates/bug-collecting-crate/devex-santiago-automatic-deref.nr b/yarn-project/noir-protocol-circuits/src/crates/bug-collecting-crate/devex-santiago-automatic-deref.nr index 47b2066fe4f..3b05e4a0896 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/bug-collecting-crate/devex-santiago-automatic-deref.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/bug-collecting-crate/devex-santiago-automatic-deref.nr @@ -1,4 +1,4 @@ -Santiago mentioned the ability to automatically deref an Address into a Field. +Santiago mentioned the ability to automatically deref an AztecAddress into a Field. I believe I mentioned something like #[transparent]. The issue with this is that you lose type safety, though perhaps its fine if you opt-in to it, and its diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr index c49b4843d22..fb05830f4be 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr @@ -11,7 +11,7 @@ use dep::types::{ private_kernel::private_call_data::PrivateCallData, previous_kernel_data::PreviousKernelData, }, - address::{Address, EthAddress}, + address::{AztecAddress, EthAddress}, contrakt::deployment_data::ContractDeploymentData, constants::{ EMPTY_NULLIFIED_COMMITMENT, diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr index b20c6b963b0..72219728b41 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr @@ -126,7 +126,7 @@ mod tests { kernel_circuit_public_inputs::KernelCircuitPublicInputs, private_kernel::private_call_data::PrivateCallData, }, - address::Address, + address::AztecAddress, hash::{ compute_constructor_hash, compute_logs_hash, @@ -320,7 +320,7 @@ mod tests { fn contract_deployment_incorrect_contract_address_fails() { let mut builder = PrivateKernelInitInputsBuilder::new_constructor(); - let random_address = Address::from_field(27); + let random_address = AztecAddress::from_field(27); builder.private_call.public_inputs.call_context.storage_contract_address = random_address; builder.tx_request.origin = random_address; builder.private_call.contract_address = random_address; @@ -332,7 +332,7 @@ mod tests { fn contract_deployment_contract_address_mismatch_fails() { let mut builder = PrivateKernelInitInputsBuilder::new_constructor(); - let random_address = Address::from_field(27); + let random_address = AztecAddress::from_field(27); builder.private_call.public_inputs.call_context.storage_contract_address = random_address; builder.private_call.contract_address = random_address; @@ -402,7 +402,7 @@ mod tests { let mut builder = PrivateKernelInitInputsBuilder::new_constructor(); // Set the storage_contract_address to a random scalar. - builder.private_call.public_inputs.call_context.storage_contract_address = Address::from_field(356); + builder.private_call.public_inputs.call_context.storage_contract_address = AztecAddress::from_field(356); builder.failed(); } diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr index a89e4010bab..767dde6dc2c 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -94,7 +94,7 @@ mod tests { previous_kernel_data_builder::PreviousKernelDataBuilder, private_call_data_builder::PrivateCallDataBuilder, }, - address::Address, + address::AztecAddress, hash::compute_logs_hash, utils::{ arrays::array_length, @@ -161,8 +161,8 @@ mod tests { let mut builder = PrivateKernelInnerInputsBuilder::new(); // Set (storage) contract_address to 0 - builder.private_call.contract_address = Address::zero(); - builder.private_call.public_inputs.call_context.storage_contract_address = Address::zero(); + builder.private_call.contract_address = AztecAddress::zero(); + builder.private_call.public_inputs.call_context.storage_contract_address = AztecAddress::zero(); builder.failed(); } @@ -172,8 +172,8 @@ mod tests { let mut builder = PrivateKernelInnerInputsBuilder::new(); // Set historical_tree_root to a wrong value (the correct value + 1). - let contract_tree_root = builder.previous_kernel.block_header.block.contract_tree_root; - builder.previous_kernel.block_header.block.contract_tree_root = contract_tree_root + 1; + let contract_tree_root = builder.previous_kernel.block_header.contract_tree_root; + builder.previous_kernel.block_header.contract_tree_root = contract_tree_root + 1; builder.failed(); } @@ -326,8 +326,8 @@ mod tests { // Tweak the (storage) contract_address to be different to msg_sender. let msg_sender = builder.private_call.public_inputs.call_context.msg_sender.to_field(); - builder.private_call.contract_address = Address::from_field(msg_sender + 1); - builder.private_call.public_inputs.call_context.storage_contract_address = Address::from_field(msg_sender + 1); + builder.private_call.contract_address = AztecAddress::from_field(msg_sender + 1); + builder.private_call.public_inputs.call_context.storage_contract_address = AztecAddress::from_field(msg_sender + 1); builder.failed(); } @@ -608,8 +608,8 @@ mod tests { builder.private_call.append_read_requests(1); // Set the root to be a different root so the above read request is not under this root. - let old_root = builder.previous_kernel.block_header.block.note_hash_tree_root; - builder.previous_kernel.block_header.block.note_hash_tree_root = old_root + 1; + let old_root = builder.previous_kernel.block_header.note_hash_tree_root; + builder.previous_kernel.block_header.note_hash_tree_root = old_root + 1; builder.failed(); } diff --git a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr index a83cda75565..36c823682f0 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr @@ -12,7 +12,7 @@ use dep::types::{ public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, }, - address::Address, + address::AztecAddress, contrakt::{ storage_read::StorageRead, storage_update_request::StorageUpdateRequest, @@ -42,7 +42,7 @@ pub fn validate_inputs(public_call: PublicCallData){ let this_call_stack_item: PublicCallStackItem = public_call.call_stack_item; assert(this_call_stack_item.public_inputs.call_context.is_contract_deployment == false, "Contract deployment cannot be a public function"); - assert(!this_call_stack_item.contract_address.eq(Address::zero()), + assert(!this_call_stack_item.contract_address.eq(AztecAddress::zero()), "Contract address cannot be zero"); assert(this_call_stack_item.function_data.selector.to_field() != 0, "Function signature cannot be zero"); diff --git a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/hash.nr b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/hash.nr index 1769f9f87f2..999d10d1eb6 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/hash.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/hash.nr @@ -1,9 +1,9 @@ use dep::types::{ - address::Address, + address::AztecAddress, constants::GENERATOR_INDEX__PUBLIC_LEAF_INDEX, }; -pub fn compute_public_data_tree_index(contract_address: Address, storage_slot: Field) -> Field { +pub fn compute_public_data_tree_index(contract_address: AztecAddress, storage_slot: Field) -> Field { dep::std::hash::pedersen_hash_with_separator([ contract_address.to_field(), storage_slot diff --git a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_private_previous.nr b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_private_previous.nr index 550f14151e3..eafedd0cdfe 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_private_previous.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_private_previous.nr @@ -73,7 +73,7 @@ mod tests { public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, }, - address::{Address, EthAddress}, + address::{AztecAddress, EthAddress}, contrakt::storage_read::StorageRead, hash::compute_logs_hash, tests::{ @@ -224,8 +224,8 @@ mod tests { // Tweak the (storage) contract_address to be different to msg_sender. let msg_sender = builder.public_call.public_inputs.call_context.msg_sender.to_field(); - builder.public_call.contract_address = Address::from_field(msg_sender + 1); - builder.public_call.public_inputs.call_context.storage_contract_address = Address::from_field(msg_sender + 1); + builder.public_call.contract_address = AztecAddress::from_field(msg_sender + 1); + builder.public_call.public_inputs.call_context.storage_contract_address = AztecAddress::from_field(msg_sender + 1); builder.failed(); } @@ -233,7 +233,7 @@ mod tests { #[test(should_fail_with="Contract address cannot be zero")] fn contract_address_must_be_valid() { let mut builder = PublicKernelPrivatePreviousInputsBuilder::new(); - builder.public_call.contract_address = Address::zero(); + builder.public_call.contract_address = AztecAddress::zero(); builder.failed(); } @@ -407,7 +407,7 @@ mod tests { let mut builder = PublicKernelPrivatePreviousInputsBuilder::new(); let new_contracts = [ NewContractData { - contract_address: Address::from_field(123), + contract_address: AztecAddress::from_field(123), portal_contract_address: EthAddress::from_field(456), function_tree_root: 78, }, diff --git a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/utils.nr b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/utils.nr index e6d8603cb77..ac4994b8342 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/utils.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/public-kernel-lib/src/utils.nr @@ -6,7 +6,7 @@ use dep::types::{ public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, }, - address::Address, + address::AztecAddress, contrakt::{ storage_read::StorageRead, storage_update_request::StorageUpdateRequest, @@ -16,7 +16,7 @@ use dep::types::{ }, }; -pub fn compute_public_data_reads(contract_address: Address, read_requests: [StorageRead; N]) -> [PublicDataRead; N] { +pub fn compute_public_data_reads(contract_address: AztecAddress, read_requests: [StorageRead; N]) -> [PublicDataRead; N] { let mut public_data_reads = [PublicDataRead::empty(); N]; for i in 0..N { let read_request = read_requests[i]; @@ -43,7 +43,7 @@ pub fn assert_eq_call_requests( } pub fn compute_public_data_update_requests( - contract_address: Address, + contract_address: AztecAddress, update_requests: [StorageUpdateRequest; N], ) -> [PublicDataUpdateRequest; N] { let mut public_data_update_requests = [PublicDataUpdateRequest::empty(); N]; diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr index 79ef5693a1d..6783a204793 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -383,7 +383,7 @@ impl BaseRollupInputs { for i in 0..KERNELS_PER_BASE_ROLLUP { // Rebuild the block hash let block_header = self.kernel_data[i].public_inputs.constants.block_header; - let previous_block_hash = block_header.block.hash(); + let previous_block_hash = block_header.block_hash(); let previous_block_hash_witness = self.archive_root_membership_witnesses[i]; @@ -564,7 +564,7 @@ mod tests { abis::public_data_update_request::PublicDataUpdateRequest, abis::previous_kernel_data::PreviousKernelData, tests::previous_kernel_data_builder::PreviousKernelDataBuilder, - address::{Address, EthAddress}, + address::{AztecAddress, EthAddress}, utils::bounded_vec::BoundedVec, utils::uint256::U256, }; @@ -613,7 +613,7 @@ mod tests { }); inputs.pre_existing_blocks = inputs.kernel_data.map(|builder: PreviousKernelDataBuilder|{ - builder.block_header.block.hash() + builder.block_header.block_hash() }); inputs @@ -841,7 +841,7 @@ mod tests { #[test] unconstrained fn contract_leaf_inserted() { let new_contract = NewContractData { - contract_address: Address::from_field(1), + contract_address: AztecAddress::from_field(1), portal_contract_address: EthAddress::from_field(2), function_tree_root: 3 }; @@ -872,7 +872,7 @@ mod tests { #[test] unconstrained fn contract_leaf_inserted_in_non_empty_snapshot_tree() { let new_contract = NewContractData { - contract_address: Address::from_field(1), + contract_address: AztecAddress::from_field(1), portal_contract_address: EthAddress::from_field(2), function_tree_root: 3 }; diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr index 390c59c94aa..abcee907241 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr @@ -1,40 +1,84 @@ -use crate::block::Block; +use crate::{ + constants::{ + BLOCK_HEADER_LENGTH, + GENERATOR_INDEX__BLOCK_HASH, + }, + hash::pedersen_hash, +}; +// docs:start:block-header struct BlockHeader { - archive_root : Field, - block : Block, - // Private data - // This is marked in the cpp code as an enhancement - private_kernel_vk_tree_root : Field, + note_hash_tree_root : Field, + nullifier_tree_root : Field, + contract_tree_root : Field, + l1_to_l2_messages_tree_root : Field, + archive_root: Field, + public_data_tree_root: Field, + global_variables_hash: Field, } +// docs:end:block-header impl BlockHeader { - fn assert_is_zero(self) { - self.block.assert_is_zero(); - assert(self.private_kernel_vk_tree_root == 0); + pub fn assert_is_zero(self) { + assert(self.note_hash_tree_root == 0); + assert(self.nullifier_tree_root == 0); + assert(self.contract_tree_root == 0); + assert(self.l1_to_l2_messages_tree_root == 0); + assert(self.archive_root == 0); + assert(self.public_data_tree_root == 0); } - fn to_array(self) -> [Field;7] { + pub fn serialize(self) -> [Field; BLOCK_HEADER_LENGTH] { // This comment was copied from the cpp codebase. // // TODO(#3441): Note private_kernel_vk_tree_root, is not included yet as // it is not present in noir, [ - self.block.note_hash_tree_root, - self.block.nullifier_tree_root, - self.block.contract_tree_root, - self.block.l1_to_l2_messages_tree_root, + self.note_hash_tree_root, + self.nullifier_tree_root, + self.contract_tree_root, + self.l1_to_l2_messages_tree_root, self.archive_root, - self.block.public_data_tree_root, - self.block.global_variables_hash + self.public_data_tree_root, + self.global_variables_hash ] } + + pub fn deserialize(deserialized: [Field; BLOCK_HEADER_LENGTH]) -> Self { + BlockHeader { + note_hash_tree_root: deserialized[0], + nullifier_tree_root: deserialized[1], + contract_tree_root: deserialized[2], + l1_to_l2_messages_tree_root: deserialized[3], + archive_root: deserialized[4], + public_data_tree_root: deserialized[5], + global_variables_hash: deserialized[6], + } + } - fn note_hash_tree_root(self) -> Field { - self.block.note_hash_tree_root + pub fn note_hash_tree_root(self) -> Field { + self.note_hash_tree_root + } + + pub fn contract_tree_root(self) -> Field { + self.contract_tree_root + } + + pub fn block_hash(self) -> Field { + // TODO(#3442): Unify the ordering in `BlockHeader::serialize` function and the ordering + // in the block hash preimage --> This requires changes in the circuits. + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) + pedersen_hash([ + self.global_variables_hash, + self.note_hash_tree_root, + self.nullifier_tree_root, + self.contract_tree_root, + self.l1_to_l2_messages_tree_root, + self.public_data_tree_root, + ], GENERATOR_INDEX__BLOCK_HASH) } - fn contract_tree_root(self) -> Field { - self.block.contract_tree_root + pub fn empty() -> Self { + BlockHeader::deserialize([0; BLOCK_HEADER_LENGTH]) } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr index 012ab922e5d..973affb7669 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr @@ -1,10 +1,17 @@ -use crate::abis::function_selector::FunctionSelector; -use crate::address::{EthAddress,Address}; -use crate::constants::GENERATOR_INDEX__CALL_CONTEXT; +use crate::{ + abis::function_selector::FunctionSelector, + address::{EthAddress,AztecAddress}, + constants::{ + CALL_CONTEXT_LENGTH, + GENERATOR_INDEX__CALL_CONTEXT, + }, + hash::pedersen_hash, +}; -struct CallContext{ - msg_sender : Address, - storage_contract_address : Address, +// docs:start:call-context +struct CallContext { + msg_sender : AztecAddress, + storage_contract_address : AztecAddress, portal_contract_address : EthAddress, function_selector : FunctionSelector, @@ -13,10 +20,11 @@ struct CallContext{ is_static_call : bool, is_contract_deployment : bool, } +// docs:end:call-context impl CallContext { - fn hash(self) -> Field { - dep::std::hash::pedersen_hash_with_separator([ + fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] { + [ self.msg_sender.to_field(), self.storage_contract_address.to_field(), self.portal_contract_address.to_field(), @@ -24,10 +32,15 @@ impl CallContext { self.is_delegate_call as Field, self.is_static_call as Field, self.is_contract_deployment as Field, - ], GENERATOR_INDEX__CALL_CONTEXT) + ] + } + + fn hash(self) -> Field { + pedersen_hash(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT) } fn assert_is_zero(self) { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) assert(self.msg_sender.to_field() == 0); assert(self.storage_contract_address.to_field() == 0); assert(self.portal_contract_address.to_field() == 0); @@ -38,6 +51,7 @@ impl CallContext { } fn eq(self, call_context: CallContext) -> bool { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) call_context.msg_sender.eq(self.msg_sender) & call_context.storage_contract_address.eq(self.storage_contract_address) & call_context.portal_contract_address.eq(self.portal_contract_address) diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr index 9c6737c9e3e..4c3d0724d87 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr @@ -1,15 +1,15 @@ -use crate::address::Address; +use crate::address::AztecAddress; struct CallerContext { - msg_sender: Address, - storage_contract_address: Address, + msg_sender: AztecAddress, + storage_contract_address: AztecAddress, } impl CallerContext { pub fn empty() -> Self { CallerContext { - msg_sender: Address::zero(), - storage_contract_address: Address::zero(), + msg_sender: AztecAddress::zero(), + storage_contract_address: AztecAddress::zero(), } } @@ -25,7 +25,7 @@ impl CallerContext { struct CallRequest { hash: Field, - caller_contract_address: Address, + caller_contract_address: AztecAddress, caller_context: CallerContext, } @@ -33,7 +33,7 @@ impl CallRequest { pub fn empty() -> Self { Self { hash: 0, - caller_contract_address: Address::zero(), + caller_contract_address: AztecAddress::zero(), caller_context: dep::std::unsafe::zeroed(), } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_stack_item.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_stack_item.nr index ea323fba8fe..201ae8b307d 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_stack_item.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_stack_item.nr @@ -3,7 +3,7 @@ use crate::abis::{ private_circuit_public_inputs::PrivateCircuitPublicInputs, public_circuit_public_inputs::PublicCircuitPublicInputs, }; -use crate::address::Address; +use crate::address::AztecAddress; use crate::constants::{ GENERATOR_INDEX__CALL_STACK_ITEM, }; @@ -14,7 +14,7 @@ struct PrivateCallStackItem { // `contract_address` _does not change_. Amongst other things, it's used as a lookup for // getting the correct code from the tree. There is a separate `storage_contract_address` // within a CallStackItem which varies depending on whether this is a call or delegatecall. - contract_address: Address, + contract_address: AztecAddress, public_inputs: PrivateCircuitPublicInputs, function_data: FunctionData, // Not really needed for PrivateCallStackItem. @@ -32,7 +32,7 @@ impl PrivateCallStackItem { } struct PublicCallStackItem { - contract_address: Address, + contract_address: AztecAddress, public_inputs: PublicCircuitPublicInputs, function_data: FunctionData, // True if this call stack item represents a request to execute a function rather than a diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/complete_address.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/complete_address.nr index 84cd894b326..1bf1ed8dfe0 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/complete_address.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/complete_address.nr @@ -1,11 +1,11 @@ use crate::point::Point; -use crate::address::Address; +use crate::address::AztecAddress; use crate::hash::{compute_partial_address,compute_contract_address_from_partial}; struct CompleteAddress{ - address : Address, + address : AztecAddress, public_key : Point, - // TODO(David): Can we type this as Address instead of Field? + // TODO(David): Can we type this as AztecAddress instead of Field? partial_address: Field, } 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 5a1e4095b7f..94a5e1f93b6 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 @@ -8,12 +8,18 @@ impl FunctionSelector { self.inner as Field } - pub fn from_u32(value: u32) -> FunctionSelector { - FunctionSelector { + pub fn from_u32(value: u32) -> Self { + Self { inner : value, } } + pub fn from_field(value : Field) -> Self { + Self { + inner : value as u32, + } + } + pub fn zero() -> Self { FunctionSelector { inner: 0 } } @@ -21,4 +27,14 @@ impl FunctionSelector { pub fn eq(self, function_selector: FunctionSelector) -> bool { function_selector.inner == self.inner } + + pub fn serialize(self: Self) -> [Field; 1] { + [self.inner as Field] + } + + pub fn deserialize(fields: [Field; 1]) -> Self { + Self { + inner: fields[0] as u32 + } + } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/new_contract_data.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/new_contract_data.nr index 784b698da5b..89085c0e67f 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/new_contract_data.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/new_contract_data.nr @@ -1,8 +1,8 @@ -use crate::address::{Address, EthAddress}; +use crate::address::{AztecAddress, EthAddress}; use crate::constants::GENERATOR_INDEX__CONTRACT_LEAF; struct NewContractData { - contract_address: Address, + contract_address: AztecAddress, portal_contract_address: EthAddress, function_tree_root: Field, } @@ -22,7 +22,7 @@ impl NewContractData { pub fn default() -> Self { Self { - contract_address : Address::default(), + contract_address : AztecAddress::default(), portal_contract_address : EthAddress::default(), function_tree_root : 0, } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr index 8bee165fda4..66baeee3a0f 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr @@ -4,7 +4,10 @@ use crate::{ block_header::BlockHeader, }, contrakt::deployment_data::ContractDeploymentData, - hash::NUM_FIELDS_PER_SHA256, + hash::{ + NUM_FIELDS_PER_SHA256, + pedersen_hash, + }, utils::bounded_vec::BoundedVec, }; use crate::constants::{ @@ -17,6 +20,7 @@ use crate::constants::{ MAX_NEW_L2_TO_L1_MSGS_PER_CALL, RETURN_VALUES_LENGTH, PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, + PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS, }; @@ -54,8 +58,8 @@ struct PrivateCircuitPublicInputs { } impl PrivateCircuitPublicInputs { - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3059) : Reuse aztec-nr - fn hash(self) -> Field { + fn hash(self) -> Field { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) let mut fields: BoundedVec = BoundedVec::new(0); fields.push(self.call_context.hash()); fields.push(self.args_hash); @@ -72,13 +76,36 @@ impl PrivateCircuitPublicInputs { fields.push_array(self.unencrypted_logs_hash); fields.push(self.encrypted_log_preimages_length); fields.push(self.unencrypted_log_preimages_length); - fields.push_array(self.block_header.to_array()); + fields.push_array(self.block_header.serialize()); fields.push(self.contract_deployment_data.hash()); fields.push(self.chain_id); fields.push(self.version); assert_eq(fields.len(), PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, "Incorrect number of input fields when hashing PrivateCircuitPublicInputs"); - dep::std::hash::pedersen_hash_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS) + pedersen_hash(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS) + } + + fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] { + let mut fields: BoundedVec = BoundedVec::new(0); + fields.push_array(self.call_context.serialize()); + fields.push(self.args_hash); + fields.push_array(self.return_values); + fields.push_array(self.read_requests); + fields.push_array(self.pending_read_requests); + fields.push_array(self.new_commitments); + fields.push_array(self.new_nullifiers); + fields.push_array(self.private_call_stack_hashes); + fields.push_array(self.public_call_stack_hashes); + fields.push_array(self.new_l2_to_l1_msgs); + fields.push_array(self.encrypted_logs_hash); + fields.push_array(self.unencrypted_logs_hash); + fields.push(self.encrypted_log_preimages_length); + fields.push(self.unencrypted_log_preimages_length); + fields.push_array(self.block_header.serialize()); + fields.push_array(self.contract_deployment_data.serialize()); + fields.push(self.chain_id); + fields.push(self.version); + fields.storage } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr index 69b6ab7af68..07892cce2fc 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr @@ -7,14 +7,15 @@ use crate::constants::{ MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, RETURN_VALUES_LENGTH, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS, - PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH + PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, + PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH, }; use crate::{ abis::{ call_context::CallContext, block_header::BlockHeader, }, - address::Address, + address::AztecAddress, contrakt::{ storage_read::StorageRead, storage_update_request::StorageUpdateRequest, @@ -45,12 +46,12 @@ struct PublicCircuitPublicInputs{ block_header: BlockHeader, - prover_address: Address, + prover_address: AztecAddress, } impl PublicCircuitPublicInputs{ - // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3059): Reuse aztec-nr - fn hash(self) -> Field { + fn hash(self) -> Field { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) have mercy por favor let mut inputs: BoundedVec = BoundedVec::new(0); inputs.push(self.call_context.hash()); inputs.push(self.args_hash); @@ -67,11 +68,33 @@ impl PublicCircuitPublicInputs{ inputs.push_array(self.new_l2_to_l1_msgs); inputs.push_array(self.unencrypted_logs_hash); inputs.push(self.unencrypted_log_preimages_length); - inputs.push_array(self.block_header.to_array()); + inputs.push_array(self.block_header.serialize()); inputs.push(self.prover_address.to_field()); assert_eq(inputs.len(), PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, "Incorrect number of input fields when hashing PublicCircuitPublicInputs"); dep::std::hash::pedersen_hash_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS) } + + pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] { + let mut fields: BoundedVec = BoundedVec::new(0); + fields.push_array(self.call_context.serialize()); + fields.push(self.args_hash); + fields.push_array(self.return_values); + for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL { + fields.push_array(self.contract_storage_update_requests[i].serialize()); + } + for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL { + fields.push_array(self.contract_storage_reads[i].serialize()); + } + fields.push_array(self.public_call_stack_hashes); + fields.push_array(self.new_commitments); + fields.push_array(self.new_nullifiers); + fields.push_array(self.new_l2_to_l1_msgs); + fields.push_array(self.unencrypted_logs_hash); + fields.push(self.unencrypted_log_preimages_length); + fields.push_array(self.block_header.serialize()); + fields.push(self.prover_address.to_field()); + fields.storage + } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr index 2686f693844..cc8142d7b6a 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/address.nr @@ -1,11 +1,11 @@ use crate::utils; // Aztec address -struct Address { +struct AztecAddress { inner : Field } -impl Address { +impl AztecAddress { pub fn zero() -> Self { Self { inner: 0 @@ -24,7 +24,7 @@ impl Address { } } - pub fn to_field(self) -> Field{ + pub fn to_field(self) -> Field { self.inner } @@ -46,6 +46,16 @@ impl Address { pub fn eq(self, other : Self) -> bool { self.to_field() == other.to_field() } + + pub fn serialize(self: Self) -> [Field; 1] { + [self.inner] + } + + pub fn deserialize(fields: [Field; 1]) -> Self { + Self { + inner: fields[0] + } + } } struct EthAddress{ @@ -93,5 +103,15 @@ impl EthAddress{ pub fn eq(self, other : Self) -> bool { self.to_field() == other.to_field() } + + pub fn serialize(self: Self) -> [Field; 1] { + [self.inner] + } + + pub fn deserialize(fields: [Field; 1]) -> Self { + Self { + inner: fields[0] + } + } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/block.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/block.nr deleted file mode 100644 index a692491d3f4..00000000000 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/block.nr +++ /dev/null @@ -1,36 +0,0 @@ -use crate::constants::GENERATOR_INDEX__BLOCK_HASH; - -// This is not in the cpp code. -struct Block { - // Private data - note_hash_tree_root : Field, - nullifier_tree_root : Field, - contract_tree_root : Field, - l1_to_l2_messages_tree_root : Field, - - // Public data - public_data_tree_root : Field, - global_variables_hash : Field, -} - - -impl Block { - fn assert_is_zero(self) { - assert(self.note_hash_tree_root == 0); - assert(self.nullifier_tree_root == 0); - assert(self.contract_tree_root == 0); - assert(self.l1_to_l2_messages_tree_root == 0); - assert(self.public_data_tree_root == 0); - } - - fn hash(self) -> Field { - dep::std::hash::pedersen_hash_with_separator([ - self.global_variables_hash, - self.note_hash_tree_root, - self.nullifier_tree_root, - self.contract_tree_root, - self.l1_to_l2_messages_tree_root, - self.public_data_tree_root, - ], GENERATOR_INDEX__BLOCK_HASH) - } -} \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr index 083122ff942..c20a49d78d3 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/deployment_data.nr @@ -1,7 +1,12 @@ use crate::address::EthAddress; +use crate::constants::{ + CONTRACT_DEPLOYMENT_DATA_LENGTH, + GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA, +}; +use crate::hash::pedersen_hash; use crate::point::Point; -use crate::constants::GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA; +// docs:start:contract-deployment-data struct ContractDeploymentData { deployer_public_key : Point, constructor_vk_hash : Field, @@ -9,8 +14,20 @@ struct ContractDeploymentData { contract_address_salt : Field, portal_contract_address : EthAddress, } +// docs:end:contract-deployment-data impl ContractDeploymentData { + fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] { + [ + self.deployer_public_key.x, + self.deployer_public_key.y, + self.constructor_vk_hash, + self.function_tree_root, + self.contract_address_salt, + self.portal_contract_address.to_field(), + ] + } + fn assert_is_zero(self) { self.deployer_public_key.assert_is_zero(); assert(self.constructor_vk_hash == 0); @@ -20,13 +37,6 @@ impl ContractDeploymentData { } fn hash(self) -> Field { - dep::std::hash::pedersen_hash_with_separator([ - self.deployer_public_key.x, - self.deployer_public_key.y, - self.constructor_vk_hash, - self.function_tree_root, - self.contract_address_salt, - self.portal_contract_address.to_field() - ], GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA) + pedersen_hash(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA) } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_read.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_read.nr index 71de424e162..58aeaa55214 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_read.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_read.nr @@ -1,6 +1,12 @@ -use crate::constants::GENERATOR_INDEX__PUBLIC_DATA_READ; +use crate::{ + constants::{ + CONTRACT_STORAGE_READ_LENGTH, + GENERATOR_INDEX__PUBLIC_DATA_READ, + }, + hash::pedersen_hash, +}; -struct StorageRead{ +struct StorageRead { storage_slot: Field, current_value: Field, } @@ -13,11 +19,12 @@ impl StorageRead { } } + pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] { + [self.storage_slot, self.current_value] + } + pub fn hash(self) -> Field { - dep::std::hash::pedersen_hash_with_separator([ - self.storage_slot, - self.current_value, - ], GENERATOR_INDEX__PUBLIC_DATA_READ) + pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ) } pub fn is_empty(self) -> bool { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr index 7d1f90b0d89..95f1d68bf4d 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/contrakt/storage_update_request.nr @@ -1,4 +1,10 @@ -use crate::constants::GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST; +use crate::{ + constants::{ + CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH, + GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST, + }, + hash::pedersen_hash, +}; struct StorageUpdateRequest{ storage_slot : Field, @@ -15,12 +21,12 @@ impl StorageUpdateRequest { } } + pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] { + [self.storage_slot, self.old_value, self.new_value] + } + pub fn hash(self) -> Field { - dep::std::hash::pedersen_hash_with_separator([ - self.storage_slot, - self.old_value, - self.new_value, - ], GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST) + pedersen_hash(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST) } pub fn is_empty(self) -> bool { @@ -28,6 +34,7 @@ impl StorageUpdateRequest { } pub fn eq(self, request: Self) -> bool { + // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3595) (request.storage_slot == self.storage_slot) & (request.old_value == self.old_value) & (request.new_value == self.new_value) diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/hash.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/hash.nr index a792107a9cd..e9457f53b93 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/hash.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/hash.nr @@ -1,4 +1,4 @@ -use crate::address::{Address, EthAddress}; +use crate::address::{AztecAddress, EthAddress}; use crate::mocked::VerificationKey; use crate::point::Point; use crate::abis::function_selector::FunctionSelector; @@ -25,7 +25,7 @@ use crate::constants::{ GENERATOR_INDEX__FUNCTION_ARGS, }; -use dep::std::hash::sha256; +use dep::std::hash::{pedersen_hash_with_separator, sha256}; pub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field { let sha256_hashed = sha256(bytes_to_hash); @@ -63,11 +63,11 @@ pub fn hash_args(args: [Field; N]) -> Field { chunk_args[j] = args[item_index]; } } - chunk_hash = dep::std::hash::pedersen_hash_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS); + chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS); } chunks_hashes[i] = chunk_hash; } - dep::std::hash::pedersen_hash_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS) + pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS) } } @@ -128,7 +128,7 @@ pub fn function_tree_root_from_siblings(selector : FunctionSelector, is_internal } // Calculate the contract tree root from the sibling path and leaf preimage. -pub fn contract_tree_root_from_siblings(function_tree_root : Field, storage_contract_address : Address, portal_contract_address : EthAddress, contract_leaf_index : Field,contract_leaf_sibling_path : [Field; CONTRACT_TREE_HEIGHT]) -> Field { +pub fn contract_tree_root_from_siblings(function_tree_root : Field, storage_contract_address : AztecAddress, portal_contract_address : EthAddress, contract_leaf_index : Field,contract_leaf_sibling_path : [Field; CONTRACT_TREE_HEIGHT]) -> Field { //TODO(Kev): if we use shorthand syntax here, we get an error as expected, // since variable name is `storage_contract_address` but the span is incorrect. let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, @@ -147,22 +147,22 @@ pub fn read_request_root_from_siblings(read_request : Field, leaf_index : Field, root_from_sibling_path(read_request, leaf_index, sibling_path) } -pub fn silo_commitment(address : Address, inner_commitment : Field) -> Field { - dep::std::hash::pedersen_hash_with_separator([ +pub fn silo_commitment(address : AztecAddress, inner_commitment : Field) -> Field { + pedersen_hash([ address.to_field(), inner_commitment, ], GENERATOR_INDEX__SILOED_COMMITMENT) } -pub fn silo_nullifier(address : Address, nullifier : Field) -> Field { - dep::std::hash::pedersen_hash_with_separator([ +pub fn silo_nullifier(address : AztecAddress, nullifier : Field) -> Field { + pedersen_hash([ address.to_field(), nullifier, ], GENERATOR_INDEX__OUTER_NULLIFIER) } fn merkle_hash(left : Field, right : Field) -> Field { - dep::std::hash::pedersen_hash_with_separator([left, right], 0) + pedersen_hash([left, right], 0) } pub fn stdlib_recursion_verification_key_compress_native_vk(_vk : VerificationKey) -> Field { @@ -174,11 +174,11 @@ pub fn stdlib_recursion_verification_key_compress_native_vk(_vk : VerificationKe } // TODO CPP uses blake2s for this -pub fn compute_new_contract_address_hash(new_contract_address : Address) -> Field { +pub fn compute_new_contract_address_hash(new_contract_address : AztecAddress) -> Field { dep::std::hash::pedersen_hash([new_contract_address.to_field()]) } -pub fn compute_l2_to_l1_hash(contract_address : Address, rollup_version_id: Field, portal_contract_address : EthAddress, chain_id : Field, content : Field) -> Field { +pub fn compute_l2_to_l1_hash(contract_address : AztecAddress, rollup_version_id: Field, portal_contract_address : EthAddress, chain_id : Field, content : Field) -> Field { let mut bytes: BoundedVec = BoundedVec::new(0); let inputs = [contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content]; @@ -196,7 +196,7 @@ pub fn compute_l2_to_l1_hash(contract_address : Address, rollup_version_id: Fiel pub fn compute_constructor_hash(function_data : FunctionData, args_hash : Field, constructor_vk_hash : Field) -> Field { let function_data_hash = function_data.hash(); - dep::std::hash::pedersen_hash_with_separator([ + pedersen_hash([ function_data_hash, args_hash, constructor_vk_hash @@ -251,7 +251,7 @@ pub fn compute_logs_hash(previous_log_hash : [Field;2], current_log_hash : [Fiel } pub fn compute_partial_address(contract_address_salt : Field, function_tree_root : Field, constructor_hash : Field) -> Field { - dep::std::hash::pedersen_hash_with_separator([ + pedersen_hash([ // TODO why the zeroes? 0, 0, @@ -261,24 +261,24 @@ pub fn compute_partial_address(contract_address_salt : Field, function_tree_root ], GENERATOR_INDEX__PARTIAL_ADDRESS) } -pub fn compute_contract_address_from_partial(point : Point, partial_address : Field) -> Address { - let field = dep::std::hash::pedersen_hash_with_separator([ +pub fn compute_contract_address_from_partial(point : Point, partial_address : Field) -> AztecAddress { + let field = pedersen_hash([ point.x, point.y, partial_address ], GENERATOR_INDEX__CONTRACT_ADDRESS); - Address::from_field(field) + AztecAddress::from_field(field) } pub fn compute_commitment_nonce(first_nullifier : Field, commitment_index : Field) -> Field { - dep::std::hash::pedersen_hash_with_separator([ + pedersen_hash([ first_nullifier, commitment_index ], GENERATOR_INDEX__COMMITMENT_NONCE) } pub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field { - dep::std::hash::pedersen_hash_with_separator([ + pedersen_hash([ nonce, siloed_commitment ], GENERATOR_INDEX__UNIQUE_COMMITMENT) @@ -294,4 +294,8 @@ pub fn compute_unique_siloed_commitments(first_nullifier: Field, siloed_commi } } unique_siloed_commitments +} + +pub fn pedersen_hash(inputs: [Field; N], hash_index: u32) -> Field { + dep::std::hash::pedersen_hash_with_separator(inputs, hash_index) } \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/interop_testing.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/interop_testing.nr index d3140b40e9b..58b7b0cd9a3 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/interop_testing.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/interop_testing.nr @@ -1,7 +1,7 @@ use crate::abis::complete_address::CompleteAddress; use crate::point::Point; use crate::transaction::request::TxRequest; -use crate::address::{Address, EthAddress}; +use crate::address::{AztecAddress, EthAddress}; use crate::transaction::context::TxContext; use crate::abis::function_data::FunctionData; use crate::abis::function_leaf_preimage::FunctionLeafPreimage; @@ -33,7 +33,7 @@ fn compute_complete_address() { #[test] fn compute_tx_request_hash() { let tx_request = TxRequest { - origin : Address::from_field(1), + origin : AztecAddress::from_field(1), args_hash : 3, tx_context : TxContext { is_fee_payment_tx : false, @@ -62,11 +62,11 @@ fn compute_tx_request_hash() { #[test] fn compute_l2_l1_hash() { // All zeroes - let hash_result = compute_l2_to_l1_hash(Address::from_field(0), 0, EthAddress::from_field(0), 0, 0); + let hash_result = compute_l2_to_l1_hash(AztecAddress::from_field(0), 0, EthAddress::from_field(0), 0, 0); assert(hash_result == 0x2266ac2f9f0c19c015239ef5ea85862fc6fac00db73779b220a4d49c4856c2e1); // Non-zero case - let hash_result = compute_l2_to_l1_hash(Address::from_field(1), 2, EthAddress::from_field(3), 4, 5); + let hash_result = compute_l2_to_l1_hash(AztecAddress::from_field(1), 2, EthAddress::from_field(3), 4, 5); assert(hash_result == 0x0f24729168d4450a5681beafa5e3a899ac28bd17bf5a4877dab37bcd834e1634); } @@ -101,7 +101,7 @@ fn compute_function_leaf() { #[test] fn compute_call_stack_item_request() { - let contract_address = Address::from_field(1); + let contract_address = AztecAddress::from_field(1); let function_data = FunctionData { selector: FunctionSelector::from_u32(2), is_internal: false, @@ -124,7 +124,7 @@ fn compute_call_stack_item_request() { #[test] fn compute_call_stack_item() { - let contract_address = Address::from_field(1); + let contract_address = AztecAddress::from_field(1); let function_data = FunctionData { selector: FunctionSelector::from_u32(2), is_internal: false, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr index 90c1376598d..53d1f07fa70 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/lib.nr @@ -7,7 +7,6 @@ mod point; mod contrakt; mod transaction; mod abis; -mod block; mod constants; mod mocked; diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures.nr index 89c5da01d76..48cc27863d2 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures.nr @@ -4,25 +4,21 @@ mod contracts; mod note_hash_tree; mod read_requests; -use crate::address::Address; +use crate::address::AztecAddress; use crate::abis::block_header::BlockHeader; -use crate::block::Block; use crate::point::Point; use crate::tests::fixtures; -global MSG_SENDER = Address { inner: 27 }; +global MSG_SENDER = AztecAddress { inner: 27 }; global DEPLOYER_PUBLIC_KEY = Point { x: 123456789, y: 123456789 }; global BLOCK_HEADER = BlockHeader { + note_hash_tree_root: fixtures::note_hash_tree::ROOT, + nullifier_tree_root: 0, + contract_tree_root: fixtures::contract_tree::ROOT, + l1_to_l2_messages_tree_root: 0, archive_root: 0, - block: Block { - note_hash_tree_root: fixtures::note_hash_tree::ROOT, - nullifier_tree_root: 0, - contract_tree_root: fixtures::contract_tree::ROOT, - l1_to_l2_messages_tree_root: 0, - public_data_tree_root: 0, - global_variables_hash: 0, - }, - private_kernel_vk_tree_root: 0, + public_data_tree_root: 0, + global_variables_hash: 0, }; \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures/contracts.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures/contracts.nr index c5e52943a98..2ac70bcd438 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures/contracts.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures/contracts.nr @@ -1,10 +1,10 @@ use crate::abis::membership_witness::ContractLeafMembershipWitness; -use crate::address::{Address, EthAddress}; +use crate::address::{AztecAddress, EthAddress}; use crate::tests::fixtures; struct ContractData { contract_address_salt: Field, - address: Address, + address: AztecAddress, portal_contract_address: EthAddress, membership_witness: ContractLeafMembershipWitness, function_tree_root: Field, @@ -12,7 +12,7 @@ struct ContractData { global default_contract = ContractData { contract_address_salt: 34567, - address: Address { inner: 12345 }, + address: AztecAddress { inner: 12345 }, portal_contract_address: EthAddress { inner: 23456 }, membership_witness: ContractLeafMembershipWitness { leaf_index: 0, @@ -23,7 +23,7 @@ global default_contract = ContractData { global parent_contract = ContractData { contract_address_salt: 11111, - address: Address { inner: 667788 }, + address: AztecAddress { inner: 667788 }, portal_contract_address: EthAddress { inner: 990011 }, membership_witness: ContractLeafMembershipWitness { leaf_index: 1, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr index 9c4c26dffc6..cdb5d867f96 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr @@ -10,7 +10,7 @@ use crate::{ public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, }, - address::{Address, EthAddress}, + address::{AztecAddress, EthAddress}, hash::NUM_FIELDS_PER_SHA256, mocked::{Proof, VerificationKey}, tests::{ @@ -29,7 +29,7 @@ use crate::constants::{ }; struct PreviousKernelDataBuilder { - contract_address: Address, + contract_address: AztecAddress, portal_contract_address: EthAddress, end: CombinedAccumulatedDataBuilder, block_header: BlockHeader, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/private_call_data_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/private_call_data_builder.nr index 0cb9b217f54..db29a15be9e 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/private_call_data_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/private_call_data_builder.nr @@ -11,7 +11,7 @@ use crate::{ private_circuit_public_inputs::{PrivateCircuitPublicInputs}, private_kernel::private_call_data::PrivateCallData, }, - address::{Address, EthAddress}, + address::{AztecAddress, EthAddress}, hash::NUM_FIELDS_PER_SHA256, mocked::{Proof, VerificationKey}, tests::{ @@ -34,7 +34,7 @@ use crate::constants::{ struct PrivateCallDataBuilder { // Values of PrivateCallStackItem. - contract_address: Address, + contract_address: AztecAddress, public_inputs: PrivateCircuitPublicInputsBuilder, is_execution_request: bool, function_data: FunctionData, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_call_data_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_call_data_builder.nr index 01ee980b65b..f2fb6be2839 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_call_data_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_call_data_builder.nr @@ -7,7 +7,7 @@ use crate::{ public_call_data::PublicCallData, public_circuit_public_inputs::PublicCircuitPublicInputs, }, - address::{Address, EthAddress}, + address::{AztecAddress, EthAddress}, contrakt::{ storage_read::StorageRead, storage_update_request::StorageUpdateRequest, @@ -27,7 +27,7 @@ use crate::constants::{ }; struct PublicCallDataBuilder { - contract_address: Address, + contract_address: AztecAddress, public_inputs: PublicCircuitPublicInputsBuilder, is_execution_request: bool, function_data: FunctionData, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr index 34d3df007c4..99a1096943f 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr @@ -4,7 +4,7 @@ use crate::{ block_header::BlockHeader, public_circuit_public_inputs::PublicCircuitPublicInputs, }, - address::Address, + address::AztecAddress, contrakt::{ storage_read::StorageRead, storage_update_request::StorageUpdateRequest, @@ -36,7 +36,7 @@ struct PublicCircuitPublicInputsBuilder { unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], unencrypted_log_preimages_length: Field, block_header: BlockHeader, - prover_address: Address, + prover_address: AztecAddress, } impl PublicCircuitPublicInputsBuilder { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/request.nr index 89d48366778..f659a81cebd 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/transaction/request.nr @@ -1,10 +1,10 @@ use crate::constants::GENERATOR_INDEX__TX_REQUEST; -use crate::address::Address; +use crate::address::AztecAddress; use crate::transaction::context::TxContext; use crate::abis::function_data::FunctionData; struct TxRequest { - origin : Address, + origin : AztecAddress, args_hash : Field, tx_context : TxContext, function_data : FunctionData diff --git a/yarn-project/noir-protocol-circuits/src/index.test.ts b/yarn-project/noir-protocol-circuits/src/index.test.ts index ee456f8e4fb..d0196cdaf5d 100644 --- a/yarn-project/noir-protocol-circuits/src/index.test.ts +++ b/yarn-project/noir-protocol-circuits/src/index.test.ts @@ -113,7 +113,7 @@ describe('Private kernel', () => { Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), Fr.fromString('0x1759d221795419503f86c032e8f8762f2b739e74835099584b6531f5f27390fe'), - Fr.ZERO, + Fr.ZERO, // TODO(#3441) Fr.fromString('0x0ccaafdc9c353743970d4e305ae73641ce694f07db67886d2769c9ed88e969d8'), Fr.fromString('0x200569267c0f73ac89aaa414239398db9445dd4ad3a8cf37015cd55b8d4c5e8d'), ); @@ -225,7 +225,7 @@ describe('Private kernel', () => { Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), Fr.fromString('0x1759d221795419503f86c032e8f8762f2b739e74835099584b6531f5f27390fe'), - Fr.ZERO, + Fr.ZERO, // TODO(#3441) Fr.fromString('0x0ccaafdc9c353743970d4e305ae73641ce694f07db67886d2769c9ed88e969d8'), Fr.fromString('0x200569267c0f73ac89aaa414239398db9445dd4ad3a8cf37015cd55b8d4c5e8d'), ); diff --git a/yarn-project/noir-protocol-circuits/src/type_conversion.test.ts b/yarn-project/noir-protocol-circuits/src/type_conversion.test.ts index f9cd72f820e..c810d356cde 100644 --- a/yarn-project/noir-protocol-circuits/src/type_conversion.test.ts +++ b/yarn-project/noir-protocol-circuits/src/type_conversion.test.ts @@ -92,7 +92,7 @@ describe('Noir<>Circuits.js type conversion test suite', () => { new Fr(37n), new Fr(38n), new Fr(39n), - new Fr(40n), + new Fr(0n), // TODO(#3441) this currently doesn't exist in Noir is it gets squashed to 0 new Fr(41n), new Fr(42n), ); diff --git a/yarn-project/noir-protocol-circuits/src/type_conversion.ts b/yarn-project/noir-protocol-circuits/src/type_conversion.ts index ebcf5bd5856..986d7a9817c 100644 --- a/yarn-project/noir-protocol-circuits/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits/src/type_conversion.ts @@ -81,7 +81,7 @@ import { FunctionSelector as FunctionSelectorNoir, KernelCircuitPublicInputs as KernelCircuitPublicInputsNoir, NewContractData as NewContractDataNoir, - Address as NoirAztecAddress, + AztecAddress as NoirAztecAddress, EthAddress as NoirEthAddress, Field as NoirField, Point as NoirPoint, @@ -442,16 +442,14 @@ export function mapCallRequestToNoir(callRequest: CallRequest): CallRequestNoir */ export function mapBlockHeaderToNoir(blockHeader: BlockHeader): BlockHeaderNoir { return { + note_hash_tree_root: mapFieldToNoir(blockHeader.noteHashTreeRoot), + nullifier_tree_root: mapFieldToNoir(blockHeader.nullifierTreeRoot), + contract_tree_root: mapFieldToNoir(blockHeader.contractTreeRoot), + l1_to_l2_messages_tree_root: mapFieldToNoir(blockHeader.l1ToL2MessagesTreeRoot), archive_root: mapFieldToNoir(blockHeader.archiveRoot), - block: { - note_hash_tree_root: mapFieldToNoir(blockHeader.noteHashTreeRoot), - nullifier_tree_root: mapFieldToNoir(blockHeader.nullifierTreeRoot), - contract_tree_root: mapFieldToNoir(blockHeader.contractTreeRoot), - l1_to_l2_messages_tree_root: mapFieldToNoir(blockHeader.l1ToL2MessagesTreeRoot), - public_data_tree_root: mapFieldToNoir(blockHeader.publicDataTreeRoot), - global_variables_hash: mapFieldToNoir(blockHeader.globalVariablesHash), - }, - private_kernel_vk_tree_root: mapFieldToNoir(blockHeader.privateKernelVkTreeRoot), + public_data_tree_root: mapFieldToNoir(blockHeader.publicDataTreeRoot), + global_variables_hash: mapFieldToNoir(blockHeader.globalVariablesHash), + // TODO(#3441) }; } @@ -462,14 +460,14 @@ export function mapBlockHeaderToNoir(blockHeader: BlockHeader): BlockHeaderNoir */ export function mapBlockHeaderFromNoir(blockHeader: BlockHeaderNoir): BlockHeader { return new BlockHeader( - mapFieldFromNoir(blockHeader.block.note_hash_tree_root), - mapFieldFromNoir(blockHeader.block.nullifier_tree_root), - mapFieldFromNoir(blockHeader.block.contract_tree_root), - mapFieldFromNoir(blockHeader.block.l1_to_l2_messages_tree_root), + mapFieldFromNoir(blockHeader.note_hash_tree_root), + mapFieldFromNoir(blockHeader.nullifier_tree_root), + mapFieldFromNoir(blockHeader.contract_tree_root), + mapFieldFromNoir(blockHeader.l1_to_l2_messages_tree_root), mapFieldFromNoir(blockHeader.archive_root), - mapFieldFromNoir(blockHeader.private_kernel_vk_tree_root), - mapFieldFromNoir(blockHeader.block.public_data_tree_root), - mapFieldFromNoir(blockHeader.block.global_variables_hash), + Fr.zero(), // TODO(#3441) + mapFieldFromNoir(blockHeader.public_data_tree_root), + mapFieldFromNoir(blockHeader.global_variables_hash), ); } diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts index 73ae45036ae..fc97eb92e9e 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts @@ -7,7 +7,7 @@ export type FixedLengthArray = L extends 0 ? never[] : T[] export type Field = string; export type u32 = string; -export interface Address { +export interface AztecAddress { inner: Field; } @@ -49,15 +49,15 @@ export interface FunctionData { } export interface TxRequest { - origin: Address; + origin: AztecAddress; args_hash: Field; tx_context: TxContext; function_data: FunctionData; } export interface CallContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; portal_contract_address: EthAddress; function_selector: FunctionSelector; is_delegate_call: boolean; @@ -65,21 +65,16 @@ export interface CallContext { is_contract_deployment: boolean; } -export interface Block { +export interface BlockHeader { note_hash_tree_root: Field; nullifier_tree_root: Field; contract_tree_root: Field; l1_to_l2_messages_tree_root: Field; + archive_root: Field; public_data_tree_root: Field; global_variables_hash: Field; } -export interface BlockHeader { - archive_root: Field; - block: Block; - private_kernel_vk_tree_root: Field; -} - export interface PrivateCircuitPublicInputs { call_context: CallContext; args_hash: Field; @@ -103,20 +98,20 @@ export interface PrivateCircuitPublicInputs { } export interface PrivateCallStackItem { - contract_address: Address; + contract_address: AztecAddress; public_inputs: PrivateCircuitPublicInputs; function_data: FunctionData; is_execution_request: boolean; } export interface CallerContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; } export interface CallRequest { hash: Field; - caller_contract_address: Address; + caller_contract_address: AztecAddress; caller_context: CallerContext; } @@ -162,7 +157,7 @@ export interface PrivateKernelInputsInit { export interface AggregationObject {} export interface NewContractData { - contract_address: Address; + contract_address: AztecAddress; portal_contract_address: EthAddress; function_tree_root: Field; } diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts index 1c9123613e5..65ef8c19fab 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts @@ -9,18 +9,18 @@ export type u32 = string; export interface AggregationObject {} -export interface Address { +export interface AztecAddress { inner: Field; } export interface CallerContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; } export interface CallRequest { hash: Field; - caller_contract_address: Address; + caller_contract_address: AztecAddress; caller_context: CallerContext; } @@ -29,7 +29,7 @@ export interface EthAddress { } export interface NewContractData { - contract_address: Address; + contract_address: AztecAddress; portal_contract_address: EthAddress; function_tree_root: Field; } @@ -87,21 +87,16 @@ export interface CombinedAccumulatedData { public_data_reads: FixedLengthArray; } -export interface Block { +export interface BlockHeader { note_hash_tree_root: Field; nullifier_tree_root: Field; contract_tree_root: Field; l1_to_l2_messages_tree_root: Field; + archive_root: Field; public_data_tree_root: Field; global_variables_hash: Field; } -export interface BlockHeader { - archive_root: Field; - block: Block; - private_kernel_vk_tree_root: Field; -} - export interface Point { x: Field; y: Field; @@ -148,8 +143,8 @@ export interface PreviousKernelData { } export interface CallContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; portal_contract_address: EthAddress; function_selector: FunctionSelector; is_delegate_call: boolean; @@ -180,7 +175,7 @@ export interface PrivateCircuitPublicInputs { } export interface PrivateCallStackItem { - contract_address: Address; + contract_address: AztecAddress; public_inputs: PrivateCircuitPublicInputs; function_data: FunctionData; is_execution_request: boolean; diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts index d48a7eb892b..b59356818fa 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts @@ -9,18 +9,18 @@ export type u32 = string; export interface AggregationObject {} -export interface Address { +export interface AztecAddress { inner: Field; } export interface CallerContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; } export interface CallRequest { hash: Field; - caller_contract_address: Address; + caller_contract_address: AztecAddress; caller_context: CallerContext; } @@ -29,7 +29,7 @@ export interface EthAddress { } export interface NewContractData { - contract_address: Address; + contract_address: AztecAddress; portal_contract_address: EthAddress; function_tree_root: Field; } @@ -87,21 +87,16 @@ export interface CombinedAccumulatedData { public_data_reads: FixedLengthArray; } -export interface Block { +export interface BlockHeader { note_hash_tree_root: Field; nullifier_tree_root: Field; contract_tree_root: Field; l1_to_l2_messages_tree_root: Field; + archive_root: Field; public_data_tree_root: Field; global_variables_hash: Field; } -export interface BlockHeader { - archive_root: Field; - block: Block; - private_kernel_vk_tree_root: Field; -} - export interface Point { x: Field; y: Field; diff --git a/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts b/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts index 2d92f904cb5..f0ba294ede2 100644 --- a/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts @@ -9,18 +9,18 @@ export type u32 = string; export interface AggregationObject {} -export interface Address { +export interface AztecAddress { inner: Field; } export interface CallerContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; } export interface CallRequest { hash: Field; - caller_contract_address: Address; + caller_contract_address: AztecAddress; caller_context: CallerContext; } @@ -29,7 +29,7 @@ export interface EthAddress { } export interface NewContractData { - contract_address: Address; + contract_address: AztecAddress; portal_contract_address: EthAddress; function_tree_root: Field; } @@ -87,21 +87,16 @@ export interface CombinedAccumulatedData { public_data_reads: FixedLengthArray; } -export interface Block { +export interface BlockHeader { note_hash_tree_root: Field; nullifier_tree_root: Field; contract_tree_root: Field; l1_to_l2_messages_tree_root: Field; + archive_root: Field; public_data_tree_root: Field; global_variables_hash: Field; } -export interface BlockHeader { - archive_root: Field; - block: Block; - private_kernel_vk_tree_root: Field; -} - export interface Point { x: Field; y: Field; @@ -148,8 +143,8 @@ export interface PreviousKernelData { } export interface CallContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; portal_contract_address: EthAddress; function_selector: FunctionSelector; is_delegate_call: boolean; @@ -181,11 +176,11 @@ export interface PublicCircuitPublicInputs { unencrypted_logs_hash: FixedLengthArray; unencrypted_log_preimages_length: Field; block_header: BlockHeader; - prover_address: Address; + prover_address: AztecAddress; } export interface PublicCallStackItem { - contract_address: Address; + contract_address: AztecAddress; public_inputs: PublicCircuitPublicInputs; function_data: FunctionData; is_execution_request: boolean; diff --git a/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts b/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts index 8a974060677..11118ebb0b3 100644 --- a/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts @@ -9,18 +9,18 @@ export type u32 = string; export interface AggregationObject {} -export interface Address { +export interface AztecAddress { inner: Field; } export interface CallerContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; } export interface CallRequest { hash: Field; - caller_contract_address: Address; + caller_contract_address: AztecAddress; caller_context: CallerContext; } @@ -29,7 +29,7 @@ export interface EthAddress { } export interface NewContractData { - contract_address: Address; + contract_address: AztecAddress; portal_contract_address: EthAddress; function_tree_root: Field; } @@ -87,21 +87,16 @@ export interface CombinedAccumulatedData { public_data_reads: FixedLengthArray; } -export interface Block { +export interface BlockHeader { note_hash_tree_root: Field; nullifier_tree_root: Field; contract_tree_root: Field; l1_to_l2_messages_tree_root: Field; + archive_root: Field; public_data_tree_root: Field; global_variables_hash: Field; } -export interface BlockHeader { - archive_root: Field; - block: Block; - private_kernel_vk_tree_root: Field; -} - export interface Point { x: Field; y: Field; @@ -148,8 +143,8 @@ export interface PreviousKernelData { } export interface CallContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; portal_contract_address: EthAddress; function_selector: FunctionSelector; is_delegate_call: boolean; @@ -181,11 +176,11 @@ export interface PublicCircuitPublicInputs { unencrypted_logs_hash: FixedLengthArray; unencrypted_log_preimages_length: Field; block_header: BlockHeader; - prover_address: Address; + prover_address: AztecAddress; } export interface PublicCallStackItem { - contract_address: Address; + contract_address: AztecAddress; public_inputs: PublicCircuitPublicInputs; function_data: FunctionData; is_execution_request: boolean; diff --git a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts index 9fe5308c761..4ffad0677f6 100644 --- a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts @@ -9,18 +9,18 @@ export type u32 = string; export interface AggregationObject {} -export interface Address { +export interface AztecAddress { inner: Field; } export interface CallerContext { - msg_sender: Address; - storage_contract_address: Address; + msg_sender: AztecAddress; + storage_contract_address: AztecAddress; } export interface CallRequest { hash: Field; - caller_contract_address: Address; + caller_contract_address: AztecAddress; caller_context: CallerContext; } @@ -29,7 +29,7 @@ export interface EthAddress { } export interface NewContractData { - contract_address: Address; + contract_address: AztecAddress; portal_contract_address: EthAddress; function_tree_root: Field; } @@ -87,21 +87,16 @@ export interface CombinedAccumulatedData { public_data_reads: FixedLengthArray; } -export interface Block { +export interface BlockHeader { note_hash_tree_root: Field; nullifier_tree_root: Field; contract_tree_root: Field; l1_to_l2_messages_tree_root: Field; + archive_root: Field; public_data_tree_root: Field; global_variables_hash: Field; } -export interface BlockHeader { - archive_root: Field; - block: Block; - private_kernel_vk_tree_root: Field; -} - export interface Point { x: Field; y: Field;