From 59ca6db2a64f8e0c9f389816a146abc3dd22ba79 Mon Sep 17 00:00:00 2001 From: Dan Lee Date: Wed, 18 Oct 2023 17:46:38 +0100 Subject: [PATCH 1/3] wrap the buttons --- .../blank-react/src/artifacts/Blank.json | 6 +- .../boxes/blank/src/artifacts/Blank.json | 6 +- .../boxes/token/src/app/contract.module.scss | 1 + .../boxes/token/src/artifacts/Token.json | 82 +++++++++---------- 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/yarn-project/boxes/blank-react/src/artifacts/Blank.json b/yarn-project/boxes/blank-react/src/artifacts/Blank.json index 3ea55fe86ec..98550669a69 100644 --- a/yarn-project/boxes/blank-react/src/artifacts/Blank.json +++ b/yarn-project/boxes/blank-react/src/artifacts/Blank.json @@ -37,15 +37,15 @@ "fileMap": { "34": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\n\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)[0]\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)[0]\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n private_data_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.private_data_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)[0]\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n dep::std::hash::pedersen_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n dep::std::hash::pedersen_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = dep::std::hash::pedersen_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS)[0];\n }\n chunks_hashes[i] = chunk_hash;\n }\n dep::std::hash::pedersen_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)[0]\n }\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/abi" }, "35": { "source": "use dep::std::hash;\nuse crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n hash::pedersen_with_separator([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0]\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/address" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/address" }, "58": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKey)]\nfn get_public_key_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_internal(address: Field) -> [Field; 3] {\n get_public_key_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" } } } diff --git a/yarn-project/boxes/blank/src/artifacts/Blank.json b/yarn-project/boxes/blank/src/artifacts/Blank.json index 3ea55fe86ec..98550669a69 100644 --- a/yarn-project/boxes/blank/src/artifacts/Blank.json +++ b/yarn-project/boxes/blank/src/artifacts/Blank.json @@ -37,15 +37,15 @@ "fileMap": { "34": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\n\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)[0]\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)[0]\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n private_data_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.private_data_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)[0]\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n dep::std::hash::pedersen_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n dep::std::hash::pedersen_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = dep::std::hash::pedersen_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS)[0];\n }\n chunks_hashes[i] = chunk_hash;\n }\n dep::std::hash::pedersen_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)[0]\n }\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/abi" }, "35": { "source": "use dep::std::hash;\nuse crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n hash::pedersen_with_separator([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0]\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/address" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/address" }, "58": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKey)]\nfn get_public_key_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_internal(address: Field) -> [Field; 3] {\n get_public_key_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" } } } diff --git a/yarn-project/boxes/token/src/app/contract.module.scss b/yarn-project/boxes/token/src/app/contract.module.scss index d5404d25035..c976043d163 100644 --- a/yarn-project/boxes/token/src/app/contract.module.scss +++ b/yarn-project/boxes/token/src/app/contract.module.scss @@ -17,6 +17,7 @@ display: flex; flex-direction: row; gap: 20px; + flex-wrap: wrap; } .tag { diff --git a/yarn-project/boxes/token/src/artifacts/Token.json b/yarn-project/boxes/token/src/artifacts/Token.json index 152a1b40e75..d5200e45a82 100644 --- a/yarn-project/boxes/token/src/artifacts/Token.json +++ b/yarn-project/boxes/token/src/artifacts/Token.json @@ -274,7 +274,7 @@ ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -1576,7 +1576,7 @@ ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -1852,7 +1852,7 @@ ] } ], - "bytecode": "H4sIAAAAAAAA/+2dCZwd1XXmX3W3WqoutdRa0IroJ7WklhBC3SWJ1VhPxnqITSAQm9gkJDWbkEALiB3JGMxiMGAMGGPAJJPJZDKejCdxPI7tJI6T2B5vkzge2/HEjidxPEkmk8lksju5p9796E9XRYU297pP/3Tv73f73aXqfv9zzq16r269ev2RWq2W1Fqp3eTptSMT+hv2deCtpcHE31gDITnbxghn+xjh7BgjnOPGCGfnGOEcP0Y4J4wRznSMcHaNEc5sjHBOHCOc3WOEc9IY4Zw8Rjh7xgjnlDHCOXWMcE4bI5zTPXLOJs5j7OsM+zrTvs6yr9h2jn2da1+PtTZ22Po8k48zudfkuu2DQ+abvMDkPpMXmrzI5MUm95u8xOSlJh9v8jKTTzB5ucknmrzCjjFocm7ySpNXmbza5JNMPtnkU0w+1eTTTD7d5LeZfIbJbzd5jfXZWpPfYfKZJr/T5HUmN00+y+T1Jp9t8jkmn2vyeSafb/IGky8w+UJrS93astHki0y+2ORNJl9i8qUmX2by5SZfYfJmk680+SqTrzb5GpOvNXmLyVtNvs7kbSZvN3mHyUMmX2/yDSbfaPJNJt9s8k6TbzF5l8m7Tb7V8fltJu8xea/J+2xfj+3bb/LtJt9h8gGT7zT5LpPvNvkek+81+T6T7zf5AZMPmnzI5HeZ/KAz1rtNfsjkh01+j8mPmPyoyY+Z/LjJ7zX5CZOfNPl9Jj9l8tMmP2Py++1YbXasZ03+gNP2nMnP2/IL9vWD9vVF+/oh+/qSff2wfX3Zvr5iX1+tDad7rAHymRPzfFptuA3rBVOpDf1TqA39PdSG/snUhv5J1Ib+bmpD/0RqQ39Gbejvojbuxyv6J1Ab+sdTG/o7qQ3946gN/R3Uhv52akN/G7WhP6E29NccfUkN+zrwFlNnzfs5d0BsHiQ7aiX28vqTa29HiV/GlfiP44F+jhv6Ob7cj1f083xBP88b9PP8Qz/PU/TzfEY/z3v08/GBfj6O0M/HG/r5uET/dGpD/zHUhv4Z1Ib+mdSG/lnUhv7Z1IZ+vNeJXeL7Y229YV8H3lrKRQvvo0iJU29QGfrCMs8vy4CwHGfHmks6vX51inXT4xz7UIdWRgzzArJkJdoBdPLUsVlSVZyZZb5fliLO9RGwzCeWBQFYMOZxpNPnV6eYcwsc+1CHFs+FOrUt+An5AecmjC3vCeeQpudzT+ETPrYaxACtdtrmtJ5hrg22rYv651Ib9oc/ec5xnD3P7UH+fI5xUZ9PfDi+6sQSYs65LPBVX2Bdd673Orop+QOp6hywgHgX+uUdEN1FNH6DNPg8uDiAnxaR7QlpoL2dykPD7nh9O0mY62CW+dVXsh2X5zv7ZNTfF9jmhcTRoDq05Pi+khg8z88i3n0OA+q91L6wxF98rkY/fw5EP39+8TxfB6v4OZ5gqAdkyUq02Q/HKfADGOZTG7YLeV6pkU4HxQE67dT/nWR4uzuJ6Ti/TMXnQJ7jkqrOuxw/v+//g8VnjnkjYOFrj7leWVrX7L7PMzIGn0Pczyl8DuFzbojjZK7jU9SZL7JG1sgaWSNrZI2skTWyHt2sfG+gd5RZMmKYF4xlcCAr0Q5xvcH3fTB2h8lfIE2/91cGB/i+h4xfJwZotdM23yKuL9tyV638foVf1nxbAJ8X1764hkSqut6c6/jKZyzkfub42pHr/fAjONuIwfeav4zB6yfQhI7E2l33Eh/iPiX6ZH58Nxnm9HxfcMT3rvj84PmexQCfE0PfL3qjc2LZ/aJjA7JkJdr+dfIBtlnmfb02fH7i+YfzMh+fntepD7snULMsdVuGFq/X4xwBNl6/xzZ/Zl/leHmajpcQ9/R/3HU13zEd6fcLAn7mKdb4FnkeU8ZYTPxln1vcezqjdV8lskbWyBpZI2tkjayRNbJG1sgaWSNrZI2skTWyRtbIGlnHEivfD5g3yixZ7cj7+f5Z8oGsRLuz5n+9nJ9DxNgdJt9L9y783qNt3QPi+xF1YoBWO23zUfre9EFb5ud/eE54Zt0WwOc5f3ceqep+CX9Hwe+9jfz1e9Tw5SInDuDke9T9Xhla91eWkL3QhI7EGscAtkupzPdol/plK84JzNagOrT4Hu3igCxZiTbfZ+Tn5HrJd8eW+MnvPcDBt3QP0Pf9OveebYM0WNfzPB5kXTzrBQ20873i18hB/cPF12MIZonhwpLtuDzX2Sej/oWBbeZ76A2qQ0vm6PNk68IS7pnEjX5+jwjxfTQ+B9eJgb8bB1t+Us8Iuj7kzx29js/8s7S+G+dq8/fY+Fkn/h5byM8I7vdE5hIXeLCt+xmuTtvw7zHAxoDHxmHnIbDUbbmfePuJoV470v/ttM0n6LPQN+m8734+5vntjlundr9xa81lxGKcw1H22e4z1oZux2ZJ8+0rnwePdbbzH7fW91mYA/7k1KAyx8/ze34xh46n8RukwbrL/OoOsi7ey6CB9nYqf5UctGy4+Pq8BLPEcEnJdlxe7OyTUf+SwDYvJY4G1aElx93nyNYlJdyziBv9mLcytxA3vm5ZEsCWfseWfoeZr2UXB2NpXcu62nz+Cn0eklSvHXmNyde+xxJXuGvf1vX2bIdDNL8b+LuCP87v//B3DPkzh+fnlQ/7jRCMizq0+PupbQFZshLtADoj/v4m/8ZJ2TMSdc9+SGqHP0PeqB35eybsq/aALFmt/LdUPOuM+Ln5un3l3znh64QFnv2Q1A7/PZUG1aHFvuoIyJKVaAfQyX/c35Dha4P5xBf6OrJRK/99CjCMC8hS9jsdmtYv+bor9O/PvJnraWYIxVJ2PR1AJ08dmyVVxYSv7fHZjO/zjNbnUTCMD8hS9nk0gE6eOjZLqooJr22XXeMd79kPVdc70GJfTQjIkpVoB9DJU8dmSVUxgb7sh2vApcR3gmc/8HU2xkUdWuyrNCBLVqIdQCdPHZslVcXkBLJ9uS0vI74TPfshIR2Mizq02FddAVmyEu0AOnnq2CypKibQl/1W2PJy4hvw7IeEdDAu6tBiX2UBWbIS7QA6eerYLKkqJtCX/fC70iuIL/fsh4R0MC7qOcUBDBMDsmQl2gF08tSxWVJVTKAv+6205UHiW+XZDwnpYFzUocW+6g7IkpVoB9DJU8dmSVUxgb7st9qWVxLfSZ79kJAOxkUdWuyrSQFZshLtADp56tgsqSom0Jf9Trbl1cR3imc/JKSDcVGHFvtqckCWrEQ7gE6eOjZLqooJ9GW/U235ZOI7zbMfEtLBuKhDi33VE5AlK9EOoJOnjs2SqmICfdnvdFs+lfje5tkPCelgXNShxb6aEpAlK9EOoJOnjs2SqmICfdnvDFs+nfje7tkPCelgXNShxb6aGpAlK9EOoJOnjs2SqmICfdlvjS2fQXwNz35ISAfjrnE02FfTArJkJdoBdHL2LVJVTFCW/dba8hrie4dnPySkg3FRhxb7anZAlqxEO4BOnjo2S6qKCbO80y/LKmE5cwQs7ySWdX5Zit+JaXoeU8Y4i/hhK9gz6m+SbWf55Sjm+bra4T5Fnfki69HNmlLb2lFm4fPhmeFYVmUl2gF08tSxWVLVuY5jst6W1xHf2X75ipisd1hQhxb7qhmQJSvRDqCTp47NkqpiwiznemVZWXwP7JwRsJxLLOd5ZWm9b51PWuCCTkb9PA/O98tRzMnzHPtRZ77IGlkja2SNrJE1skbWyBpZI2tkjayRNbJG1sgaWSNrZI2skTWyRtbIGlkja2SNrJE1svpnTalt/Siz8HdJzgnGsrL4TSNXO4DNeerYLKnqeyIckw22fB7xXeCXr4jJBocFdWixr5oBWbIS7QA6eerYLKkqJsyy0StL67fqLhwBy0ZiucgrS+t7RBeTFrigk1E/z4OL/XIUc/Iix37UmS+yRtbIGlkja2SNrJE1skbWyBpZI2tkjayRNbJG1sgaWccKa0ptG0aZhdfiLwzG0vrfEq52AJvz1LFZUtU6O8dkky1fRHyX+OUrYrLJYUEdWuyrZkCWrEQ7gE6eOjZLqooJs1zml6X4bZNLR8ByGbFc7peluA9zBWmBCzoZ9fM8uMIvRzEnL3fsR535IuvRzZpS26ZRZuFz16XhWIrfIXG1A+jkqWOzpKrzEsdksy1fTnxX+uUrYrLZYUEdWuyrZkCWrEQ7gE6eOjZLqooJs1ztlaX1f1uvGgHL1cRyjVeW1vvWtaQFLuhk1M/z4Fq/HMWcvMaxH3Xmi6yRNbJG1sgaWSNrZI2sRzdrSm2bR5mFr2WuCsbS+n/xrnYAm/PUsVlS1XUKx2SLLV9DfFv98hUx2eKwoA4t9lUzIEtWoh1AJ2ffIlXFhFm2eWVpXcdeNwKWbcSy3StL6zp2B2mBCzoZ9fM82OGXo5iT2x37UWe+yBpZI2tkjayRNbJG1sh6dLOm1LZllFn4Wua6YCyt61hXO4DNeerYLKnqOoVjMmTL24nver98RUyGHBbUocW+agZkyUq0A+jkqWOzpKqYMMuNAVhuGAHLjcRyk1+W4jr2ZtICF3Qy6ud5cLNfjmJO3uTYjzrzjRXWlNqGRpmFj7EbwrHkWYl2CJ3UsVlS1fHDMdlpyzcR3y1++YqY7HRYUIcW+6oZkCUr0Q6gk6eOzZKqYsIsuwOw7BoBy25iudUvS3F+vY20wAWdjPp5Htzml6OYk7c69qPOfGOFNaW2naPMwsfYrnAsxfnV1Q6hkzo2S6o6fjgme2z5VuLb65eviMkehwV1aLGvmgFZshLtADp56tgsqSom0Jf99tnyHuLb79kPCelgXNShxb5qBmTJSrQD6OSpY7OkqphAX/a73Zb3Ed8dnv2QkA7GRR1a7Ks0IEtWoh1AJ08dmyVVxeQOsv2ALd9OfHd69kNCOhgXdWixr7oCsmQl2gF08tSxWVJVTKAv+91lyweI727PfkhIB+OiDi32VRaQJSvRDqCTp47NkqpiAn3Z7x5bvov47vXsh4R0MC7q91IcwDAxIEtWoh1AJ08dmyVVxQT6st99tnwP8d3v2Q8J6WBc1KHFvuoOyJKVaAfQyVPHZklVMYG+7PeALd9HfAc9+yEhHYyLOrTYV5MCsmQl2gF0cvYtUlVMoC/7HbLlB4jvXZ79kJAOxkUdWuyryQFZshLtADp56tgsqSom0Jf9HrTlQ8T3bs9+SEgH46IOLfZVMyBLVqIdQCdPHZslVcUE+rLfQ7b8IPE97NkPCelgXNShxb5qBmTJSrQD6OSpY7OkqphAX/Z7jy0/RHyPePZDQjoYF3Vosa+aAVmyEu0AOnnq2CypKibQl/0etWXsL3yPOfsMvLVUxORRhwV1aLGvmgFZshLtADp56tgsqSom0Jf9HrflR4nvvZ79kJAOxkUdWuyrZkCWrEQ7gE6eOjZLqooJszzhl6X4LviTdqzHSed9nn2bkA7GRR1a7P8nArJkJdoBdPLUsVlSVZyhL/s9ZctPEt/Tnv2QkA7GRR1a7KsnArJkJdoBdPLUsVlSVUygL/s9Y8tPEd/7PfshIR2Mizq02FdPBGTJSrQD6OSpY7OkqphAX/Z71pafIb4PePZDQjoYF3Vosa+aAVmyEu0AOnnq2CypKibQl/2es+Vnie95z35ISAfjog4t9lUzIEtWoh1AJ08dmyVVxQT6st8Ltvwc8X3Qsx8S0sG4qEOLfdUMyJKVaAfQyVPHZklVMYG+7PeiLb9AfB/y7IeEdDAu6tBiXzUDsmQl2gF08tSxWVJVTKAv+71kyy8S34c9+yEhHYyLOrTYV82ALFmJdgCdPHVsllQVE+jLfi/b8kvE94pnPySkg3FRhxb7qhmQJSvRDqCTs2+RqmLyin2V/V615ZeJ7yOe/ZCQDsZFHVrsq2ZAlqxEO4BOnjo2S6qKCfRlv9ds+VXi+ynPfkhIB+OiDi32VTMgS1aiHUAnTx2bJVXFBPqy30/b8mvE9288+yEhHYyLOrTYV82ALFmJdgCdPHVsllQVE+jLfj9jyz9NfP/Wsx8S0sG4qEOLfdUMyJKVaAfQyVPHZklVMYG+7PeztvwzxPfvPPshIR2Mizq02FfNgCxZiXYAnTx1bJZUFRPoy34/Z8s/S3z/3rMfEtLBuKhDi33VDMiSlWgH0MlTx2ZJVTGBvuz387b8c8T3Hzz7ISEdjIs6tNhXzYAsWYl2AJ08dWyWVBUT6Mt+H7Xlnye+/+jZDwnpYFzUocW+agZkyUq0A+jkqWOzpKqYQF/2+wVb/ijx/SfPfkhIB+OiDi32VTMgS1aiHUAnTx2bJVXFBPqy38ds+ReI7z979kNCOhgXdWixr5oBWbIS7QA6eerYLKkqJszyS35Ziv/t8IsjYPklYvm4X5bimcFfJi1wQSejfp4Hv+yXo5iTH3fsR535IuvRzZpS28dGmYXPXb8YjqX43w6udgCdPHVsllR1XuKYfMKWP058/8UvXxGTTzgsqEOLfdUMyJKVaAfQyVPHZklVMWGWX/HKkhffg/rkCFh+hVg+5ZWl9b71adICF3Qy6ud58Gm/HMWc/JRjP+rMF1kja2SNrJE1skbWyBpZI2tkjayRNbJG1sgaWSNrZI2sY4U1pbZPjDILr8V/MhhLXvymu6sdwOY8dWyWVLXOzjH5jC1/ivh+1S9fEZPPOCyoQ4t91QzIkpVoB9DJ2bdIVTH5VWL5da8srfswvzYCll8nls96ZWndh/kN0gIXdDLq53nwG345ijn5Wcd+1JkvskbWyBpZI2tkjayRNbJG1sgaWSNrZI2skTWyRtbIGlnHCmtKbZ8ZZRZei/+1YCyt+zCudgCb89SxWVLVOjvH5HO2/Fni+02/fEVMPuewoA4t9lUzIEtWoh1AJ08dmyVVxYRZftsry2BxH+a3RsDy28Tyea8srfswXyAtcEEno36eB1/wy1HMyc879qPOfJE1skbWyBpZI2tkjayR9ehmTantc6PMwtcyvxWMZbC4jnW1A9icp47NkqquUzgmX7TlzxPff/XLV8Tkiw4L6tBiXzUDsmQl2gF08tSxWVJVTJjly15ZWtexXxoBy5eJ5SteWVrXsV8lLXBBJ6N+ngdf9ctRzMmvOPajznyRNbJG1sgaWSNrZI2skfXoZk2p7YujzMLXMl8KxtK6jnW1A9icp47NkqquUzgmX7PlrxDff/PLV8Tkaw4L6tBiXzUDsmQl2gF08tSxWVJVTJjld72ytK5jf2cELL9LLF/3ytK6jv090gIXdDLq53nwe345ijn5dcd+1JkvskbWyBpZI2tkjayRNbIe3awptX1tlFn4WuZ3grG0rmNd7QA256ljs6Sq6xSOyTds+evE99/98hUx+YbDgjq02FfNgCxZiXYAnTx1bJZUFRNm+ZZfluL/w3xzBCzfIpZv+2UprmN/n7TABZ2M+nke/L5fjmJOftuxH3Xmi6xHN2tKbd8YZRY+d30zHEvx/2Fc7QA6eerYLKnqvMQx+Y4tf5v4/odfviIm33FYUIcW+6oZkCUr0Q6gk6eOzZKqYsIs3/XLUrxv/cEIWL5LLN/zy1K8b/0haYELOhn18zz4Q78cxZz8nmM/6swXWY9u1pTavjPKLHzu+oNwLMX7lqsdQCdPHZslVZ2XOCbft+XvEd//9MtXxOT7Dgvq0GJfNQOyZCXaAXTy1LFZUlVMmOWPA7D80QhY/phYfuCXpXjf+hPSAhd0MurnefAnfjmKOfkDx37UmW+ssKbU9v1RZuFj7I/CseRZiXYIndSxWVLV8cMx+aEt/4D4/pdfviImP3RYUIcW+6oZkCUr0Q6gk6eOzZKqYgJ92e9PbfmHxPdnnv2QkA7GRR1a7KtmQJasRDuATp46Nkuqign0Zb8/t+U/Jb7/7dkPCelgXNShxb5qBmTJSrQD6OSpY7OkqphAX/b7C1v+c+L7P579kJAOxkUdWuyrZkCWrEQ7gE6eOjZLqooJ9GW/v7TlvyC+/+vZDwnpYFzUocW+agZkyUq0A+jkqWOzpKqYQF/2+ytb/kvi+3+e/ZCQDsZFHVrsq2ZAlqxEO4BOnjo2S6qKCfRlv7+25b8ivv/v2Q8J6WBc1KHFvmoGZMlKtAPo5Kljs6SqmEBf9vsbW/5r4vtbz35ISAfjog4t9lUzIEtWoh1AJ08dmyVVxYRZ/s4vy4CM+fee7ZMx/oH4YSvYM+r/e7LtH/xyFHPr72qH+xR15nuzrG2jzBoq/v/od8xifrNPJVXN738k+/7JM8tEM8b42nBcMb7r2zbi+Wcqox/nnS6Tf1SyHcod1M/nqiTxalcxX+DUBDk5nEV02wLoQmccEGwdWu20zVDaeu2utY4lpPWhfUOpQWVoMctcRSwzFbHMV8SyUhHLIUUsMxSxDCli2aSI5RhFLGsVsSxVxNKniGWeIpYVilhWK2KZo4hliyKWHyli2aCIZZ0ilmWKWBYpYpmliKVXEcugIpbNilimK2JZo4hluSKWfkUsySizpLUj1+FS6v8RtbU5+8paz+6e4f52rPmUjNOeHLkd294RwHbWaVAdWl3EgL7RZOlXxLJcEcsaRSzTFbFsVsQyqIilVxHLLEUsixSxLFPEsk4RywZFLD9SxLJFEcscRSyrFbGsUMQyTxFLnyKWpYpY1ipiOUYRyyZFLEOKWGYoYjmkiGWlIpb5ilhmKmKZq4hlfQnLOL8sxTOCnXbMgseWxxEHmDqJY7xnjsTlIN3xpDshQCwwPr4TBQ5otdM2J3W1XrtD+GGw9Z2+1KuNefFbtl12TIwtbRNL2jKKAeLAqUHlibRfty3z9yUmB5gjPTQXGqQxkdqnBJgjPXS8JqTRQ3ME5XO7hrfFdvhuYbczp+Vlqi232W2mlGwzico8zlQKEJcRR/gno34eq/tf4euk/Rp27IG3lgp/TibWBtWnEs/bu4YZuv0y5OzTDjsu5lB3ONsHeE5gDrtxkfZpAXw+xZnD0JhCcxjlrdb3NdpOUubEqYv8NY3OB2XH5bSA8wjvo5Mdlqpt+HiZVnHsiI09yZHbVfklo/6eN6nD+3QH9ttU5/ib6tgnx8QGOv58n8tljmB9ZjJpbidNv+/1g4XdqXPsgYHf67HNsp5hrhuI64GaT67WOeFgbTgdqA2/j0JLdO/3q1t81/+B2uEpceoNKt9PLPf5ZSk+99zrd8yTZIx7iP8B+wr2jPrvJdvu8ctRzLv7aof7FHXme7Os00eZNVT87/Y7ZjG/2aeSqub33WTfXZ5Z8CzLA3Y8jO/6to0YDvhlKK717iB7oQkdOcXdacu8Hcod1H+AOPf75Szm4O12LHxW2e+wiO6+ALrQwbUgOKDVTts8TNeCb/TsRQjfcGpQGVpv9HzMaLO0KWKZrYhlpiKWKYpYJiliyRSxHFLEMkERyzhFLHcqYhlSxDJDEcsmRSxrFbFMVcSyWhHLCkUsSxWx9ClimaeIZbIilomKWFJFLJ2KWNoVsRxUxDJHEcsWRSwbFLGsU8QyTRFLjyKWQUUsyxSxLFLE0quIpVsRS5cilvGKWDoUscxSxLJZEct0RSxrFLGsV8SyUhHLckUs/YpYklFmeaNnsNF/J7W1Ofu6z2Dvte1tJePsrR25Hdu+J4DtrNOgOrT4Gey9Clj6FbEsV8SyUhHLekUsaxSxTFfEslkRyyxFLB2KWMYrYulSxNKtiKVXEcsiRSzLFLEMKmLpUcQyTRHLOkUsGxSxbFHEMkcRy0FFLO2KWDoVsaSKWCYqYpmsiGWeIpY+RSxLFbGsUMSyWhHLVEUsaxWxbFLEMkMRy5AiljsVsYxTxDJBEcshRSyZIpZJilimKGKZqYhltiKWNkUscxWxzC9huc0vS/Hs56214YR7jbcRB5huJY7dnjkSh+MA6e4mX+12tsE+B+2rXFPuKtnvFmI/QNuwTTf7tamI805iSEiDeW4KoAsdPK8KDmi10zZftm8e3WH8sOqNnoG9MYDdnBpUhtYbPQM72ixtilhmK2KZqYhliiKWSYpYMkUshxSxTFDEMk4Ry5AilhmKWDYpYlmriGWqIpbVilhWKGJZqoilTxHLPEUskxWxTFTEkipi6VTE0q6IZZciloOKWOYoYtmiiGWDIpZ1ilimKWLpUcQyqIhlmSKWRYpYehWxdCti6VLEMl4RS4cillmKWDYrYpmuiGWNIpb1ilhWKmJZroilXxFLMsosaa38GVj030xtbc6+7jOwN9j2tpJxbqgduR3bfn0A21mnQXVo8TOwNyhg6VfEslwRy0pFLOsVsaxRxDJdEctmRSyzFLF0KGIZr4ilSxFLtyKWXkUsixSxLFPEMqiIpUcRyzRFLOsUsWxQxLJFEcscRSwHFbHsUsTSroilUxFLqohloiKWyYpY5ili6VPEslQRywpFLKsVsUxVxLJWEcsmRSwzFLEMKWIZp4hlgiKWQ4pYMkUskxSxTFHEMlMRy2xFLG2KWOYqYplfwrLDL0vxDOz22nDCvcYdxAGm7cSxzTNH4nAcIN1t5KttzjbY56B9leu460r220rsB2gbtukavzYVcb6WGBLSYJ6rA+hCB8/AggNa7bTNDLtgjmdgr/LLU/zPYWjVyB+cGlS+inxzpV+W4n8qX+F3zOJ/al9O/LAV7Bn1X0G2Xe6Xo4j7lbXDfYo6871Z1umjzBoq/pf5HbOY3+xTSVXz+zKy71LPLPif2ogrxnd920Y8F1MZ/Xz+v6RkO5Q7qH8H2bXRr13FfLnIjoVz6UaHhdtw3sM+fN7DNoN03kupnZ+3uMCzHaJzYe3wVDVXLiCW8/2yFO/955EWuKCTUf9G4jjPs08S0sS4qJ9HLEjzw/mk8vte55ewzFXE0qaIZbYilpmKWKYoYpmkiCVTxHJIEcsERSzjFLFcoohlSBHLDEUsmxSxbFTEslYRy1RFLKsVsaxQxLJUEUufIpZ5ilgmK2KZqIglVcTSqYilXRHLHEUsWxSxbFDEsk4RyzRFLD2KWAYVsSxTxLJIEUuvIpZuRSxdiljGK2LpUMQySxHLdYpYNitiWaOIZb0ilpWKWJYrYulXxJKMMssb/Y4C+i+hNtwXvJDa2krGw3UWtpc17Dt6jhwntO2s06A6tPh3FM5TwNKviGW5IpaViljWK2JZo4hlsyKW6xSxzFLE0qGIZbwili5FLN2KWHoVsSxSxLJMEcugIpYeRSzTFLGsU8SyQRHLFkUscxSxtCti6VTEkipimaiIZbIilnmKWPoUsSxVxLJCEctqRSxTFbGsVcSyURHLJkUsMxSxDCliuUQRyzhFLBMUsRxSxJIpYpmkiGWKIpaZilhmK2JpU8QyVxHLfIeF7yny9xjO9cu3SsY827PNwn5O7fBUdW/1bLLvLL8sxfOjTdICF3Qy6j+fOJqefZKQJsZFvUksSPPD+aTyPvdZJSxzFbG0KWKZrYhlpiKWKYpYJiliyRSxHFLEMkERyzhFLEOKWGYoYtmkiGWtIpapilhWK2JZoYhlqSKWPkUs8xSxTFbEMlERS6qIpVMRS7silvMVscxRxLJFEcsGRSzrFLFMU8TSo4hlUBHLMkUsixSx9Cpi6VbE0qWIZbwilg5FLLMUsWxWxLJGEct6RSwrFbEsV8TSr4glGWWWN3pOEv3nUlvTls+htraS8XCdhe3d5ySbPyHbWadBdWjxc5JNBSz9iliWK2JZqYhlvSKWNYpYNitimaWIpUMRy3hFLF2KWLoVsfQqYlmkiGWZIpZBRSw9ilimKWJZp4hlgyKWLYpY5ihiOV8RS7silk5FLKkilomKWCYrYpmniKVPEctSRSwrFLGsVsQyVRHLWkUsmxSxzFDEMqSIZZwilgmKWA4pYskUsUxSxDJFEctMRSyzFbG0KWKZq4hlvsPSRf38na0z/fIV/+P4nbXh1CDdM0n3HX51VyXO+A3ieAe1vz1APDAW/h8nOKDVTtt8zF4UdduYoB2fq6TtDFteR21vc9rEltM92yJjnuo5LnJtfFrt8FR1//dUsu9kvyzF3DyJxm+QBuuu8uxX1k1shgba26n8m7hwpu2YB8wyL04p2Y7Lpzn7ZNR/SmCbT3bYT3b45B7UJ8nWU0q430bc6D+dtjuVymc4/Snts5Zs9TyvCltPcWxFnf2+1rEtAMuqrESb/bBOgR/AEPBYHyzzAx8vc6kN/fOoDcdiL7Vh3s6nttyW+6htwJYXUduJttxPbSfY8lJqO96Wl1HbElteTm2LbXkFtS205UFqW2DLK6mtbsurqe04W15Dbcfa8npqe5ctb6C2B215E7W925Y3U9tDtryF2h625SFqe48t4xpJ5sejttywrwNvLRX/z/yR2uGp6n3pUWJ5zC9L8f/aH/c8pozxXuKHrWDPqP9xsu29fjmKc8JjtcN9ijrzjRXWlNpOoTb08zn3CVs+idqetOVV1PY+W86p7SnYRG1P2/KJ1PaMLR9Hbe+35dOo7VlbPpbaPmDL76K252z5QWp73pbfTW0v2PJD1PZBW36Y2l605Ueo7UO2/Di1vWTLJ1Dbh235eGp72ZaXUNsrtryY2l615YXU9hFbXkBtr9lyndp+ypbfQ224znyM2nA/jOcGvlfzBLVhDexJauu05fdR23hbforasGb1NLXhftMz1Ibvrbyf2rCu8yy14f7QB6gN3zN5jtqwDvM8teGj2gvUhvv8H6Q2rJu8SG1Yw/4QteG+/EvUNt2WP0xtx9jyy9SG9dZXqA1rJK9SG75z9RFqw/rFa9SGe76IvcRCzgepfVPA9QK266L28bbcsH0Dby0V56EJdsxxDge02mmbARuE15/boDeyzJZf56b9OsmGcX5tKK61OsmGCWwT2YBtTiIbhKcjgE/ZLw3yCbR4HmBbOZ63dw37Dp8R+fMjzql8Dq47bWLTfNL2ZRN0MC7q/BkVn2HrxLLAM0tKmkhVn6cWEEufX5biLXMhaYELOhn1TyeOhZ59kpAmxkWd+fpKWHF+48/r/Lz94p8AK+b64sC6ixzdXkc3dfwlqWpu8XN9/X55i/PaEhq/QRr8DN/SAH5aQrYnpIH2dipfhTdm2k4SzlV8Hbq4ZDsuL3T2yah/cWCb+4mjQXVoyfl5Y88wg+f5WcR7scOAei+195f4azH5C/11+5pSP/8+muf5OljFz/EEQ19AlqxEm/1wnAI/gGEhtWG7gOeVUr4ZJb5CG7aV+X8OcbV75io+G3oek6+TkKrO59CfUBu+ptm7b/eerdfvuGjH1u0JDdHhDNdGw3C5nVzaSa5EG7ZF33hb1uSKiYe74rI9N+7bMVJfJOSLhGx1GbwZPJ3E2qx4hzWs04qLcbimzayhcl0g16RyDSqne7nGlGtKuYacTpy4FpdrRjlW5JpQrgHlmk8+28t5Tt4D5bONHOtyDq/XWp+75DOpnP/k2JdjXY4xOfbkPVXeb2QdQtZlZY1C1mJlHUbWX+UDp6y5yvqNrLPK2o6srcq6j6wHyTqRrHXLeozcm5B7GnKvQu4PrrG+XVtr3aeUe4dy31LWyJu11r1TWX89u9Y6zuW5R/mNV/lesKzBXlBr/X9I+c34i0y+uNZah5XfBL/U5MtMvtzkK2qttdgrTb7K5KtNvsbka2ut9dittdbvxG4zebvJO2qtNdnrTb7B5BtNvsnkm03eafItJu8yebfJt5p8m8l7TN5r8j6T95t8u8l3mHzA5DtNvsvku02+x+R7Tb7P5PtNfsDkg7XWeq+sRcnak6w1PVRrrSXJOswjtdYarKy/PG7jLGsssqYiayiyZiJrJLImImsgsuYhaxyypiFrGLJmIWsUsiYhaxCy5iBrDLKm8EqttWaAdRWe/J+2FaxVnL1r+44D9d3799V3D9Wv271/1/a9vPkOOwZuW13cOjbre3fu3lcfqO8yf7fu3Ln7jh3bT6xz3976Lfv37qvv3bd1z7760J7dt9QHT+RxV9tLUEz1bWaUHXvqN+4thrzlxl37duzh7R/qCsPxJXv+xbLUBbfv2DNkxuFtjun+17cZ6A7Dt6JnROFabTfHp+JLt+7cv6O+b/fu+s6te4zk0O499Yu3Du24ZDAf+BesoYFBausCAA==", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -3185,7 +3185,7 @@ "fileMap": { "1": { "source": "// docs:start:token_all\n// docs:start:imports\nmod types;\n\n// Minimal token implementation that supports `AuthWit` accounts.\n// The auth message follows a similar pattern to the cross-chain message and includes a designated caller.\n// The designated caller is ALWAYS used here, and not based on a flag as cross-chain.\n// message hash = H([caller, contract, selector, ...args])\n// To be read as `caller` calls function at `contract` defined by `selector` with `args`\n// Including a nonce in the message hash ensures that the message can only be used once.\n\ncontract Token {\n // Libs\n use dep::std::option::Option;\n\n use dep::safe_math::SafeU120;\n\n use dep::aztec::{\n note::{\n note_getter_options::NoteGetterOptions,\n note_header::NoteHeader,\n utils as note_utils,\n },\n context::{PrivateContext, PublicContext, Context},\n hash::{compute_secret_hash},\n state_vars::{map::Map, public_state::PublicState, set::Set},\n types::type_serialization::{\n field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN},\n bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN},\n aztec_address_serialization::{AztecAddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN},\n },\n types::address::{AztecAddress},\n selector::compute_selector,\n };\n\n // docs:start:import_authwit\n use dep::authwit::{\n auth::{\n assert_current_call_valid_authwit, \n assert_current_call_valid_authwit_public, \n },\n };\n // docs:end:import_authwit\n\n use crate::types::{\n transparent_note::{TransparentNote, TransparentNoteMethods, TRANSPARENT_NOTE_LEN},\n token_note::{TokenNote, TokenNoteMethods, TOKEN_NOTE_LEN},\n balances_map::{BalancesMap},\n safe_u120_serialization::{SafeU120SerializationMethods, SAFE_U120_SERIALIZED_LEN}\n };\n // docs:end::imports\n\n // docs:start:storage_struct\n struct Storage {\n // docs:start:storage_admin\n admin: PublicState,\n // docs:end:storage_admin\n // docs:start:storage_minters\n minters: Map>,\n // docs:end:storage_minters\n // docs:start:storage_balances\n balances: BalancesMap,\n // docs:end:storage_balances\n total_supply: PublicState,\n // docs:start:storage_pending_shields\n pending_shields: Set,\n // docs:end:storage_pending_shields\n public_balances: Map>,\n }\n // docs:end:storage_struct\n\n // docs:start:storage_init\n impl Storage {\n fn init(context: Context) -> pub Self {\n Storage {\n // docs:start:storage_admin_init\n admin: PublicState::new(\n context,\n 1,\n AztecAddressSerializationMethods,\n ),\n // docs:end:storage_admin_init\n // docs:start:storage_minters_init\n minters: Map::new(\n context,\n 2,\n |context, slot| {\n PublicState::new(\n context,\n slot,\n BoolSerializationMethods,\n )\n },\n ),\n // docs:end:storage_minters_init\n balances: BalancesMap::new(context, 3),\n total_supply: PublicState::new(\n context,\n 4,\n SafeU120SerializationMethods,\n ),\n // docs:start:storage_pending_shields_init\n pending_shields: Set::new(context, 5, TransparentNoteMethods),\n // docs:end:storage_pending_shields_init\n public_balances: Map::new(\n context,\n 6,\n |context, slot| {\n PublicState::new(\n context,\n slot,\n SafeU120SerializationMethods,\n )\n },\n ),\n }\n }\n }\n // docs:end:storage_init\n\n // docs:start:constructor\n #[aztec(private)]\n fn constructor(admin: AztecAddress) {\n let selector = compute_selector(\"_initialize((Field))\");\n context.call_public_function(context.this_address(), selector, [admin.address]);\n }\n // docs:end:constructor\n\n // docs:start:set_admin\n #[aztec(public)]\n fn set_admin(\n new_admin: AztecAddress,\n ) {\n assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), \"caller is not admin\");\n // docs:start:write_admin\n storage.admin.write(new_admin);\n // docs:end:write_admin\n }\n // docs:end:set_admin\n\n // docs:start:set_minter\n #[aztec(public)]\n fn set_minter(\n minter: AztecAddress,\n approve: bool,\n ) {\n // docs:start:read_admin\n assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), \"caller is not admin\");\n // docs:end:read_admin\n // docs:start:write_minter\n storage.minters.at(minter.address).write(approve);\n // docs:end:write_minter\n }\n // docs:end:set_minter\n\n // docs:start:mint_public\n #[aztec(public)]\n fn mint_public(\n to: AztecAddress,\n amount: Field,\n ) -> Field {\n // docs:start:read_minter\n assert(storage.minters.at(context.msg_sender()).read(), \"caller is not minter\");\n // docs:end:read_minter\n let amount = SafeU120::new(amount);\n let new_balance = storage.public_balances.at(to.address).read().add(amount);\n let supply = storage.total_supply.read().add(amount);\n\n storage.public_balances.at(to.address).write(new_balance);\n storage.total_supply.write(supply);\n 1\n }\n // docs:end:mint_public\n\n // docs:start:mint_private\n #[aztec(public)]\n fn mint_private(\n amount: Field,\n secret_hash: Field,\n ) -> Field {\n assert(storage.minters.at(context.msg_sender()).read(), \"caller is not minter\");\n let pending_shields = storage.pending_shields;\n let mut note = TransparentNote::new(amount, secret_hash);\n let supply = storage.total_supply.read().add(SafeU120::new(amount));\n\n storage.total_supply.write(supply);\n // docs:start:insert_from_public\n pending_shields.insert_from_public(&mut note);\n // docs:end:insert_from_public\n 1\n }\n // docs:end:mint_private\n\n // docs:start:shield\n #[aztec(public)]\n fn shield(\n from: AztecAddress,\n amount: Field,\n secret_hash: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n // The redeem is only spendable once, so we need to ensure that you cannot insert multiple shields from the same message.\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n\n let pending_shields = storage.pending_shields;\n let mut note = TransparentNote::new(amount.value as Field, secret_hash);\n\n storage.public_balances.at(from.address).write(from_balance);\n pending_shields.insert_from_public(&mut note);\n 1\n }\n // docs:end:shield\n\n // docs:start:transfer_public\n #[aztec(public)]\n fn transfer_public(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n storage.public_balances.at(from.address).write(from_balance);\n\n let to_balance = storage.public_balances.at(to.address).read().add(amount);\n storage.public_balances.at(to.address).write(to_balance);\n\n 1\n }\n // docs:end:transfer_public\n\n // docs:start:burn_public\n #[aztec(public)]\n fn burn_public(\n from: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n storage.public_balances.at(from.address).write(from_balance);\n\n let new_supply = storage.total_supply.read().sub(amount);\n storage.total_supply.write(new_supply);\n\n 1\n }\n // docs:end:burn_public\n\n // docs:start:redeem_shield\n #[aztec(private)]\n fn redeem_shield(\n to: AztecAddress,\n amount: Field,\n secret: Field,\n ) -> Field {\n let pending_shields = storage.pending_shields;\n let secret_hash = compute_secret_hash(secret);\n let options = NoteGetterOptions::new().select(0, amount).select(1, secret_hash).set_limit(1);\n let notes = pending_shields.get_notes(options);\n let note = notes[0].unwrap_unchecked();\n pending_shields.remove(note);\n\n storage.balances.at(to).add(SafeU120::new(amount));\n\n 1\n }\n // docs:end:redeem_shield\n\n // docs:start:unshield\n #[aztec(private)]\n fn unshield(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n storage.balances.at(from).sub(SafeU120::new(amount));\n\n let selector = compute_selector(\"_increase_public_balance((Field),Field)\");\n let _void = context.call_public_function(context.this_address(), selector, [to.address, amount]);\n\n 1\n }\n // docs:end:unshield\n\n // docs:start:transfer\n #[aztec(private)]\n fn transfer(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n storage.balances.at(from).sub(amount);\n storage.balances.at(to).add(amount);\n\n 1\n }\n // docs:end:transfer\n\n // docs:start:burn\n #[aztec(private)]\n fn burn(\n from: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n storage.balances.at(from).sub(SafeU120::new(amount));\n\n let selector = compute_selector(\"_reduce_total_supply(Field)\");\n let _void = context.call_public_function(context.this_address(), selector, [amount]);\n\n 1\n }\n // docs:end:burn\n\n // docs:start:initialize\n #[aztec(public)]\n internal fn _initialize(\n new_admin: AztecAddress,\n ) {\n storage.admin.write(new_admin);\n storage.minters.at(new_admin.address).write(true);\n }\n // docs:end:initialize\n\n /// Internal ///\n\n // docs:start:increase_public_balance\n #[aztec(public)]\n internal fn _increase_public_balance(\n to: AztecAddress,\n amount: Field,\n ) {\n let new_balance = storage.public_balances.at(to.address).read().add(SafeU120::new(amount));\n storage.public_balances.at(to.address).write(new_balance);\n }\n // docs:end:increase_public_balance\n\n // docs:start:reduce_total_supply\n #[aztec(public)]\n internal fn _reduce_total_supply(\n amount: Field,\n ) {\n // Only to be called from burn.\n let new_supply = storage.total_supply.read().sub(SafeU120::new(amount));\n storage.total_supply.write(new_supply);\n }\n // docs:end:reduce_total_supply\n\n /// Unconstrained ///\n\n // docs:start:admin\n unconstrained fn admin() -> Field {\n storage.admin.read().address\n }\n // docs:end:admin\n\n // docs:start:is_minter\n unconstrained fn is_minter(\n minter: AztecAddress,\n ) -> bool {\n storage.minters.at(minter.address).read()\n }\n // docs:end:is_minter\n\n // docs:start:total_supply\n unconstrained fn total_supply() -> u120 {\n storage.total_supply.read().value\n }\n // docs:end:total_supply\n\n // docs:start:balance_of_private\n unconstrained fn balance_of_private(\n owner: AztecAddress,\n ) -> u120 {\n storage.balances.at(owner).balance_of().value\n }\n // docs:end:balance_of_private\n\n // docs:start:balance_of_public\n unconstrained fn balance_of_public(\n owner: AztecAddress,\n ) -> u120 {\n storage.public_balances.at(owner.address).read().value\n }\n // docs:end:balance_of_public\n\n // Below this point is the stuff of nightmares.\n // This should ideally not be required. What do we do if vastly different types of preimages?\n\n // docs:start:compute_note_hash_and_nullifier\n // Computes note hash and nullifier.\n // Note 1: Needs to be defined by every contract producing logs.\n // 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.\n unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; TOKEN_NOTE_LEN]) -> [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n if (storage_slot == 5) {\n note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, preimage)\n } else {\n note_utils::compute_note_hash_and_nullifier(TokenNoteMethods, note_header, preimage)\n }\n }\n // docs:end:compute_note_hash_and_nullifier\n}\n// docs:end:token_all\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/main" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/main" }, "6": { "source": "mod poseidon;\n\n#[foreign(sha256)]\npub fn sha256(_input : [u8; N]) -> [u8; 32] {}\n\n#[foreign(blake2s)]\npub fn blake2s(_input : [u8; N]) -> [u8; 32] {}\n\npub fn pedersen(input : [Field; N]) -> [Field; 2] {\n pedersen_with_separator(input, 0)\n}\n\n#[foreign(pedersen)]\npub fn pedersen_with_separator(_input : [Field; N], _separator : u32) -> [Field; 2] {}\n\n#[foreign(hash_to_field_128_security)]\npub fn hash_to_field(_input : [Field; N]) -> Field {}\n\n#[foreign(keccak256)]\npub fn keccak256(_input : [u8; N], _message_size: u32) -> [u8; 32] {}\n\n// mimc-p/p implementation\n// constants are (publicly generated) random numbers, for instance using keccak as a ROM.\n// You must use constants generated for the native field\n// Rounds number should be ~ log(p)/log(exp)\n// For 254 bit primes, exponent 7 and 91 rounds seems to be recommended\nfn mimc(x: Field, k: Field, constants: [Field; N], exp : Field) -> Field {\n //round 0\n let mut t = x + k;\n let mut h = t.pow_32(exp);\n //next rounds\n for i in 1 .. constants.len() {\n t = h + k + constants[i];\n h = t.pow_32(exp);\n };\n h + k\n}\n\nglobal MIMC_BN254_ROUNDS = 91;\n\n//mimc implementation with hardcoded parameters for BN254 curve.\npub fn mimc_bn254(array: [Field; N]) -> Field {\n //mimc parameters\n let exponent = 7;\n //generated from seed \"mimc\" using keccak256 \n let constants: [Field; MIMC_BN254_ROUNDS] = [\n 0, \n 20888961410941983456478427210666206549300505294776164667214940546594746570981,\n 15265126113435022738560151911929040668591755459209400716467504685752745317193,\n 8334177627492981984476504167502758309043212251641796197711684499645635709656,\n 1374324219480165500871639364801692115397519265181803854177629327624133579404,\n 11442588683664344394633565859260176446561886575962616332903193988751292992472,\n 2558901189096558760448896669327086721003508630712968559048179091037845349145,\n 11189978595292752354820141775598510151189959177917284797737745690127318076389,\n 3262966573163560839685415914157855077211340576201936620532175028036746741754,\n 17029914891543225301403832095880481731551830725367286980611178737703889171730,\n 4614037031668406927330683909387957156531244689520944789503628527855167665518,\n 19647356996769918391113967168615123299113119185942498194367262335168397100658,\n 5040699236106090655289931820723926657076483236860546282406111821875672148900,\n 2632385916954580941368956176626336146806721642583847728103570779270161510514,\n 17691411851977575435597871505860208507285462834710151833948561098560743654671,\n 11482807709115676646560379017491661435505951727793345550942389701970904563183,\n 8360838254132998143349158726141014535383109403565779450210746881879715734773,\n 12663821244032248511491386323242575231591777785787269938928497649288048289525,\n 3067001377342968891237590775929219083706800062321980129409398033259904188058,\n 8536471869378957766675292398190944925664113548202769136103887479787957959589,\n 19825444354178182240559170937204690272111734703605805530888940813160705385792,\n 16703465144013840124940690347975638755097486902749048533167980887413919317592,\n 13061236261277650370863439564453267964462486225679643020432589226741411380501,\n 10864774797625152707517901967943775867717907803542223029967000416969007792571,\n 10035653564014594269791753415727486340557376923045841607746250017541686319774,\n 3446968588058668564420958894889124905706353937375068998436129414772610003289,\n 4653317306466493184743870159523234588955994456998076243468148492375236846006,\n 8486711143589723036499933521576871883500223198263343024003617825616410932026,\n 250710584458582618659378487568129931785810765264752039738223488321597070280,\n 2104159799604932521291371026105311735948154964200596636974609406977292675173,\n 16313562605837709339799839901240652934758303521543693857533755376563489378839,\n 6032365105133504724925793806318578936233045029919447519826248813478479197288,\n 14025118133847866722315446277964222215118620050302054655768867040006542798474,\n 7400123822125662712777833064081316757896757785777291653271747396958201309118,\n 1744432620323851751204287974553233986555641872755053103823939564833813704825,\n 8316378125659383262515151597439205374263247719876250938893842106722210729522,\n 6739722627047123650704294650168547689199576889424317598327664349670094847386,\n 21211457866117465531949733809706514799713333930924902519246949506964470524162,\n 13718112532745211817410303291774369209520657938741992779396229864894885156527,\n 5264534817993325015357427094323255342713527811596856940387954546330728068658,\n 18884137497114307927425084003812022333609937761793387700010402412840002189451,\n 5148596049900083984813839872929010525572543381981952060869301611018636120248,\n 19799686398774806587970184652860783461860993790013219899147141137827718662674,\n 19240878651604412704364448729659032944342952609050243268894572835672205984837,\n 10546185249390392695582524554167530669949955276893453512788278945742408153192,\n 5507959600969845538113649209272736011390582494851145043668969080335346810411,\n 18177751737739153338153217698774510185696788019377850245260475034576050820091,\n 19603444733183990109492724100282114612026332366576932662794133334264283907557,\n 10548274686824425401349248282213580046351514091431715597441736281987273193140,\n 1823201861560942974198127384034483127920205835821334101215923769688644479957,\n 11867589662193422187545516240823411225342068709600734253659804646934346124945,\n 18718569356736340558616379408444812528964066420519677106145092918482774343613,\n 10530777752259630125564678480897857853807637120039176813174150229243735996839,\n 20486583726592018813337145844457018474256372770211860618687961310422228379031,\n 12690713110714036569415168795200156516217175005650145422920562694422306200486,\n 17386427286863519095301372413760745749282643730629659997153085139065756667205,\n 2216432659854733047132347621569505613620980842043977268828076165669557467682,\n 6309765381643925252238633914530877025934201680691496500372265330505506717193,\n 20806323192073945401862788605803131761175139076694468214027227878952047793390,\n 4037040458505567977365391535756875199663510397600316887746139396052445718861,\n 19948974083684238245321361840704327952464170097132407924861169241740046562673,\n 845322671528508199439318170916419179535949348988022948153107378280175750024,\n 16222384601744433420585982239113457177459602187868460608565289920306145389382,\n 10232118865851112229330353999139005145127746617219324244541194256766741433339,\n 6699067738555349409504843460654299019000594109597429103342076743347235369120,\n 6220784880752427143725783746407285094967584864656399181815603544365010379208,\n 6129250029437675212264306655559561251995722990149771051304736001195288083309,\n 10773245783118750721454994239248013870822765715268323522295722350908043393604,\n 4490242021765793917495398271905043433053432245571325177153467194570741607167,\n 19596995117319480189066041930051006586888908165330319666010398892494684778526,\n 837850695495734270707668553360118467905109360511302468085569220634750561083,\n 11803922811376367215191737026157445294481406304781326649717082177394185903907,\n 10201298324909697255105265958780781450978049256931478989759448189112393506592,\n 13564695482314888817576351063608519127702411536552857463682060761575100923924,\n 9262808208636973454201420823766139682381973240743541030659775288508921362724,\n 173271062536305557219323722062711383294158572562695717740068656098441040230,\n 18120430890549410286417591505529104700901943324772175772035648111937818237369,\n 20484495168135072493552514219686101965206843697794133766912991150184337935627,\n 19155651295705203459475805213866664350848604323501251939850063308319753686505,\n 11971299749478202793661982361798418342615500543489781306376058267926437157297,\n 18285310723116790056148596536349375622245669010373674803854111592441823052978,\n 7069216248902547653615508023941692395371990416048967468982099270925308100727,\n 6465151453746412132599596984628739550147379072443683076388208843341824127379,\n 16143532858389170960690347742477978826830511669766530042104134302796355145785,\n 19362583304414853660976404410208489566967618125972377176980367224623492419647,\n 1702213613534733786921602839210290505213503664731919006932367875629005980493,\n 10781825404476535814285389902565833897646945212027592373510689209734812292327,\n 4212716923652881254737947578600828255798948993302968210248673545442808456151,\n 7594017890037021425366623750593200398174488805473151513558919864633711506220,\n 18979889247746272055963929241596362599320706910852082477600815822482192194401,\n 13602139229813231349386885113156901793661719180900395818909719758150455500533,\n ];\n\n let mut r = 0;\n for elem in array {\n let h = mimc(elem, r, constants, exponent);\n r = r + elem + h;\n }\n r\n}\n", @@ -3209,151 +3209,151 @@ }, "37": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\n\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)[0]\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)[0]\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n private_data_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.private_data_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)[0]\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n dep::std::hash::pedersen_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n dep::std::hash::pedersen_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = dep::std::hash::pedersen_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS)[0];\n }\n chunks_hashes[i] = chunk_hash;\n }\n dep::std::hash::pedersen_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)[0]\n }\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/abi" }, "38": { "source": "use dep::std::hash;\nuse crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n hash::pedersen_with_separator([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0]\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/address" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/address" }, "40": { "source": "use crate::constants_gen::{\n EMPTY_NULLIFIED_COMMITMENT,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n};\n\nuse crate::abi;\n\nuse crate::abi::{\n hash_args,\n CallContext,\n ContractDeploymentData,\n HistoricBlockData,\n FunctionData,\n PrivateCircuitPublicInputs,\n PublicCircuitPublicInputs,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// l1 to l2 messaging\nuse crate::messaging::process_l1_to_l2_message;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem;\n\nuse crate::types::{\n vec::BoundedVec,\n point::Point,\n};\n\nuse crate::utils::arr_copy_slice;\n\nuse crate::oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n};\n\nuse dep::std::option::Option;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: abi::PrivateContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n pending_read_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n nullified_commitments: BoundedVec,\n\n private_call_stack : BoundedVec,\n public_call_stack : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n block_data: HistoricBlockData,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: abi::PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(0),\n pending_read_requests: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n nullified_commitments: BoundedVec::new(0),\n\n block_data: inputs.block_data,\n\n private_call_stack: BoundedVec::new(0),\n public_call_stack: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> Field {\n self.inputs.call_context.function_selector\n }\n\n pub fn finish(self) -> abi::PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = abi::PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n pending_read_requests: self.pending_read_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n nullified_commitments: self.nullified_commitments.storage,\n private_call_stack: self.private_call_stack.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.block_data,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n self.read_requests.push(read_request);\n }\n\n pub fn push_pending_read_request(&mut self, pending_read_request: Field) {\n self.pending_read_requests.push(pending_read_request);\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n // We never push a zero nullified_commitment as zero is used to indicate the end\n // of a field array in private kernel. This routine transparently replaces a\n // zero value into the special placeholder: EMPTY_NULLIFIED_COMMITMENT.\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n let mut non_zero_nullified = nullified_commitment;\n if (non_zero_nullified == 0) {\n non_zero_nullified = EMPTY_NULLIFIED_COMMITMENT;\n }\n self.nullified_commitments.push(non_zero_nullified);\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) \n // docs:end:context_message_portal\n {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n msg_key: Field,\n content: Field,\n secret: Field\n ) \n // docs:end:context_consume_l1_to_l2_message\n {\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, self.this_address(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PrivateCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n function_selector: fields[8], // practically same as fields[1]\n is_delegate_call : fields[9] as bool,\n is_static_call : fields[10] as bool,\n is_contract_deployment: fields[11] as bool,\n },\n // TODO handle the offsets as a variable incremented during extraction?\n args_hash: fields[12],\n return_values: arr_copy_slice(fields, [0; RETURN_VALUES_LENGTH], 13),\n read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 17),\n pending_read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 49),\n new_commitments: arr_copy_slice(fields, [0; MAX_NEW_COMMITMENTS_PER_CALL], 81),\n new_nullifiers: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 97),\n nullified_commitments: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 113),\n private_call_stack: arr_copy_slice(fields, [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], 129),\n public_call_stack: arr_copy_slice(fields, [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], 133),\n new_l2_to_l1_msgs: arr_copy_slice(fields, [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], 137),\n encrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 139),\n unencrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 141),\n encrypted_log_preimages_length: fields[143],\n unencrypted_log_preimages_length: fields[144],\n block_data: HistoricBlockData {\n // Must match order in `private_circuit_public_inputs.hpp`\n private_data_tree_root : fields[145],\n nullifier_tree_root : fields[146],\n contract_tree_root : fields[147],\n l1_to_l2_messages_tree_root : fields[148],\n blocks_tree_root : fields[149],\n public_data_tree_root: fields[150],\n global_variables_hash: fields[151],\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: Point::new(fields[152], fields[153]),\n constructor_vk_hash : fields[154],\n function_tree_root : fields[155],\n contract_address_salt : fields[156],\n portal_contract_address : fields[157],\n },\n chain_id: fields[158],\n version: fields[159],\n },\n is_execution_request: fields[160] as bool,\n };\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.private_call_stack.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PublicCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n function_selector: fields[8], // practically same as fields[1]\n is_delegate_call : fields[9] as bool,\n is_static_call : fields[10] as bool,\n is_contract_deployment: fields[11] as bool,\n },\n args_hash: fields[12],\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [0; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [0; MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_data: HistoricBlockData::empty(),\n prover_address: 0,\n },\n is_execution_request: true,\n };\n\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.public_call_stack.push(item.hash());\n }\n}\n\nuse crate::abi::{\n ContractStorageRead,\n ContractStorageUpdateRequest\n};\n\nstruct PublicContext {\n inputs: abi::PublicContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_read: BoundedVec,\n public_call_stack: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicContext {\n pub fn new(inputs: abi::PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = ContractStorageRead::empty();\n let empty_storage_update = ContractStorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_read: BoundedVec::new(empty_storage_read),\n public_call_stack: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_data: inputs.block_data,\n prover_address: 0,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n pub fn selector(self) -> Field {\n self.inputs.call_context.function_selector\n }\n\n pub fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n pub fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n pub fn finish(self) -> abi::PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = abi::PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_read: self.contract_storage_read.storage,\n return_values: self.return_values.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.inputs.block_data,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n }\n\n pub fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, this, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_public_function(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = abi::hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n pub fn call_public_function_no_args(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context {\n private: Option::some(context),\n public: Option::none()\n }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context {\n public: Option::some(context),\n private: Option::none()\n }\n }\n\n pub fn none() -> Context {\n Context {\n public: Option::none(),\n private: Option::none()\n }\n }\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/context" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/context" }, "41": { "source": "use dep::std::hash::{pedersen_with_separator, sha256};\nuse crate::constants_gen::{\n GENERATOR_INDEX__SIGNATURE_PAYLOAD,\n GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET,\n};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n // TODO(#1205) This is probably not the right index to use\n pedersen_with_separator([secret], GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET)[0]\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/hash" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/hash" }, "42": { "source": "use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse crate::types::point::Point;\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n log: [Field; N],\n) {\n let _ = oracle::logs::emit_encrypted_log(contract_address, storage_slot, encryption_pub_key, log);\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(\n context: &mut PublicContext,\n log: T,\n) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(\n context: &mut PrivateContext,\n log: T,\n) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/log" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/log" }, "47": { "source": "use dep::std::option::Option;\nuse crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\nuse crate::constants_gen::EMPTY_NULLIFIED_COMMITMENT;\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialize = note_interface.serialize;\n let preimage = serialize(*note);\n assert(notify_created_note(storage_slot, preimage, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(\n context: &mut PrivateContext,\n note: Note,\n note_interface: NoteInterface,\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = EMPTY_NULLIFIED_COMMITMENT;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // `nullified_commitment` is used to inform the kernel which pending commitment\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(nullifier, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/lifecycle" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/lifecycle" }, "48": { "source": "use dep::std::option::Option;\nuse crate::constants_gen::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n};\nuse crate::oracle;\nuse crate::types::vec::BoundedVec;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: Note,\n) {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n let contract_address = context.this_address();\n assert(header.contract_address == contract_address);\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(\n fields: [Field; N],\n selects: BoundedVec, N>,\n) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n assert(fields[select.field_index] == select.value, \"Mismatch return note field.\");\n }\n}\n\nfn check_notes_order(fields_0: [Field; N], fields_1: [Field; N], sorts: BoundedVec, N>) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let note = get_note_internal(storage_slot, note_interface);\n\n check_note_header(*context, storage_slot, note_interface, note);\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let opt_notes = get_notes_internal(storage_slot, note_interface, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let serialize = note_interface.serialize;\n let fields = serialize(note);\n check_note_header(*context, storage_slot, note_interface, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n };\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n 0,\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n placeholder_note,\n placeholder_fields,\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteViewerOptions,\n) -> [Option; MAX_NOTES_PER_PAGE] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>,\n) -> (u8, [u8; N], [Field; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n num_selects += 1;\n };\n };\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n };\n\n (num_selects, select_by, select_values, sort_by, sort_order)\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_getter" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/note_getter" }, "50": { "source": "use dep::std::hash::{pedersen, pedersen_with_separator};\nuse crate::constants_gen::{GENERATOR_INDEX__UNIQUE_COMMITMENT, GENERATOR_INDEX__SILOED_COMMITMENT};\n\npub fn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen([storage_slot, note_hash])[0]\n}\n\npub fn compute_siloed_hash(contract_address: Field, inner_note_hash: Field) -> Field {\n let inputs = [contract_address, inner_note_hash];\n pedersen_with_separator(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)[0]\n}\n\npub fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_with_separator(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)[0]\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_hash" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/note_hash" }, "53": { "source": "use dep::std::option::Option;\nuse crate::constants_gen::MAX_NOTES_PER_PAGE;\nuse crate::note::note_getter_options::{Select, Sort};\nuse crate::types::vec::BoundedVec;\n\n// docs:start:NoteViewerOptions\nstruct NoteViewerOptions {\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>,\n limit: u32,\n offset: u32,\n}\n// docs:end:NoteViewerOptions\n\nimpl NoteViewerOptions {\n pub fn new() -> NoteViewerOptions {\n NoteViewerOptions {\n selects: BoundedVec::new(Option::none()),\n sorts: BoundedVec::new(Option::none()),\n limit: MAX_NOTES_PER_PAGE as u32,\n offset: 0,\n }\n }\n\n pub fn select(&mut self, field_index: u8, value: Field) -> Self {\n self.selects.push(Option::some(Select::new(field_index, value)));\n *self\n }\n\n pub fn sort(&mut self, field_index: u8, order: u2) -> Self {\n self.sorts.push(Option::some(Sort::new(field_index, order)));\n *self\n }\n\n pub fn set_limit(&mut self, limit: u32) -> Self {\n assert(limit <= MAX_NOTES_PER_PAGE as u32);\n self.limit = limit;\n *self\n }\n\n pub fn set_offset(&mut self, offset: u32) -> Self {\n self.offset = offset;\n *self\n }\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_viewer_options" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/note_viewer_options" }, "54": { "source": "use crate::note::{\n note_hash::{compute_inner_hash, compute_siloed_hash, compute_unique_hash},\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\npub fn compute_inner_note_hash(\n note_interface: NoteInterface,\n note: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n\n compute_inner_hash(header.storage_slot, note_hash)\n}\n\npub fn compute_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let inner_note_hash = compute_inner_note_hash(note_interface, note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\npub fn compute_unique_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let siloed_note_hash = compute_siloed_note_hash(note_interface, note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_note_hash_for_read_or_nullify(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note_interface, note_with_header)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note_interface, note_with_header)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note_interface, note_with_header)\n }\n\n}\n\npub fn compute_note_hash_and_nullifier(\n note_interface: NoteInterface,\n note_header: NoteHeader,\n preimage: [Field; S],\n) -> [Field; 4] {\n let deserialize = note_interface.deserialize;\n let set_header = note_interface.set_header;\n let mut note = deserialize(arr_copy_slice(preimage, [0; N], 0));\n set_header(&mut note, note_header);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n let inner_note_hash = compute_inner_hash(note_header.storage_slot, note_hash);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let compute_nullifier = note_interface.compute_nullifier;\n let inner_nullifier = compute_nullifier(note);\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/utils" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/utils" }, "56": { "source": "#[oracle(packArguments)]\nfn pack_arguments_oracle(_args: [Field; N]) -> Field {}\n\n// TODO: explain what this does.\nunconstrained pub fn pack_arguments(args: [Field; N]) -> Field {\n pack_arguments_oracle(args)\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/arguments" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/arguments" }, "57": { "source": "use crate::constants_gen::CALL_PRIVATE_FUNCTION_RETURN_SIZE;\n\n#[oracle(callPrivateFunction)]\nfn call_private_function_oracle(\n _contract_address: Field,\n _function_selector: Field,\n _args_hash: Field\n) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {}\n\nunconstrained pub fn call_private_function_internal(\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {\n call_private_function_oracle(\n contract_address,\n function_selector,\n args_hash,\n )\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/call_private_function" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/call_private_function" }, "61": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKey)]\nfn get_public_key_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_internal(address: Field) -> [Field; 3] {\n get_public_key_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" }, "62": { "source": "use crate::oracle::get_public_key::get_public_key;\nuse crate::types::point::Point;\n\n#[oracle(getSecretKey)]\nfn get_secret_key_oracle(\n _owner: Point,\n) -> [Field; dep::std::grumpkin_scalar::GRUMPKIN_SCALAR_SERIALIZED_LEN] {\n}\n\nunconstrained fn get_secret_key_internal(owner_public_key: Point) -> dep::std::grumpkin_scalar::GrumpkinScalar {\n dep::std::grumpkin_scalar::deserialize_grumpkin_scalar(get_secret_key_oracle(owner_public_key))\n}\n\npub fn get_secret_key(owner: Field) -> dep::std::grumpkin_scalar::GrumpkinScalar {\n let owner_public_key = get_public_key(owner);\n let secret = get_secret_key_internal(owner_public_key);\n\n // Constrain the owner - Nullifier secret key is currently just the encryption private key so we can constrain\n // the owner by deriving the public key from the secret key and checking the result.\n let computed_public_key = dep::std::grumpkin_scalar_mul::grumpkin_fixed_base(secret);\n assert(owner_public_key.x == computed_public_key[0]);\n assert(owner_public_key.y == computed_public_key[1]);\n\n secret\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key" }, "63": { "source": "\n\n#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/rand" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/rand" }, "64": { "source": "\n// contract_address + \n// args_hash +\n// crate::abi::FUNCTION_DATA_SIZE +\n// crate::abi::CALL_CONTEXT_SIZE +\n// = 2 + 4 + 7\nglobal ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE: Field = 13;\n\n#[oracle(enqueuePublicFunctionCall)]\nfn enqueue_public_function_call_oracle(\n _contract_address: Field, \n _function_selector: Field, \n _args_hash: Field,\n) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {}\n\nunconstrained pub fn enqueue_public_function_call_internal(\n contract_address: Field, \n function_selector: Field,\n args_hash: Field\n) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {\n enqueue_public_function_call_oracle(\n contract_address, \n function_selector, \n args_hash,\n )\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call" }, "65": { "source": "use crate::constants_gen::RETURN_VALUES_LENGTH;\n\n#[oracle(callPublicFunction)]\nfn call_public_function_oracle(\n _contract_address: Field, \n _function_selector: Field, \n _args_hash: Field\n) -> [Field; RETURN_VALUES_LENGTH] {}\n\nunconstrained pub fn call_public_function_internal(\n contract_address: Field, \n function_selector: Field,\n args_hash: Field\n) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_oracle(\n contract_address, \n function_selector, \n args_hash,\n )\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/public_call" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/public_call" }, "66": { "source": "use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _preimage: [Field; N],\n _inner_note_hash: Field,\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n preimage: [Field; N],\n inner_note_hash: Field,\n) -> Field {\n notify_created_note_oracle(storage_slot, preimage, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(\n _nullifier: Field,\n _inner_note_hash: Field,\n) -> Field {}\n\nunconstrained pub fn notify_nullified_note(\n nullifier: Field,\n inner_note_hash: Field,\n) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _return_size: u32,\n _placeholder_fields: [Field; S],\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n mut placeholder_fields: [Field; S],\n)-> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(storage_slot, num_selects, select_by, select_values, sort_by, sort_order, limit, offset, return_size, placeholder_fields)\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n) -> [Option; S] {\n let fields = get_notes_oracle_wrapper(storage_slot, num_selects, select_by, select_values, sort_by, sort_order, limit, offset, placeholder_fields);\n let num_notes = fields[0] as u32;\n let contract_address = fields[1];\n let deserialize = note_interface.deserialize;\n let set_header = note_interface.set_header;\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let preimage = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = deserialize(preimage);\n set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n };\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(\n _inner_nullifier: Field,\n) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/notes" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/notes" }, "67": { "source": "\n#[oracle(storageRead)]\nfn storage_read_oracle(\n _storage_slot: Field,\n _number_of_elements: Field,\n) -> [Field; N] {}\n\nunconstrained fn storage_read_oracle_wrapper(_storage_slot: Field)-> [Field; N] {\n storage_read_oracle(_storage_slot, N)\n}\n\npub fn storage_read(\n storage_slot: Field,\n deserialize: fn ([Field; N]) -> T,\n) -> T {\n let fields = storage_read_oracle_wrapper(storage_slot);\n deserialize(fields)\n}\n\n#[oracle(storageWrite)]\nfn storage_write_oracle(\n _storage_slot: Field,\n _values: [Field; N],\n) -> [Field; N] {}\n\n// TODO: Remove return value.\nunconstrained pub fn storage_write(\n storage_slot: Field,\n fields: [Field; N]\n) {\n let _hash = storage_write_oracle(storage_slot, fields);\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/storage" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/storage" }, "68": { "source": "use crate::types::point::Point;\nuse crate::constants_gen::NUM_FIELDS_PER_SHA256;\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: Field,\n _storage_slot: Field,\n _encryption_pub_key: Point,\n _preimage: [Field; N],\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n preimage: [Field; N],\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n encryption_pub_key,\n preimage,\n ), 0]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(_contract_address: Field, _event_selector: Field, _message: T) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(contract_address: Field, event_selector: Field, message: T) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/logs" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/logs" }, "69": { "source": "use crate::abi::FunctionData;\nuse crate::abi::PrivateCircuitPublicInputs;\nuse crate::constants_gen::GENERATOR_INDEX__CALL_STACK_ITEM;\n\nstruct PrivateCallStackItem {\n contract_address: Field,\n function_data: FunctionData,\n public_inputs: PrivateCircuitPublicInputs,\n is_execution_request: bool,\n}\n\nimpl PrivateCallStackItem {\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.contract_address,\n self.function_data.hash(),\n self.public_inputs.hash(),\n ], GENERATOR_INDEX__CALL_STACK_ITEM)[0]\n }\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/private_call_stack_item" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/private_call_stack_item" }, "70": { "source": "use crate::{\n abi,\n abi::{\n PublicCircuitPublicInputs,\n FunctionData,\n },\n};\nuse crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n GENERATOR_INDEX__CALL_STACK_ITEM,\n};\n\n// oracles\nuse crate::oracle::{\n enqueue_public_function_call::enqueue_public_function_call_internal,\n};\n\nstruct PublicCallStackItem {\n contract_address: Field,\n function_data: FunctionData,\n public_inputs: PublicCircuitPublicInputs,\n is_execution_request: bool,\n}\n\nimpl PublicCallStackItem {\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.contract_address,\n self.function_data.hash(),\n self.public_inputs.hash(),\n ], GENERATOR_INDEX__CALL_STACK_ITEM)[0]\n }\n}\n\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/public_call_stack_item" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/public_call_stack_item" }, "74": { "source": "use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n ) -> Map {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map {\n context,\n storage_slot,\n state_var_constructor,\n }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: Field) -> V {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = dep::std::hash::pedersen([self.storage_slot, key])[0];\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/map" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/state_vars/map" }, "75": { "source": "use crate::context::{Context};\nuse crate::oracle::storage::storage_read;\nuse crate::oracle::storage::storage_write;\nuse crate::types::type_serialization::TypeSerializationInterface;\nuse dep::std::option::Option;\n\n// docs:start:public_state_struct\nstruct PublicState {\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n}\n// docs:end:public_state_struct\n\nimpl PublicState {\n // docs:start:public_state_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicState {\n context,\n storage_slot,\n serialization_methods,\n }\n }\n // docs:end:public_state_struct_new\n\n // docs:start:public_state_struct_read\n pub fn read(self) -> T {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n storage_read(self.storage_slot, self.serialization_methods.deserialize)\n }\n // docs:end:public_state_struct_read\n\n // docs:start:public_state_struct_write\n pub fn write(self, value: T) {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n let serialize = self.serialization_methods.serialize;\n let fields = serialize(value);\n storage_write(self.storage_slot, fields);\n }\n // docs:end:public_state_struct_write\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/public_state" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/state_vars/public_state" }, "76": { "source": "use dep::std::option::Option;\nuse crate::abi::PublicContextInputs;\nuse crate::constants_gen::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL};\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, create_note_hash_from_public, destroy_note},\n note_getter::{get_notes, view_notes},\n note_getter_options::NoteGetterOptions,\n note_header::NoteHeader,\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n};\n\n// docs:start:struct\nstruct Set {\n context: Context,\n storage_slot: Field,\n note_interface: NoteInterface,\n}\n// docs:end:struct\n\nimpl Set {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n note_interface: NoteInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Set {\n context,\n storage_slot,\n note_interface,\n }\n }\n // docs:end:new\n\n // docs:start:insert\n pub fn insert(self, note: &mut Note) {\n create_note(\n self.context.private.unwrap(),\n self.storage_slot,\n note,\n self.note_interface,\n );\n }\n // docs:end:insert\n\n // docs:start:insert_from_public\n pub fn insert_from_public(self, note: &mut Note) {\n create_note_hash_from_public(\n self.context.public.unwrap(),\n self.storage_slot,\n note,\n self.note_interface,\n );\n }\n // docs:end:insert_from_public\n \n // DEPRECATED\n fn assert_contains_and_remove(_self: Self, _note: &mut Note, _nonce: Field) {\n assert(false, \"`assert_contains_and_remove` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note.\");\n }\n\n // DEPRECATED\n fn assert_contains_and_remove_publicly_created(_self: Self, _note: &mut Note) {\n assert(false, \"`assert_contains_and_remove_publicly_created` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note.\");\n }\n\n // docs:start:remove\n pub fn remove(self, note: Note) {\n let context = self.context.private.unwrap();\n let note_hash = compute_note_hash_for_read_or_nullify(self.note_interface, note);\n let has_been_read = context.read_requests.any(|r| r == note_hash);\n assert(has_been_read, \"Can only remove a note that has been read from the set.\");\n\n destroy_note(\n context,\n note,\n self.note_interface,\n );\n }\n // docs:end:remove\n\n // docs:start:get_notes\n pub fn get_notes(\n self,\n options: NoteGetterOptions,\n ) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let storage_slot = self.storage_slot;\n let opt_notes = get_notes(\n self.context.private.unwrap(),\n storage_slot,\n self.note_interface,\n options,\n );\n opt_notes\n }\n // docs:end:get_notes\n\n // docs:start:view_notes\n unconstrained pub fn view_notes(\n self,\n options: NoteViewerOptions,\n ) -> [Option; MAX_NOTES_PER_PAGE] {\n view_notes(self.storage_slot, self.note_interface, options)\n }\n // docs:end:view_notes\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/set" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/state_vars/set" }, "79": { "source": "struct AztecAddress {\n address: Field\n}\n\nimpl AztecAddress {\n pub fn new(address: Field) -> Self {\n Self {\n address\n }\n }\n\n pub fn eq(self: Self, other: Self) -> bool {\n self.address == other.address\n }\n\n pub fn serialize(self: Self) -> [Field; 1] {\n [self.address]\n }\n\n pub fn deserialize(fields: [Field; 1]) -> Self {\n Self {\n address: fields[0]\n }\n }\n}\n\nstruct EthereumAddress {\n address: Field\n}\n\nimpl EthereumAddress {\n pub fn new(address: Field) -> Self {\n // Check that it actually will fit. Spending a lot of constraints here :grimacing:\n let bytes = address.to_be_bytes(32);\n for i in 0..12 {\n assert(bytes[i] == 0, \"Value too large for an ethereum address\");\n }\n Self {\n address\n }\n }\n\n\n pub fn serialize(self: Self) -> [Field; 1] {\n [self.address]\n }\n\n pub fn deserialize(fields: [Field; 1]) -> Self {\n Self {\n address: fields[0]\n }\n }\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/address" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/types/address" }, "81": { "source": "\nstruct BoundedVec {\n storage: [T; MaxLen],\n len: Field,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0 }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64);\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn push_array(&mut self, array: [T; Len]) {\n let newLen = self.len + array.len();\n assert(newLen as u64 <= MaxLen as u64);\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = newLen;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n\n let elem = self.storage[self.len - 1];\n self.len -= 1;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}\n\n#[test]\nfn test_vec_push_pop() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n assert(vec.len == 0);\n vec.push(2);\n assert(vec.len == 1);\n vec.push(4);\n assert(vec.len == 2);\n vec.push(6);\n assert(vec.len == 3);\n let x = vec.pop();\n assert(x == 6);\n assert(vec.len == 2);\n assert(vec.get(0) == 2);\n assert(vec.get(1) == 4);\n}\n\n#[test]\nfn test_vec_push_array() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4]);\n assert(vec.len == 2);\n assert(vec.get(0) == 2);\n assert(vec.get(1) == 4);\n}\n\n#[test(should_fail)]\nfn test_vec_get_out_of_bound() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4]);\n let _x = vec.get(2);\n}\n\n#[test(should_fail)]\nfn test_vec_get_not_declared() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2]);\n let _x = vec.get(1);\n}\n\n#[test(should_fail)]\nfn test_vec_get_uninitialized() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n let _x = vec.get(0);\n}\n\n#[test(should_fail)]\nfn test_vec_push_overflow() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push(1);\n vec.push(2);\n}\n\n#[test]\nfn test_vec_any() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4, 6]);\n assert(vec.any(|v| v == 2) == true);\n assert(vec.any(|v| v == 4) == true);\n assert(vec.any(|v| v == 6) == true);\n assert(vec.any(|v| v == 3) == false);\n}\n\n#[test]\nfn test_vec_any_not_default() {\n let default_value = 1;\n let mut vec: BoundedVec = BoundedVec::new(default_value);\n vec.push_array([2, 4]);\n assert(vec.any(|v| v == default_value) == false);\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/vec" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/types/vec" }, "83": { "source": "use crate::types::type_serialization::TypeSerializationInterface;\n\nglobal BOOL_SERIALIZED_LEN: Field = 1;\n\nfn deserializeBool(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool {\n fields[0] as bool\n}\n\nfn serializeBool(value: bool) -> [Field; BOOL_SERIALIZED_LEN] {\n [value as Field]\n}\n\nglobal BoolSerializationMethods = TypeSerializationInterface {\n deserialize: deserializeBool,\n serialize: serializeBool,\n};", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization" }, "86": { "source": "use crate::types::type_serialization::TypeSerializationInterface;\nuse crate::types::address::AztecAddress;\n\nglobal AZTEC_ADDRESS_SERIALIZED_LEN: Field = 1;\n\nfn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> AztecAddress {\n AztecAddress::new(fields[0])\n}\n\nfn serialize(value: AztecAddress) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [value.address]\n}\n\nglobal AztecAddressSerializationMethods = TypeSerializationInterface {\n deserialize,\n serialize,\n};", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization" }, "87": { "source": "pub fn arr_copy_slice(\n src: [T; N],\n mut dst: [T; M],\n offset: Field,\n) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n\npub fn field_from_bytes(bytes: [u8; N], big_endian: bool) -> Field {\n assert(bytes.len() as u32 < 32, \"field_from_bytes: N must be less than 32\");\n let mut as_field = 0;\n let mut offset = 1;\n for i in 0..N {\n let mut index = i;\n if big_endian {\n index = N - i - 1;\n }\n as_field += (bytes[index] as Field) * offset;\n offset *= 256;\n }\n\n as_field\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/utils" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/utils" }, "90": { "source": "use dep::std::hash::pedersen_with_separator;\n\nuse dep::aztec::{\n context::{PrivateContext, PublicContext, Context},\n constants_gen::{EMPTY_NULLIFIED_COMMITMENT, GENERATOR_INDEX__SIGNATURE_PAYLOAD},\n types::address::AztecAddress,\n abi::hash_args,\n};\n\nglobal IS_VALID_SELECTOR = 0xe86ab4ff;\nglobal IS_VALID_PUBLIC_SELECTOR = 0xf3661153;\n\n// @todo #2676 Should use different generator than the payload to limit probability of collisions.\n\n// docs:start:assert_valid_authwit\n// Assert that `on_behalf_of` have authorized `message_hash` with a valid authentication witness\npub fn assert_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress, message_hash: Field) {\n let result = context.call_private_function(on_behalf_of.address, IS_VALID_SELECTOR, [message_hash])[0];\n context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT);\n assert(result == IS_VALID_SELECTOR, \"Message not authorized by account\");\n}\n// docs:end:assert_valid_authwit\n\n// docs:start:assert_current_call_valid_authwit\n// Assert that `on_behalf_of` have authorized the current call with a valid authentication witness\npub fn assert_current_call_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress) {\n // message_hash = H(caller, contract_this, selector, args_hash)\n let message_hash = pedersen_with_separator(\n [context.msg_sender(), context.this_address(), context.selector(), context.args_hash],\n GENERATOR_INDEX__SIGNATURE_PAYLOAD\n )[0];\n assert_valid_authwit(context, on_behalf_of, message_hash);\n}\n// docs:end:assert_current_call_valid_authwit\n\n// docs:start:assert_valid_authwit_public\n// Assert that `on_behalf_of` have authorized `message_hash` in a public context\npub fn assert_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress, message_hash: Field) {\n let result = context.call_public_function(on_behalf_of.address, IS_VALID_PUBLIC_SELECTOR, [message_hash])[0];\n context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT);\n assert(result == IS_VALID_SELECTOR, \"Message not authorized by account\");\n}\n// docs:end:assert_valid_authwit_public\n\n// docs:start:assert_current_call_valid_authwit_public\n// Assert that `on_behalf_of` have authorized the current call in a public context\npub fn assert_current_call_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress) {\n // message_hash = H(caller, contract_this, selector, args_hash)\n let message_hash = pedersen_with_separator(\n [context.msg_sender(), context.this_address(), context.selector(), context.args_hash],\n GENERATOR_INDEX__SIGNATURE_PAYLOAD\n )[0];\n assert_valid_authwit_public(context, on_behalf_of, message_hash);\n}\n// docs:end:assert_current_call_valid_authwit_public\n\n// docs:start:compute_authwit_message_hash\n// Compute the message hash to be used by an authentication witness \npub fn compute_authwit_message_hash(\n caller: AztecAddress, \n target: AztecAddress, \n selector: Field, \n args: [Field; N]\n) -> Field {\n let args_hash = hash_args(args);\n pedersen_with_separator([caller.address, target.address, selector, args_hash], GENERATOR_INDEX__SIGNATURE_PAYLOAD)[0]\n}\n// docs:end:compute_authwit_message_hash", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/authwit/src/auth" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/authwit/src/auth" }, "92": { "source": "struct SafeU120 {\n value: u120,\n}\n\nimpl SafeU120 {\n pub fn min() -> Self {\n Self {\n value: 0\n }\n }\n\n pub fn max() -> Self {\n Self {\n value: 0xffffffffffffffffffffffffffffff\n }\n }\n\n pub fn new(\n value: Field,\n ) -> Self {\n // Check that it actually will fit. Spending a lot of constraints here :grimacing:\n let bytes = value.to_be_bytes(32);\n for i in 0..17 {\n assert(bytes[i] == 0, \"Value too large for SafeU120\");\n }\n Self {\n value: value as u120\n }\n }\n\n pub fn is_zero(\n self: Self,\n ) -> bool {\n self.value == 0\n }\n\n pub fn eq(\n self: Self,\n other: Self\n ) -> bool {\n self.value == other.value\n }\n\n pub fn lt(self: Self, other: Self) -> bool {\n self.value < other.value\n }\n\n pub fn le(self: Self, other: Self) -> bool {\n self.value <= other.value\n }\n\n pub fn gt(self: Self, other: Self) -> bool {\n self.value > other.value\n }\n\n pub fn ge(self: Self, other: Self) -> bool {\n self.value >= other.value\n }\n\n pub fn sub(\n self: Self,\n b: Self,\n ) -> Self {\n assert(self.value >= b.value, \"Underflow\");\n Self {\n value: self.value - b.value\n }\n }\n\n pub fn add(\n self: Self,\n b: Self,\n ) -> Self {\n let c: u120 = self.value + b.value;\n assert(c >= self.value, \"Overflow\");\n Self {\n value: c\n }\n }\n\n pub fn mul(\n self: Self,\n b: Self,\n ) -> Self {\n let c: u120 = self.value * b.value;\n if !b.is_zero() {\n assert(c / b.value == self.value, \"Overflow\");\n }\n Self {\n value: c\n }\n }\n\n pub fn div(\n self: Self,\n b: Self,\n ) -> Self {\n assert(!b.is_zero(), \"Divide by zero\");\n Self {\n value: self.value / b.value\n }\n }\n\n pub fn mul_div(\n self: Self,\n b: Self,\n divisor: Self\n ) -> Self {\n self.mul(b).div(divisor)\n }\n\n pub fn mul_div_up(\n self: Self,\n b: Self,\n divisor: Self\n ) -> Self {\n let c = self.mul(b);\n assert(!divisor.is_zero(), \"Divide by zero\");\n let adder = ((self.value * b.value % divisor.value) as u120 > 0) as u120;\n c.div(divisor).add(Self {value: adder})\n }\n\n // todo: implement mul_div with 240 bit intermediate values.\n}\n\n#[test]\nfn test_init() {\n let a = SafeU120::new(1);\n assert(a.value == 1);\n}\n\n#[test]\nfn test_init_max() {\n let a = SafeU120::max();\n assert(a.value == 0xffffffffffffffffffffffffffffff);\n}\n\n#[test]\nfn test_init_min() {\n let a = SafeU120::min();\n assert(a.value == 0);\n}\n\n#[test]\nfn test_is_zero() {\n let a = SafeU120::min();\n assert(a.value == 0);\n assert(a.is_zero() == true);\n}\n\n#[test]\nfn test_eq() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(1);\n assert(a.eq(b));\n}\n\n#[test]\nfn test_lt() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n assert(a.lt(b));\n assert(b.lt(a) == false);\n}\n\n\n#[test]\nfn test_le() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(2);\n let c = SafeU120::new(5);\n assert(a.le(b));\n assert(a.le(c));\n assert(c.le(a) == false);\n}\n\n#[test]\nfn test_gt() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n assert(b.gt(a));\n assert(a.gt(b) == false);\n}\n\n\n#[test]\nfn test_ge() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(2);\n let c = SafeU120::new(5);\n assert(a.ge(b));\n assert(a.ge(c) == false);\n assert(c.ge(a));\n}\n\n#[test(should_fail)]\nfn test_init_too_large() {\n let b = SafeU120::max().value as Field + 1; // max + 1\n let _a = SafeU120::new(b);\n}\n\n#[test]\nfn test_add() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n let c = SafeU120::add(a, b);\n assert(c.value == 3);\n}\n\n#[test(should_fail)]\nfn test_add_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(1);\n let _c = SafeU120::add(a, b);\n}\n\n#[test]\nfn test_sub() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(1);\n let c = SafeU120::sub(a, b);\n assert(c.value == 1);\n}\n\n#[test(should_fail)]\nfn test_sub_underflow() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n let _c = SafeU120::sub(a, b);\n}\n\n#[test]\nfn test_mul() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(3);\n let c = SafeU120::mul(a, b);\n assert(c.value == 6);\n}\n\n#[test(should_fail)]\nfn test_mul_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let _c = SafeU120::mul(a, b);\n}\n\n#[test]\nfn test_div() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::div(a, b);\n assert(c.value == 2);\n}\n\n#[test(should_fail)]\nfn test_div_by_zero() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(0);\n let _c = SafeU120::div(a, b);\n}\n\n#[test]\nfn test_mul_div() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(2);\n let d = SafeU120::mul_div(a, b, c);\n assert(d.value == 9);\n}\n\n#[test(should_fail)]\nfn test_mul_div_zero_divisor() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(0);\n let _d = SafeU120::mul_div(a, b, c);\n}\n\n#[test(should_fail)]\nfn test_mul_div_ghost_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let c = SafeU120::new(4);\n let _d = SafeU120::mul_div(a, b, c);\n}\n\n#[test]\nfn test_mul_div_up_rounding() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(5);\n let d = SafeU120::mul_div_up(a, b, c);\n assert(d.value == 4);\n}\n\n#[test]\nfn test_mul_div_up_non_rounding() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(2);\n let d = SafeU120::mul_div_up(a, b, c);\n assert(d.value == 9);\n}\n\n\n#[test(should_fail)]\nfn test_mul_div_up_ghost_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let c = SafeU120::new(9);\n let _d = SafeU120::mul_div_up(a, b, c);\n}\n\n// It should not be possible for us to overflow `mul_div_up` through the adder, since that require the divisor to be 1\n// since we otherwise would not be at the max value. If divisor is 1, adder is 0.\n#[test(should_fail)]\nfn test_mul_div_up_zero_divisor() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(0);\n let _d = SafeU120::mul_div_up(a, b, c);\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/safe-math/src/safe_u120" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/safe-math/src/safe_u120" }, "98": { "source": "// docs:start:token_types_all\nuse dep::std::hash::pedersen;\nuse dep::aztec::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_siloed_note_hash,\n};\nuse dep::aztec::hash::{compute_secret_hash};\n\nglobal TRANSPARENT_NOTE_LEN: Field = 2;\n\n// Transparent note represents a note that is created in the clear (public execution),\n// but can only be spent by those that know the preimage of the \"secret_hash\"\nstruct TransparentNote {\n amount: Field,\n secret_hash: Field,\n // the secret is just here for ease of use and won't be (de)serialized\n secret: Field,\n // header is just here to satisfy the NoteInterface\n header: NoteHeader,\n}\n\nimpl TransparentNote {\n\n // CONSTRUCTORS\n\n pub fn new(amount: Field, secret_hash: Field) -> Self {\n TransparentNote {\n amount: amount,\n secret_hash: secret_hash,\n secret: 0,\n header: NoteHeader::empty(),\n }\n }\n\n // new oracle call primitive\n // get me the secret corresponding to this hash\n pub fn new_from_secret(amount: Field, secret: Field) -> Self {\n TransparentNote {\n amount: amount,\n secret_hash: compute_secret_hash(secret),\n secret: secret,\n header: NoteHeader::empty(),\n }\n }\n\n\n // STANDARD NOTE_INTERFACE FUNCTIONS\n\n pub fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] {\n [self.amount, self.secret_hash]\n }\n\n pub fn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> Self {\n TransparentNote {\n amount: preimage[0],\n secret_hash: preimage[1],\n secret: 0,\n header: NoteHeader::empty(),\n }\n }\n\n pub fn compute_note_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n dep::std::hash::pedersen([\n self.amount,\n self.secret_hash,\n ])[0]\n }\n\n pub fn compute_nullifier(self) -> Field {\n // TODO(#1386): should use `compute_note_hash_for_read_or_nullify` once public functions inject nonce!\n let siloed_note_hash = compute_siloed_note_hash(TransparentNoteMethods, self);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen([self.secret, siloed_note_hash])[0]\n }\n\n pub fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n\n // CUSTOM FUNCTIONS FOR THIS NOTE TYPE\n\n pub fn knows_secret(self, secret: Field) {\n let hash = compute_secret_hash(secret);\n assert(self.secret_hash == hash);\n }\n}\n\nfn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> TransparentNote {\n TransparentNote::deserialize(preimage)\n}\n\nfn serialize(note: TransparentNote) -> [Field; TRANSPARENT_NOTE_LEN] {\n note.serialize()\n}\n\nfn compute_note_hash(note: TransparentNote) -> Field {\n note.compute_note_hash()\n}\n\nfn compute_nullifier(note: TransparentNote) -> Field {\n note.compute_nullifier()\n}\n\nfn get_header(note: TransparentNote) -> NoteHeader {\n note.header\n}\n\nfn set_header(note: &mut TransparentNote, header: NoteHeader) {\n note.set_header(header)\n}\n\nglobal TransparentNoteMethods = NoteInterface {\n deserialize,\n serialize,\n compute_note_hash,\n compute_nullifier,\n get_header,\n set_header,\n};\n// docs:end:token_types_all", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/transparent_note" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/transparent_note" }, "99": { "source": "use dep::std::option::Option;\nuse dep::safe_math::SafeU120;\nuse dep::aztec::{\n context::Context,\n constants_gen::MAX_READ_REQUESTS_PER_CALL,\n state_vars::set::Set,\n log::emit_encrypted_log,\n types::address::AztecAddress,\n};\nuse dep::aztec::note::{\n note_getter::view_notes,\n note_getter_options::{NoteGetterOptions, SortOrder},\n note_viewer_options::NoteViewerOptions\n};\nuse dep::aztec::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_note_hash_for_read_or_nullify,\n};\nuse dep::aztec::oracle::{\n rand::rand,\n get_secret_key::get_secret_key,\n get_public_key::get_public_key,\n};\n\nuse crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN, TokenNoteMethods};\n\n// A set implementing standard manipulation of balances.\n// Does not require spending key, but only knowledge.\n// Spending key requirement should be enforced by the contract using this.\nstruct BalanceSet {\n context: Context,\n owner: AztecAddress,\n set: Set\n}\n\nimpl BalanceSet {\n pub fn new(context: Context, owner: AztecAddress, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n let set = Set {\n context,\n storage_slot,\n note_interface: TokenNoteMethods,\n };\n Self {\n context,\n owner,\n set,\n }\n }\n\n unconstrained pub fn balance_of(self: Self) -> SafeU120 {\n self.balance_of_with_offset(0)\n }\n\n unconstrained pub fn balance_of_with_offset(self: Self, offset: u32) -> SafeU120 {\n // Same as SafeU120::new(0), but fewer constraints because no check. \n let mut balance = SafeU120::min();\n // docs:start:view_notes\n let options = NoteViewerOptions::new().set_offset(offset);\n let opt_notes = self.set.view_notes(options);\n // docs:end:view_notes\n let len = opt_notes.len();\n for i in 0..len {\n if opt_notes[i].is_some() {\n balance = balance.add(opt_notes[i].unwrap_unchecked().amount);\n }\n }\n if (opt_notes[len - 1].is_some()) {\n balance = balance.add(self.balance_of_with_offset(offset + opt_notes.len() as u32));\n }\n\n balance\n }\n\n pub fn add(self: Self, addend: SafeU120) {\n let mut addend_note = TokenNote::new(addend, self.owner);\n\n // docs:start:insert\n self.set.insert(&mut addend_note);\n // docs:end:insert\n\n addend_note.emit_encrypted(\n self.context.private.unwrap(),\n self.set.storage_slot\n );\n }\n\n pub fn sub(self: Self, subtrahend: SafeU120) {\n // docs:start:get_notes\n let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend);\n let maybe_notes = self.set.get_notes(options);\n // docs:end:get_notes\n\n let mut minuend: SafeU120 = SafeU120::min();\n for i in 0..maybe_notes.len() {\n if maybe_notes[i].is_some() {\n let note = maybe_notes[i].unwrap_unchecked();\n\n // Removes the note from the owner's set of notes.\n // This will call the the `compute_nullifer` function of the `token_note`\n // which require knowledge of the secret key (currently the users encryption key).\n // The contract logic must ensure that the spending key is used as well.\n // docs:start:remove\n self.set.remove(note);\n // docs:end:remove\n\n minuend = minuend.add(note.amount);\n }\n }\n\n // This is to provide a nicer error msg,\n // without it minuend-subtrahend would still catch it, but more generic error then.\n // without the == true, it includes 'minuend.ge(subtrahend)' as part of the error.\n assert(minuend.ge(subtrahend) == true, \"Balance too low\");\n\n self.add(minuend.sub(subtrahend));\n }\n}\n\npub fn filter_notes_min_sum(notes: [Option; MAX_READ_REQUESTS_PER_CALL], min_sum: SafeU120) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let mut selected = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let mut sum = SafeU120::min();\n for i in 0..notes.len() {\n if notes[i].is_some() & sum.lt(min_sum) {\n let note = notes[i].unwrap_unchecked();\n selected[i] = Option::some(note);\n sum = sum.add(note.amount);\n }\n }\n selected\n}", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balance_set" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/balance_set" }, "100": { "source": "use dep::aztec::context::{PrivateContext, PublicContext, Context};\nuse dep::aztec::types::address::AztecAddress;\nuse dep::std::option::Option;\nuse crate::types::balance_set::BalanceSet;\n\nstruct BalancesMap {\n context: Context,\n storage_slot: Field,\n}\n\nimpl BalancesMap {\n pub fn new(\n context: Context,\n storage_slot: Field,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self {\n context,\n storage_slot,\n }\n }\n\n pub fn at(self, owner: AztecAddress) -> BalanceSet {\n let derived_storage_slot = dep::std::hash::pedersen([self.storage_slot, owner.address])[0];\n BalanceSet::new(self.context, owner, derived_storage_slot)\n }\n}\n", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balances_map" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/balances_map" }, "101": { "source": "use dep::aztec::{\n note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_note_hash_for_read_or_nullify,\n },\n context::PrivateContext,\n constants_gen::MAX_READ_REQUESTS_PER_CALL,\n state_vars::set::Set,\n log::emit_encrypted_log\n};\nuse dep::aztec::types::address::AztecAddress;\nuse dep::aztec::oracle::{\n rand::rand,\n get_secret_key::get_secret_key,\n get_public_key::get_public_key,\n};\n\nuse dep::safe_math::SafeU120;\nuse dep::std::option::Option;\n\nglobal TOKEN_NOTE_LEN: Field = 3; // 3 plus a header.\n\nstruct TokenNote {\n // the amount of tokens in the note\n amount: SafeU120,\n // the provider of secrets for the nullifier. The owner (recipient) to ensure that the note \n // can be privately spent. When nullifier secret and encryption private key is same \n // we can simply use the owner for this one.\n owner: AztecAddress,\n // randomness of the note to hide contents.\n randomness: Field,\n // the note header (contract_address, nonce, storage_slot)\n // included in the note such that it becomes part of encrypted logs for later use.\n header: NoteHeader,\n}\n\nimpl TokenNote {\n pub fn new(amount: SafeU120, owner: AztecAddress) -> Self {\n Self {\n amount,\n owner,\n randomness: rand(),\n header: NoteHeader::empty(),\n }\n }\n\n pub fn serialize(self) -> [Field; TOKEN_NOTE_LEN] {\n [self.amount.value as Field, self.owner.address, self.randomness]\n }\n\n pub fn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> Self {\n Self {\n amount: SafeU120::new(preimage[0]),\n owner: AztecAddress::new(preimage[1]),\n randomness: preimage[2],\n header: NoteHeader::empty(),\n }\n }\n\n pub fn compute_note_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n dep::std::hash::pedersen([\n self.amount.value as Field, \n self.owner.address as Field,\n self.randomness,\n ])[0]\n }\n\n // docs:start:nullifier\n pub fn compute_nullifier(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(TokenNoteMethods, self);\n let secret = get_secret_key(self.owner.address);\n // TODO(#1205) Should use a non-zero generator index.\n dep::std::hash::pedersen([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ])[0]\n }\n // docs:end:nullifier\n\n pub fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n\n pub fn emit_encrypted(\n self: &mut Self,\n context: &mut PrivateContext,\n storage_slot: Field,\n ) {\n // We only bother inserting the note if non-empty to save funds on gas.\n if !self.amount.is_zero() {\n // docs:start:encrypted\n let application_contract_address = (*context).this_address();\n let encryption_pub_key = get_public_key(self.owner.address);\n let encrypted_data = (*self).serialize();\n\n emit_encrypted_log(\n context,\n application_contract_address,\n storage_slot,\n encryption_pub_key,\n encrypted_data,\n );\n // docs:end:encrypted\n }\n }\n}\n\nfn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> TokenNote {\n TokenNote::deserialize(preimage)\n}\n\nfn serialize(note: TokenNote) -> [Field; TOKEN_NOTE_LEN] {\n note.serialize()\n}\n\nfn compute_note_hash(note: TokenNote) -> Field {\n note.compute_note_hash()\n}\n\nfn compute_nullifier(note: TokenNote) -> Field {\n note.compute_nullifier()\n}\n\nfn get_header(note: TokenNote) -> NoteHeader {\n note.header\n}\n\nfn set_header(note: &mut TokenNote, header: NoteHeader) {\n note.set_header(header)\n}\n\nglobal TokenNoteMethods = NoteInterface {\n deserialize,\n serialize,\n compute_note_hash,\n compute_nullifier,\n get_header,\n set_header,\n};", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/token_note" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/token_note" }, "102": { "source": "use dep::aztec::types::type_serialization::TypeSerializationInterface;\nuse dep::safe_math::SafeU120;\n\nglobal SAFE_U120_SERIALIZED_LEN: Field = 1;\n\n// This is safe when reading from storage IF only correct safeu120 was written to storage\nfn deserializeU120(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 {\n SafeU120{value: fields[0] as u120}\n}\n\nfn serializeU120(value: SafeU120) -> [Field; SAFE_U120_SERIALIZED_LEN] {\n [value.value as Field]\n}\n\nglobal SafeU120SerializationMethods = TypeSerializationInterface {\n deserialize: deserializeU120,\n serialize: serializeU120,\n};", - "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/safe_u120_serialization" + "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/safe_u120_serialization" } } } From 429c8b348bb3a167fb2f479bae09cd997b0c8370 Mon Sep 17 00:00:00 2001 From: Dan Lee Date: Wed, 18 Oct 2023 17:47:50 +0100 Subject: [PATCH 2/3] undo artifact changes --- .../blank-react/src/artifacts/Blank.json | 6 +- .../boxes/blank/src/artifacts/Blank.json | 6 +- .../boxes/token/src/artifacts/Token.json | 82 +++++++++---------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/yarn-project/boxes/blank-react/src/artifacts/Blank.json b/yarn-project/boxes/blank-react/src/artifacts/Blank.json index 98550669a69..3ea55fe86ec 100644 --- a/yarn-project/boxes/blank-react/src/artifacts/Blank.json +++ b/yarn-project/boxes/blank-react/src/artifacts/Blank.json @@ -37,15 +37,15 @@ "fileMap": { "34": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\n\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)[0]\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)[0]\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n private_data_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.private_data_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)[0]\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n dep::std::hash::pedersen_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n dep::std::hash::pedersen_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = dep::std::hash::pedersen_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS)[0];\n }\n chunks_hashes[i] = chunk_hash;\n }\n dep::std::hash::pedersen_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)[0]\n }\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/abi" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi" }, "35": { "source": "use dep::std::hash;\nuse crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n hash::pedersen_with_separator([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0]\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/address" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/address" }, "58": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKey)]\nfn get_public_key_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_internal(address: Field) -> [Field; 3] {\n get_public_key_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" } } } diff --git a/yarn-project/boxes/blank/src/artifacts/Blank.json b/yarn-project/boxes/blank/src/artifacts/Blank.json index 98550669a69..3ea55fe86ec 100644 --- a/yarn-project/boxes/blank/src/artifacts/Blank.json +++ b/yarn-project/boxes/blank/src/artifacts/Blank.json @@ -37,15 +37,15 @@ "fileMap": { "34": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\n\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)[0]\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)[0]\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n private_data_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.private_data_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)[0]\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n dep::std::hash::pedersen_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n dep::std::hash::pedersen_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = dep::std::hash::pedersen_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS)[0];\n }\n chunks_hashes[i] = chunk_hash;\n }\n dep::std::hash::pedersen_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)[0]\n }\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/abi" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi" }, "35": { "source": "use dep::std::hash;\nuse crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n hash::pedersen_with_separator([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0]\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/address" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/address" }, "58": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKey)]\nfn get_public_key_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_internal(address: Field) -> [Field; 3] {\n get_public_key_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" } } } diff --git a/yarn-project/boxes/token/src/artifacts/Token.json b/yarn-project/boxes/token/src/artifacts/Token.json index d5200e45a82..152a1b40e75 100644 --- a/yarn-project/boxes/token/src/artifacts/Token.json +++ b/yarn-project/boxes/token/src/artifacts/Token.json @@ -274,7 +274,7 @@ ] } ], - "bytecode": "H4sIAAAAAAAA/+2dCZweRZnGv56ZHD01OQkJkOubXJMQQmY6REDATAQ+whWucIUrgWS4AoEknAJCBFREEBABEQFd13Vd13VdD1blRi655JJLLgURXWVFxYvdqv7qYZ6pNK1j6nVqfqn6/d756uiu5/++Vd1fH1/3fK5SqSSVemrUNqqybkJ7p/1sX7/Ukfjrq12Ss6GfcDb2E86mfsI5oJ9wDuwnnIP6CefgfsKZ9hPO5n7CqfoJZ0s/4RzSTziH9hPOYf2Ec3g/4RzRTzhH9hPOjfoJ5yiPnJsS58b2c7T9HGM/N7GfWHYz+znWfo6zPjbZ8nhtE7RN1Fa1bQhIq7ZJ2iZrm6JtqrZp2tq0Tdc2Q9vm2mZq20LbLG1baptt++jQlmmbo20rbXO1vUfb1tq20battvdq207b9tp20PY+bfNszOZre7+2HbXtpG1nbTVtu2hboG1Xbbtp213bHtr21LZQ217a9ra+VK0v+2jbV9t+2hZp21/bAdoO1HaQtoO1LdZ2iLZDtR2m7XBtR2hbom2ptiO1HaVtmbbl2rq0Ha3tGG3HajtO2/HaVmg7QduJ2lZqO8mJ+cnaVmlbrW2NbRtu207Rdqq207Sdru0MbWdq+4C2s7Sdre0cbR/Udq6287St1fYhbec7fV2g7UJtH9b2EW0f1XaRto9pu1jbx7Vdou1SbZ/Qdpm2y7Vdoe2Ttq8G29eV2j7l1F2l7Wqbv8Z+ftp+Xms/P2M/r7Ofn7Wf19vPG+znjZXudFRL/dMcc2Keb1TprsP1gpFUh/YRVIf24VSH9mFUh/ahVIf2IVSH9haqQ7uiOrQ3Ux234xPtg6kO7YOoDu0DqQ7tA6gO7U1Uh/ZGqkN7A9WhPaE6tFccfZM67Wf7eqaBFe/73Hbjcwf5USnwl68/uf42FcRlQEH8eDzQzuOGdh5fbscn2nm+oJ3nDdp5/qGd5ynaeT6jnec92nn7QDtvR2jn7Q3tvF2ifRTVoX1jqkP7aKpD+xiqQ/smVIf2TakO7fiuM36Z2I+z5U772b5+KTNa+B5FSpxyJ+Whb1jG+2VpNywTbF9jSWeiX538uukExz+UoaWIYbwgiyrQFtDJUsdnk8rGmVla/bLk41ztBUsrsUwSYEGfE0hnsl+dfM5NcvxDGVo8F6pUN+kfFAfsm9C3+U7YjTQ973vymPC21UkM0GqkZVpburkW2rpmah9LdVgf8eQ5x+PseW538PE5+kW5lfiwfVWJRWLOuSyI1WRhXXeuT3R0U4oHUtk+YBLxTvHL2250p1L/naTB+8FpAnGaSr4npIH6Rsp3dYfjneVMwlwHs5lfkwuW43yrs46i9snCPk8hjk4qQ8ts34cQg+f5mY/3ZIcB5YlUP6UgXryvRjsfB6Kdj188z9eOMn4eTzBUBVlUgTbHYUIAcQBDK9VhOcn9SoV0mmgcoNNI7c8l3cudQUwT/DLlx4E8x00q2+/y+Pn9/u/IjznG94KFzz3GemWpn7P73s+YPngf4h6n8D6E97kS28lYJ6YoM19kjayRNbJG1sgaWSNrZN2wWfnewMQ+ZlHEMF6MpaNdFWhLnG/wfR/03aTtPtL0e3+lo53ve5j+q8QArUZa5mnietDmmyvF9yv8smZHCcQ8P/fFOSRS2fnmWCdWPsfCXMoeVFn3ej/iCM4GYvB9zd/0wddPoAkdM9budS8TQ9ynRJuZHy8k3Zye7wv2+t4V7x8837No532i9P2id9snFt0vGifIogq0/etk7eyzmffVSvf+iecf9su8fXq+Tt3jnkDFslRtHlp8vR77CLDx9Xss8wv7abaXy2l7kbin//deV/M9pr39fYHgMU9+jW+q5z5NH9OIv+i4xb2n01f3VSJrZI2skTWyRtbIGlkja2SNrJE1skbWyBpZI2tkjayRtT+x8v2A8X3Moirr3s/3z5K1qwLtgRX/18v5OUT03aTtbLp34fcebf0eEN+PqBIDtBppma/S76bPs3l+/ofnhGfWowRinvFv55HK7pfwbxT83tvI3rlHjVhOdcYBnHyPus0rQ/3+ynTyF5rQMWONbQDLpZTne7Qz/LLl+wRm66QytPge7TRBFlWgzfcZ+Tm5iRS7cQVx8nsPsGO97gH6vl/n3rPtJA3W9TyPO1gXz3pBA/V8r/jzFKC27uw7YwhmM4ZTCpbj/FhnHUXtU4R95nvonVSGlpmjV5OvUwq4xxA32vk7QuL3aLwPrhID/zYOvvyjnhF0Y8jHHROdmPlnqf82ztXm37Hxs078OzbJYwT3dyJjiQs8WNY9hqvSMvw+BvgouG302A+BpWrzbcTbRgzVyrrxb6RlbqJjoadov+8eH/P8dvutUr3fcavPZYzFAIej6NjuFuvDEMdnk1rtJ+8HxznL+R+3+u9ZmAPx5NRJeR4/z9/5+RzanPrvJA3WnelXt4N18V0GDdQ3Uv5hCtDM7uw78xLMZgynFyzH+WnOOorapwv7PIM4OqkMLbPd3UW+Ti/g3oS40Y55a+YWxo3PW6YL+NLm+NLmMPO57DQxlvq5rKvN+y/p/ZBJ1cq655h87juOuOTOfevn25s6HEbzBeHfCv497//h3xjyMYfn55V7vCME/aIMLf59aoMgiyrQFtDp9e83+R0nRc9IVD3HIan0fIa8s7Lu+0w4Vo2CLKpS/C4Vzzq9fm6+aj/5PSd8njDJcxySSs/3qXRSGVocqyZBFlWgLaCT/b3vkOFzg1bikz6P7KwUv58CDAMEWYre0xHS9Us+75J+/8zfcj7NDFIsRefTAjpZ6vhsUtmY8Lk9js34Pk9fHY+CYZAgS9HxqIBOljo+m1Q2Jnxtu+gcb3PPcSg734EWx2qwIIsq0BbQyVLHZ5PKxgT6Zj2cA84gvi08x4HPs9EvytDiWKWCLKpAW0AnSx2fTSobky3I91k2P5P4tvQch4R00C/K0OJYNQuyqAJtAZ0sdXw2qWxMoG/Wm23zs4iv3XMcEtJBvyhDi2OlBFlUgbaATpY6PptUNibQN+vhvdKziS/zHIeEdNAvyhmNAxhaBFlUgbaATpY6PptUNibQN+vNsfkO4tvKcxwS0kG/KEOLYzVEkEUVaAvoZKnjs0llYwJ9s95cm59DfO/xHIeEdNAvytDiWA0VZFEF2gI6Wer4bFLZmEDfrLe1zc8lvm08xyEhHfSLMrQ4VsMEWVSBtoBOljo+m1Q2JtA3621r81sT33s9xyEhHfSLMrQ4VsMFWVSBtoBOljo+m1Q2JtA3621n89sS3/ae45CQDvpFGVocqxGCLKpAW0AnSx2fTSobE+ib9Xaw+e2I732e45CQDvpFGVocq5GCLKpAW0AnSx2fTSobE+ib9ebZ/A7E1+k5DgnpoN95jgbHaiNBFlWgLaCTcWyRysYEebPefJufR3zv9xyHhHTQL8rQ4lhtKsiiCrQFdLLU8dmksjFhlp38smxlWHbsBctOxLKzX5b8PTE1z32aPnYhfvgKdkXtNfJtF78c+TzfudIzpigzX2TdsFlTqpvfxyy8P9xRjmUrVaAtoJOljs8mle3reEwW2PzOxLerX758TBY4LChDi2NVE2RRBdoCOlnq+GxS2Zgwy+5eWebkvwPbrRcsuxPLHl5Z6t9be5IWuKCjqJ3nwZ5+OfI5uYfjP8rMF1kja2SNrJE1skbWyBpZI2tkjayRNbJG1sgaWSNrZI2skTWyRtbIGlkja2SNrJE1skZW/6wp1S3oYxb+LcluYixz8ncaudoCPmep47NJZb8T4TFZaPN7EN9efvnyMVnosKAMLY5VTZBFFWgL6GSp47NJZWPCLPt4Zam/q27vXrDsQyz7emWp/45oP9ICF3QUtfM82M8vRz4n93X8R5n5ImtkjayRNbJG1sgaWSNrZI2skTWyRtbIGlkja2SNrJG1v7CmVLewj1n4WvzeYiz1/y3hagv4nKWOzyaVXWfnMVlk8/sS3/5++fIxWeSwoAwtjlVNkEUVaAvoZKnjs0llY8IsB/plyd9tckAvWA4kloP8suT3YQ4mLXBBR1E7z4OD/XLkc/Igx3+UmS+ybtisKdUt6mMW3ncdIMeSv4fE1RbQyVLHZ5PK9ks8Jott/iDiO8QvXz4mix0WlKHFsaoJsqgCbQGdLHV8NqlsTJjlMK8s9f/bemgvWA4jlsO9stS/t44gLXBBR1E7z4Mj/HLkc/Jwx3+UmS+yRtbIGlkja2SNrJE1sm7YrCnVLe5jFj6XOVSMpf7/4l1tAZ+z1PHZpLLzFB6TJTZ/OPEt9cuXj8kShwVlaHGsaoIsqkBbQCfj2CKVjQmzHOWVpX4ee2QvWI4ilmVeWernsctJC1zQUdTO82C5X458Ti5z/EeZ+SJrZI2skTWyRtbIGlkj64bNmlLdkj5m4XOZI8VY6uexrraAz1nq+GxS2XkKj0mXzS8jvqP98uVj0uWwoAwtjlVNkEUVaAvoZKnjs0llY8IsxwqwHNMLlmOJ5Ti/LPl57PGkBS7oKGrneXC8X458Th7n+I8y8/UX1pTquvqYhbexY+RYMlWgLaGTOj6bVLb98JissPnjiO8Ev3z5mKxwWFCGFseqJsiiCrQFdLLU8dmksjFhlpUCLCf2gmUlsZzklyXfv55MWuCCjqJ2ngcn++XI5+RJjv8oM19/YU2pbkUfs/A2dqIcS75/dbUldFLHZ5PKth8ek1U2fxLxrfbLl4/JKocFZWhxrGqCLKpAW0AnSx2fTSobE+ib9dbY/CriO8VzHBLSQb8oQ4tjVRNkUQXaAjpZ6vhsUtmYQN+sd6rNryG+0zzHISEd9IsytDhWqSCLKtAW0MlSx2eTysbkNPL9dJs/lfjO8ByHhHTQL8rQ4lg1C7KoAm0BnSx1fDapbEygb9Y70+ZPJ74PeI5DQjroF2VocayUIIsq0BbQyVLHZ5PKxgT6Zr2zbP5M4jvbcxwS0kG/KJ9N4wCGFkEWVaAtoJOljs8mlY0J9M1659j8WcT3Qc9xSEgH/aIMLY7VEEEWVaAtoJOljs8mlY0J9M1659r8OcR3nuc4JKSDflGGFsdqqCCLKtAW0Mk4tkhlYwJ9s95amz+X+D7kOQ4J6aBflKHFsRomyKIKtAV0stTx2aSyMYG+We98m19LfBd4jkNCOugXZWhxrGqCLKpAW0AnSx2fTSobE+ib9S60+fOJ78Oe45CQDvpFGVocq5ogiyrQFtDJUsdnk8rGBPpmvY/Y/IXE91HPcUhIB/2iDC2OVU2QRRVoC+hkqeOzSWVjAn2z3kU2j/UN38ecddrXL+VjcpHDgjK0OFY1QRZVoC2gk6WOzyaVjQn0zXoX2/xFxPdxz3FISAf9ogwtjlVNkEUVaAvoZKnjs0llY8Isl/hlyX8Lfqnt62LS+YTn2Cakg35RhhbH/xJBFlWgLaCTpY7PJpWNM/TNepfZ/KXEd7nnOCSkg35RhhbH6hJBFlWgLaCTpY7PJpWNCfTNelfY/GXE90nPcUhIB/2iDC2O1SWCLKpAW0AnSx2fTSobE+ib9a60+SuI71Oe45CQDvpFGVocq5ogiyrQFtDJUsdnk8rGBPpmvats/kriu9pzHBLSQb8oQ4tjVRNkUQXaAjpZ6vhsUtmYQN+sd43NX0V8n/Ych4R00C/K0OJY1QRZVIG2gE6WOj6bVDYm0DfrXWvz1xDfZzzHISEd9IsytDhWNUEWVaAtoJOljs8mlY0J9M1619n8tcT3Wc9xSEgH/aIMLY5VTZBFFWgL6GSp47NJZWMCfbPe9TZ/HfHd4DkOCemgX5ShxbGqCbKoAm0BnYxji1Q2JjfYT7PejTZ/PfF9znMcEtJBvyhDi2NVE2RRBdoCOlnq+GxS2ZhA36z3eZu/kfj+yXMcEtJBvyhDi2NVE2RRBdoCOlnq+GxS2ZhA36z3BZv/PPH9s+c4JKSDflGGFseqJsiiCrQFdLLU8dmksjGBvlnvizb/BeL7F89xSEgH/aIMLY5VTZBFFWgL6GSp47NJZWMCfbPel2z+i8T3r57jkJAO+kUZWhyrmiCLKtAW0MlSx2eTysYE+ma9L9v8l4jv3zzHISEd9IsytDhWNUEWVaAtoJOljs8mlY0J9M16X7H5LxPfv3uOQ0I66BdlaHGsaoIsqkBbQCdLHZ9NKhsT6Jv1vmrzXyG+//Ach4R00C/K0OJY1QRZVIG2gE6WOj6bVDYm0Dfrfc3mv0p8/+k5DgnpoF+UocWxqgmyqAJtAZ0sdXw2qWxMoG/W+7rNf434/stzHBLSQb8oQ4tjVRNkUQXaAjpZ6vhsUtmYMMs3/bLk/9vhG71g+SaxfMsvS/7M4LdJC1zQUdTO8+DbfjnyOfktx3+UmS+ybtisKdV9vY9ZeN/1DTmW/H87uNoCOlnq+GxS2X6Jx+Qmm/8W8f23X758TG5yWFCGFseqJsiiCrQFdLLU8dmksjFhlu96Zcny30F9pxcs3yWW73llqX9v3Uxa4IKOonaeBzf75cjn5Pcc/1FmvsgaWSNrZI2skTWyRtbIGlkja2SNrJE1skbWyBpZI2tk7S+sKdXd1McsfC3+O2IsWf5Od1dbwOcsdXw2qew6O4/JLTb/PeK71S9fPia3OCwoQ4tjVRNkUQXaAjoZxxapbExuJZbbvbLU78Pc1guW24nlDq8s9fswd5IWuKCjqJ3nwZ1+OfI5eYfjP8rMF1kja2SNrJE1skbWyBpZI2tkjayRNbJG1sgaWSNrZI2s/YU1pbpb+piFr8XfJsZSvw/jagv4nKWOzyaVXWfnMbnL5u8gvu/75cvH5C6HBWVocaxqgiyqQFtAJ0sdn00qGxNmuccrS0d+H+buXrDcQyz3emWp34e5j7TABR1F7TwP7vPLkc/Jex3/UWa+yBpZI2tkjayRNbJG1si6YbOmVHdXH7PwuczdYiwd+Xmsqy3gc5Y6PptUdp7CY3K/zd9LfD/wy5ePyf0OC8rQ4ljVBFlUgbaATpY6PptUNibM8qBXlvp57AO9YHmQWB7yylI/j32YtMAFHUXtPA8e9suRz8mHHP9RZr7IGlkja2SNrJE1skbWyLphs6ZUd38fs/C5zANiLPXzWFdbwOcsdXw2qew8hcfkEZt/iPh+6JcvH5NHHBaUocWxqgmyqAJtAZ0sdXw2qWxMmOUxryz189hHe8HyGLE87pWlfh77BGmBCzqK2nkePOGXI5+Tjzv+o8x8kTWyRtbIGlkja2SNrJF1w2ZNqe6RPmbhc5lHxVjq57GutoDPWer4bFLZeQqPyZM2/zjx/cgvXz4mTzosKEOLY1UTZFEF2gI6Wer4bFLZmDDL035Z8v8P81QvWJ4mlmf8suTnsc+SFrigo6id58GzfjnyOfmM4z/KzBdZN2zWlOqe7GMW3nc9JceS/38YV1tAJ0sdn00q2y/xmDxn888Q34/98uVj8pzDgjK0OFY1QRZVoC2gk6WOzyaVjQmzvOCXJf/eer4XLC8Qy4t+WfLvrZdIC1zQUdTO8+Alvxz5nHzR8R9l5ousGzZrSnXP9TEL77uel2PJv7dcbQGdLHV8Nqlsv8Rj8rLNv0h8P/HLl4/Jyw4LytDiWNUEWVSBtoBOljo+m1Q2JszyigDLT3vB8gqxvOqXJf/e+hlpgQs6itp5HvzML0c+J191/EeZ+foLa0p1L/cxC29jP5VjyVSBtoRO6vhsUtn2w2Pyms2/Snw/98uXj8lrDgvK0OJY1QRZVIG2gE6WOj6bVDYm0DfrvW7zrxHfLzzHISEd9IsytDhWNUEWVaAtoJOljs8mlY0J9M16v7T514nvfzzHISEd9IsytDhWNUEWVaAtoJOljs8mlY0J9M16v7L5XxLfrz3HISEd9IsytDhWNUEWVaAtoJOljs8mlY0J9M16b9j8r4jvfz3HISEd9IsytDhWNUEWVaAtoJOljs8mlY0J9M16v7H5N4jvTc9xSEgH/aIMLY5VTZBFFWgL6GSp47NJZWMCfbPeb23+N8T3O89xSEgH/aIMLY5VTZBFFWgL6GSp47NJZWMCfbPe723+t8T3luc4JKSDflGGFseqJsiiCrQFdLLU8dmksjFhlj/4ZWk3ff7Rb5/vMX38ifjhK9gVtf+RfPuTX458bv2h0jOmKDPf38o6qo9Zpcb/z377zOc3x9Sksvn9Z/LvL55ZWnQfgyrd44r+3dg2EM//UR7t2O80a3u7YDnkm6id91VJ4tWvfL4gqAks6clidBsEdKEzAAi2DK1GWqYrrX8OqdS3JaQx0rGh1El5aDHLzIBYJgbEsnFALIsDYlkQEMusgFhaA2KZHRDL5IBYlgTEsjAglo6AWKYGxDI6IJZ5AbHMCYilLSCWsQGxrA2IpSsglk0CYlkUEMv8gFjmBsQyIyCW8QGxjAqIZbOAWN4OiCXpY5a0su61r5Ta36a6Bmddc33lgJbu9kZcZynopzFZdzn2vUnAd9bppDK0mokBbX3J8nZALJsFxDIqIJbxAbHMCIhlbkAs8wNiWRQQyyYBsXQFxLI2IJaxAbG0BcQyJyCWeQGxjA6IZWpALB0BsSwMiGVJQCyTA2KZHRBLa0AsswJiWRAQy+KAWDYOiGViQCwzA2IZU8AywC9L/izcQNtnzmPzA4gDTAOJY5BnjsThOJ10B0npdtR/KzbYqy9Z/o7U1PaJvk2dKqhrJp/z+Pcs9rj+pmi9Fpvn37MMFRiTYRT7TtJQVD9cYPsYRttHQhqob6T8/ObuZbEcfrPW4swh8zHC5hvsMsMLlhlCee5nBA0Q5zGO78SH2rmvlr/CN5DW67R9t69fyuM5lFg7qTyCeLZq7mZo8cuQcUybbL+YQy1yvrfznMAcdsfF1I8UiPlwZw5DYzjNYeQPtLGv0HImNTvj1EzxGkn7g6LtcqTgPML31lCHpWwZ3l5Glmw7xsdhybrLlcVFUfuwv1GH12kRjtsIZ/sb4fhntomdaPvzvS83cwTX54eS5mLS9Pud3pH7PdjZ9sAwiLYBLDOypZvrcOLyfPyV7xMGOMca+B5tornb5Cwz0Dk24vtSvF4D+Xw6LcPHTxWBOZY4+xv3N8xGF7+j9qkLHfx22v3NdiMtc6wd1yGW522/PPnv9N2DKKfY45iK7+t6/p2+xHMI6zyHAufAzs928DMIEs92/KXSM6Yov9tzKGWs0s+h/DVWqfH3/BxSr59D4WeRPD9n885zKABA/25sG4jh934Z8vPX31W6EzShY3Y3eNaMl0O+idp/T5wSz87ieT/sn990WLgO+1Ksw/tSLHMB7UtTqufrBb6fhe7t87D8vPQbflnysf81abnPQCtq52eEJd4f8G7PqvP7A5Aa5GJS+vudNwpYZgbEMiYglokBsQwLiGVxQCxpQCwLAmJpDIhlVkAsrQGxDA+IpTkglqaAWGYHxDI5IJa3AmIZERDLkoBYVEAsCwNiGRAQy6YBsXQExDI1IJbRAbGMDIilJSCWgQGxzAuIZU5ALG0BsYwNiGVtQCwbBcTSFRDLkIBYFgXEMigglvkBsWwSEMvcgFhmBMQyPiCWNwNi2SwglqEBsQwOiCXpY5Z3e/4b7W9RHe5//YbqGgr6wzVrLG/O0w9vWbcfad9Zp5PK0OLnv38dAMvggFiGBsSyWUAsbwbEMj4glhkBscwNiGWTgFjmB8QyKCCWRQGxDAmIpSsglo0CYlkbEMvYgFjaAmKZExDLvIBYBgbE0hIQy8iAWEYHxDI1IJaOgFg2DYhlQEAsCwNiUQGxLAmIZURALG8FxDI5IJbZAbE0BcTSHBDL8IBYWgNimRUQS2NALAsCYkkDYlkcEMuwgFgmBsQyJiCWmQGxNDgszdQ+lurwv03HUx3+N+5EqsP/pW2lOvxf48lU97rNT6W6n9t8G9W9ZvMzqA7/T3wm1eF/ec+iuldsfjbV4f+vd1DdT2x+DtXh/7XPpbqXbH4e1b1o8/Op7gWbX0B1z9v8Qqr7sc0vorrnbH4x1T1r80uo7hmb76K6p20e1/fMvPqRzXfaz/b1S/kzv09Veqay+7Q/IpYn/bLkzzQ/4blP08fjxA9fwa6o/Qny7XG/HPn2+2SlZ0xRZr7+wppSHd9rR/uvqO4xm+f/vf2ozf+S6n5o8/x/0x+x+dep7mGb/znVPWTzL1Hdgzb/ItU9YPMvUN0PbP55qrvf5n9MdffZ/HNUd6/NP0t199j8M1R3t80/RXXft/knqO4um3+N6u60+Z9R3R02/yrV3W7zr1DdbTb/U6q71eZ/QnW32PzLVHezzT9Ndfh+eZLqcEzLcwPnaI9RHa4LPUp1uP77Q6rDvbhHqA6/RXiY6nDM+BDV4XzsQarDdZcHqA7Xen9AdbjXdT/V4XcH91EdjsnupTqce91DdbiucTfV4bru96kO95Luojq8s+JOqsN7ZO6gOlybvZ3qcGx0G9Xhvu+tVIdrhrdQHX7bgLE3Y2H2B+/2rp2U6j2/PzDfD+FdPgMcDmg10jJj7KBiHPkdO3g/E7ibab0m8qHRrw/5+4CayIfBpNtIPmCZ8eSD4ZH4f6Qcl06KCbR4HmBZfp8T/9aDjynH2fyESnc/VafO+NRK2r58gg76RZmPW3FcWyWWSZ5ZUtJEKjuemkQsk/2y5Mc+U0gLXNBR1M7vyJniOSYJaaJflJlvcgEr9m9m/KrOcoZ12j+AFXN9mrDuVEd3oqObOvEyqWxu8bNubX558/3adOq/kzT4/RYzBOI0nXxPSAP1jZTfEV/0tJxJ2Ffxuem0guU4P8VZR1H7NGGf24ijk8rQMvvnbVq6GTzPz3y8pzkMKE+k+raCeE2jeKG9aj9TaudnpzzP144yfh5PMEwWZFEF2hyHCQHEAQxTqA7LCe5XCvlGF8QKdVjWzP/diKvRM1d+fOu5Tz5PQirbn0N/cKX7nGb1mpWrlh69fN/lS5cl1EWT010DdcP5RgrpQAol6rAs2gbZfEihaOkZigNXHbtmeW9jkVAsEvLVZfDm8CgSa7DiTdaxgVbcOIdzWmUdNecF5pzUnIOac05zjmnOKc055Cji/Lj9NOeMZlsx54TmHNCc85lje7OfM9+B5tjGbOtmH16t1I+7zDGp2f+Zbd9s62YbM9ue+U413zebV+rXareo1K/PblmpX5M1B5zmOmxWqV973apSv95qXiy5tbZttG2r7b3attO2vbYdtL2vUr8G21mpX3d9v7Ydte2kbWdtNW27VOrXX3et1Lfz3bXtoW3PSv0a7F7a9ta2j7Z9te1XqV+H3V/bAdoO1HaQtoMr9Wuxh2g7VNth2g7XdkSlfj12qbYjtR2lbZm25ZX6NdmjtR2j7Vhtx2k7XtsKbSdoO1HbSm0naTtZ2yptq7Wt0XaKtlO1nVapv6/1DG1navuAtrO0na3tHG0f1HautvMq9eu9H9J2vrYLtF2o7cPaPqLto9ou0vYxbRdX6uN8ibZLtX1C22XaLtd2hbZPartS26e0XaXtam3XaPu0tmu1fUbbddo+q+16bTdou7HSvbHz5L/ZFnCtYtcTly0/vbrylDXVlV3VI1eecuKy1bz4cnttZntb3q++bVZXr1i5ptpePVH/XbpixcrTli/bssptq6snnLJ6TXX1mqWr1lS7Vq08odqxJfd7jD0FxeWgvU5dvqpL98PLnN8soz26pVchGGcXx5HmAUtXnLK8umblyuqKpau0ZNfKVdX9lnYt378ja/9/htUO70ouAgA=", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -1576,7 +1576,7 @@ ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -1852,7 +1852,7 @@ ] } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { @@ -3185,7 +3185,7 @@ "fileMap": { "1": { "source": "// docs:start:token_all\n// docs:start:imports\nmod types;\n\n// Minimal token implementation that supports `AuthWit` accounts.\n// The auth message follows a similar pattern to the cross-chain message and includes a designated caller.\n// The designated caller is ALWAYS used here, and not based on a flag as cross-chain.\n// message hash = H([caller, contract, selector, ...args])\n// To be read as `caller` calls function at `contract` defined by `selector` with `args`\n// Including a nonce in the message hash ensures that the message can only be used once.\n\ncontract Token {\n // Libs\n use dep::std::option::Option;\n\n use dep::safe_math::SafeU120;\n\n use dep::aztec::{\n note::{\n note_getter_options::NoteGetterOptions,\n note_header::NoteHeader,\n utils as note_utils,\n },\n context::{PrivateContext, PublicContext, Context},\n hash::{compute_secret_hash},\n state_vars::{map::Map, public_state::PublicState, set::Set},\n types::type_serialization::{\n field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN},\n bool_serialization::{BoolSerializationMethods, BOOL_SERIALIZED_LEN},\n aztec_address_serialization::{AztecAddressSerializationMethods, AZTEC_ADDRESS_SERIALIZED_LEN},\n },\n types::address::{AztecAddress},\n selector::compute_selector,\n };\n\n // docs:start:import_authwit\n use dep::authwit::{\n auth::{\n assert_current_call_valid_authwit, \n assert_current_call_valid_authwit_public, \n },\n };\n // docs:end:import_authwit\n\n use crate::types::{\n transparent_note::{TransparentNote, TransparentNoteMethods, TRANSPARENT_NOTE_LEN},\n token_note::{TokenNote, TokenNoteMethods, TOKEN_NOTE_LEN},\n balances_map::{BalancesMap},\n safe_u120_serialization::{SafeU120SerializationMethods, SAFE_U120_SERIALIZED_LEN}\n };\n // docs:end::imports\n\n // docs:start:storage_struct\n struct Storage {\n // docs:start:storage_admin\n admin: PublicState,\n // docs:end:storage_admin\n // docs:start:storage_minters\n minters: Map>,\n // docs:end:storage_minters\n // docs:start:storage_balances\n balances: BalancesMap,\n // docs:end:storage_balances\n total_supply: PublicState,\n // docs:start:storage_pending_shields\n pending_shields: Set,\n // docs:end:storage_pending_shields\n public_balances: Map>,\n }\n // docs:end:storage_struct\n\n // docs:start:storage_init\n impl Storage {\n fn init(context: Context) -> pub Self {\n Storage {\n // docs:start:storage_admin_init\n admin: PublicState::new(\n context,\n 1,\n AztecAddressSerializationMethods,\n ),\n // docs:end:storage_admin_init\n // docs:start:storage_minters_init\n minters: Map::new(\n context,\n 2,\n |context, slot| {\n PublicState::new(\n context,\n slot,\n BoolSerializationMethods,\n )\n },\n ),\n // docs:end:storage_minters_init\n balances: BalancesMap::new(context, 3),\n total_supply: PublicState::new(\n context,\n 4,\n SafeU120SerializationMethods,\n ),\n // docs:start:storage_pending_shields_init\n pending_shields: Set::new(context, 5, TransparentNoteMethods),\n // docs:end:storage_pending_shields_init\n public_balances: Map::new(\n context,\n 6,\n |context, slot| {\n PublicState::new(\n context,\n slot,\n SafeU120SerializationMethods,\n )\n },\n ),\n }\n }\n }\n // docs:end:storage_init\n\n // docs:start:constructor\n #[aztec(private)]\n fn constructor(admin: AztecAddress) {\n let selector = compute_selector(\"_initialize((Field))\");\n context.call_public_function(context.this_address(), selector, [admin.address]);\n }\n // docs:end:constructor\n\n // docs:start:set_admin\n #[aztec(public)]\n fn set_admin(\n new_admin: AztecAddress,\n ) {\n assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), \"caller is not admin\");\n // docs:start:write_admin\n storage.admin.write(new_admin);\n // docs:end:write_admin\n }\n // docs:end:set_admin\n\n // docs:start:set_minter\n #[aztec(public)]\n fn set_minter(\n minter: AztecAddress,\n approve: bool,\n ) {\n // docs:start:read_admin\n assert(storage.admin.read().eq(AztecAddress::new(context.msg_sender())), \"caller is not admin\");\n // docs:end:read_admin\n // docs:start:write_minter\n storage.minters.at(minter.address).write(approve);\n // docs:end:write_minter\n }\n // docs:end:set_minter\n\n // docs:start:mint_public\n #[aztec(public)]\n fn mint_public(\n to: AztecAddress,\n amount: Field,\n ) -> Field {\n // docs:start:read_minter\n assert(storage.minters.at(context.msg_sender()).read(), \"caller is not minter\");\n // docs:end:read_minter\n let amount = SafeU120::new(amount);\n let new_balance = storage.public_balances.at(to.address).read().add(amount);\n let supply = storage.total_supply.read().add(amount);\n\n storage.public_balances.at(to.address).write(new_balance);\n storage.total_supply.write(supply);\n 1\n }\n // docs:end:mint_public\n\n // docs:start:mint_private\n #[aztec(public)]\n fn mint_private(\n amount: Field,\n secret_hash: Field,\n ) -> Field {\n assert(storage.minters.at(context.msg_sender()).read(), \"caller is not minter\");\n let pending_shields = storage.pending_shields;\n let mut note = TransparentNote::new(amount, secret_hash);\n let supply = storage.total_supply.read().add(SafeU120::new(amount));\n\n storage.total_supply.write(supply);\n // docs:start:insert_from_public\n pending_shields.insert_from_public(&mut note);\n // docs:end:insert_from_public\n 1\n }\n // docs:end:mint_private\n\n // docs:start:shield\n #[aztec(public)]\n fn shield(\n from: AztecAddress,\n amount: Field,\n secret_hash: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n // The redeem is only spendable once, so we need to ensure that you cannot insert multiple shields from the same message.\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n\n let pending_shields = storage.pending_shields;\n let mut note = TransparentNote::new(amount.value as Field, secret_hash);\n\n storage.public_balances.at(from.address).write(from_balance);\n pending_shields.insert_from_public(&mut note);\n 1\n }\n // docs:end:shield\n\n // docs:start:transfer_public\n #[aztec(public)]\n fn transfer_public(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n storage.public_balances.at(from.address).write(from_balance);\n\n let to_balance = storage.public_balances.at(to.address).read().add(amount);\n storage.public_balances.at(to.address).write(to_balance);\n\n 1\n }\n // docs:end:transfer_public\n\n // docs:start:burn_public\n #[aztec(public)]\n fn burn_public(\n from: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit_public(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n let from_balance = storage.public_balances.at(from.address).read().sub(amount);\n storage.public_balances.at(from.address).write(from_balance);\n\n let new_supply = storage.total_supply.read().sub(amount);\n storage.total_supply.write(new_supply);\n\n 1\n }\n // docs:end:burn_public\n\n // docs:start:redeem_shield\n #[aztec(private)]\n fn redeem_shield(\n to: AztecAddress,\n amount: Field,\n secret: Field,\n ) -> Field {\n let pending_shields = storage.pending_shields;\n let secret_hash = compute_secret_hash(secret);\n let options = NoteGetterOptions::new().select(0, amount).select(1, secret_hash).set_limit(1);\n let notes = pending_shields.get_notes(options);\n let note = notes[0].unwrap_unchecked();\n pending_shields.remove(note);\n\n storage.balances.at(to).add(SafeU120::new(amount));\n\n 1\n }\n // docs:end:redeem_shield\n\n // docs:start:unshield\n #[aztec(private)]\n fn unshield(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n storage.balances.at(from).sub(SafeU120::new(amount));\n\n let selector = compute_selector(\"_increase_public_balance((Field),Field)\");\n let _void = context.call_public_function(context.this_address(), selector, [to.address, amount]);\n\n 1\n }\n // docs:end:unshield\n\n // docs:start:transfer\n #[aztec(private)]\n fn transfer(\n from: AztecAddress,\n to: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n let amount = SafeU120::new(amount);\n storage.balances.at(from).sub(amount);\n storage.balances.at(to).add(amount);\n\n 1\n }\n // docs:end:transfer\n\n // docs:start:burn\n #[aztec(private)]\n fn burn(\n from: AztecAddress,\n amount: Field,\n nonce: Field,\n ) -> Field {\n if (from.address != context.msg_sender()) {\n assert_current_call_valid_authwit(&mut context, from);\n } else {\n assert(nonce == 0, \"invalid nonce\");\n }\n\n storage.balances.at(from).sub(SafeU120::new(amount));\n\n let selector = compute_selector(\"_reduce_total_supply(Field)\");\n let _void = context.call_public_function(context.this_address(), selector, [amount]);\n\n 1\n }\n // docs:end:burn\n\n // docs:start:initialize\n #[aztec(public)]\n internal fn _initialize(\n new_admin: AztecAddress,\n ) {\n storage.admin.write(new_admin);\n storage.minters.at(new_admin.address).write(true);\n }\n // docs:end:initialize\n\n /// Internal ///\n\n // docs:start:increase_public_balance\n #[aztec(public)]\n internal fn _increase_public_balance(\n to: AztecAddress,\n amount: Field,\n ) {\n let new_balance = storage.public_balances.at(to.address).read().add(SafeU120::new(amount));\n storage.public_balances.at(to.address).write(new_balance);\n }\n // docs:end:increase_public_balance\n\n // docs:start:reduce_total_supply\n #[aztec(public)]\n internal fn _reduce_total_supply(\n amount: Field,\n ) {\n // Only to be called from burn.\n let new_supply = storage.total_supply.read().sub(SafeU120::new(amount));\n storage.total_supply.write(new_supply);\n }\n // docs:end:reduce_total_supply\n\n /// Unconstrained ///\n\n // docs:start:admin\n unconstrained fn admin() -> Field {\n storage.admin.read().address\n }\n // docs:end:admin\n\n // docs:start:is_minter\n unconstrained fn is_minter(\n minter: AztecAddress,\n ) -> bool {\n storage.minters.at(minter.address).read()\n }\n // docs:end:is_minter\n\n // docs:start:total_supply\n unconstrained fn total_supply() -> u120 {\n storage.total_supply.read().value\n }\n // docs:end:total_supply\n\n // docs:start:balance_of_private\n unconstrained fn balance_of_private(\n owner: AztecAddress,\n ) -> u120 {\n storage.balances.at(owner).balance_of().value\n }\n // docs:end:balance_of_private\n\n // docs:start:balance_of_public\n unconstrained fn balance_of_public(\n owner: AztecAddress,\n ) -> u120 {\n storage.public_balances.at(owner.address).read().value\n }\n // docs:end:balance_of_public\n\n // Below this point is the stuff of nightmares.\n // This should ideally not be required. What do we do if vastly different types of preimages?\n\n // docs:start:compute_note_hash_and_nullifier\n // Computes note hash and nullifier.\n // Note 1: Needs to be defined by every contract producing logs.\n // 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.\n unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; TOKEN_NOTE_LEN]) -> [Field; 4] {\n let note_header = NoteHeader::new(contract_address, nonce, storage_slot);\n if (storage_slot == 5) {\n note_utils::compute_note_hash_and_nullifier(TransparentNoteMethods, note_header, preimage)\n } else {\n note_utils::compute_note_hash_and_nullifier(TokenNoteMethods, note_header, preimage)\n }\n }\n // docs:end:compute_note_hash_and_nullifier\n}\n// docs:end:token_all\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/main" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/main" }, "6": { "source": "mod poseidon;\n\n#[foreign(sha256)]\npub fn sha256(_input : [u8; N]) -> [u8; 32] {}\n\n#[foreign(blake2s)]\npub fn blake2s(_input : [u8; N]) -> [u8; 32] {}\n\npub fn pedersen(input : [Field; N]) -> [Field; 2] {\n pedersen_with_separator(input, 0)\n}\n\n#[foreign(pedersen)]\npub fn pedersen_with_separator(_input : [Field; N], _separator : u32) -> [Field; 2] {}\n\n#[foreign(hash_to_field_128_security)]\npub fn hash_to_field(_input : [Field; N]) -> Field {}\n\n#[foreign(keccak256)]\npub fn keccak256(_input : [u8; N], _message_size: u32) -> [u8; 32] {}\n\n// mimc-p/p implementation\n// constants are (publicly generated) random numbers, for instance using keccak as a ROM.\n// You must use constants generated for the native field\n// Rounds number should be ~ log(p)/log(exp)\n// For 254 bit primes, exponent 7 and 91 rounds seems to be recommended\nfn mimc(x: Field, k: Field, constants: [Field; N], exp : Field) -> Field {\n //round 0\n let mut t = x + k;\n let mut h = t.pow_32(exp);\n //next rounds\n for i in 1 .. constants.len() {\n t = h + k + constants[i];\n h = t.pow_32(exp);\n };\n h + k\n}\n\nglobal MIMC_BN254_ROUNDS = 91;\n\n//mimc implementation with hardcoded parameters for BN254 curve.\npub fn mimc_bn254(array: [Field; N]) -> Field {\n //mimc parameters\n let exponent = 7;\n //generated from seed \"mimc\" using keccak256 \n let constants: [Field; MIMC_BN254_ROUNDS] = [\n 0, \n 20888961410941983456478427210666206549300505294776164667214940546594746570981,\n 15265126113435022738560151911929040668591755459209400716467504685752745317193,\n 8334177627492981984476504167502758309043212251641796197711684499645635709656,\n 1374324219480165500871639364801692115397519265181803854177629327624133579404,\n 11442588683664344394633565859260176446561886575962616332903193988751292992472,\n 2558901189096558760448896669327086721003508630712968559048179091037845349145,\n 11189978595292752354820141775598510151189959177917284797737745690127318076389,\n 3262966573163560839685415914157855077211340576201936620532175028036746741754,\n 17029914891543225301403832095880481731551830725367286980611178737703889171730,\n 4614037031668406927330683909387957156531244689520944789503628527855167665518,\n 19647356996769918391113967168615123299113119185942498194367262335168397100658,\n 5040699236106090655289931820723926657076483236860546282406111821875672148900,\n 2632385916954580941368956176626336146806721642583847728103570779270161510514,\n 17691411851977575435597871505860208507285462834710151833948561098560743654671,\n 11482807709115676646560379017491661435505951727793345550942389701970904563183,\n 8360838254132998143349158726141014535383109403565779450210746881879715734773,\n 12663821244032248511491386323242575231591777785787269938928497649288048289525,\n 3067001377342968891237590775929219083706800062321980129409398033259904188058,\n 8536471869378957766675292398190944925664113548202769136103887479787957959589,\n 19825444354178182240559170937204690272111734703605805530888940813160705385792,\n 16703465144013840124940690347975638755097486902749048533167980887413919317592,\n 13061236261277650370863439564453267964462486225679643020432589226741411380501,\n 10864774797625152707517901967943775867717907803542223029967000416969007792571,\n 10035653564014594269791753415727486340557376923045841607746250017541686319774,\n 3446968588058668564420958894889124905706353937375068998436129414772610003289,\n 4653317306466493184743870159523234588955994456998076243468148492375236846006,\n 8486711143589723036499933521576871883500223198263343024003617825616410932026,\n 250710584458582618659378487568129931785810765264752039738223488321597070280,\n 2104159799604932521291371026105311735948154964200596636974609406977292675173,\n 16313562605837709339799839901240652934758303521543693857533755376563489378839,\n 6032365105133504724925793806318578936233045029919447519826248813478479197288,\n 14025118133847866722315446277964222215118620050302054655768867040006542798474,\n 7400123822125662712777833064081316757896757785777291653271747396958201309118,\n 1744432620323851751204287974553233986555641872755053103823939564833813704825,\n 8316378125659383262515151597439205374263247719876250938893842106722210729522,\n 6739722627047123650704294650168547689199576889424317598327664349670094847386,\n 21211457866117465531949733809706514799713333930924902519246949506964470524162,\n 13718112532745211817410303291774369209520657938741992779396229864894885156527,\n 5264534817993325015357427094323255342713527811596856940387954546330728068658,\n 18884137497114307927425084003812022333609937761793387700010402412840002189451,\n 5148596049900083984813839872929010525572543381981952060869301611018636120248,\n 19799686398774806587970184652860783461860993790013219899147141137827718662674,\n 19240878651604412704364448729659032944342952609050243268894572835672205984837,\n 10546185249390392695582524554167530669949955276893453512788278945742408153192,\n 5507959600969845538113649209272736011390582494851145043668969080335346810411,\n 18177751737739153338153217698774510185696788019377850245260475034576050820091,\n 19603444733183990109492724100282114612026332366576932662794133334264283907557,\n 10548274686824425401349248282213580046351514091431715597441736281987273193140,\n 1823201861560942974198127384034483127920205835821334101215923769688644479957,\n 11867589662193422187545516240823411225342068709600734253659804646934346124945,\n 18718569356736340558616379408444812528964066420519677106145092918482774343613,\n 10530777752259630125564678480897857853807637120039176813174150229243735996839,\n 20486583726592018813337145844457018474256372770211860618687961310422228379031,\n 12690713110714036569415168795200156516217175005650145422920562694422306200486,\n 17386427286863519095301372413760745749282643730629659997153085139065756667205,\n 2216432659854733047132347621569505613620980842043977268828076165669557467682,\n 6309765381643925252238633914530877025934201680691496500372265330505506717193,\n 20806323192073945401862788605803131761175139076694468214027227878952047793390,\n 4037040458505567977365391535756875199663510397600316887746139396052445718861,\n 19948974083684238245321361840704327952464170097132407924861169241740046562673,\n 845322671528508199439318170916419179535949348988022948153107378280175750024,\n 16222384601744433420585982239113457177459602187868460608565289920306145389382,\n 10232118865851112229330353999139005145127746617219324244541194256766741433339,\n 6699067738555349409504843460654299019000594109597429103342076743347235369120,\n 6220784880752427143725783746407285094967584864656399181815603544365010379208,\n 6129250029437675212264306655559561251995722990149771051304736001195288083309,\n 10773245783118750721454994239248013870822765715268323522295722350908043393604,\n 4490242021765793917495398271905043433053432245571325177153467194570741607167,\n 19596995117319480189066041930051006586888908165330319666010398892494684778526,\n 837850695495734270707668553360118467905109360511302468085569220634750561083,\n 11803922811376367215191737026157445294481406304781326649717082177394185903907,\n 10201298324909697255105265958780781450978049256931478989759448189112393506592,\n 13564695482314888817576351063608519127702411536552857463682060761575100923924,\n 9262808208636973454201420823766139682381973240743541030659775288508921362724,\n 173271062536305557219323722062711383294158572562695717740068656098441040230,\n 18120430890549410286417591505529104700901943324772175772035648111937818237369,\n 20484495168135072493552514219686101965206843697794133766912991150184337935627,\n 19155651295705203459475805213866664350848604323501251939850063308319753686505,\n 11971299749478202793661982361798418342615500543489781306376058267926437157297,\n 18285310723116790056148596536349375622245669010373674803854111592441823052978,\n 7069216248902547653615508023941692395371990416048967468982099270925308100727,\n 6465151453746412132599596984628739550147379072443683076388208843341824127379,\n 16143532858389170960690347742477978826830511669766530042104134302796355145785,\n 19362583304414853660976404410208489566967618125972377176980367224623492419647,\n 1702213613534733786921602839210290505213503664731919006932367875629005980493,\n 10781825404476535814285389902565833897646945212027592373510689209734812292327,\n 4212716923652881254737947578600828255798948993302968210248673545442808456151,\n 7594017890037021425366623750593200398174488805473151513558919864633711506220,\n 18979889247746272055963929241596362599320706910852082477600815822482192194401,\n 13602139229813231349386885113156901793661719180900395818909719758150455500533,\n ];\n\n let mut r = 0;\n for elem in array {\n let h = mimc(elem, r, constants, exponent);\n r = r + elem + h;\n }\n r\n}\n", @@ -3209,151 +3209,151 @@ }, "37": { "source": "use crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n GENERATOR_INDEX__FUNCTION_ARGS,\n HISTORIC_BLOCK_DATA_LENGTH,\n CONTRACT_DEPLOYMENT_DATA_LENGTH,\n CALL_CONTEXT_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH,\n CONTRACT_STORAGE_READ_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH,\n PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH,\n GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__FUNCTION_DATA,\n GENERATOR_INDEX__PUBLIC_DATA_READ,\n GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST,\n GENERATOR_INDEX__CALL_CONTEXT,\n GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS,\n GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA,\n};\n\nuse crate::oracle::debug_log;\nuse crate::types::vec::BoundedVec;\nuse crate::types::point::Point;\n\n\n// docs:start:private-global-variables\nstruct PrivateGlobalVariables {\n chain_id: Field,\n version: Field,\n}\n// docs:end:private-global-variables\n\nimpl PrivateGlobalVariables {\n fn serialize(self) -> [Field; 2] {\n [self.chain_id, self.version]\n }\n}\n\n// docs:start:public-global-variables\nstruct PublicGlobalVariables {\n chain_id: Field,\n version: Field,\n block_number: Field,\n timestamp: Field,\n}\n// docs:end:public-global-variables\n\nimpl PublicGlobalVariables {\n fn serialize(self) -> [Field; 4] {\n [self.chain_id, self.version, self.block_number, self.timestamp]\n }\n}\n\n// docs:start:contract-deployment-data\nstruct ContractDeploymentData {\n deployer_public_key: Point,\n constructor_vk_hash : Field,\n function_tree_root : Field,\n contract_address_salt : Field,\n portal_contract_address : Field,\n}\n// docs:end:contract-deployment-data\n\nimpl ContractDeploymentData {\n fn serialize(self) -> [Field; CONTRACT_DEPLOYMENT_DATA_LENGTH] {\n [\n self.deployer_public_key.x,\n self.deployer_public_key.y,\n self.constructor_vk_hash,\n self.function_tree_root,\n self.contract_address_salt,\n self.portal_contract_address,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA)[0]\n }\n}\n\n// PrivateContextInputs are expected to be provided to each private function\n// docs:start:private-context-inputs\nstruct PrivateContextInputs {\n call_context : CallContext,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n private_global_variables: PrivateGlobalVariables,\n}\n// docs:end:private-context-inputs\n\n// PublicContextInputs are expected to be provided to each public function\n// docs:start:public-context-inputs\nstruct PublicContextInputs {\n call_context: CallContext,\n block_data: HistoricBlockData,\n\n public_global_variables: PublicGlobalVariables,\n}\n// docs:end:public-context-inputs\n\n// docs:start:call-context\nstruct CallContext {\n msg_sender : Field,\n storage_contract_address : Field,\n portal_contract_address : Field,\n function_selector: Field,\n\n is_delegate_call : bool,\n is_static_call : bool,\n is_contract_deployment: bool,\n}\n// docs:end:call-context\n\nimpl CallContext {\n fn serialize(self) -> [Field; CALL_CONTEXT_LENGTH] {\n [\n self.msg_sender,\n self.storage_contract_address,\n self.portal_contract_address,\n self.function_selector,\n self.is_delegate_call as Field,\n self.is_static_call as Field,\n self.is_contract_deployment as Field,\n ]\n }\n\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__CALL_CONTEXT)[0]\n }\n}\n\n// docs:start:historic-block-data\nstruct HistoricBlockData {\n private_data_tree_root : Field,\n nullifier_tree_root : Field,\n contract_tree_root : Field,\n l1_to_l2_messages_tree_root : Field,\n blocks_tree_root: Field,\n public_data_tree_root: Field,\n global_variables_hash: Field,\n}\n// docs:end:historic-block-data\n\nimpl HistoricBlockData {\n // NOTE: this order must match the order in `private_circuit_public_inputs.hpp`\n pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {\n [\n self.private_data_tree_root,\n self.nullifier_tree_root,\n self.contract_tree_root,\n self.l1_to_l2_messages_tree_root,\n self.blocks_tree_root,\n self.public_data_tree_root,\n self.global_variables_hash,\n ]\n }\n\n pub fn empty() -> Self {\n Self { private_data_tree_root: 0, nullifier_tree_root: 0, contract_tree_root: 0, l1_to_l2_messages_tree_root: 0, blocks_tree_root: 0, public_data_tree_root: 0, global_variables_hash: 0 }\n }\n}\n\nstruct FunctionData {\n function_selector: Field,\n is_internal: bool,\n is_private: bool,\n is_constructor: bool,\n}\n\nimpl FunctionData {\n fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.function_selector,\n self.is_internal as Field,\n self.is_private as Field,\n self.is_constructor as Field,\n ], GENERATOR_INDEX__FUNCTION_DATA)[0]\n }\n}\n\nstruct PrivateCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n read_requests: [Field; crate::abi::MAX_READ_REQUESTS_PER_CALL],\n pending_read_requests: [Field; crate::abi::MAX_PENDING_READ_REQUESTS_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n nullified_commitments: [Field; MAX_NEW_NULLIFIERS_PER_CALL],\n private_call_stack: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n // Explore introducing a new type like uint256 (similar to Point), so it's more explicit that\n // we're talking about a single number backed by two field elements.\n encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n encrypted_log_preimages_length: Field,\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n contract_deployment_data: ContractDeploymentData,\n chain_id: Field,\n version: Field,\n}\n\nimpl PrivateCircuitPublicInputs {\n fn hash(self) -> Field {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push(self.call_context.hash());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.nullified_commitments);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.contract_deployment_data.hash());\n fields.push(self.chain_id);\n fields.push(self.version);\n\n dep::std::hash::pedersen_with_separator(fields.storage, GENERATOR_INDEX__PRIVATE_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n fn serialize(self) -> [Field; PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize());\n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n fields.push_array(self.read_requests);\n fields.push_array(self.pending_read_requests);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.private_call_stack);\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.encrypted_logs_hash);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.encrypted_log_preimages_length);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push_array(self.contract_deployment_data.serialize());\n fields.push(self.chain_id);\n fields.push(self.version);\n fields.storage\n }\n}\n\nstruct ContractStorageRead {\n storage_slot: Field,\n value: Field,\n}\n\nimpl ContractStorageRead {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_READ_LENGTH] {\n [self.storage_slot, self.value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_READ)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, value: 0 }\n }\n}\n\nstruct ContractStorageUpdateRequest {\n storage_slot: Field,\n old_value: Field,\n new_value: Field,\n}\n\nimpl ContractStorageUpdateRequest {\n pub fn serialize(self) -> [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH] {\n [self.storage_slot, self.old_value, self.new_value]\n }\n\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_DATA_UPDATE_REQUEST)[0]\n }\n\n pub fn empty() -> Self {\n Self { storage_slot: 0, old_value: 0, new_value: 0 }\n }\n}\n\n\nstruct PublicCircuitPublicInputs {\n call_context: CallContext,\n args_hash: Field,\n return_values: [Field; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead; MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [Field; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [Field; crate::abi::MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: Field,\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicCircuitPublicInputs {\n \n pub fn hash(self) -> Field {\n let mut inputs: BoundedVec = BoundedVec::new(0);\n inputs.push(self.call_context.hash());\n inputs.push(self.args_hash);\n inputs.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n inputs.push(self.contract_storage_update_requests[i].hash());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n inputs.push(self.contract_storage_read[i].hash());\n }\n inputs.push_array(self.public_call_stack);\n inputs.push_array(self.new_commitments);\n inputs.push_array(self.new_nullifiers);\n inputs.push_array(self.new_l2_to_l1_msgs);\n\n inputs.push_array(self.unencrypted_logs_hash);\n inputs.push(self.unencrypted_log_preimages_length);\n inputs.push_array(self.block_data.serialize());\n inputs.push(self.prover_address);\n\n dep::std::hash::pedersen_with_separator(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS)[0]\n }\n\n pub fn serialize(self) -> [Field; PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH] {\n let mut fields: BoundedVec = BoundedVec::new(0); \n fields.push_array(self.call_context.serialize()); \n fields.push(self.args_hash);\n fields.push_array(self.return_values);\n for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL {\n fields.push_array(self.contract_storage_update_requests[i].serialize());\n }\n for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL {\n fields.push_array(self.contract_storage_read[i].serialize());\n }\n fields.push_array(self.public_call_stack);\n fields.push_array(self.new_commitments);\n fields.push_array(self.new_nullifiers);\n fields.push_array(self.new_l2_to_l1_msgs);\n fields.push_array(self.unencrypted_logs_hash);\n fields.push(self.unencrypted_log_preimages_length);\n fields.push_array(self.block_data.serialize());\n fields.push(self.prover_address);\n fields.storage\n }\n}\n\nstruct Hasher {\n fields: [Field],\n}\n\nimpl Hasher {\n pub fn new()-> Self {\n Self { fields: [] }\n }\n\n pub fn add(&mut self, field: Field) {\n self.fields = self.fields.push_back(field);\n }\n\n pub fn add_multiple(&mut self, fields: [Field; N]) {\n for i in 0..N {\n self.fields = self.fields.push_back(fields[i]);\n }\n }\n\n pub fn hash(self) -> Field {\n hash_args(self.fields)\n }\n}\n\nglobal ARGS_HASH_CHUNK_LENGTH: u32 = 32;\nglobal ARGS_HASH_CHUNK_COUNT: u32 = 16;\n\npub fn hash_args(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = dep::std::hash::pedersen_with_separator(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS)[0];\n }\n chunks_hashes[i] = chunk_hash;\n }\n dep::std::hash::pedersen_with_separator(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)[0]\n }\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/abi" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/abi" }, "38": { "source": "use dep::std::hash;\nuse crate::constants_gen::GENERATOR_INDEX__CONTRACT_ADDRESS;\n\npub fn compute_address(pub_key_x: Field, pub_key_y: Field, partial_address: Field) -> Field {\n hash::pedersen_with_separator([pub_key_x, pub_key_y, partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0]\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/address" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/address" }, "40": { "source": "use crate::constants_gen::{\n EMPTY_NULLIFIED_COMMITMENT,\n MAX_NEW_COMMITMENTS_PER_CALL,\n MAX_NEW_L2_TO_L1_MSGS_PER_CALL,\n MAX_NEW_NULLIFIERS_PER_CALL,\n MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,\n MAX_PUBLIC_DATA_READS_PER_CALL,\n MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,\n MAX_READ_REQUESTS_PER_CALL,\n MAX_PENDING_READ_REQUESTS_PER_CALL,\n NUM_FIELDS_PER_SHA256,\n RETURN_VALUES_LENGTH,\n};\n\nuse crate::abi;\n\nuse crate::abi::{\n hash_args,\n CallContext,\n ContractDeploymentData,\n HistoricBlockData,\n FunctionData,\n PrivateCircuitPublicInputs,\n PublicCircuitPublicInputs,\n};\n\n// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n// use dep::std::collections::vec::Vec;\n\n// l1 to l2 messaging\nuse crate::messaging::process_l1_to_l2_message;\nuse crate::private_call_stack_item::PrivateCallStackItem;\nuse crate::public_call_stack_item::PublicCallStackItem;\n\nuse crate::types::{\n vec::BoundedVec,\n point::Point,\n};\n\nuse crate::utils::arr_copy_slice;\n\nuse crate::oracle::{\n arguments,\n call_private_function::call_private_function_internal,\n public_call::call_public_function_internal,\n enqueue_public_function_call::enqueue_public_function_call_internal,\n context::get_portal_address,\n};\n\nuse dep::std::option::Option;\n\n// When finished, one can call .finish() to convert back to the abi\nstruct PrivateContext {\n // docs:start:private-context\n inputs: abi::PrivateContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n read_requests: BoundedVec,\n pending_read_requests: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n nullified_commitments: BoundedVec,\n\n private_call_stack : BoundedVec,\n public_call_stack : BoundedVec,\n new_l2_to_l1_msgs : BoundedVec,\n // docs:end:private-context\n\n block_data: HistoricBlockData,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec,\n // unencrypted_logs_preimages: Vec,\n}\n\nimpl PrivateContext {\n pub fn new(inputs: abi::PrivateContextInputs, args_hash: Field) -> PrivateContext {\n PrivateContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n read_requests: BoundedVec::new(0),\n pending_read_requests: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n nullified_commitments: BoundedVec::new(0),\n\n block_data: inputs.block_data,\n\n private_call_stack: BoundedVec::new(0),\n public_call_stack: BoundedVec::new(0),\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.private_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.private_global_variables.version\n }\n\n pub fn selector(self) -> Field {\n self.inputs.call_context.function_selector\n }\n\n pub fn finish(self) -> abi::PrivateCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let encrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let encrypted_log_preimages_length = 0;\n let unencrypted_log_preimages_length = 0;\n\n let priv_circuit_pub_inputs = abi::PrivateCircuitPublicInputs {\n call_context: self.inputs.call_context,\n args_hash: self.args_hash,\n return_values: self.return_values.storage,\n read_requests: self.read_requests.storage,\n pending_read_requests: self.pending_read_requests.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n nullified_commitments: self.nullified_commitments.storage,\n private_call_stack: self.private_call_stack.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n encrypted_logs_hash: encrypted_logs_hash,\n unencrypted_logs_hash: unencrypted_logs_hash,\n encrypted_log_preimages_length: encrypted_log_preimages_length,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.block_data,\n contract_deployment_data: self.inputs.contract_deployment_data,\n chain_id: self.inputs.private_global_variables.chain_id,\n version: self.inputs.private_global_variables.version,\n };\n priv_circuit_pub_inputs\n }\n\n pub fn push_read_request(&mut self, read_request: Field) {\n self.read_requests.push(read_request);\n }\n\n pub fn push_pending_read_request(&mut self, pending_read_request: Field) {\n self.pending_read_requests.push(pending_read_request);\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n // We never push a zero nullified_commitment as zero is used to indicate the end\n // of a field array in private kernel. This routine transparently replaces a\n // zero value into the special placeholder: EMPTY_NULLIFIED_COMMITMENT.\n pub fn push_new_nullifier(&mut self, nullifier: Field, nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n let mut non_zero_nullified = nullified_commitment;\n if (non_zero_nullified == 0) {\n non_zero_nullified = EMPTY_NULLIFIED_COMMITMENT;\n }\n self.nullified_commitments.push(non_zero_nullified);\n }\n\n // docs:start:context_message_portal\n pub fn message_portal(&mut self, content: Field) \n // docs:end:context_message_portal\n {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n // docs:start:context_consume_l1_to_l2_message\n // docs:start:consume_l1_to_l2_message\n pub fn consume_l1_to_l2_message(\n &mut self,\n msg_key: Field,\n content: Field,\n secret: Field\n ) \n // docs:end:context_consume_l1_to_l2_message\n {\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, self.this_address(), msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n // docs:end:consume_l1_to_l2_message\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self.inputs;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_private_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_private_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_private_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n ) -> [Field; RETURN_VALUES_LENGTH] {\n self.call_private_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_private_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let fields = call_private_function_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PrivateCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PrivateCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n function_selector: fields[8], // practically same as fields[1]\n is_delegate_call : fields[9] as bool,\n is_static_call : fields[10] as bool,\n is_contract_deployment: fields[11] as bool,\n },\n // TODO handle the offsets as a variable incremented during extraction?\n args_hash: fields[12],\n return_values: arr_copy_slice(fields, [0; RETURN_VALUES_LENGTH], 13),\n read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 17),\n pending_read_requests: arr_copy_slice(fields, [0; MAX_READ_REQUESTS_PER_CALL], 49),\n new_commitments: arr_copy_slice(fields, [0; MAX_NEW_COMMITMENTS_PER_CALL], 81),\n new_nullifiers: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 97),\n nullified_commitments: arr_copy_slice(fields, [0; MAX_NEW_NULLIFIERS_PER_CALL], 113),\n private_call_stack: arr_copy_slice(fields, [0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], 129),\n public_call_stack: arr_copy_slice(fields, [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], 133),\n new_l2_to_l1_msgs: arr_copy_slice(fields, [0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], 137),\n encrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 139),\n unencrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 141),\n encrypted_log_preimages_length: fields[143],\n unencrypted_log_preimages_length: fields[144],\n block_data: HistoricBlockData {\n // Must match order in `private_circuit_public_inputs.hpp`\n private_data_tree_root : fields[145],\n nullifier_tree_root : fields[146],\n contract_tree_root : fields[147],\n l1_to_l2_messages_tree_root : fields[148],\n blocks_tree_root : fields[149],\n public_data_tree_root: fields[150],\n global_variables_hash: fields[151],\n },\n contract_deployment_data: ContractDeploymentData {\n deployer_public_key: Point::new(fields[152], fields[153]),\n constructor_vk_hash : fields[154],\n function_tree_root : fields[155],\n contract_address_salt : fields[156],\n portal_contract_address : fields[157],\n },\n chain_id: fields[158],\n version: fields[159],\n },\n is_execution_request: fields[160] as bool,\n };\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n\n assert(args_hash == item.public_inputs.args_hash);\n\n assert(item.is_execution_request == false);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.private_call_stack.push(item.hash());\n\n item.public_inputs.return_values\n }\n\n pub fn call_public_function(\n &mut self,\n contract_address: Field, \n function_selector: Field, \n args: [Field; ARGS_COUNT]\n ) {\n let args_hash = hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n self.call_public_function_with_packed_args(contract_address, function_selector, args_hash)\n }\n\n pub fn call_public_function_no_args(\n &mut self,\n contract_address: Field, \n function_selector: Field,\n ) {\n self.call_public_function_with_packed_args(contract_address, function_selector, 0)\n }\n\n pub fn call_public_function_with_packed_args(\n &mut self,\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n ) {\n let fields = enqueue_public_function_call_internal(\n contract_address, \n function_selector, \n args_hash\n );\n let item = PublicCallStackItem {\n contract_address: fields[0],\n function_data: FunctionData {\n function_selector: fields[1],\n is_internal: fields[2] as bool,\n is_private: fields[3] as bool,\n is_constructor: fields[4] as bool,\n },\n public_inputs: PublicCircuitPublicInputs {\n call_context: CallContext {\n msg_sender : fields[5],\n storage_contract_address : fields[6],\n portal_contract_address : fields[7],\n function_selector: fields[8], // practically same as fields[1]\n is_delegate_call : fields[9] as bool,\n is_static_call : fields[10] as bool,\n is_contract_deployment: fields[11] as bool,\n },\n args_hash: fields[12],\n return_values: [0; RETURN_VALUES_LENGTH],\n contract_storage_update_requests: [ContractStorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL],\n contract_storage_read: [ContractStorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL],\n public_call_stack: [0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL],\n new_commitments: [0; MAX_NEW_COMMITMENTS_PER_CALL],\n new_nullifiers: [0; MAX_NEW_NULLIFIERS_PER_CALL],\n new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL],\n unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256],\n unencrypted_log_preimages_length: 0,\n block_data: HistoricBlockData::empty(),\n prover_address: 0,\n },\n is_execution_request: true,\n };\n\n assert(contract_address == item.contract_address);\n assert(function_selector == item.function_data.function_selector);\n \n assert(args_hash == item.public_inputs.args_hash);\n\n // Assert that the call context of the enqueued call generated by the oracle matches our request.\n // We are issuing a regular call which is not delegate, static, or deployment. We also constrain\n // the msg_sender in the nested call to be equal to our address, and the execution context address\n // for the nested call to be equal to the address we actually called.\n assert(item.public_inputs.call_context.is_delegate_call == false);\n assert(item.public_inputs.call_context.is_static_call == false);\n assert(item.public_inputs.call_context.is_contract_deployment == false);\n assert(item.public_inputs.call_context.msg_sender == self.inputs.call_context.storage_contract_address);\n assert(item.public_inputs.call_context.storage_contract_address == contract_address);\n\n self.public_call_stack.push(item.hash());\n }\n}\n\nuse crate::abi::{\n ContractStorageRead,\n ContractStorageUpdateRequest\n};\n\nstruct PublicContext {\n inputs: abi::PublicContextInputs,\n\n args_hash : Field,\n return_values : BoundedVec,\n\n contract_storage_update_requests: BoundedVec,\n contract_storage_read: BoundedVec,\n public_call_stack: BoundedVec,\n\n new_commitments: BoundedVec,\n new_nullifiers: BoundedVec,\n\n new_l2_to_l1_msgs: BoundedVec,\n\n unencrypted_logs_hash: BoundedVec,\n unencrypted_logs_preimages_length: Field,\n\n block_data: HistoricBlockData,\n prover_address: Field,\n}\n\nimpl PublicContext {\n pub fn new(inputs: abi::PublicContextInputs, args_hash: Field) -> PublicContext {\n let empty_storage_read = ContractStorageRead::empty();\n let empty_storage_update = ContractStorageUpdateRequest::empty();\n PublicContext {\n inputs: inputs,\n\n args_hash: args_hash,\n return_values: BoundedVec::new(0),\n\n contract_storage_update_requests: BoundedVec::new(empty_storage_update),\n contract_storage_read: BoundedVec::new(empty_storage_read),\n public_call_stack: BoundedVec::new(0),\n\n new_commitments: BoundedVec::new(0),\n new_nullifiers: BoundedVec::new(0),\n\n new_l2_to_l1_msgs: BoundedVec::new(0),\n\n \n unencrypted_logs_hash: BoundedVec::new(0),\n unencrypted_logs_preimages_length: 0,\n\n block_data: inputs.block_data,\n prover_address: 0,\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n // encrypted_logs_preimages: Vec::new(),\n // unencrypted_logs_preimages: Vec::new(),\n }\n }\n\n pub fn msg_sender(self) -> Field {\n self.inputs.call_context.msg_sender\n }\n\n pub fn this_address(self) -> Field {\n self.inputs.call_context.storage_contract_address\n }\n\n pub fn this_portal_address(self) -> Field {\n self.inputs.call_context.portal_contract_address\n }\n\n pub fn chain_id(self) -> Field {\n self.inputs.public_global_variables.chain_id\n }\n\n pub fn version(self) -> Field {\n self.inputs.public_global_variables.version\n }\n\n pub fn selector(self) -> Field {\n self.inputs.call_context.function_selector\n }\n\n pub fn block_number(self) -> Field {\n self.inputs.public_global_variables.block_number\n }\n\n pub fn timestamp(self) -> Field {\n self.inputs.public_global_variables.timestamp\n }\n\n pub fn finish(self) -> abi::PublicCircuitPublicInputs {\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n let unencrypted_logs_hash = [0; NUM_FIELDS_PER_SHA256];\n let unencrypted_log_preimages_length = 0;\n\n\n // Compute the public call stack hashes\n let pub_circuit_pub_inputs = abi::PublicCircuitPublicInputs {\n call_context: self.inputs.call_context, // Done\n args_hash: self.args_hash, // Done\n contract_storage_update_requests: self.contract_storage_update_requests.storage,\n contract_storage_read: self.contract_storage_read.storage,\n return_values: self.return_values.storage,\n new_commitments: self.new_commitments.storage,\n new_nullifiers: self.new_nullifiers.storage,\n public_call_stack: self.public_call_stack.storage,\n new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage,\n unencrypted_logs_hash: unencrypted_logs_hash,\n unencrypted_log_preimages_length: unencrypted_log_preimages_length,\n block_data: self.inputs.block_data,\n prover_address: self.prover_address,\n };\n pub_circuit_pub_inputs\n }\n\n pub fn push_new_note_hash(&mut self, note_hash: Field) {\n self.new_commitments.push(note_hash);\n }\n\n pub fn push_new_nullifier(&mut self, nullifier: Field, _nullified_commitment: Field) {\n self.new_nullifiers.push(nullifier);\n }\n\n pub fn message_portal(&mut self, content: Field) {\n self.new_l2_to_l1_msgs.push(content);\n }\n\n // PrivateContextInputs must be temporarily passed in to prevent too many unknowns\n // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned\n pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) {\n let this = (*self).this_address();\n let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, this, msg_key, content, secret);\n\n // Push nullifier (and the \"commitment\" corresponding to this can be \"empty\")\n self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT)\n }\n\n pub fn accumulate_encrypted_logs(&mut self, log: [Field; N]) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn accumulate_unencrypted_logs(&mut self, log: T) {\n let _void1 = self;\n let _void2 = log;\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165)\n }\n\n pub fn call_public_function(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n args: [Field; ARGS_COUNT],\n ) -> [Field; RETURN_VALUES_LENGTH] {\n let args_hash = abi::hash_args(args);\n assert(args_hash == arguments::pack_arguments(args));\n call_public_function_internal(\n contract_address, \n function_selector, \n args_hash,\n )\n }\n\n pub fn call_public_function_no_args(\n _self: Self,\n contract_address: Field, \n function_selector: Field,\n ) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_internal(\n contract_address, \n function_selector, \n 0,\n )\n }\n\n}\n\nstruct Context {\n private: Option<&mut PrivateContext>,\n public: Option<&mut PublicContext>,\n}\n\nimpl Context {\n pub fn private(context: &mut PrivateContext) -> Context {\n Context {\n private: Option::some(context),\n public: Option::none()\n }\n }\n\n pub fn public(context: &mut PublicContext) -> Context {\n Context {\n public: Option::some(context),\n private: Option::none()\n }\n }\n\n pub fn none() -> Context {\n Context {\n public: Option::none(),\n private: Option::none()\n }\n }\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/context" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/context" }, "41": { "source": "use dep::std::hash::{pedersen_with_separator, sha256};\nuse crate::constants_gen::{\n GENERATOR_INDEX__SIGNATURE_PAYLOAD,\n GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET,\n};\n\npub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn compute_secret_hash(secret: Field) -> Field {\n // TODO(#1205) This is probably not the right index to use\n pedersen_with_separator([secret], GENERATOR_INDEX__L1_TO_L2_MESSAGE_SECRET)[0]\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/hash" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/hash" }, "42": { "source": "use crate::context::{PrivateContext, PublicContext};\nuse crate::oracle;\nuse crate::types::point::Point;\n\npub fn emit_encrypted_log(\n context: &mut PrivateContext,\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n log: [Field; N],\n) {\n let _ = oracle::logs::emit_encrypted_log(contract_address, storage_slot, encryption_pub_key, log);\n context.accumulate_encrypted_logs(log);\n}\n\npub fn emit_unencrypted_log(\n context: &mut PublicContext,\n log: T,\n) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n\n// TODO: We might want to remove this since emitting unencrypted logs from private functions is violating privacy.\n// --> might be a better approach to force devs to make a public function call that emits the log if needed then\n// it would be less easy to accidentally leak information.\n// If we decide to keep this function around would make sense to wait for traits and then merge it with emit_unencrypted_log.\npub fn emit_unencrypted_log_from_private(\n context: &mut PrivateContext,\n log: T,\n) {\n let contract_address = context.this_address();\n let event_selector = 5; // TODO: compute actual event selector.\n let _ = oracle::logs::emit_unencrypted_log(contract_address, event_selector, log);\n // context.accumulate_unencrypted_logs(log);\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/log" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/log" }, "47": { "source": "use dep::std::option::Option;\nuse crate::abi::PublicContextInputs;\nuse crate::context::{\n PrivateContext,\n PublicContext,\n};\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_inner_note_hash,\n};\nuse crate::oracle::notes::{notify_created_note, notify_nullified_note};\nuse crate::constants_gen::EMPTY_NULLIFIED_COMMITMENT;\n\npub fn create_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n let serialize = note_interface.serialize;\n let preimage = serialize(*note);\n assert(notify_created_note(storage_slot, preimage, inner_note_hash) == 0);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn create_note_hash_from_public(\n context: &mut PublicContext,\n storage_slot: Field,\n note: &mut Note,\n note_interface: NoteInterface,\n) {\n let contract_address = (*context).this_address();\n\n let header = NoteHeader { contract_address, storage_slot, nonce: 0, is_transient: true };\n let set_header = note_interface.set_header;\n set_header(note, header);\n let inner_note_hash = compute_inner_note_hash(note_interface, *note);\n\n context.push_new_note_hash(inner_note_hash);\n}\n\npub fn destroy_note(\n context: &mut PrivateContext,\n note: Note,\n note_interface: NoteInterface,\n) {\n let mut nullifier = 0;\n let mut nullified_commitment: Field = EMPTY_NULLIFIED_COMMITMENT;\n let compute_nullifier = note_interface.compute_nullifier;\n nullifier = compute_nullifier(note);\n\n // We also need the note commitment corresponding to the \"nullifier\"\n let get_header = note_interface.get_header;\n let header = get_header(note);\n // `nullified_commitment` is used to inform the kernel which pending commitment\n // the nullifier corresponds to so they can be matched and both squashed/deleted.\n // nonzero nonce implies \"persistable\" nullifier (nullifies a persistent/in-tree\n // commitment) in which case `nullified_commitment` is not used since the kernel\n // just siloes and forwards the nullier to its output.\n if (header.is_transient) {\n // TODO(1718): Can we reuse the note commitment computed in `compute_nullifier`?\n nullified_commitment = compute_inner_note_hash(note_interface, note);\n }\n assert(notify_nullified_note(nullifier, nullified_commitment) == 0);\n\n context.push_new_nullifier(nullifier, nullified_commitment)\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/lifecycle" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/lifecycle" }, "48": { "source": "use dep::std::option::Option;\nuse crate::constants_gen::{\n MAX_READ_REQUESTS_PER_CALL,\n GET_NOTE_ORACLE_RETURN_LENGTH,\n GET_NOTES_ORACLE_RETURN_LENGTH,\n MAX_NOTES_PER_PAGE,\n VIEW_NOTE_ORACLE_RETURN_LENGTH,\n};\nuse crate::context::PrivateContext;\nuse crate::note::{\n note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder},\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n};\nuse crate::oracle;\nuse crate::types::vec::BoundedVec;\n\nfn check_note_header(\n context: PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n note: Note,\n) {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n let contract_address = context.this_address();\n assert(header.contract_address == contract_address);\n assert(header.storage_slot == storage_slot);\n}\n\nfn check_note_fields(\n fields: [Field; N],\n selects: BoundedVec, N>,\n) {\n for i in 0..selects.len {\n let select = selects.get_unchecked(i).unwrap_unchecked();\n assert(fields[select.field_index] == select.value, \"Mismatch return note field.\");\n }\n}\n\nfn check_notes_order(fields_0: [Field; N], fields_1: [Field; N], sorts: BoundedVec, N>) {\n for i in 0..sorts.len {\n let sort = sorts.get_unchecked(i).unwrap_unchecked();\n let eq = fields_0[sort.field_index] == fields_1[sort.field_index];\n let lt = fields_0[sort.field_index] as u120 < fields_1[sort.field_index] as u120;\n if sort.order == SortOrder.ASC {\n assert(eq | lt, \"Return notes not sorted in ascending order.\");\n } else if !eq {\n assert(!lt, \"Return notes not sorted in descending order.\");\n }\n }\n}\n\npub fn get_note(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let note = get_note_internal(storage_slot, note_interface);\n\n check_note_header(*context, storage_slot, note_interface, note);\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n\n context.push_read_request(note_hash_for_read_request);\n note\n}\n\npub fn get_notes(\n context: &mut PrivateContext,\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let opt_notes = get_notes_internal(storage_slot, note_interface, options);\n let mut num_notes = 0;\n let mut prev_fields = [0; N];\n for i in 0..opt_notes.len() {\n let opt_note = opt_notes[i];\n if opt_note.is_some() {\n let note = opt_note.unwrap_unchecked();\n let serialize = note_interface.serialize;\n let fields = serialize(note);\n check_note_header(*context, storage_slot, note_interface, note);\n check_note_fields(fields, options.selects);\n if i != 0 {\n check_notes_order(prev_fields, fields, options.sorts);\n }\n prev_fields = fields;\n\n let note_hash_for_read_request = compute_note_hash_for_read_or_nullify(note_interface, note);\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1410): test to ensure\n // failure if malicious oracle injects 0 nonce here for a \"pre-existing\" note.\n context.push_read_request(note_hash_for_read_request);\n\n num_notes += 1;\n };\n };\n if options.limit != 0 {\n assert(num_notes <= options.limit, \"Invalid number of return notes.\");\n }\n opt_notes\n}\n\nunconstrained fn get_note_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n) -> Note {\n let placeholder_note = [Option::none()];\n let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n 0,\n [],\n [],\n [],\n [],\n 1, // limit\n 0, // offset\n placeholder_note,\n placeholder_fields,\n )[0].unwrap() // Notice: we don't allow dummies to be returned from get_note (singular).\n}\n\nunconstrained fn get_notes_internal(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteGetterOptions,\n) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH];\n let opt_notes = oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n );\n\n let filter = options.filter;\n let filter_args = options.filter_args;\n filter(opt_notes, filter_args)\n}\n\nunconstrained pub fn view_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n options: NoteViewerOptions,\n) -> [Option; MAX_NOTES_PER_PAGE] {\n let (num_selects, select_by, select_values, sort_by, sort_order) = flatten_options(options.selects, options.sorts);\n let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];\n let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];\n oracle::notes::get_notes(\n storage_slot,\n note_interface,\n num_selects,\n select_by,\n select_values,\n sort_by,\n sort_order,\n options.limit,\n options.offset,\n placeholder_opt_notes,\n placeholder_fields,\n )\n}\n\nunconstrained fn flatten_options(\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>,\n) -> (u8, [u8; N], [Field; N], [u8; N], [u2; N]) {\n let mut num_selects = 0;\n let mut select_by = [0; N];\n let mut select_values = [0; N];\n for i in 0..selects.len {\n let select = selects.get(i);\n if select.is_some() {\n select_by[num_selects] = select.unwrap_unchecked().field_index;\n select_values[num_selects] = select.unwrap_unchecked().value;\n num_selects += 1;\n };\n };\n\n let mut sort_by = [0; N];\n let mut sort_order = [0; N];\n for i in 0..sorts.len {\n let sort = sorts.get(i);\n if sort.is_some() {\n sort_by[i] = sort.unwrap_unchecked().field_index;\n sort_order[i] = sort.unwrap_unchecked().order;\n };\n };\n\n (num_selects, select_by, select_values, sort_by, sort_order)\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/note_getter" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_getter" }, "50": { "source": "use dep::std::hash::{pedersen, pedersen_with_separator};\nuse crate::constants_gen::{GENERATOR_INDEX__UNIQUE_COMMITMENT, GENERATOR_INDEX__SILOED_COMMITMENT};\n\npub fn compute_inner_hash(storage_slot: Field, note_hash: Field) -> Field {\n // TODO(#1205) Do we need a generator index here?\n pedersen([storage_slot, note_hash])[0]\n}\n\npub fn compute_siloed_hash(contract_address: Field, inner_note_hash: Field) -> Field {\n let inputs = [contract_address, inner_note_hash];\n pedersen_with_separator(inputs, GENERATOR_INDEX__SILOED_COMMITMENT)[0]\n}\n\npub fn compute_unique_hash(nonce: Field, siloed_note_hash: Field) -> Field {\n let inputs = [nonce, siloed_note_hash];\n pedersen_with_separator(inputs, GENERATOR_INDEX__UNIQUE_COMMITMENT)[0]\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/note_hash" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_hash" }, "53": { "source": "use dep::std::option::Option;\nuse crate::constants_gen::MAX_NOTES_PER_PAGE;\nuse crate::note::note_getter_options::{Select, Sort};\nuse crate::types::vec::BoundedVec;\n\n// docs:start:NoteViewerOptions\nstruct NoteViewerOptions {\n selects: BoundedVec, N>,\n sorts: BoundedVec, N>,\n limit: u32,\n offset: u32,\n}\n// docs:end:NoteViewerOptions\n\nimpl NoteViewerOptions {\n pub fn new() -> NoteViewerOptions {\n NoteViewerOptions {\n selects: BoundedVec::new(Option::none()),\n sorts: BoundedVec::new(Option::none()),\n limit: MAX_NOTES_PER_PAGE as u32,\n offset: 0,\n }\n }\n\n pub fn select(&mut self, field_index: u8, value: Field) -> Self {\n self.selects.push(Option::some(Select::new(field_index, value)));\n *self\n }\n\n pub fn sort(&mut self, field_index: u8, order: u2) -> Self {\n self.sorts.push(Option::some(Sort::new(field_index, order)));\n *self\n }\n\n pub fn set_limit(&mut self, limit: u32) -> Self {\n assert(limit <= MAX_NOTES_PER_PAGE as u32);\n self.limit = limit;\n *self\n }\n\n pub fn set_offset(&mut self, offset: u32) -> Self {\n self.offset = offset;\n *self\n }\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/note_viewer_options" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/note_viewer_options" }, "54": { "source": "use crate::note::{\n note_hash::{compute_inner_hash, compute_siloed_hash, compute_unique_hash},\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\npub fn compute_inner_note_hash(\n note_interface: NoteInterface,\n note: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n\n compute_inner_hash(header.storage_slot, note_hash)\n}\n\npub fn compute_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let inner_note_hash = compute_inner_note_hash(note_interface, note_with_header);\n\n compute_siloed_hash(header.contract_address, inner_note_hash)\n}\n\npub fn compute_unique_siloed_note_hash(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n let siloed_note_hash = compute_siloed_note_hash(note_interface, note_with_header);\n\n compute_unique_hash(header.nonce, siloed_note_hash)\n}\n\npub fn compute_note_hash_for_read_or_nullify(\n note_interface: NoteInterface,\n note_with_header: Note,\n) -> Field {\n let get_header = note_interface.get_header;\n let header = get_header(note_with_header);\n\n // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)\n if (header.is_transient) {\n // If a note is transient, we just read the inner_note_hash (kernel will silo by contract address).\n compute_inner_note_hash(note_interface, note_with_header)\n } else if (header.nonce == 0) {\n // If not transient and nonce is zero, that means we are reading a public note.\n compute_siloed_note_hash(note_interface, note_with_header)\n } else {\n // When nonce is nonzero, that means we are reading a settled note (from tree) created in a\n // previous TX. So we need the unique_siloed_note_hash which has already been hashed with\n // contract address and then nonce. This hash will match the existing leaf in the private\n // data tree, so the kernel can just perform a membership check directly on this hash/leaf.\n compute_unique_siloed_note_hash(note_interface, note_with_header)\n }\n\n}\n\npub fn compute_note_hash_and_nullifier(\n note_interface: NoteInterface,\n note_header: NoteHeader,\n preimage: [Field; S],\n) -> [Field; 4] {\n let deserialize = note_interface.deserialize;\n let set_header = note_interface.set_header;\n let mut note = deserialize(arr_copy_slice(preimage, [0; N], 0));\n set_header(&mut note, note_header);\n\n let compute_note_hash = note_interface.compute_note_hash;\n let note_hash = compute_note_hash(note);\n let inner_note_hash = compute_inner_hash(note_header.storage_slot, note_hash);\n\n let siloed_note_hash = compute_siloed_hash(note_header.contract_address, inner_note_hash);\n\n let unique_siloed_note_hash = compute_unique_hash(note_header.nonce, siloed_note_hash);\n\n let compute_nullifier = note_interface.compute_nullifier;\n let inner_nullifier = compute_nullifier(note);\n\n [inner_note_hash, siloed_note_hash, unique_siloed_note_hash, inner_nullifier]\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/note/utils" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/note/utils" }, "56": { "source": "#[oracle(packArguments)]\nfn pack_arguments_oracle(_args: [Field; N]) -> Field {}\n\n// TODO: explain what this does.\nunconstrained pub fn pack_arguments(args: [Field; N]) -> Field {\n pack_arguments_oracle(args)\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/arguments" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/arguments" }, "57": { "source": "use crate::constants_gen::CALL_PRIVATE_FUNCTION_RETURN_SIZE;\n\n#[oracle(callPrivateFunction)]\nfn call_private_function_oracle(\n _contract_address: Field,\n _function_selector: Field,\n _args_hash: Field\n) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {}\n\nunconstrained pub fn call_private_function_internal(\n contract_address: Field,\n function_selector: Field,\n args_hash: Field\n) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {\n call_private_function_oracle(\n contract_address,\n function_selector,\n args_hash,\n )\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/call_private_function" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/call_private_function" }, "61": { "source": "use crate::types::point::Point;\nuse crate::address::compute_address;\n\n#[oracle(getPublicKey)]\nfn get_public_key_oracle(_address: Field) -> [Field; 3] {}\n\nunconstrained fn get_public_key_internal(address: Field) -> [Field; 3] {\n get_public_key_oracle(address)\n}\n\npub fn get_public_key(address: Field) -> Point {\n let result = get_public_key_internal(address);\n let pub_key_x = result[0];\n let pub_key_y = result[1];\n let partial_address = result[2];\n \n let calculated_address = compute_address(pub_key_x, pub_key_y, partial_address);\n assert(calculated_address == address);\n \n Point::new(pub_key_x, pub_key_y)\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_public_key" }, "62": { "source": "use crate::oracle::get_public_key::get_public_key;\nuse crate::types::point::Point;\n\n#[oracle(getSecretKey)]\nfn get_secret_key_oracle(\n _owner: Point,\n) -> [Field; dep::std::grumpkin_scalar::GRUMPKIN_SCALAR_SERIALIZED_LEN] {\n}\n\nunconstrained fn get_secret_key_internal(owner_public_key: Point) -> dep::std::grumpkin_scalar::GrumpkinScalar {\n dep::std::grumpkin_scalar::deserialize_grumpkin_scalar(get_secret_key_oracle(owner_public_key))\n}\n\npub fn get_secret_key(owner: Field) -> dep::std::grumpkin_scalar::GrumpkinScalar {\n let owner_public_key = get_public_key(owner);\n let secret = get_secret_key_internal(owner_public_key);\n\n // Constrain the owner - Nullifier secret key is currently just the encryption private key so we can constrain\n // the owner by deriving the public key from the secret key and checking the result.\n let computed_public_key = dep::std::grumpkin_scalar_mul::grumpkin_fixed_base(secret);\n assert(owner_public_key.x == computed_public_key[0]);\n assert(owner_public_key.y == computed_public_key[1]);\n\n secret\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/get_secret_key" }, "63": { "source": "\n\n#[oracle(getRandomField)]\nfn rand_oracle() -> Field {}\n\nunconstrained pub fn rand() -> Field {\n rand_oracle()\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/rand" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/rand" }, "64": { "source": "\n// contract_address + \n// args_hash +\n// crate::abi::FUNCTION_DATA_SIZE +\n// crate::abi::CALL_CONTEXT_SIZE +\n// = 2 + 4 + 7\nglobal ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE: Field = 13;\n\n#[oracle(enqueuePublicFunctionCall)]\nfn enqueue_public_function_call_oracle(\n _contract_address: Field, \n _function_selector: Field, \n _args_hash: Field,\n) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {}\n\nunconstrained pub fn enqueue_public_function_call_internal(\n contract_address: Field, \n function_selector: Field,\n args_hash: Field\n) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {\n enqueue_public_function_call_oracle(\n contract_address, \n function_selector, \n args_hash,\n )\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call" }, "65": { "source": "use crate::constants_gen::RETURN_VALUES_LENGTH;\n\n#[oracle(callPublicFunction)]\nfn call_public_function_oracle(\n _contract_address: Field, \n _function_selector: Field, \n _args_hash: Field\n) -> [Field; RETURN_VALUES_LENGTH] {}\n\nunconstrained pub fn call_public_function_internal(\n contract_address: Field, \n function_selector: Field,\n args_hash: Field\n) -> [Field; RETURN_VALUES_LENGTH] {\n call_public_function_oracle(\n contract_address, \n function_selector, \n args_hash,\n )\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/public_call" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/public_call" }, "66": { "source": "use dep::std::option::Option;\nuse crate::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n};\nuse crate::utils::arr_copy_slice;\n\n#[oracle(notifyCreatedNote)]\nfn notify_created_note_oracle(\n _storage_slot: Field,\n _preimage: [Field; N],\n _inner_note_hash: Field,\n) -> Field {}\n\nunconstrained pub fn notify_created_note(\n storage_slot: Field,\n preimage: [Field; N],\n inner_note_hash: Field,\n) -> Field {\n notify_created_note_oracle(storage_slot, preimage, inner_note_hash)\n}\n\n#[oracle(notifyNullifiedNote)]\nfn notify_nullified_note_oracle(\n _nullifier: Field,\n _inner_note_hash: Field,\n) -> Field {}\n\nunconstrained pub fn notify_nullified_note(\n nullifier: Field,\n inner_note_hash: Field,\n) -> Field {\n notify_nullified_note_oracle(nullifier, inner_note_hash)\n}\n\n#[oracle(getNotes)]\nfn get_notes_oracle(\n _storage_slot: Field,\n _num_selects: u8,\n _select_by: [u8; N],\n _select_values: [Field; N],\n _sort_by: [u8; N],\n _sort_order: [u2; N],\n _limit: u32,\n _offset: u32,\n _return_size: u32,\n _placeholder_fields: [Field; S],\n) -> [Field; S] {}\n\nunconstrained fn get_notes_oracle_wrapper(\n storage_slot: Field,\n num_selects: u8,\n select_by: [u8; N],\n select_values: [Field; N],\n sort_by: [u8; N],\n sort_order: [u2; N],\n limit: u32,\n offset: u32,\n mut placeholder_fields: [Field; S],\n)-> [Field; S] {\n let return_size = placeholder_fields.len() as u32;\n get_notes_oracle(storage_slot, num_selects, select_by, select_values, sort_by, sort_order, limit, offset, return_size, placeholder_fields)\n}\n\nunconstrained pub fn get_notes(\n storage_slot: Field,\n note_interface: NoteInterface,\n num_selects: u8,\n select_by: [u8; M],\n select_values: [Field; M],\n sort_by: [u8; M],\n sort_order: [u2; M],\n limit: u32,\n offset: u32,\n mut placeholder_opt_notes: [Option; S], // TODO: Remove it and use `limit` to initialize the note array.\n placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array.\n) -> [Option; S] {\n let fields = get_notes_oracle_wrapper(storage_slot, num_selects, select_by, select_values, sort_by, sort_order, limit, offset, placeholder_fields);\n let num_notes = fields[0] as u32;\n let contract_address = fields[1];\n let deserialize = note_interface.deserialize;\n let set_header = note_interface.set_header;\n for i in 0..placeholder_opt_notes.len() {\n if i as u32 < num_notes {\n // lengths named as per typescript.\n let return_header_length: Field = 2; // num_notes & contract_address.\n let extra_preimage_length: Field = 2; // nonce & is_transient.\n let read_offset: Field = return_header_length + i * (N + extra_preimage_length);\n let nonce = fields[read_offset];\n let is_transient = fields[read_offset + 1] as bool;\n let header = NoteHeader { contract_address, nonce, storage_slot, is_transient };\n let preimage = arr_copy_slice(fields, [0; N], read_offset + 2);\n let mut note = deserialize(preimage);\n set_header(&mut note, header);\n placeholder_opt_notes[i] = Option::some(note);\n };\n };\n placeholder_opt_notes\n}\n\n#[oracle(checkNullifierExists)]\nfn check_nullifier_exists_oracle(\n _inner_nullifier: Field,\n) -> Field {}\n\nunconstrained pub fn check_nullifier_exists(inner_nullifier: Field) -> bool {\n check_nullifier_exists_oracle(inner_nullifier) == 1\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/notes" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/notes" }, "67": { "source": "\n#[oracle(storageRead)]\nfn storage_read_oracle(\n _storage_slot: Field,\n _number_of_elements: Field,\n) -> [Field; N] {}\n\nunconstrained fn storage_read_oracle_wrapper(_storage_slot: Field)-> [Field; N] {\n storage_read_oracle(_storage_slot, N)\n}\n\npub fn storage_read(\n storage_slot: Field,\n deserialize: fn ([Field; N]) -> T,\n) -> T {\n let fields = storage_read_oracle_wrapper(storage_slot);\n deserialize(fields)\n}\n\n#[oracle(storageWrite)]\nfn storage_write_oracle(\n _storage_slot: Field,\n _values: [Field; N],\n) -> [Field; N] {}\n\n// TODO: Remove return value.\nunconstrained pub fn storage_write(\n storage_slot: Field,\n fields: [Field; N]\n) {\n let _hash = storage_write_oracle(storage_slot, fields);\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/storage" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/storage" }, "68": { "source": "use crate::types::point::Point;\nuse crate::constants_gen::NUM_FIELDS_PER_SHA256;\n\n// TODO: Should take encrypted data.\n#[oracle(emitEncryptedLog)]\nfn emit_encrypted_log_oracle(\n _contract_address: Field,\n _storage_slot: Field,\n _encryption_pub_key: Point,\n _preimage: [Field; N],\n) -> Field {}\n\nunconstrained pub fn emit_encrypted_log(\n contract_address: Field,\n storage_slot: Field,\n encryption_pub_key: Point,\n preimage: [Field; N],\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n [emit_encrypted_log_oracle(\n contract_address,\n storage_slot,\n encryption_pub_key,\n preimage,\n ), 0]\n}\n\n#[oracle(emitUnencryptedLog)]\nfn emit_unencrypted_log_oracle(_contract_address: Field, _event_selector: Field, _message: T) -> Field {}\n\nunconstrained pub fn emit_unencrypted_log(contract_address: Field, event_selector: Field, message: T) -> [Field; NUM_FIELDS_PER_SHA256] {\n // https://github.com/AztecProtocol/aztec-packages/issues/885\n [emit_unencrypted_log_oracle(contract_address, event_selector, message), 0]\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/oracle/logs" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/oracle/logs" }, "69": { "source": "use crate::abi::FunctionData;\nuse crate::abi::PrivateCircuitPublicInputs;\nuse crate::constants_gen::GENERATOR_INDEX__CALL_STACK_ITEM;\n\nstruct PrivateCallStackItem {\n contract_address: Field,\n function_data: FunctionData,\n public_inputs: PrivateCircuitPublicInputs,\n is_execution_request: bool,\n}\n\nimpl PrivateCallStackItem {\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.contract_address,\n self.function_data.hash(),\n self.public_inputs.hash(),\n ], GENERATOR_INDEX__CALL_STACK_ITEM)[0]\n }\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/private_call_stack_item" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/private_call_stack_item" }, "70": { "source": "use crate::{\n abi,\n abi::{\n PublicCircuitPublicInputs,\n FunctionData,\n },\n};\nuse crate::constants_gen::{\n RETURN_VALUES_LENGTH,\n GENERATOR_INDEX__CALL_STACK_ITEM,\n};\n\n// oracles\nuse crate::oracle::{\n enqueue_public_function_call::enqueue_public_function_call_internal,\n};\n\nstruct PublicCallStackItem {\n contract_address: Field,\n function_data: FunctionData,\n public_inputs: PublicCircuitPublicInputs,\n is_execution_request: bool,\n}\n\nimpl PublicCallStackItem {\n pub fn hash(self) -> Field {\n dep::std::hash::pedersen_with_separator([\n self.contract_address,\n self.function_data.hash(),\n self.public_inputs.hash(),\n ], GENERATOR_INDEX__CALL_STACK_ITEM)[0]\n }\n}\n\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/public_call_stack_item" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/public_call_stack_item" }, "74": { "source": "use crate::context::{PrivateContext, PublicContext, Context};\nuse dep::std::option::Option;\n\n// docs:start:map\nstruct Map {\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n}\n// docs:end:map\n\nimpl Map {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n state_var_constructor: fn(Context, Field) -> V,\n ) -> Map {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Map {\n context,\n storage_slot,\n state_var_constructor,\n }\n }\n // docs:end:new\n\n // docs:start:at\n pub fn at(self, key: Field) -> V {\n // TODO(#1204): use a generator index for the storage slot\n let derived_storage_slot = dep::std::hash::pedersen([self.storage_slot, key])[0];\n\n let state_var_constructor = self.state_var_constructor;\n state_var_constructor(self.context, derived_storage_slot)\n }\n // docs:end:at\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/state_vars/map" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/map" }, "75": { "source": "use crate::context::{Context};\nuse crate::oracle::storage::storage_read;\nuse crate::oracle::storage::storage_write;\nuse crate::types::type_serialization::TypeSerializationInterface;\nuse dep::std::option::Option;\n\n// docs:start:public_state_struct\nstruct PublicState {\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n}\n// docs:end:public_state_struct\n\nimpl PublicState {\n // docs:start:public_state_struct_new\n pub fn new(\n // Note: Passing the contexts to new(...) just to have an interface compatible with a Map.\n context: Context,\n storage_slot: Field,\n serialization_methods: TypeSerializationInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n PublicState {\n context,\n storage_slot,\n serialization_methods,\n }\n }\n // docs:end:public_state_struct_new\n\n // docs:start:public_state_struct_read\n pub fn read(self) -> T {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n storage_read(self.storage_slot, self.serialization_methods.deserialize)\n }\n // docs:end:public_state_struct_read\n\n // docs:start:public_state_struct_write\n pub fn write(self, value: T) {\n assert(self.context.private.is_none(), \"Public state writes only supported in public functions\");\n let serialize = self.serialization_methods.serialize;\n let fields = serialize(value);\n storage_write(self.storage_slot, fields);\n }\n // docs:end:public_state_struct_write\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/state_vars/public_state" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/public_state" }, "76": { "source": "use dep::std::option::Option;\nuse crate::abi::PublicContextInputs;\nuse crate::constants_gen::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL};\nuse crate::context::{PrivateContext, PublicContext, Context};\nuse crate::note::{\n lifecycle::{create_note, create_note_hash_from_public, destroy_note},\n note_getter::{get_notes, view_notes},\n note_getter_options::NoteGetterOptions,\n note_header::NoteHeader,\n note_interface::NoteInterface,\n note_viewer_options::NoteViewerOptions,\n utils::compute_note_hash_for_read_or_nullify,\n};\n\n// docs:start:struct\nstruct Set {\n context: Context,\n storage_slot: Field,\n note_interface: NoteInterface,\n}\n// docs:end:struct\n\nimpl Set {\n // docs:start:new\n pub fn new(\n context: Context,\n storage_slot: Field,\n note_interface: NoteInterface,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Set {\n context,\n storage_slot,\n note_interface,\n }\n }\n // docs:end:new\n\n // docs:start:insert\n pub fn insert(self, note: &mut Note) {\n create_note(\n self.context.private.unwrap(),\n self.storage_slot,\n note,\n self.note_interface,\n );\n }\n // docs:end:insert\n\n // docs:start:insert_from_public\n pub fn insert_from_public(self, note: &mut Note) {\n create_note_hash_from_public(\n self.context.public.unwrap(),\n self.storage_slot,\n note,\n self.note_interface,\n );\n }\n // docs:end:insert_from_public\n \n // DEPRECATED\n fn assert_contains_and_remove(_self: Self, _note: &mut Note, _nonce: Field) {\n assert(false, \"`assert_contains_and_remove` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note.\");\n }\n\n // DEPRECATED\n fn assert_contains_and_remove_publicly_created(_self: Self, _note: &mut Note) {\n assert(false, \"`assert_contains_and_remove_publicly_created` has been deprecated. Please call PXE.addNote() to add a note to the database. Then use Set.get_notes() and Set.remove() in your contract to verify and remove a note.\");\n }\n\n // docs:start:remove\n pub fn remove(self, note: Note) {\n let context = self.context.private.unwrap();\n let note_hash = compute_note_hash_for_read_or_nullify(self.note_interface, note);\n let has_been_read = context.read_requests.any(|r| r == note_hash);\n assert(has_been_read, \"Can only remove a note that has been read from the set.\");\n\n destroy_note(\n context,\n note,\n self.note_interface,\n );\n }\n // docs:end:remove\n\n // docs:start:get_notes\n pub fn get_notes(\n self,\n options: NoteGetterOptions,\n ) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let storage_slot = self.storage_slot;\n let opt_notes = get_notes(\n self.context.private.unwrap(),\n storage_slot,\n self.note_interface,\n options,\n );\n opt_notes\n }\n // docs:end:get_notes\n\n // docs:start:view_notes\n unconstrained pub fn view_notes(\n self,\n options: NoteViewerOptions,\n ) -> [Option; MAX_NOTES_PER_PAGE] {\n view_notes(self.storage_slot, self.note_interface, options)\n }\n // docs:end:view_notes\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/state_vars/set" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/state_vars/set" }, "79": { "source": "struct AztecAddress {\n address: Field\n}\n\nimpl AztecAddress {\n pub fn new(address: Field) -> Self {\n Self {\n address\n }\n }\n\n pub fn eq(self: Self, other: Self) -> bool {\n self.address == other.address\n }\n\n pub fn serialize(self: Self) -> [Field; 1] {\n [self.address]\n }\n\n pub fn deserialize(fields: [Field; 1]) -> Self {\n Self {\n address: fields[0]\n }\n }\n}\n\nstruct EthereumAddress {\n address: Field\n}\n\nimpl EthereumAddress {\n pub fn new(address: Field) -> Self {\n // Check that it actually will fit. Spending a lot of constraints here :grimacing:\n let bytes = address.to_be_bytes(32);\n for i in 0..12 {\n assert(bytes[i] == 0, \"Value too large for an ethereum address\");\n }\n Self {\n address\n }\n }\n\n\n pub fn serialize(self: Self) -> [Field; 1] {\n [self.address]\n }\n\n pub fn deserialize(fields: [Field; 1]) -> Self {\n Self {\n address: fields[0]\n }\n }\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/types/address" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/address" }, "81": { "source": "\nstruct BoundedVec {\n storage: [T; MaxLen],\n len: Field,\n}\n\nimpl BoundedVec {\n pub fn new(initial_value: T) -> Self {\n BoundedVec { storage: [initial_value; MaxLen], len: 0 }\n }\n\n pub fn get(mut self: Self, index: Field) -> T {\n assert(index as u64 < self.len as u64);\n self.storage[index]\n }\n\n pub fn get_unchecked(mut self: Self, index: Field) -> T {\n self.storage[index]\n }\n\n pub fn push(&mut self, elem: T) {\n assert(self.len as u64 < MaxLen as u64);\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n pub fn push_array(&mut self, array: [T; Len]) {\n let newLen = self.len + array.len();\n assert(newLen as u64 <= MaxLen as u64);\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = newLen;\n }\n\n pub fn pop(&mut self) -> T {\n assert(self.len as u64 > 0);\n\n let elem = self.storage[self.len - 1];\n self.len -= 1;\n elem\n }\n\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if (!exceeded_len) {\n ret |= predicate(self.storage[i]);\n }\n }\n ret\n }\n}\n\n#[test]\nfn test_vec_push_pop() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n assert(vec.len == 0);\n vec.push(2);\n assert(vec.len == 1);\n vec.push(4);\n assert(vec.len == 2);\n vec.push(6);\n assert(vec.len == 3);\n let x = vec.pop();\n assert(x == 6);\n assert(vec.len == 2);\n assert(vec.get(0) == 2);\n assert(vec.get(1) == 4);\n}\n\n#[test]\nfn test_vec_push_array() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4]);\n assert(vec.len == 2);\n assert(vec.get(0) == 2);\n assert(vec.get(1) == 4);\n}\n\n#[test(should_fail)]\nfn test_vec_get_out_of_bound() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4]);\n let _x = vec.get(2);\n}\n\n#[test(should_fail)]\nfn test_vec_get_not_declared() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2]);\n let _x = vec.get(1);\n}\n\n#[test(should_fail)]\nfn test_vec_get_uninitialized() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n let _x = vec.get(0);\n}\n\n#[test(should_fail)]\nfn test_vec_push_overflow() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push(1);\n vec.push(2);\n}\n\n#[test]\nfn test_vec_any() {\n let mut vec: BoundedVec = BoundedVec::new(0);\n vec.push_array([2, 4, 6]);\n assert(vec.any(|v| v == 2) == true);\n assert(vec.any(|v| v == 4) == true);\n assert(vec.any(|v| v == 6) == true);\n assert(vec.any(|v| v == 3) == false);\n}\n\n#[test]\nfn test_vec_any_not_default() {\n let default_value = 1;\n let mut vec: BoundedVec = BoundedVec::new(default_value);\n vec.push_array([2, 4]);\n assert(vec.any(|v| v == default_value) == false);\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/types/vec" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/vec" }, "83": { "source": "use crate::types::type_serialization::TypeSerializationInterface;\n\nglobal BOOL_SERIALIZED_LEN: Field = 1;\n\nfn deserializeBool(fields: [Field; BOOL_SERIALIZED_LEN]) -> bool {\n fields[0] as bool\n}\n\nfn serializeBool(value: bool) -> [Field; BOOL_SERIALIZED_LEN] {\n [value as Field]\n}\n\nglobal BoolSerializationMethods = TypeSerializationInterface {\n deserialize: deserializeBool,\n serialize: serializeBool,\n};", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/bool_serialization" }, "86": { "source": "use crate::types::type_serialization::TypeSerializationInterface;\nuse crate::types::address::AztecAddress;\n\nglobal AZTEC_ADDRESS_SERIALIZED_LEN: Field = 1;\n\nfn deserialize(fields: [Field; AZTEC_ADDRESS_SERIALIZED_LEN]) -> AztecAddress {\n AztecAddress::new(fields[0])\n}\n\nfn serialize(value: AztecAddress) -> [Field; AZTEC_ADDRESS_SERIALIZED_LEN] {\n [value.address]\n}\n\nglobal AztecAddressSerializationMethods = TypeSerializationInterface {\n deserialize,\n serialize,\n};", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/types/type_serialization/aztec_address_serialization" }, "87": { "source": "pub fn arr_copy_slice(\n src: [T; N],\n mut dst: [T; M],\n offset: Field,\n) -> [T; M] {\n for i in 0..dst.len() {\n dst[i] = src[i + offset];\n }\n dst\n}\n\npub fn field_from_bytes(bytes: [u8; N], big_endian: bool) -> Field {\n assert(bytes.len() as u32 < 32, \"field_from_bytes: N must be less than 32\");\n let mut as_field = 0;\n let mut offset = 1;\n for i in 0..N {\n let mut index = i;\n if big_endian {\n index = N - i - 1;\n }\n as_field += (bytes[index] as Field) * offset;\n offset *= 256;\n }\n\n as_field\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/aztec/src/utils" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/aztec/src/utils" }, "90": { "source": "use dep::std::hash::pedersen_with_separator;\n\nuse dep::aztec::{\n context::{PrivateContext, PublicContext, Context},\n constants_gen::{EMPTY_NULLIFIED_COMMITMENT, GENERATOR_INDEX__SIGNATURE_PAYLOAD},\n types::address::AztecAddress,\n abi::hash_args,\n};\n\nglobal IS_VALID_SELECTOR = 0xe86ab4ff;\nglobal IS_VALID_PUBLIC_SELECTOR = 0xf3661153;\n\n// @todo #2676 Should use different generator than the payload to limit probability of collisions.\n\n// docs:start:assert_valid_authwit\n// Assert that `on_behalf_of` have authorized `message_hash` with a valid authentication witness\npub fn assert_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress, message_hash: Field) {\n let result = context.call_private_function(on_behalf_of.address, IS_VALID_SELECTOR, [message_hash])[0];\n context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT);\n assert(result == IS_VALID_SELECTOR, \"Message not authorized by account\");\n}\n// docs:end:assert_valid_authwit\n\n// docs:start:assert_current_call_valid_authwit\n// Assert that `on_behalf_of` have authorized the current call with a valid authentication witness\npub fn assert_current_call_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress) {\n // message_hash = H(caller, contract_this, selector, args_hash)\n let message_hash = pedersen_with_separator(\n [context.msg_sender(), context.this_address(), context.selector(), context.args_hash],\n GENERATOR_INDEX__SIGNATURE_PAYLOAD\n )[0];\n assert_valid_authwit(context, on_behalf_of, message_hash);\n}\n// docs:end:assert_current_call_valid_authwit\n\n// docs:start:assert_valid_authwit_public\n// Assert that `on_behalf_of` have authorized `message_hash` in a public context\npub fn assert_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress, message_hash: Field) {\n let result = context.call_public_function(on_behalf_of.address, IS_VALID_PUBLIC_SELECTOR, [message_hash])[0];\n context.push_new_nullifier(message_hash, EMPTY_NULLIFIED_COMMITMENT);\n assert(result == IS_VALID_SELECTOR, \"Message not authorized by account\");\n}\n// docs:end:assert_valid_authwit_public\n\n// docs:start:assert_current_call_valid_authwit_public\n// Assert that `on_behalf_of` have authorized the current call in a public context\npub fn assert_current_call_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress) {\n // message_hash = H(caller, contract_this, selector, args_hash)\n let message_hash = pedersen_with_separator(\n [context.msg_sender(), context.this_address(), context.selector(), context.args_hash],\n GENERATOR_INDEX__SIGNATURE_PAYLOAD\n )[0];\n assert_valid_authwit_public(context, on_behalf_of, message_hash);\n}\n// docs:end:assert_current_call_valid_authwit_public\n\n// docs:start:compute_authwit_message_hash\n// Compute the message hash to be used by an authentication witness \npub fn compute_authwit_message_hash(\n caller: AztecAddress, \n target: AztecAddress, \n selector: Field, \n args: [Field; N]\n) -> Field {\n let args_hash = hash_args(args);\n pedersen_with_separator([caller.address, target.address, selector, args_hash], GENERATOR_INDEX__SIGNATURE_PAYLOAD)[0]\n}\n// docs:end:compute_authwit_message_hash", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/authwit/src/auth" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/authwit/src/auth" }, "92": { "source": "struct SafeU120 {\n value: u120,\n}\n\nimpl SafeU120 {\n pub fn min() -> Self {\n Self {\n value: 0\n }\n }\n\n pub fn max() -> Self {\n Self {\n value: 0xffffffffffffffffffffffffffffff\n }\n }\n\n pub fn new(\n value: Field,\n ) -> Self {\n // Check that it actually will fit. Spending a lot of constraints here :grimacing:\n let bytes = value.to_be_bytes(32);\n for i in 0..17 {\n assert(bytes[i] == 0, \"Value too large for SafeU120\");\n }\n Self {\n value: value as u120\n }\n }\n\n pub fn is_zero(\n self: Self,\n ) -> bool {\n self.value == 0\n }\n\n pub fn eq(\n self: Self,\n other: Self\n ) -> bool {\n self.value == other.value\n }\n\n pub fn lt(self: Self, other: Self) -> bool {\n self.value < other.value\n }\n\n pub fn le(self: Self, other: Self) -> bool {\n self.value <= other.value\n }\n\n pub fn gt(self: Self, other: Self) -> bool {\n self.value > other.value\n }\n\n pub fn ge(self: Self, other: Self) -> bool {\n self.value >= other.value\n }\n\n pub fn sub(\n self: Self,\n b: Self,\n ) -> Self {\n assert(self.value >= b.value, \"Underflow\");\n Self {\n value: self.value - b.value\n }\n }\n\n pub fn add(\n self: Self,\n b: Self,\n ) -> Self {\n let c: u120 = self.value + b.value;\n assert(c >= self.value, \"Overflow\");\n Self {\n value: c\n }\n }\n\n pub fn mul(\n self: Self,\n b: Self,\n ) -> Self {\n let c: u120 = self.value * b.value;\n if !b.is_zero() {\n assert(c / b.value == self.value, \"Overflow\");\n }\n Self {\n value: c\n }\n }\n\n pub fn div(\n self: Self,\n b: Self,\n ) -> Self {\n assert(!b.is_zero(), \"Divide by zero\");\n Self {\n value: self.value / b.value\n }\n }\n\n pub fn mul_div(\n self: Self,\n b: Self,\n divisor: Self\n ) -> Self {\n self.mul(b).div(divisor)\n }\n\n pub fn mul_div_up(\n self: Self,\n b: Self,\n divisor: Self\n ) -> Self {\n let c = self.mul(b);\n assert(!divisor.is_zero(), \"Divide by zero\");\n let adder = ((self.value * b.value % divisor.value) as u120 > 0) as u120;\n c.div(divisor).add(Self {value: adder})\n }\n\n // todo: implement mul_div with 240 bit intermediate values.\n}\n\n#[test]\nfn test_init() {\n let a = SafeU120::new(1);\n assert(a.value == 1);\n}\n\n#[test]\nfn test_init_max() {\n let a = SafeU120::max();\n assert(a.value == 0xffffffffffffffffffffffffffffff);\n}\n\n#[test]\nfn test_init_min() {\n let a = SafeU120::min();\n assert(a.value == 0);\n}\n\n#[test]\nfn test_is_zero() {\n let a = SafeU120::min();\n assert(a.value == 0);\n assert(a.is_zero() == true);\n}\n\n#[test]\nfn test_eq() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(1);\n assert(a.eq(b));\n}\n\n#[test]\nfn test_lt() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n assert(a.lt(b));\n assert(b.lt(a) == false);\n}\n\n\n#[test]\nfn test_le() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(2);\n let c = SafeU120::new(5);\n assert(a.le(b));\n assert(a.le(c));\n assert(c.le(a) == false);\n}\n\n#[test]\nfn test_gt() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n assert(b.gt(a));\n assert(a.gt(b) == false);\n}\n\n\n#[test]\nfn test_ge() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(2);\n let c = SafeU120::new(5);\n assert(a.ge(b));\n assert(a.ge(c) == false);\n assert(c.ge(a));\n}\n\n#[test(should_fail)]\nfn test_init_too_large() {\n let b = SafeU120::max().value as Field + 1; // max + 1\n let _a = SafeU120::new(b);\n}\n\n#[test]\nfn test_add() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n let c = SafeU120::add(a, b);\n assert(c.value == 3);\n}\n\n#[test(should_fail)]\nfn test_add_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(1);\n let _c = SafeU120::add(a, b);\n}\n\n#[test]\nfn test_sub() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(1);\n let c = SafeU120::sub(a, b);\n assert(c.value == 1);\n}\n\n#[test(should_fail)]\nfn test_sub_underflow() {\n let a = SafeU120::new(1);\n let b = SafeU120::new(2);\n let _c = SafeU120::sub(a, b);\n}\n\n#[test]\nfn test_mul() {\n let a = SafeU120::new(2);\n let b = SafeU120::new(3);\n let c = SafeU120::mul(a, b);\n assert(c.value == 6);\n}\n\n#[test(should_fail)]\nfn test_mul_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let _c = SafeU120::mul(a, b);\n}\n\n#[test]\nfn test_div() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::div(a, b);\n assert(c.value == 2);\n}\n\n#[test(should_fail)]\nfn test_div_by_zero() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(0);\n let _c = SafeU120::div(a, b);\n}\n\n#[test]\nfn test_mul_div() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(2);\n let d = SafeU120::mul_div(a, b, c);\n assert(d.value == 9);\n}\n\n#[test(should_fail)]\nfn test_mul_div_zero_divisor() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(0);\n let _d = SafeU120::mul_div(a, b, c);\n}\n\n#[test(should_fail)]\nfn test_mul_div_ghost_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let c = SafeU120::new(4);\n let _d = SafeU120::mul_div(a, b, c);\n}\n\n#[test]\nfn test_mul_div_up_rounding() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(5);\n let d = SafeU120::mul_div_up(a, b, c);\n assert(d.value == 4);\n}\n\n#[test]\nfn test_mul_div_up_non_rounding() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(2);\n let d = SafeU120::mul_div_up(a, b, c);\n assert(d.value == 9);\n}\n\n\n#[test(should_fail)]\nfn test_mul_div_up_ghost_overflow() {\n let a = SafeU120::max();\n let b = SafeU120::new(2);\n let c = SafeU120::new(9);\n let _d = SafeU120::mul_div_up(a, b, c);\n}\n\n// It should not be possible for us to overflow `mul_div_up` through the adder, since that require the divisor to be 1\n// since we otherwise would not be at the max value. If divisor is 1, adder is 0.\n#[test(should_fail)]\nfn test_mul_div_up_zero_divisor() {\n let a = SafeU120::new(6);\n let b = SafeU120::new(3);\n let c = SafeU120::new(0);\n let _d = SafeU120::mul_div_up(a, b, c);\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/aztec-nr/safe-math/src/safe_u120" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/aztec-nr/safe-math/src/safe_u120" }, "98": { "source": "// docs:start:token_types_all\nuse dep::std::hash::pedersen;\nuse dep::aztec::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_siloed_note_hash,\n};\nuse dep::aztec::hash::{compute_secret_hash};\n\nglobal TRANSPARENT_NOTE_LEN: Field = 2;\n\n// Transparent note represents a note that is created in the clear (public execution),\n// but can only be spent by those that know the preimage of the \"secret_hash\"\nstruct TransparentNote {\n amount: Field,\n secret_hash: Field,\n // the secret is just here for ease of use and won't be (de)serialized\n secret: Field,\n // header is just here to satisfy the NoteInterface\n header: NoteHeader,\n}\n\nimpl TransparentNote {\n\n // CONSTRUCTORS\n\n pub fn new(amount: Field, secret_hash: Field) -> Self {\n TransparentNote {\n amount: amount,\n secret_hash: secret_hash,\n secret: 0,\n header: NoteHeader::empty(),\n }\n }\n\n // new oracle call primitive\n // get me the secret corresponding to this hash\n pub fn new_from_secret(amount: Field, secret: Field) -> Self {\n TransparentNote {\n amount: amount,\n secret_hash: compute_secret_hash(secret),\n secret: secret,\n header: NoteHeader::empty(),\n }\n }\n\n\n // STANDARD NOTE_INTERFACE FUNCTIONS\n\n pub fn serialize(self) -> [Field; TRANSPARENT_NOTE_LEN] {\n [self.amount, self.secret_hash]\n }\n\n pub fn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> Self {\n TransparentNote {\n amount: preimage[0],\n secret_hash: preimage[1],\n secret: 0,\n header: NoteHeader::empty(),\n }\n }\n\n pub fn compute_note_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n dep::std::hash::pedersen([\n self.amount,\n self.secret_hash,\n ])[0]\n }\n\n pub fn compute_nullifier(self) -> Field {\n // TODO(#1386): should use `compute_note_hash_for_read_or_nullify` once public functions inject nonce!\n let siloed_note_hash = compute_siloed_note_hash(TransparentNoteMethods, self);\n // TODO(#1205) Should use a non-zero generator index.\n pedersen([self.secret, siloed_note_hash])[0]\n }\n\n pub fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n\n // CUSTOM FUNCTIONS FOR THIS NOTE TYPE\n\n pub fn knows_secret(self, secret: Field) {\n let hash = compute_secret_hash(secret);\n assert(self.secret_hash == hash);\n }\n}\n\nfn deserialize(preimage: [Field; TRANSPARENT_NOTE_LEN]) -> TransparentNote {\n TransparentNote::deserialize(preimage)\n}\n\nfn serialize(note: TransparentNote) -> [Field; TRANSPARENT_NOTE_LEN] {\n note.serialize()\n}\n\nfn compute_note_hash(note: TransparentNote) -> Field {\n note.compute_note_hash()\n}\n\nfn compute_nullifier(note: TransparentNote) -> Field {\n note.compute_nullifier()\n}\n\nfn get_header(note: TransparentNote) -> NoteHeader {\n note.header\n}\n\nfn set_header(note: &mut TransparentNote, header: NoteHeader) {\n note.set_header(header)\n}\n\nglobal TransparentNoteMethods = NoteInterface {\n deserialize,\n serialize,\n compute_note_hash,\n compute_nullifier,\n get_header,\n set_header,\n};\n// docs:end:token_types_all", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/transparent_note" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/transparent_note" }, "99": { "source": "use dep::std::option::Option;\nuse dep::safe_math::SafeU120;\nuse dep::aztec::{\n context::Context,\n constants_gen::MAX_READ_REQUESTS_PER_CALL,\n state_vars::set::Set,\n log::emit_encrypted_log,\n types::address::AztecAddress,\n};\nuse dep::aztec::note::{\n note_getter::view_notes,\n note_getter_options::{NoteGetterOptions, SortOrder},\n note_viewer_options::NoteViewerOptions\n};\nuse dep::aztec::note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_note_hash_for_read_or_nullify,\n};\nuse dep::aztec::oracle::{\n rand::rand,\n get_secret_key::get_secret_key,\n get_public_key::get_public_key,\n};\n\nuse crate::types::token_note::{TokenNote, TOKEN_NOTE_LEN, TokenNoteMethods};\n\n// A set implementing standard manipulation of balances.\n// Does not require spending key, but only knowledge.\n// Spending key requirement should be enforced by the contract using this.\nstruct BalanceSet {\n context: Context,\n owner: AztecAddress,\n set: Set\n}\n\nimpl BalanceSet {\n pub fn new(context: Context, owner: AztecAddress, storage_slot: Field) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n let set = Set {\n context,\n storage_slot,\n note_interface: TokenNoteMethods,\n };\n Self {\n context,\n owner,\n set,\n }\n }\n\n unconstrained pub fn balance_of(self: Self) -> SafeU120 {\n self.balance_of_with_offset(0)\n }\n\n unconstrained pub fn balance_of_with_offset(self: Self, offset: u32) -> SafeU120 {\n // Same as SafeU120::new(0), but fewer constraints because no check. \n let mut balance = SafeU120::min();\n // docs:start:view_notes\n let options = NoteViewerOptions::new().set_offset(offset);\n let opt_notes = self.set.view_notes(options);\n // docs:end:view_notes\n let len = opt_notes.len();\n for i in 0..len {\n if opt_notes[i].is_some() {\n balance = balance.add(opt_notes[i].unwrap_unchecked().amount);\n }\n }\n if (opt_notes[len - 1].is_some()) {\n balance = balance.add(self.balance_of_with_offset(offset + opt_notes.len() as u32));\n }\n\n balance\n }\n\n pub fn add(self: Self, addend: SafeU120) {\n let mut addend_note = TokenNote::new(addend, self.owner);\n\n // docs:start:insert\n self.set.insert(&mut addend_note);\n // docs:end:insert\n\n addend_note.emit_encrypted(\n self.context.private.unwrap(),\n self.set.storage_slot\n );\n }\n\n pub fn sub(self: Self, subtrahend: SafeU120) {\n // docs:start:get_notes\n let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend);\n let maybe_notes = self.set.get_notes(options);\n // docs:end:get_notes\n\n let mut minuend: SafeU120 = SafeU120::min();\n for i in 0..maybe_notes.len() {\n if maybe_notes[i].is_some() {\n let note = maybe_notes[i].unwrap_unchecked();\n\n // Removes the note from the owner's set of notes.\n // This will call the the `compute_nullifer` function of the `token_note`\n // which require knowledge of the secret key (currently the users encryption key).\n // The contract logic must ensure that the spending key is used as well.\n // docs:start:remove\n self.set.remove(note);\n // docs:end:remove\n\n minuend = minuend.add(note.amount);\n }\n }\n\n // This is to provide a nicer error msg,\n // without it minuend-subtrahend would still catch it, but more generic error then.\n // without the == true, it includes 'minuend.ge(subtrahend)' as part of the error.\n assert(minuend.ge(subtrahend) == true, \"Balance too low\");\n\n self.add(minuend.sub(subtrahend));\n }\n}\n\npub fn filter_notes_min_sum(notes: [Option; MAX_READ_REQUESTS_PER_CALL], min_sum: SafeU120) -> [Option; MAX_READ_REQUESTS_PER_CALL] {\n let mut selected = [Option::none(); MAX_READ_REQUESTS_PER_CALL];\n let mut sum = SafeU120::min();\n for i in 0..notes.len() {\n if notes[i].is_some() & sum.lt(min_sum) {\n let note = notes[i].unwrap_unchecked();\n selected[i] = Option::some(note);\n sum = sum.add(note.amount);\n }\n }\n selected\n}", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/balance_set" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balance_set" }, "100": { "source": "use dep::aztec::context::{PrivateContext, PublicContext, Context};\nuse dep::aztec::types::address::AztecAddress;\nuse dep::std::option::Option;\nuse crate::types::balance_set::BalanceSet;\n\nstruct BalancesMap {\n context: Context,\n storage_slot: Field,\n}\n\nimpl BalancesMap {\n pub fn new(\n context: Context,\n storage_slot: Field,\n ) -> Self {\n assert(storage_slot != 0, \"Storage slot 0 not allowed. Storage slots must start from 1.\");\n Self {\n context,\n storage_slot,\n }\n }\n\n pub fn at(self, owner: AztecAddress) -> BalanceSet {\n let derived_storage_slot = dep::std::hash::pedersen([self.storage_slot, owner.address])[0];\n BalanceSet::new(self.context, owner, derived_storage_slot)\n }\n}\n", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/balances_map" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/balances_map" }, "101": { "source": "use dep::aztec::{\n note::{\n note_header::NoteHeader,\n note_interface::NoteInterface,\n utils::compute_note_hash_for_read_or_nullify,\n },\n context::PrivateContext,\n constants_gen::MAX_READ_REQUESTS_PER_CALL,\n state_vars::set::Set,\n log::emit_encrypted_log\n};\nuse dep::aztec::types::address::AztecAddress;\nuse dep::aztec::oracle::{\n rand::rand,\n get_secret_key::get_secret_key,\n get_public_key::get_public_key,\n};\n\nuse dep::safe_math::SafeU120;\nuse dep::std::option::Option;\n\nglobal TOKEN_NOTE_LEN: Field = 3; // 3 plus a header.\n\nstruct TokenNote {\n // the amount of tokens in the note\n amount: SafeU120,\n // the provider of secrets for the nullifier. The owner (recipient) to ensure that the note \n // can be privately spent. When nullifier secret and encryption private key is same \n // we can simply use the owner for this one.\n owner: AztecAddress,\n // randomness of the note to hide contents.\n randomness: Field,\n // the note header (contract_address, nonce, storage_slot)\n // included in the note such that it becomes part of encrypted logs for later use.\n header: NoteHeader,\n}\n\nimpl TokenNote {\n pub fn new(amount: SafeU120, owner: AztecAddress) -> Self {\n Self {\n amount,\n owner,\n randomness: rand(),\n header: NoteHeader::empty(),\n }\n }\n\n pub fn serialize(self) -> [Field; TOKEN_NOTE_LEN] {\n [self.amount.value as Field, self.owner.address, self.randomness]\n }\n\n pub fn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> Self {\n Self {\n amount: SafeU120::new(preimage[0]),\n owner: AztecAddress::new(preimage[1]),\n randomness: preimage[2],\n header: NoteHeader::empty(),\n }\n }\n\n pub fn compute_note_hash(self) -> Field {\n // TODO(#1205) Should use a non-zero generator index.\n dep::std::hash::pedersen([\n self.amount.value as Field, \n self.owner.address as Field,\n self.randomness,\n ])[0]\n }\n\n // docs:start:nullifier\n pub fn compute_nullifier(self) -> Field {\n let note_hash_for_nullify = compute_note_hash_for_read_or_nullify(TokenNoteMethods, self);\n let secret = get_secret_key(self.owner.address);\n // TODO(#1205) Should use a non-zero generator index.\n dep::std::hash::pedersen([\n note_hash_for_nullify,\n secret.low,\n secret.high,\n ])[0]\n }\n // docs:end:nullifier\n\n pub fn set_header(&mut self, header: NoteHeader) {\n self.header = header;\n }\n\n\n pub fn emit_encrypted(\n self: &mut Self,\n context: &mut PrivateContext,\n storage_slot: Field,\n ) {\n // We only bother inserting the note if non-empty to save funds on gas.\n if !self.amount.is_zero() {\n // docs:start:encrypted\n let application_contract_address = (*context).this_address();\n let encryption_pub_key = get_public_key(self.owner.address);\n let encrypted_data = (*self).serialize();\n\n emit_encrypted_log(\n context,\n application_contract_address,\n storage_slot,\n encryption_pub_key,\n encrypted_data,\n );\n // docs:end:encrypted\n }\n }\n}\n\nfn deserialize(preimage: [Field; TOKEN_NOTE_LEN]) -> TokenNote {\n TokenNote::deserialize(preimage)\n}\n\nfn serialize(note: TokenNote) -> [Field; TOKEN_NOTE_LEN] {\n note.serialize()\n}\n\nfn compute_note_hash(note: TokenNote) -> Field {\n note.compute_note_hash()\n}\n\nfn compute_nullifier(note: TokenNote) -> Field {\n note.compute_nullifier()\n}\n\nfn get_header(note: TokenNote) -> NoteHeader {\n note.header\n}\n\nfn set_header(note: &mut TokenNote, header: NoteHeader) {\n note.set_header(header)\n}\n\nglobal TokenNoteMethods = NoteInterface {\n deserialize,\n serialize,\n compute_note_hash,\n compute_nullifier,\n get_header,\n set_header,\n};", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/token_note" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/token_note" }, "102": { "source": "use dep::aztec::types::type_serialization::TypeSerializationInterface;\nuse dep::safe_math::SafeU120;\n\nglobal SAFE_U120_SERIALIZED_LEN: Field = 1;\n\n// This is safe when reading from storage IF only correct safeu120 was written to storage\nfn deserializeU120(fields: [Field; SAFE_U120_SERIALIZED_LEN]) -> SafeU120 {\n SafeU120{value: fields[0] as u120}\n}\n\nfn serializeU120(value: SafeU120) -> [Field; SAFE_U120_SERIALIZED_LEN] {\n [value.value as Field]\n}\n\nglobal SafeU120SerializationMethods = TypeSerializationInterface {\n deserialize: deserializeU120,\n serialize: serializeU120,\n};", - "path": "/Users/danlee/code/aztec-packages-2/yarn-project/boxes/token/src/contracts/src/types/safe_u120_serialization" + "path": "/mnt/user-data/dan/aztec-packages/yarn-project/boxes/token/src/contracts/src/types/safe_u120_serialization" } } } From 40d4837d7815e8bda8276b30b87bdf428ee1fdcd Mon Sep 17 00:00:00 2001 From: Dan Lee Date: Wed, 18 Oct 2023 17:57:38 +0100 Subject: [PATCH 3/3] center horizontally --- yarn-project/boxes/token/src/app/contract.module.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn-project/boxes/token/src/app/contract.module.scss b/yarn-project/boxes/token/src/app/contract.module.scss index c976043d163..fa75392ba4a 100644 --- a/yarn-project/boxes/token/src/app/contract.module.scss +++ b/yarn-project/boxes/token/src/app/contract.module.scss @@ -18,6 +18,7 @@ flex-direction: row; gap: 20px; flex-wrap: wrap; + justify-content: center; } .tag {