Skip to main content

How to Deploy a Contract

Once you have compiled your contracts you can proceed to deploying them using Aztec.js.

You can use this method to deploy your contracts to the sandbox or to a remote network.

Prerequisites

  • Contract artifacts ready (go to How to Compile Contract for instructions on how to compile contracts)
  • Aztec Sandbox running (go to Getting Started for instructions on how to install and run the sandbox)

Deploy

Contracts can be deployed using the aztec.js library.

Generate the typescript artifact

Compile the contract:

aztec-nargo compile

Generate the typescript class:

aztec codegen ./aztec-nargo/output/target/path -o src/artifacts

This would create a typescript file like Example.ts in ./src/artifacts.

Deploying

Import the typescript artifact into your file.

import_artifact
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
Source code: yarn-project/end-to-end/src/sample-dapp/deploy.mjs#L5-L7

Then you can use the Contract class or the generated contract class to deploy the contract.

To use the Contract class to deploy a contract:

dapp-deploy
const { PXE_URL = 'http://localhost:8080' } = process.env;

async function main() {
const pxe = createPXEClient(PXE_URL);
await waitForPXE(pxe);

const [ownerWallet] = await getInitialTestAccountsWallets(pxe);
const ownerAddress = ownerWallet.getAddress();

const token = await Contract.deploy(ownerWallet, TokenContractArtifact, [ownerAddress, 'TokenName', 'TKN', 18])
.send()
.deployed();

console.log(`Token deployed at ${token.address.toString()}`);

const addresses = { token: token.address.toString() };
writeFileSync('addresses.json', JSON.stringify(addresses, null, 2));
}
Source code: yarn-project/end-to-end/src/sample-dapp/deploy.mjs#L13-L32

Deploy Arguments

There are several optional arguments that can be passed:

The deploy(...) method is generated automatically with the typescript class representing your contract.

Additionally the .send() method can have a few optional arguments too, which are specified in an optional object:

deploy_options
export type DeployOptions = {
/** An optional salt value used to deterministically calculate the contract address. */
contractAddressSalt?: Fr;
/** Set to true to *not* include the sender in the address computation. */
universalDeploy?: boolean;
/** Skip contract class registration. */
skipClassRegistration?: boolean;
/** Skip public deployment, instead just privately initialize the contract. */
skipPublicDeployment?: boolean;
/** Skip contract initialization. */
skipInitialization?: boolean;
} & SendMethodOptions;
Source code: yarn-project/aztec.js/src/contract/deploy_method.ts#L30-L43

Using generated contract class

As a more complete example, here a Token contract deployment whose artifacts are included in the @aztec/noir-contracts.js package. You can use similar deployment syntax with your own contract by importing the TS artifact generated with aztec codegen. This example uses the generated TokenContract to deploy.

import { getSchnorrAccount } from '@aztec/accounts/schnorr';
import { getDeployedTestAccountsWallets } from '@aztec/accounts/testing';
import { Fr, GrumpkinScalar, createPXEClient } from '@aztec/aztec.js';
import { Contract } from '@aztec/aztec.js';
import { TokenContract, TokenContractArtifact } from '@aztec/noir-contracts.js/Token';

async function main(){

const PXE_URL = process.env.PXE_URL || 'http://localhost:8080';
const pxe = createPXEClient(PXE_URL);
const secretKey = Fr.random();
const signingPrivateKey = GrumpkinScalar.random();

// Use a pre-funded wallet to pay for the fees for the deployments.
const wallet = (await getDeployedTestAccountsWallets(pxe))[0];
const newAccount = await getSchnorrAccount(pxe, secretKey, signingPrivateKey);
await newAccount.deploy({ deployWallet: wallet }).wait();
const newWallet = await newAccount.getWallet();

const deployedContract = await TokenContract.deploy(
wallet, // wallet instance
wallet.getAddress(), // account
'TokenName', // constructor arg1
'TokenSymbol', // constructor arg2
18,
)
.send()
.deployed();

const contract = await Contract.at(deployedContract.address, TokenContractArtifact, wallet);

}
note

You can try running the deployment with the same salt the second time in which case the transaction will fail because the address has been already deployed to.