diff --git a/yarn-project/aztec.js/src/contract/contract.ts b/yarn-project/aztec.js/src/contract/contract.ts index 6f1ecc43ac2..67501983cb0 100644 --- a/yarn-project/aztec.js/src/contract/contract.ts +++ b/yarn-project/aztec.js/src/contract/contract.ts @@ -36,10 +36,11 @@ export class Contract extends ContractBase { * @param wallet - The wallet for executing the deployment. * @param artifact - Build artifact of the contract to deploy * @param args - Arguments for the constructor. + * @param constructorName - The name of the constructor function to call. */ - public static deploy(wallet: Wallet, artifact: ContractArtifact, args: any[]) { + public static deploy(wallet: Wallet, artifact: ContractArtifact, args: any[], constructorName?: string) { const postDeployCtor = (address: AztecAddress, wallet: Wallet) => Contract.at(address, artifact, wallet); - return new DeployMethod(Point.ZERO, wallet, artifact, postDeployCtor, args); + return new DeployMethod(Point.ZERO, wallet, artifact, postDeployCtor, args, constructorName); } /** @@ -48,9 +49,16 @@ export class Contract extends ContractBase { * @param wallet - The wallet for executing the deployment. * @param artifact - Build artifact of the contract. * @param args - Arguments for the constructor. + * @param constructorName - The name of the constructor function to call. */ - public static deployWithPublicKey(publicKey: PublicKey, wallet: Wallet, artifact: ContractArtifact, args: any[]) { + public static deployWithPublicKey( + publicKey: PublicKey, + wallet: Wallet, + artifact: ContractArtifact, + args: any[], + constructorName?: string, + ) { const postDeployCtor = (address: AztecAddress, wallet: Wallet) => Contract.at(address, artifact, wallet); - return new DeployMethod(publicKey, wallet, artifact, postDeployCtor, args); + return new DeployMethod(publicKey, wallet, artifact, postDeployCtor, args, constructorName); } } diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index 8eaa0fa52f4..e247c9a3a0f 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -58,9 +58,10 @@ export class DeployMethod extends Bas private artifact: ContractArtifact, private postDeployCtor: (address: AztecAddress, wallet: Wallet) => Promise, private args: any[] = [], + constructorName: string = 'constructor', ) { super(wallet); - const constructorArtifact = artifact.functions.find(f => f.name === 'constructor'); + const constructorArtifact = artifact.functions.find(f => f.name === constructorName); if (!constructorArtifact) { throw new Error('Cannot find constructor in the artifact.'); } diff --git a/yarn-project/aztec.js/src/deployment/contract_deployer.ts b/yarn-project/aztec.js/src/deployment/contract_deployer.ts index 9c674b30691..09420c60401 100644 --- a/yarn-project/aztec.js/src/deployment/contract_deployer.ts +++ b/yarn-project/aztec.js/src/deployment/contract_deployer.ts @@ -12,7 +12,12 @@ import { Contract } from '../contract/index.js'; * @remarks Keeping this around even though we have Aztec.nr contract types because it can be useful for non-TS users. */ export class ContractDeployer { - constructor(private artifact: ContractArtifact, private wallet: Wallet, private publicKey?: PublicKey) {} + constructor( + private artifact: ContractArtifact, + private wallet: Wallet, + private publicKey?: PublicKey, + private constructorName?: string, + ) {} /** * Deploy a contract using the provided ABI and constructor arguments. @@ -25,6 +30,13 @@ export class ContractDeployer { */ public deploy(...args: any[]) { const postDeployCtor = (address: AztecAddress, wallet: Wallet) => Contract.at(address, this.artifact, wallet); - return new DeployMethod(this.publicKey ?? Point.ZERO, this.wallet, this.artifact, postDeployCtor, args); + return new DeployMethod( + this.publicKey ?? Point.ZERO, + this.wallet, + this.artifact, + postDeployCtor, + args, + this.constructorName, + ); } } diff --git a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts index 99ff6665cd0..39051bb7c0b 100644 --- a/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_deploy_contract.test.ts @@ -446,6 +446,18 @@ 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 () => { + const owner = accounts[0]; + logger.debug(`Deploying contract via a public constructor`); + const contract = await StatefulTestContract.deployWithOpts({ wallet, method: 'public_constructor' }, owner, 42) + .send() + .deployed(); + expect(await contract.methods.get_public_value(owner).view()).toEqual(42n); + logger.debug(`Calling a private function to ensure the contract was properly initialized`); + await contract.methods.create_note(owner, 30).send().wait(); + expect(await contract.methods.summed_values(owner).view()).toEqual(30n); + }, 60_000); + it.skip('publicly deploys and calls a public function in the same batched call', async () => { // TODO(@spalladino) }); diff --git a/yarn-project/noir-compiler/src/contract-interface-gen/typescript.ts b/yarn-project/noir-compiler/src/contract-interface-gen/typescript.ts index 73c0c253623..8710ceabd42 100644 --- a/yarn-project/noir-compiler/src/contract-interface-gen/typescript.ts +++ b/yarn-project/noir-compiler/src/contract-interface-gen/typescript.ts @@ -81,14 +81,31 @@ function generateDeploy(input: ContractArtifact) { * Creates a tx to deploy a new instance of this contract. */ public static deploy(wallet: Wallet, ${args}) { - return new DeployMethod<${input.name}Contract>(Point.ZERO, wallet, ${artifactName}, ${contractName}.at, Array.from(arguments).slice(1)); + return new DeployMethod<${contractName}>(Point.ZERO, wallet, ${artifactName}, ${contractName}.at, Array.from(arguments).slice(1)); } /** * Creates a tx to deploy a new instance of this contract using the specified public key to derive the address. */ public static deployWithPublicKey(publicKey: PublicKey, wallet: Wallet, ${args}) { - return new DeployMethod<${input.name}Contract>(publicKey, wallet, ${artifactName}, ${contractName}.at, Array.from(arguments).slice(2)); + return new DeployMethod<${contractName}>(publicKey, wallet, ${artifactName}, ${contractName}.at, Array.from(arguments).slice(2)); + } + + /** + * Creates a tx to deploy a new instance of this contract using the specified constructor method. + */ + public static deployWithOpts( + opts: { publicKey?: PublicKey; method?: M; wallet: Wallet }, + ...args: Parameters<${contractName}['methods'][M]> + ) { + return new DeployMethod<${contractName}>( + opts.publicKey ?? Point.ZERO, + opts.wallet, + ${artifactName}, + ${contractName}.at, + Array.from(arguments).slice(1), + opts.method ?? 'constructor', + ); } `; } diff --git a/yarn-project/simulator/src/client/client_execution_context.ts b/yarn-project/simulator/src/client/client_execution_context.ts index cc756380c20..ccefed30157 100644 --- a/yarn-project/simulator/src/client/client_execution_context.ts +++ b/yarn-project/simulator/src/client/client_execution_context.ts @@ -438,7 +438,7 @@ export class ClientExecutionContext extends ViewDataOracle { // side-effects occurred in the TX. Ultimately the private kernel should // just output everything in the proper order without any counters. this.log( - `Enqueued call to public function (with side-effect counter #${sideEffectCounter}) ${targetContractAddress}:${functionSelector}`, + `Enqueued call to public function (with side-effect counter #${sideEffectCounter}) ${targetContractAddress}:${functionSelector}(${targetArtifact.name})`, ); this.enqueuedPublicFunctionCalls.push(enqueuedRequest);