Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add deploy contract helper to aztec-nr #4775

Merged
merged 8 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions l1-contracts/slither_output.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,15 +353,15 @@ src/core/messagebridge/Inbox.sol#L148-L153
Impact: Informational
Confidence: Medium
- [ ] ID-41
Variable [Constants.LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L122) is too similar to [Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L115)
Variable [Constants.LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L125) is too similar to [Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L118)

src/core/libraries/ConstantsGen.sol#L122
src/core/libraries/ConstantsGen.sol#L125


- [ ] ID-42
Variable [Constants.L1_TO_L2_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L102) is too similar to [Constants.L2_TO_L1_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L103)
Variable [Constants.L1_TO_L2_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L105) is too similar to [Constants.L2_TO_L1_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L106)

src/core/libraries/ConstantsGen.sol#L102
src/core/libraries/ConstantsGen.sol#L105


- [ ] ID-43
Expand Down
3 changes: 3 additions & 0 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ library Constants {
0xe7af816635466f128568edb04c9fa024f6c87fb9010fdbffa68b3d99;
uint256 internal constant DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE =
0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631;
uint256 internal constant DEPLOYER_CONTRACT_ADDRESS =
0x0747a20ed0c86035e44ea5606f30de459f40b55c5e82012640aa554546af9044;
uint256 internal constant L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH = 25;
uint256 internal constant MAX_NOTE_FIELDS_LENGTH = 20;
uint256 internal constant GET_NOTE_ORACLE_RETURN_LENGTH = 23;
Expand All @@ -92,6 +94,7 @@ library Constants {
uint256 internal constant CALL_CONTEXT_LENGTH = 8;
uint256 internal constant CONTENT_COMMITMENT_LENGTH = 7;
uint256 internal constant CONTRACT_DEPLOYMENT_DATA_LENGTH = 6;
uint256 internal constant CONTRACT_INSTANCE_LENGTH = 6;
uint256 internal constant CONTRACT_STORAGE_READ_LENGTH = 2;
uint256 internal constant CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH = 2;
uint256 internal constant ETH_ADDRESS_LENGTH = 1;
Expand Down
38 changes: 38 additions & 0 deletions noir-projects/aztec-nr/aztec/src/deploy.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::{
context::PrivateContext,
oracle::get_contract_instance::get_contract_instance,
};

use dep::protocol_types::{
address::AztecAddress,
abis::function_selector::FunctionSelector,
constants::DEPLOYER_CONTRACT_ADDRESS,
};

// Calls `deploy` on the deployer contract to deploy a new instance.
pub fn deploy_contract(context: &mut PrivateContext, target: AztecAddress) {
let instance = get_contract_instance(target);

let mut universal_deploy = false;
if ! instance.deployer.is_zero() {
assert(instance.deployer == context.this_address(), "Deployer address does not match current address");
universal_deploy = true;
}

// Adapted from noir-contracts/contracts/contract_instance_deployer_contract/src/interface/ContractInstanceDeployer.nr
// That file was autogenerated running the following command from noir-projects/noir-contracts:
// ../../yarn-project/node_modules/.bin/aztec-cli codegen target/contract_instance_deployer_contract-ContractInstanceDeployer.json --nr -o ./contracts/contract_instance_deployer_contract/src/interface
let mut serialized_args = [0; 6];
serialized_args[0] = instance.salt;
serialized_args[1] = instance.contract_class_id.to_field();
serialized_args[2] = instance.initialization_hash;
serialized_args[3] = instance.portal_contract_address.to_field();
serialized_args[4] = instance.public_keys_hash.to_field();
serialized_args[5] = universal_deploy as Field;

let _call_result = context.call_private_function(
AztecAddress::from_field(DEPLOYER_CONTRACT_ADDRESS),
FunctionSelector::from_field(0x883355ab),
serialized_args
);
}
1 change: 1 addition & 0 deletions noir-projects/aztec-nr/aztec/src/lib.nr
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod avm;
mod context;
mod deploy;
mod hash;
mod hasher;
mod history;
Expand Down
1 change: 1 addition & 0 deletions noir-projects/aztec-nr/aztec/src/oracle.nr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod arguments;
mod call_private_function;
mod context;
mod debug_log;
mod get_contract_instance;
mod get_l1_to_l2_message;
mod get_nullifier_membership_witness;
mod get_public_data_witness;
Expand Down
14 changes: 14 additions & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use dep::protocol_types::{address::AztecAddress, contract_instance::ContractInstance, constants::CONTRACT_INSTANCE_LENGTH};

#[oracle(getContractInstance)]
fn get_contract_instance_oracle(_address: AztecAddress) -> [Field; CONTRACT_INSTANCE_LENGTH] {}

unconstrained fn get_contract_instance_internal(address: AztecAddress) -> [Field; CONTRACT_INSTANCE_LENGTH] {
get_contract_instance_oracle(address)
}

pub fn get_contract_instance(address: AztecAddress) -> ContractInstance {
let instance = ContractInstance::deserialize(get_contract_instance_internal(address));
assert(instance.to_address().eq(address));
instance
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* Autogenerated file, do not edit! */

use dep::std;
use dep::aztec::context::{PrivateContext, PublicContext};
use dep::aztec::protocol_types::{address::AztecAddress, abis::function_selector::FunctionSelector, constants::RETURN_VALUES_LENGTH};

struct ContractClassIdDeployStruct {
inner: Field,
}

struct PortalContractAddressDeployStruct {
inner: Field,
}

struct PublicKeysHashDeployStruct {
inner: Field,
}

// Interface for calling ContractInstanceDeployer functions from a private context
struct ContractInstanceDeployerPrivateContextInterface {
address: AztecAddress,
}

impl ContractInstanceDeployerPrivateContextInterface {
pub fn at(address: AztecAddress) -> Self {
Self { address }
}

pub fn deploy(
self,
context: &mut PrivateContext,
salt: Field,
contract_class_id: ContractClassIdDeployStruct,
initialization_hash: Field,
portal_contract_address: PortalContractAddressDeployStruct,
public_keys_hash: PublicKeysHashDeployStruct,
universal_deploy: bool
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialized_args = [0; 6];
serialized_args[0] = salt;
serialized_args[1] = contract_class_id.inner;
serialized_args[2] = initialization_hash;
serialized_args[3] = portal_contract_address.inner;
serialized_args[4] = public_keys_hash.inner;
serialized_args[5] = universal_deploy as Field;

context.call_private_function(
self.address,
FunctionSelector::from_field(0x883355ab),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spalladino where does this fn selector point to/where does it come from?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rahul-kothari this is autogenerated code by the noir codegen. It calls the function with the same name as the method, in this case deploy.

serialized_args
)
}
}

// Interface for calling ContractInstanceDeployer functions from a public context
struct ContractInstanceDeployerPublicContextInterface {
address: AztecAddress,
}

impl ContractInstanceDeployerPublicContextInterface {
pub fn at(address: AztecAddress) -> Self {
Self { address }
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ contract StatefulTest {
use dep::std::option::Option;
use dep::value_note::{balance_utils, utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote}};
use dep::aztec::{
deploy::{deploy_contract as aztec_deploy_contract},
context::{PrivateContext, PublicContext, Context},
note::{note_header::NoteHeader, utils as note_utils},
state_vars::{Map, PublicMutable, PrivateSet}
state_vars::{Map, PublicMutable, PrivateSet},
oracle::get_contract_instance::get_contract_instance
};

struct Storage {
Expand Down Expand Up @@ -55,4 +57,10 @@ contract StatefulTest {
unconstrained fn get_public_value(owner: AztecAddress) -> pub Field {
storage.public_values.at(owner).read()
}

// This method is here because we've hit the 32 function limit for the TestContract
#[aztec(private)]
fn deploy_contract(target: AztecAddress) {
aztec_deploy_contract(&mut context, target);
}
}
1 change: 1 addition & 0 deletions noir-projects/noir-protocol-circuits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"build": "yarn clean && yarn noir:build",
"clean": "rm -rf ./dest src/target",
"noir:build": "cd src && ../../../noir/target/release/nargo compile --silence-warnings",
"noir:format": "cd src && ../../../noir/target/release/nargo fmt",
"test": "cd src && ../../../noir/target/release/nargo test --silence-warnings"
},
"files": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ impl Deserialize<1> for PublicKeysHash {
}
}

impl Eq for PublicKeysHash {
fn eq(self, other: Self) -> bool {
self.inner == other.inner
}
}

impl PublicKeysHash {
pub fn from_field(field: Field) -> Self {
Self { inner: field }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ global REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE = 0xe7af8166354
// CONTRACT INSTANCE CONSTANTS
// sha224sum 'struct ContractInstanceDeployed'
global DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE = 0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631;
global DEPLOYER_CONTRACT_ADDRESS = 0x0747a20ed0c86035e44ea5606f30de459f40b55c5e82012640aa554546af9044;

// NOIR CONSTANTS - constants used only in yarn-packages/noir-contracts
// Some are defined here because Noir doesn't yet support globals referencing other globals yet.
Expand All @@ -142,6 +143,7 @@ global AZTEC_ADDRESS_LENGTH = 1;
global CALL_CONTEXT_LENGTH: u64 = 8;
global CONTENT_COMMITMENT_LENGTH: u64 = 7;
global CONTRACT_DEPLOYMENT_DATA_LENGTH: u64 = 6;
global CONTRACT_INSTANCE_LENGTH: u64 = 6;
global CONTRACT_STORAGE_READ_LENGTH: u64 = 2;
global CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: u64 = 2;
global ETH_ADDRESS_LENGTH = 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use crate::{
address::{
aztec_address::AztecAddress, eth_address::EthAddress, partial_address::PartialAddress,
public_keys_hash::PublicKeysHash
},
contract_class_id::ContractClassId,
constants::{GENERATOR_INDEX__CONTRACT_DEPLOYMENT_DATA, CONTRACT_INSTANCE_LENGTH},
traits::{Deserialize, Hash, Serialize}
};

struct ContractInstance {
salt : Field,
deployer: AztecAddress,
contract_class_id : ContractClassId,
initialization_hash : Field,
portal_contract_address : EthAddress,
public_keys_hash : PublicKeysHash,
}

impl Eq for ContractInstance {
fn eq(self, other: Self) -> bool {
self.public_keys_hash.eq(other.public_keys_hash) &
self.initialization_hash.eq(other.initialization_hash) &
self.contract_class_id.eq(other.contract_class_id) &
self.salt.eq(other.salt) &
self.portal_contract_address.eq(other.portal_contract_address)
}
}

impl Serialize<CONTRACT_INSTANCE_LENGTH> for ContractInstance {
fn serialize(self) -> [Field; CONTRACT_INSTANCE_LENGTH] {
[
self.salt,
self.deployer.to_field(),
self.contract_class_id.to_field(),
self.initialization_hash,
self.portal_contract_address.to_field(),
self.public_keys_hash.to_field()
]
}
}

impl Deserialize<CONTRACT_INSTANCE_LENGTH> for ContractInstance {
fn deserialize(serialized: [Field; CONTRACT_INSTANCE_LENGTH]) -> Self {
Self {
salt: serialized[0],
deployer: AztecAddress::from_field(serialized[1]),
contract_class_id: ContractClassId::from_field(serialized[2]),
initialization_hash: serialized[3],
portal_contract_address: EthAddress::from_field(serialized[4]),
public_keys_hash: PublicKeysHash::from_field(serialized[5]),
}
}
}

impl Hash for ContractInstance {
fn hash(self) -> Field {
self.to_address().to_field()
}
}

impl ContractInstance {
fn to_address(self) -> AztecAddress {
AztecAddress::compute(
self.public_keys_hash,
PartialAddress::compute(
self.contract_class_id,
self.salt,
self.initialization_hash,
self.portal_contract_address
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod transaction;
mod abis;
mod constants;
mod contract_class_id;
mod contract_instance;

mod messaging;
mod mocked;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@ mod read_requests;
use crate::{
abis::{append_only_tree_snapshot::AppendOnlyTreeSnapshot, global_variables::GlobalVariables},
address::{AztecAddress, EthAddress}, constants::NUM_FIELDS_PER_SHA256,
grumpkin_point::GrumpkinPoint,
content_commitment::ContentCommitment,
header::Header,
partial_state_reference::PartialStateReference,
state_reference::StateReference,
tests::fixtures
grumpkin_point::GrumpkinPoint, content_commitment::ContentCommitment, header::Header,
partial_state_reference::PartialStateReference, state_reference::StateReference, tests::fixtures
};

global MSG_SENDER = AztecAddress { inner: 27 };
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/circuits.js/src/constants.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE =
0xe7af816635466f128568edb04c9fa024f6c87fb9010fdbffa68b3d99n;
export const DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE =
0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631n;
export const DEPLOYER_CONTRACT_ADDRESS = 0x0747a20ed0c86035e44ea5606f30de459f40b55c5e82012640aa554546af9044n;
export const L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH = 25;
export const MAX_NOTE_FIELDS_LENGTH = 20;
export const GET_NOTE_ORACLE_RETURN_LENGTH = 23;
Expand All @@ -78,6 +79,7 @@ export const AZTEC_ADDRESS_LENGTH = 1;
export const CALL_CONTEXT_LENGTH = 8;
export const CONTENT_COMMITMENT_LENGTH = 7;
export const CONTRACT_DEPLOYMENT_DATA_LENGTH = 6;
export const CONTRACT_INSTANCE_LENGTH = 6;
export const CONTRACT_STORAGE_READ_LENGTH = 2;
export const CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH = 2;
export const ETH_ADDRESS_LENGTH = 1;
Expand Down
Loading
Loading