diff --git a/docs/docs/dev_docs/contracts/compiling.md b/docs/docs/dev_docs/contracts/compiling.md index 8f3fa83e6a6..83faaded941 100644 --- a/docs/docs/dev_docs/contracts/compiling.md +++ b/docs/docs/dev_docs/contracts/compiling.md @@ -1,22 +1,145 @@ # Compiling contracts -Please use the [TUTORIAL-TEMPLATE](../../TUTORIAL_TEMPLATE.md) for standalone guides / tutorials. +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 +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; + + /** mint(amount: field, owner: field) */ + mint: ((amount: FieldLike, owner: FieldLike) => ContractFunctionInteraction) & Pick; + + /** transfer(amount: field, sender: field, recipient: field) */ + transfer: ((amount: FieldLike, sender: FieldLike, recipient: FieldLike) => ContractFunctionInteraction) & + Pick; + }; +} +``` + +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) + } + + + 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) + } +} +``` + +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. \ No newline at end of file +import Disclaimer from "../../misc/common/\_disclaimer.mdx"; + \ No newline at end of file diff --git a/yarn-project/noir-compiler/README.md b/yarn-project/noir-compiler/README.md index a338b2c090e..525cdc9316f 100644 --- a/yarn-project/noir-compiler/README.md +++ b/yarn-project/noir-compiler/README.md @@ -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 ` +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 +``` \ No newline at end of file