Skip to content

Commit

Permalink
docs: compile guide
Browse files Browse the repository at this point in the history
Fixes #1569
  • Loading branch information
spalladino committed Aug 16, 2023
1 parent d90c460 commit f826883
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 16 deletions.
136 changes: 125 additions & 11 deletions docs/docs/dev_docs/contracts/compiling.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,136 @@
# Compiling contracts

Please use the [TUTORIAL-TEMPLATE](../../TUTORIAL_TEMPLATE.md) for standalone guides / tutorials.
Once you have written your [contracts](../contracts/main.md) in Noir, you will need to compile them into an artifact in order to use them. In this guide we will cover how to do so, both using the CLI and programmatically, as well as generating helper typescript and Noir interfaces for interacting with them.

:::danger TODO
TODO: this entire page
## Prerequisites

You will need the Noir build tool `nargo`, which you can install via [`noirup`](https://github.com/noir-lang/noirup). Make sure you install the `aztec` version of nargo:

```bash
curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
noirup -v aztec
```

:::info
You can re-run `noirup -v aztec` whenever you want to update to the latest version of Noir supported by the Aztec Network.
:::
## Compiling a Noir Contract

You can use the `master` branch of Noir/nargo (hooray).
## Compile using the CLI

To compile using the Aztec CLI, first install it:

`npm install -g @aztec/cli`

Then run the `compile` command with the path to your Noir contract project:

```
aztec-cli compile ./src/noir
```

This will output a JSON artifact for each contract in the project to a `target` folder containing their [ABI](./abi.md), which you can use for deploying or interacting with your contracts.

### Typescript

You can use the compiler to autogenerate type-safe typescript classes for each of your contracts. These classes define type-safe methods for deploying and interacting with your contract based on their ABI.

To generate them, include a `--typescript` option in the compile command with a path to the target folder for the typescript files:

```
aztec-cli compile --typescript ./src/ts/contracts ./src/noir
```

Example code generated from the [PrivateToken](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr) contract:

```ts showLineNumbers
export class PrivateTokenContract extends ContractBase {
/** Creates a contract instance at the given address. */
public static async at(address: AztecAddress, wallet: Wallet) { ... }

/** Creates a tx to deploy a new instance of this contract. */
public static deploy(rpc: AztecRPC, initial_supply: FieldLike, owner: FieldLike) { ... }

/** Type-safe wrappers for the public methods exposed by the contract. */
public methods!: {
/** getBalance(owner: field) */
getBalance: ((owner: FieldLike) => ContractFunctionInteraction) & Pick<ContractMethod, 'selector'>;

/** mint(amount: field, owner: field) */
mint: ((amount: FieldLike, owner: FieldLike) => ContractFunctionInteraction) & Pick<ContractMethod, 'selector'>;

/** transfer(amount: field, sender: field, recipient: field) */
transfer: ((amount: FieldLike, sender: FieldLike, recipient: FieldLike) => ContractFunctionInteraction) &
Pick<ContractMethod, 'selector'>;
};
}
```

### Noir interfaces

A Noir contract can [call a function](./functions.md) in another contract via `context.call_private_function` or `context.call_public_function`. However, this requires manually assembling the function selector and manually serialising the arguments, which is not type-safe.

To make this easier, the compiler can generate a contract interface struct that exposes a convenience method for each function listed in a given contract ABI. These structs are intended to be used from another contract project that calls into the current one.

To generate them, include a `--interface` option in the compile command with ap ath to the target folder for the generated Noir interface files:

```
aztec-cli compile --interface ../client/src/noir ./src/noir
```

Example code generated from the [PrivateToken](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/private_token_contract/src/main.nr) contract:

```rust
impl PrivateTokenContractInterface {
fn at(address: Field) -> Self {
Self { address }
}

fn mint(
self, context: &mut PrivateContext, amount: Field, owner: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialised_args = [0; 2];
serialised_args[0] = amount;
serialised_args[1] = owner;

context.call_private_function(self.address, 0x1dc9c3c0, serialised_args)
}


fn transfer(
self, context: &mut PrivateContext, amount: Field, sender: Field, recipient: Field
) -> [Field; RETURN_VALUES_LENGTH] {
let mut serialised_args = [0; 3];
serialised_args[0] = amount;
serialised_args[1] = sender;
serialised_args[2] = recipient;

context.call_private_function(self.address, 0xdcd4c318, serialised_args)
}
}

```

:::info
At the moment, the compiler generates these interfaces from already compiled ABIs, and not from source code. This means that you should not import a generated interface from within the same project as its source contract, or you risk circular references.
:::

## Access the compiler using nodejs

You can also programmatically access the compiler via the `@aztec/noir-compiler` package. To do this, install the package into your nodejs project:

`cd path/to/src`
`
npm install @aztec/noir-compiler
`

`nargo compile --contracts`
The compiler exposes the following functions:
- `compileUsingNargo`: Compiles a Noir project in the target folder using the `nargo` binary available on the shell `PATH` and returns the generated ABIs.
- `compileUsingNoirWasm`: Compiles a Noir project in the target folder using an embedded noir-wasm package and returns the generated ABIs.
- `generateTypescriptContractInterface`: Generates a typescript class for the given contract ABI.
- `generateNoirContractInterface`: Generates a Noir interface struct for the given contract ABI.

> Note: the output abi json artifact file needs some manual tweaking, currently, to insert a mocked verification key. See [this script](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/scripts/compile.sh) (which itself calls upon the two other scripts in that file) to see how compilation and injection of the verification key is being done currently. [noir-compiler](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-compiler) is intended to replace these scripts, but ideally nargo should be outputting aztec-contract-compatible abis.
## Next steps

https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/noir-contracts
Once you have compiled your contracts, you can use the generated artifacts via the `Contract` class in the `aztec.js` package to deploy and interact with them, or rely on the type-safe typescript classes directly. Alternatively, use the CLI [to deploy](../../dev_docs/getting_started/cli.md#deploying-a-token-contract) and [interact](../../dev_docs/getting_started/cli.md#sending-a-transaction) with them.

## Noir Contract Artifacts

Compiling a Noir Contract will output an artifact -- a JSON ABI containing information about the contract. This file can be read by `aztec.js`, which is a neat TypeScript wrapper which enables developers to easily deploy contracts, view functions, and send transactions.
import Disclaimer from "../../misc/common/\_disclaimer.mdx";
<Disclaimer/>
7 changes: 2 additions & 5 deletions yarn-project/noir-compiler/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
# Aztec Noir compiler

The Aztec noir compiler compiles noir contracts using noir_wasm and outputs Aztec formatted contract ABIs.
The Aztec noir compiler compiles noir contracts using nargo or noir_wasm and outputs Aztec formatted contract ABIs. The compiler can also generate typescript classes for each contract, as well as Noir interfaces for calling external functions.

## Installation

To install the package, just run `yarn add @aztec/noir-compiler`.

## Usage

To run the compiler as a CLI tool, run `yarn aztec_noir_compiler compile <path_to_noir_contract_crate>`
To run the compiler as a CLI tool, first install it and then run: `yarn aztec-compile compile --help`

## Status

Currently, this noir compiler uses noir master branch. It's not compatible yet with the test contracts for Aztec that are in the `noir-contracts` package, that need to be built following its README.md instructions.

0 comments on commit f826883

Please sign in to comment.