Deploying contracts
Once you have compiled your contracts you can proceed to deploying them using aztec.js which is a Typescript client to interact with the sandbox.
Prerequisites
aztec-nargo
installed (go to Sandbox section for installation instructions)- 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.
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
. Read more on the compiling page.
You can use the Contract
class to deploy a contract:
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#L10-L29
Or you can use the generated contract class. See below for more details.
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:
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#L28-L41
Deploying token contract
To give you a more complete example we will deploy a Token
contract whose artifacts are included in the @aztec/noir-contracts.js
package.
import { getSchnorrAccount } from '@aztec/accounts/schnorr';
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 secretKey = Fr.random();
const signingPrivateKey = GrumpkinScalar.random();
const pxe = createPXEClient(PXE_URL);
const wallet = await getSchnorrAccount(pxe, secretKey, signingPrivateKey).waitSetup();
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);
}
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.