Deploying AZTEC to Ganache

This article is in English, you can read a Mandarin(中文) translation here.

This series is split into 4 parts:

Part 1 — An introduction to AZTEC

Part 2 — Deploying AZTEC on Ganache

Part 3 — Constructing Proofs, Signing Flows and Key Management.

Part 4 — Creating, Settling, & Streaming Confidential Assets

AZTEC has a full set of contracts deployed to the test networks Ropsten and Rinkeby. The addresses of these contracts are contained within the NPM package @aztec/contract-addresses . The contract artifacts are contained in the NPM packacge @aztec/contract-artifacts .

For most dApp builders, deploying to Ganache is essential to test smart contract interactions with AZTEC. This flow is the same for deploying AZTEC to a private fork of Ethereum.

To get started, check out the starter kit on the AZTEC github here. This kit contains the required migrations to deploy AZTEC to a local blockchain as well as example flows.

  1. Clone the repository git clone git@github.com:AztecProtocol/aztec-ganache-starter-kit.git
  2. Install the dependencies cd aztec-ganache-starter-kit && yarn install
  3. Rename the .env file mv RENAME_ME.env .env
  4. Start up Ganache withyarn start (This will create 5 test Ethereum accounts from the credentials in .env)
  5. Deploy AZTEC! yarn migrate

Lets take a look under the hood at the required migrations and what they do:

const ACE = artifacts.require('./ACE.sol');
const AdjustSupply = artifacts.require('./AdjustSupply.sol');
const BilateralSwap = artifacts.require('./BilateralSwap.sol');
const DividendComputation = artifacts.require('./DividendComputation.sol');
const PrivateRange = artifacts.require('./PrivateRange.sol');
const JoinSplit = artifacts.require('./JoinSplit.sol');
const utils = require('@aztec/dev-utils');
const {
constants,
proofs: {
JOIN_SPLIT_PROOF,
MINT_PROOF,
BILATERAL_SWAP_PROOF,
DIVIDEND_PROOF,
PRIVATE_RANGE_PROOF,
},
} = utils;
module.exports = async (deployer, network) => {
if (network === 'development') {
await deployer.deploy(ACE);
await deployer.deploy(AdjustSupply);
await deployer.deploy(BilateralSwap);
await deployer.deploy(JoinSplit);
await deployer.deploy(PrivateRange);
await deployer.deploy(DividendComputation);
const ACEContract = await ACE.deployed();
const AdjustSupplyContract = await AdjustSupply.deployed();
await ACEContract.setCommonReferenceString(constants.CRS);
await ACEContract.setProof(MINT_PROOF, AdjustSupplyContract.address);
await ACEContract.setProof(BILATERAL_SWAP_PROOF, BilateralSwap.address);
await ACEContract.setProof(DIVIDEND_PROOF, DividendComputation.address);
await ACEContract.setProof(JOIN_SPLIT_PROOF, JoinSplit.address);
await ACEContract.setProof(PRIVATE_RANGE_PROOF, PrivateRange.address);
}
};

Step 1:

Firstly we ensure all of the required contracts are compiled, ahead of deployment to the local ganache blockchain. To allow Truffle to build the artifacts for these contracts the @aztec/protocol package needs to be installed via NPM.

yarn add @aztec/protocol

Step 2:

AZTEC uses a trusted setup as described above to enable efficient range proofs. The Common Reference String identifies the trusted setup database that AZTEC should use. This is set using the setCommonReferenceString method.

Step 3:

ACE needs to be initialised with the addresses of the validators that will verify each proof. This is done by calling the setProof method with the corresponding proofId and the address of the deployed validator contract.

Deploying a ZkAsset

Once ACE is deployed along with its corresponding proof validators the next step is to deploy our first ZkAsset!

const ACE = artifacts.require('./ACE.sol');
const ZkAsset = artifacts.require('./ZkAsset.sol');
const TestERC20 = artifacts.require('./TestERC20.sol');
module.exports = async (deployer, network) => {
await deployer.deploy(TestERC20);
const testERC20 = await TestERC20.deployed();
let aceContract;
if (network === 'development') {
aceContract = await ACE.deployed();
// initialise the ZkAsset
await deployer.deploy(
ZkAsset,
aceContract.address,
testERC20.address,
1,
false,
true
);
}
};

The constructor of a ZkAsset needs to be called with 5 parameters.

  1. aceAddress — The address of the AZTEC cryptography engine to which this asset will listen.
  2. linkedTokenAddress — The address of a linked public ERC20 token if this asset has a public representation, if not this should be address(0).
  3. scalingFactor — A scaling factor that is used if the asset has a linked public token.
  4. canAdjustSupply — A boolean representing if the Total Supply of the notes can be changed by the owner of the ZkAsset contract.
  5. canConvert— A boolean representing if the ZkAsset is redeemable for public tokens at the linked token address.The default ZkAsset reference contract enable the user to perform basic send functions with AZTEC similar to an ERC20’s confidentialTransfer method. For more complex flows it is important to understand what is returned from a validated proof and how this can be used to process state updates inside a note registry.

Now run truffle migrate in the developer console. Truffle will deploy ACE, a set of validator contracts for each of the AZTEC toolkits and a test ZkAsset contract to the local blockchain.

That’s it! To learn more head over to Part 3 — Constructing Proofs, Signing Flows and Key Management here!