Skip to content

Commit

Permalink
feat: Use deployer in address computation (#5201)
Browse files Browse the repository at this point in the history
Includes deployer field in contract instance address computation as
specced in the yellow paper.
  • Loading branch information
spalladino committed Mar 15, 2024
1 parent 664975f commit 258ff4a
Show file tree
Hide file tree
Showing 43 changed files with 225 additions and 194 deletions.
2 changes: 1 addition & 1 deletion l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ library Constants {
uint256 internal constant DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE =
0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631;
uint256 internal constant DEPLOYER_CONTRACT_ADDRESS =
0x0bffa876f07f9fe1802579dfef599810202f9c25b9a2f58921064a267d1ad1d3;
0x00de4d0d9913ddba5fbba9286031b4a5dc9b2af5e824154ae75938f96c1bfe78;
uint256 internal constant L1_TO_L2_MESSAGE_ORACLE_CALL_LENGTH = 17;
uint256 internal constant MAX_NOTE_FIELDS_LENGTH = 20;
uint256 internal constant GET_NOTE_ORACLE_RETURN_LENGTH = 23;
Expand Down
9 changes: 3 additions & 6 deletions noir-projects/aztec-nr/aztec/src/deploy.nr
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ use dep::protocol_types::{address::AztecAddress, abis::function_selector::Functi
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;
let universal_deploy = instance.deployer.is_zero();
if !universal_deploy {
assert(instance.deployer == context.this_address(), "Deployer address does not match current address");
}

// Adapted from noir-contracts/contracts/contract_instance_deployer_contract/src/interface/ContractInstanceDeployer.nr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct ContractInstanceDeployed {
initialization_hash: Field,
portal_contract_address: EthAddress,
public_keys_hash: PublicKeysHash,
universal_deploy: bool,
deployer: AztecAddress,
}

global CONTRACT_INSTANCE_DEPLOYED_SERIALIZED_SIZE: Field = 9;
Expand All @@ -29,7 +29,7 @@ impl Serialize<CONTRACT_INSTANCE_DEPLOYED_SERIALIZED_SIZE> for ContractInstanceD
self.initialization_hash,
self.portal_contract_address.to_field(),
self.public_keys_hash.to_field(),
self.universal_deploy as Field,
self.deployer.to_field(),
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ contract ContractInstanceDeployer {
) {
// TODO(@spalladino): assert nullifier_exists silo(contract_class_id, ContractClassRegisterer)

// TODO(#4434) Add deployer field to instance calculation
// let deployer = if universal_deploy { Field::zero() } else { context.msg_sender() };
let deployer = if universal_deploy {
AztecAddress::zero()
} else {
context.msg_sender()
};

let partial_address = PartialAddress::compute(
contract_class_id,
salt,
initialization_hash,
portal_contract_address
portal_contract_address,
deployer
);

let address = AztecAddress::compute(public_keys_hash, partial_address);
Expand All @@ -45,7 +49,7 @@ contract ContractInstanceDeployer {
portal_contract_address,
initialization_hash,
salt,
universal_deploy,
deployer,
version: 1
};
let event_payload = event.serialize();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ mod tests {
let call_stack_item = PublicCallStackItem { contract_address, public_inputs, is_execution_request: true, function_data };

// Value from public_call_stack_item.test.ts "Computes a callstack item request hash" test
let test_data_call_stack_item_request_hash = 0xedd2f10c0cdf776ee2fff3c799bae6df5771f5013a2d5d7154601dffdcf869;
let test_data_call_stack_item_request_hash = 0x00edd2f10c0cdf776ee2fff3c799bae6df5771f5013a2d5d7154601dffdcf869;
assert_eq(call_stack_item.hash(), test_data_call_stack_item_request_hash);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,17 @@ impl AztecAddress {
contract_class_id: ContractClassId,
salt: Field,
initialization_hash: Field,
portal_contract_address: EthAddress
portal_contract_address: EthAddress,
deployer: AztecAddress
) -> AztecAddress {
AztecAddress::compute(
PublicKeysHash::compute(pub_key),
PartialAddress::compute(
contract_class_id,
salt,
initialization_hash,
portal_contract_address
portal_contract_address,
deployer
)
)
}
Expand Down Expand Up @@ -99,16 +101,19 @@ fn compute_address() {
let contract_class_id = ContractClassId::from_field(4);
let initialization_hash = 5;
let portal_contract_address = EthAddress::from_field(6);
let deployer = AztecAddress::from_field(7);

let address = AztecAddress::compute_from_public_key(
point,
contract_class_id,
contract_address_salt,
initialization_hash,
portal_contract_address
portal_contract_address,
deployer
);

assert(address.to_field() == 0x2fd71a4f0742364f194dd16d0ae32d2f47845ddc7f5d328f37d4148b565c4123);
let expected_computed_address_from_preimage = 0x027ea2b41ced2ec9a98305984e96dd28518536a4628883ccdc06e38aa8997220;
assert(address.to_field() == expected_computed_address_from_preimage);
}

#[test]
Expand All @@ -117,5 +122,6 @@ fn compute_address_from_partial_and_pubkey() {
let partial_address = PartialAddress::from_field(3);

let address = AztecAddress::compute(PublicKeysHash::compute(point), partial_address);
assert(address.to_field() == 0x0447f893197175723deb223696e2e96dbba1e707ee8507766373558877e74197);
let expected_computed_address_from_partial_and_pubkey = 0x0447f893197175723deb223696e2e96dbba1e707ee8507766373558877e74197;
assert(address.to_field() == expected_computed_address_from_partial_and_pubkey);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use crate::{
address::{eth_address::EthAddress, salted_initialization_hash::SaltedInitializationHash},
address::{
eth_address::EthAddress, salted_initialization_hash::SaltedInitializationHash,
aztec_address::AztecAddress
},
constants::GENERATOR_INDEX__PARTIAL_ADDRESS, contract_class_id::ContractClassId,
hash::pedersen_hash, traits::ToField
};
Expand All @@ -24,11 +27,12 @@ impl PartialAddress {
contract_class_id: ContractClassId,
salt: Field,
initialization_hash: Field,
portal_contract_address: EthAddress
portal_contract_address: EthAddress,
deployer: AztecAddress
) -> Self {
PartialAddress::compute_from_salted_initialization_hash(
contract_class_id,
SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address)
SaltedInitializationHash::compute(salt, initialization_hash, portal_contract_address, deployer)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ impl PublicKeysHash {
fn compute_public_keys_hash() {
let point = GrumpkinPoint { x: 1, y: 2 };
let actual = PublicKeysHash::compute(point);
assert(actual.to_field() == 0x1923a6246e305720b6aaf751fde0342613e93c82e455c3831e28375c16dd40d8);
let expected_public_keys_hash = 0x1923a6246e305720b6aaf751fde0342613e93c82e455c3831e28375c16dd40d8;
assert(actual.to_field() == expected_public_keys_hash);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
address::eth_address::EthAddress, constants::GENERATOR_INDEX__PARTIAL_ADDRESS, hash::pedersen_hash,
traits::ToField
address::{eth_address::EthAddress, aztec_address::AztecAddress},
constants::GENERATOR_INDEX__PARTIAL_ADDRESS, hash::pedersen_hash, traits::ToField
};

// Salted initialization hash. Used in the computation of a partial address.
Expand All @@ -19,23 +19,25 @@ impl SaltedInitializationHash {
Self { inner: field }
}

pub fn compute(salt: Field, initialization_hash: Field, portal_contract_address: EthAddress) -> Self {
pub fn compute(
salt: Field,
initialization_hash: Field,
portal_contract_address: EthAddress,
deployer: AztecAddress
) -> Self {
SaltedInitializationHash::from_field(
pedersen_hash(
[
salt,
initialization_hash,
deployer.to_field(),
portal_contract_address.to_field()
],
GENERATOR_INDEX__PARTIAL_ADDRESS
)
)
}

pub fn to_field(self) -> Field {
self.inner
}

pub fn assert_is_zero(self) {
assert(self.to_field() == 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,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 = 0x0bffa876f07f9fe1802579dfef599810202f9c25b9a2f58921064a267d1ad1d3;
global DEPLOYER_CONTRACT_ADDRESS = 0x00de4d0d9913ddba5fbba9286031b4a5dc9b2af5e824154ae75938f96c1bfe78;

// 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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ impl ContractInstance {
self.contract_class_id,
self.salt,
self.initialization_hash,
self.portal_contract_address
self.portal_contract_address,
self.deployer
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct ContractData {
public_keys_hash: PublicKeysHash,
salted_initialization_hash: SaltedInitializationHash,
partial_address: PartialAddress,
deployer: AztecAddress,
}

// taken from __snapshots__/noir_test_gen.test.ts.snap
Expand All @@ -26,7 +27,8 @@ global default_contract = ContractData {
portal_contract_address: EthAddress { inner: 0x0000000000000000000000000000000000005ba0 },
contract_class_id: ContractClassId { inner: 0x0ce2a998337b1e6da1ac1d802a8bb9e10b7d705d210e61efb9642855009814a6 },
public_keys_hash: PublicKeysHash { inner: 0x000000000000000000000000000000000000000000000000000000000000b26e },
salted_initialization_hash: SaltedInitializationHash { inner: 0x2003637d02f08887d36dc2f27dd961f51f17e0a8a43dc0268dfcefcd96efc3a4 }
salted_initialization_hash: SaltedInitializationHash { inner: 0x2003637d02f08887d36dc2f27dd961f51f17e0a8a43dc0268dfcefcd96efc3a4 },
deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 },
};

// taken from __snapshots__/noir_test_gen.test.ts.snap
Expand All @@ -40,5 +42,6 @@ global parent_contract = ContractData {
portal_contract_address: EthAddress { inner: 0x0000000000000000000000000000000000000913 },
contract_class_id: ContractClassId { inner: 0x1f1f963a350e2c883cc6730c19fc5d5b47a40694d805cbb0720fa76fe295df90 },
public_keys_hash: PublicKeysHash { inner: 0x00000000000000000000000000000000000000000000000000000000000011c1 },
salted_initialization_hash: SaltedInitializationHash { inner: 0x275e153c147f9cb61a5e7b354e81484696d6a54ffc251dcf4ed8276ab24868d2 }
salted_initialization_hash: SaltedInitializationHash { inner: 0x275e153c147f9cb61a5e7b354e81484696d6a54ffc251dcf4ed8276ab24868d2 },
deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 },
};
6 changes: 5 additions & 1 deletion yarn-project/accounts/src/defaults/account_interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AccountInterface, AuthWitnessProvider, EntrypointInterface, FeeOptions } from '@aztec/aztec.js/account';
import { AuthWitness, FunctionCall, TxExecutionRequest } from '@aztec/circuit-types';
import { CompleteAddress, Fr } from '@aztec/circuits.js';
import { AztecAddress, CompleteAddress, Fr } from '@aztec/circuits.js';
import { DefaultAccountEntrypoint } from '@aztec/entrypoints/account';
import { NodeInfo } from '@aztec/types/interfaces';

Expand Down Expand Up @@ -35,4 +35,8 @@ export class DefaultAccountInterface implements AccountInterface {
getCompleteAddress(): CompleteAddress {
return this.address;
}

getAddress(): AztecAddress {
return this.address.address;
}
}
1 change: 1 addition & 0 deletions yarn-project/accounts/src/testing/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export async function deployInitialTestAccounts(pxe: PXE) {
contractAddressSalt: x.account.salt,
skipClassRegistration: true,
skipPublicDeployment: true,
universalDeploy: true,
});
await deployMethod.simulate({});
return deployMethod;
Expand Down
1 change: 1 addition & 0 deletions yarn-project/accounts/src/testing/create_account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export async function createAccounts(pxe: PXE, numberOfAccounts = 1): Promise<Ac
contractAddressSalt: account.salt,
skipClassRegistration: true,
skipPublicDeployment: true,
universalDeploy: true,
}),
);
accounts.push(account);
Expand Down
67 changes: 2 additions & 65 deletions yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,7 @@ import { DebugLogger, createDebugLogger } from '@aztec/foundation/log';
import { RunningPromise } from '@aztec/foundation/running-promise';
import { RollupAbi } from '@aztec/l1-artifacts';
import { ClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer';
import { InstanceDeployerAddress } from '@aztec/protocol-contracts/instance-deployer';
import {
ContractClass,
ContractClassPublic,
ContractInstance,
ContractInstanceWithAddress,
} from '@aztec/types/contracts';
import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/contracts';

import { Chain, HttpTransport, PublicClient, createPublicClient, getAddress, getContract, http } from 'viem';

Expand Down Expand Up @@ -372,34 +366,13 @@ export class Archiver implements ArchiveSource {
* @param allLogs - All logs emitted in a bunch of blocks.
*/
private async storeDeployedContractInstances(allLogs: UnencryptedL2Log[], blockNum: number) {
const contractInstances = ContractInstanceDeployedEvent.fromLogs(allLogs, InstanceDeployerAddress).map(e =>
e.toContractInstance(),
);
const contractInstances = ContractInstanceDeployedEvent.fromLogs(allLogs).map(e => e.toContractInstance());
if (contractInstances.length > 0) {
contractInstances.forEach(c => this.log(`Storing contract instance at ${c.address.toString()}`));
await this.store.addContractInstances(contractInstances, blockNum);
}
}

/**
* Stores extended contract data as classes and instances.
* Temporary solution until we source this data from the contract class registerer and instance deployer.
* @param contracts - The extended contract data to be stored.
* @param l2BlockNum - The L2 block number to which the contract data corresponds.
* TODO(palla/purge-old-contract-deploy): Delete this method
*/
async storeContractDataAsClassesAndInstances(contracts: ExtendedContractData[], l2BlockNum: number) {
const classesAndInstances = contracts.map(extendedContractDataToContractClassAndInstance);
await this.store.addContractClasses(
classesAndInstances.map(([c, _]) => c),
l2BlockNum,
);
await this.store.addContractInstances(
classesAndInstances.map(([_, i]) => i),
l2BlockNum,
);
}

/**
* Stops the archiver.
* @returns A promise signalling completion of the stop process.
Expand Down Expand Up @@ -587,39 +560,3 @@ export class Archiver implements ArchiveSource {
return this.store.getContractClassIds();
}
}

/**
* Converts ExtendedContractData into contract classes and instances.
* Note that the conversion is not correct, since there is some data missing from the broadcasted ExtendedContractData.
* The archiver will trust the ids broadcasted instead of trying to recompute them.
* Eventually this function and ExtendedContractData altogether will be removed.
*/
function extendedContractDataToContractClassAndInstance(
data: ExtendedContractData,
): [ContractClassPublic, ContractInstanceWithAddress] {
const contractClass: ContractClass = {
version: 1,
artifactHash: Fr.ZERO,
publicFunctions: data.publicFunctions.map(f => ({
selector: f.selector,
bytecode: f.bytecode,
isInternal: f.isInternal,
})),
privateFunctions: [],
packedBytecode: data.bytecode,
};
const contractClassId = data.contractClassId;
const contractInstance: ContractInstance = {
version: 1,
salt: data.saltedInitializationHash,
contractClassId,
initializationHash: data.saltedInitializationHash,
portalContractAddress: data.contractData.portalContractAddress,
publicKeysHash: data.publicKeyHash,
};
const address = data.contractData.contractAddress;
return [
{ ...contractClass, id: contractClassId, privateFunctionsRoot: Fr.ZERO },
{ ...contractInstance, address },
];
}
8 changes: 5 additions & 3 deletions yarn-project/aztec.js/src/account/interface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AuthWitness, CompleteAddress, FunctionCall, TxExecutionRequest } from '@aztec/circuit-types';
import { AztecAddress } from '@aztec/circuits.js';
import { Fr } from '@aztec/foundation/fields';

import { FeePaymentMethod } from '../fee/fee_payment_method.js';
Expand Down Expand Up @@ -39,9 +40,10 @@ export interface EntrypointInterface {
* requests and authorize actions for its corresponding account.
*/
export interface AccountInterface extends AuthWitnessProvider, EntrypointInterface {
/**
* Returns the complete address for this account.
*/
/** Returns the complete address for this account. */
getCompleteAddress(): CompleteAddress;

/** Returns the address for this account. */
getAddress(): AztecAddress;
}
// docs:end:account-interface

0 comments on commit 258ff4a

Please sign in to comment.