Skip to content
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
16 changes: 12 additions & 4 deletions yarn-project/aztec.js/src/contract/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand All @@ -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);
}
}
3 changes: 2 additions & 1 deletion yarn-project/aztec.js/src/contract/deploy_method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ export class DeployMethod<TContract extends ContractBase = Contract> extends Bas
private artifact: ContractArtifact,
private postDeployCtor: (address: AztecAddress, wallet: Wallet) => Promise<TContract>,
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.');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: probably helps to include the variable name in the error here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do in a subsequent PR!

}
Expand Down
16 changes: 14 additions & 2 deletions yarn-project/aztec.js/src/deployment/contract_deployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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,
);
}
}
12 changes: 12 additions & 0 deletions yarn-project/end-to-end/src/e2e_deploy_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<M extends keyof ${contractName}['methods']>(
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',
);
}
`;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down