Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: compile guide #1575

Merged
merged 3 commits into from
Aug 17, 2023
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
145 changes: 134 additions & 11 deletions docs/docs/dev_docs/contracts/compiling.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,145 @@
# Compiling contracts

Please use the [TUTORIAL-TEMPLATE](../../TUTORIAL_TEMPLATE.md) for standalone guides / tutorials.
iAmMichaelConnor marked this conversation as resolved.
Show resolved Hide resolved
Once you have written a [contract](../contracts/main.md) in Noir, you will need to compile it into an [artifact](./abi.md) in order to use it.

:::danger TODO
TODO: this entire page
In this guide we will cover how to do so, both using the CLI and programmatically.

We'll also cover how to generate a helper [TypeScript interface](#typescript-interfaces) and a [Noir interface](#noir-interfaces) for easily interacting with your contract from your typescript app and from other noir contracts, respectively.

## 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
iAmMichaelConnor marked this conversation as resolved.
Show resolved Hide resolved
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.
:::

## Compile using the CLI

To compile a contract using the Aztec CLI, first install it:

`npm install -g @aztec/cli`

Then run the `compile` command with the path to your [contract project folder](./layout.md#directory-structure), which is the one that contains the `Nargo.toml` file:

```
aztec-cli compile ./path/to/my_aztec_contract_project
```

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 Interfaces

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 ./path/to/typescript/src ./path/to/my_aztec_contract_project
```

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'>;
};
}
```

iAmMichaelConnor marked this conversation as resolved.
Show resolved Hide resolved
Read more about interacting with contracts using `aztec.js` [here](../dapps/main.md).

### 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 a path to the target folder for the generated Noir interface files:

```
aztec-cli compile --interface ./path/to/another_aztec_contract_project/src ./path/to/my_aztec_contract_project
```

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;

// 0x1dc9c3c0 is the function selector for `mint(field,field)`
context.call_private_function(self.address, 0x1dc9c3c0, serialised_args)
iAmMichaelConnor marked this conversation as resolved.
Show resolved Hide resolved
}


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;

// 0xdcd4c318 is the function selector for `transfer(field,field,field)`
context.call_private_function(self.address, 0xdcd4c318, serialised_args)
}
}
```

iAmMichaelConnor marked this conversation as resolved.
Show resolved Hide resolved
Read more about how to use the Noir interfaces [here](./functions.md#contract-interface).

:::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.
:::
## Compiling a Noir Contract

You can use the `master` branch of Noir/nargo (hooray).
## Compile 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/>
21 changes: 16 additions & 5 deletions yarn-project/noir-compiler/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
# 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`.
To install the package, run:

```bash
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 the package and then run:

```bash
yarn aztec-compile compile --help
```

## Status
You can also run the compiler from the [main Aztec CLI](../aztec-cli/README.md), which includes several other features for interacting with the Aztec Network:

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.
```bash
yarn add @aztec/cli
yarn aztec-cli compile --help
```