Skip to content

Commit

Permalink
Allow alternative constructor name in getContractInstanceFromDeployPa…
Browse files Browse the repository at this point in the history
…rams
  • Loading branch information
spalladino committed Mar 12, 2024
1 parent b5f6fff commit 72013c0
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 61 deletions.
13 changes: 5 additions & 8 deletions yarn-project/aztec.js/src/account_manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,11 @@ export class AccountManager {
public getInstance(): ContractInstanceWithAddress {
if (!this.instance) {
const encryptionPublicKey = generatePublicKey(this.encryptionPrivateKey);
const portalAddress = EthAddress.ZERO;
this.instance = getContractInstanceFromDeployParams(
this.accountContract.getContractArtifact(),
this.accountContract.getDeploymentArgs(),
this.salt,
encryptionPublicKey,
portalAddress,
);
this.instance = getContractInstanceFromDeployParams(this.accountContract.getContractArtifact(), {
constructorArgs: this.accountContract.getDeploymentArgs(),
salt: this.salt,
publicKey: encryptionPublicKey,
});
}
return this.instance;
}
Expand Down
11 changes: 7 additions & 4 deletions yarn-project/aztec.js/src/contract/deploy_method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,13 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
*/
public getInstance(options: DeployOptions = {}): ContractInstanceWithAddress {
if (!this.instance) {
const portalContract = options.portalContract ?? EthAddress.ZERO;
const contractAddressSalt = options.contractAddressSalt ?? Fr.random();
const deployParams = [this.artifact, this.args, contractAddressSalt, this.publicKey, portalContract] as const;
this.instance = getContractInstanceFromDeployParams(...deployParams);
this.instance = getContractInstanceFromDeployParams(this.artifact, {
constructorArgs: this.args,
salt: options.contractAddressSalt,
portalAddress: options.portalContract,
publicKey: this.publicKey,
constructorName: this.constructorArtifact.name,
});
}
return this.instance;
}
Expand Down
29 changes: 17 additions & 12 deletions yarn-project/circuits.js/src/contract/contract_instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,32 @@ import {
computeInitializationHash,
computePublicKeysHash,
} from './contract_address.js';
import { isConstructor } from './contract_tree/contract_tree.js';

/**
* Generates a Contract Instance from the deployment params.
* @param artifact - The account contract build artifact.
* @param args - The args to the account contract constructor
* @param contractAddressSalt - The salt to be used in the contract address derivation
* @param publicKey - The account public key
* @param portalContractAddress - The portal contract address
* @param opts - Options for the deployment.
* @returns - The contract instance
*/
export function getContractInstanceFromDeployParams(
artifact: ContractArtifact,
args: any[] = [],
contractAddressSalt: Fr = Fr.random(),
publicKey: PublicKey = Point.ZERO,
portalContractAddress: EthAddress = EthAddress.ZERO,
opts: {
constructorName?: string;
constructorArgs?: any[];
salt?: Fr;
publicKey?: PublicKey;
portalAddress?: EthAddress;
},
): ContractInstanceWithAddress {
const constructorArtifact = artifact.functions.find(isConstructor);
const args = opts.constructorArgs ?? [];
const salt = opts.salt ?? Fr.random();
const publicKey = opts.publicKey ?? Point.ZERO;
const portalContractAddress = opts.portalAddress ?? EthAddress.ZERO;
const constructorName = opts.constructorName ?? 'constructor';

const constructorArtifact = artifact.functions.find(fn => fn.name === constructorName);
if (!constructorArtifact) {
throw new Error('Cannot find constructor in the artifact.');
throw new Error(`Cannot find constructor with name ${constructorName} in the artifact.`);
}
if (!constructorArtifact.verificationKey) {
throw new Error('Missing verification key for the constructor.');
Expand All @@ -47,7 +52,7 @@ export function getContractInstanceFromDeployParams(
initializationHash,
portalContractAddress,
publicKeysHash,
salt: contractAddressSalt,
salt,
version: 1,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function hashVKStr(vk: string) {
* Determine if the given function is a constructor.
* This utility function checks if the 'name' property of the input object is "constructor".
* Returns true if the function is a constructor, false otherwise.
*
* TODO(palla/purge-old-contract-deploy): Remove me
* @param Object - An object containing a 'name' property.
* @returns Boolean indicating if the function is a constructor.
*/
Expand Down
12 changes: 5 additions & 7 deletions yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
generatePublicKey,
getContractInstanceFromDeployParams,
} from '@aztec/aztec.js';
import { EthAddress, computePartialAddress } from '@aztec/circuits.js';
import { computePartialAddress } from '@aztec/circuits.js';
import { InclusionProofsContract } from '@aztec/noir-contracts.js';
import { ClaimContract } from '@aztec/noir-contracts.js/Claim';
import { CrowdfundingContract, CrowdfundingContractArtifact } from '@aztec/noir-contracts.js/Crowdfunding';
Expand Down Expand Up @@ -108,13 +108,11 @@ describe('e2e_crowdfunding_and_claim', () => {
const salt = Fr.random();

const args = [donationToken.address, operatorWallet.getAddress(), deadline];
const deployInfo = getContractInstanceFromDeployParams(
CrowdfundingContractArtifact,
args,
const deployInfo = getContractInstanceFromDeployParams(CrowdfundingContractArtifact, {
constructorArgs: args,
salt,
crowdfundingPublicKey,
EthAddress.ZERO,
);
publicKey: crowdfundingPublicKey,
});
await pxe.registerAccount(crowdfundingPrivateKey, computePartialAddress(deployInfo));

crowdfundingContract = await CrowdfundingContract.deployWithPublicKey(
Expand Down
26 changes: 15 additions & 11 deletions yarn-project/end-to-end/src/e2e_deploy_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,9 @@ describe('e2e_deploy_contract', () => {
* https://hackmd.io/ouVCnacHQRq2o1oRc5ksNA#Interfaces-and-Responsibilities
*/
it('should deploy a test contract', async () => {
const publicKey = accounts[0].publicKey;
const salt = Fr.random();
const deploymentData = getContractInstanceFromDeployParams(
TestContractArtifact,
[],
salt,
publicKey,
EthAddress.ZERO,
);
const publicKey = accounts[0].publicKey;
const deploymentData = getContractInstanceFromDeployParams(TestContractArtifact, { salt, publicKey });
const deployer = new ContractDeployer(TestContractArtifact, wallet, publicKey);
const receipt = await deployer.deploy().send({ contractAddressSalt: salt }).wait({ wallet });
expect(receipt.contract.address).toEqual(deploymentData.address);
Expand Down Expand Up @@ -312,7 +306,12 @@ describe('e2e_deploy_contract', () => {
const salt = Fr.random();
const portalAddress = EthAddress.random();
const publicKey = Point.random();
const instance = getContractInstanceFromDeployParams(artifact, initArgs, salt, publicKey, portalAddress);
const instance = getContractInstanceFromDeployParams(artifact, {
constructorArgs: initArgs,
salt,
publicKey,
portalAddress,
});
const { address, contractClassId } = instance;
logger(`Deploying contract instance at ${address.toString()} class id ${contractClassId.toString()}`);
await deployFn(instance);
Expand Down Expand Up @@ -455,7 +454,7 @@ describe('e2e_deploy_contract', () => {
expect(await token.methods.is_minter(owner).view()).toEqual(true);
}, 60_000);

it('publicly deploys and initializes via a public function', async () => {
it.only('publicly deploys and initializes via a public function', async () => {
const owner = accounts[0];
logger.debug(`Deploying contract via a public constructor`);
const contract = await StatefulTestContract.deployWithOpts({ wallet, method: 'public_constructor' }, owner, 42)
Expand Down Expand Up @@ -497,7 +496,12 @@ async function registerContract<T extends ContractBase>(
opts: { salt?: Fr; publicKey?: Point; portalAddress?: EthAddress } = {},
): Promise<T> {
const { salt, publicKey, portalAddress } = opts;
const instance = getContractInstanceFromDeployParams(contractArtifact.artifact, args, salt, publicKey, portalAddress);
const instance = getContractInstanceFromDeployParams(contractArtifact.artifact, {
constructorArgs: args,
salt,
publicKey,
portalAddress,
});
await wallet.addContracts([{ artifact: contractArtifact.artifact, instance }]);
return contractArtifact.at(instance.address, wallet);
}
11 changes: 4 additions & 7 deletions yarn-project/end-to-end/src/e2e_escrow_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
BatchCall,
CompleteAddress,
DebugLogger,
EthAddress,
ExtendedNote,
Fr,
GrumpkinPrivateKey,
Expand Down Expand Up @@ -59,13 +58,11 @@ describe('e2e_escrow_contract', () => {
escrowPrivateKey = GrumpkinScalar.random();
escrowPublicKey = generatePublicKey(escrowPrivateKey);
const salt = Fr.random();
const deployInfo = getContractInstanceFromDeployParams(
EscrowContractArtifact,
[owner],
const deployInfo = getContractInstanceFromDeployParams(EscrowContractArtifact, {
constructorArgs: [owner],
salt,
escrowPublicKey,
EthAddress.ZERO,
);
publicKey: escrowPublicKey,
});
await pxe.registerAccount(escrowPrivateKey, computePartialAddress(deployInfo));

escrowContract = await EscrowContract.deployWithPublicKey(escrowPublicKey, wallet, owner)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ describe('e2e_inclusion_proofs_contract', () => {
it('proves public deployment of a contract', async () => {
// Publicly deploy another contract (so we don't test on the same contract)
const initArgs = [accounts[0], 42n];
const instance = getContractInstanceFromDeployParams(StatefulTestContractArtifact, initArgs);
const instance = getContractInstanceFromDeployParams(StatefulTestContractArtifact, { constructorArgs: initArgs });
await (await registerContractClass(wallets[0], StatefulTestContractArtifact)).send().wait();
const receipt = await deployInstance(wallets[0], instance).send().wait();

Expand Down
15 changes: 7 additions & 8 deletions yarn-project/protocol-contracts/src/protocol_contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,18 @@ export interface ProtocolContract {
export function getCanonicalProtocolContract(
artifact: ContractArtifact,
salt: Fr | number | bigint,
initArgs: any[] = [],
constructorArgs: any[] = [],
publicKey: Point = Point.ZERO,
portalContractAddress = EthAddress.ZERO,
portalAddress = EthAddress.ZERO,
): ProtocolContract {
// TODO(@spalladino): This computes the contract class from the artifact twice.
const contractClass = getContractClassFromArtifact(artifact);
const instance = getContractInstanceFromDeployParams(
artifact,
initArgs,
new Fr(salt),
const instance = getContractInstanceFromDeployParams(artifact, {
constructorArgs,
salt: new Fr(salt),
publicKey,
portalContractAddress,
);
portalAddress,
});
return {
instance,
contractClass,
Expand Down
5 changes: 3 additions & 2 deletions yarn-project/simulator/src/client/private_execution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,11 @@ describe('Private Execution test suite', () => {
});

it('should have a constructor with arguments that inserts notes', async () => {
const instance = getContractInstanceFromDeployParams(StatefulTestContractArtifact, [owner, 140]);
const initArgs = [owner, 140];
const instance = getContractInstanceFromDeployParams(StatefulTestContractArtifact, { constructorArgs: initArgs });
oracle.getContractInstance.mockResolvedValue(instance);
const artifact = getFunctionArtifact(StatefulTestContractArtifact, 'constructor');
const topLevelResult = await runSimulator({ args: [owner, 140], artifact, contractAddress: instance.address });
const topLevelResult = await runSimulator({ args: initArgs, artifact, contractAddress: instance.address });
const result = topLevelResult.nestedExecutions[0];

expect(result.newNotes).toHaveLength(1);
Expand Down

0 comments on commit 72013c0

Please sign in to comment.