Skip to main content

Calling Other Functions

A contract is a collection of persistent state variables and functions which may manipulate these variables.

Functions and state variables within a contract's scope are said to belong to that contract. A contract can only access and modify its own state.

If a contract wishes to access or modify another contract's state, it must make a call to an external function of the other contract. For anything to happen on the Aztec network, an external function of a contract needs to be called.

Defining a contract

A contract may be declared and given a name using the contract keyword (see snippet below). By convention, contracts are named in PascalCase.

contract keyword
contract MyContract {

// Imports

// Storage

// Functions
}
A note for vanilla Noir devs

There is no main() (GitHub link) function within a Noir contract scope. More than one function can be an entrypoint.

Add as a dependency in Nargo.toml

Import the contract that you want to call into your Nargo.toml under dependencies like this:

token = { git="https://github.com/AztecProtocol/aztec-packages/", tag="aztec-packages-v0.66.0", directory="noir-projects/noir-contracts/contracts/token_contract" }

Import into your contract

At the top of your contract, import the contract you want to call like this:

use token::Token;

Call the function

To call the function, you need to

  • Specify the address of the contract with Contract::at(contract_address)
  • Call the function name with .function_name()
  • Pass the parameters into the function call, like .function_name(param1,param2)
  • Specify the type of call you want to make and pass a mut reference to the context, like .call(&mut context)

Private calls

To call a private function, you can just use call() like this:

call_function
Token::at(token).transfer(recipient, amount).call(&mut context);
Source code: noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr#L46-L48

Public -> Public calls

To call a public function from a public function, it is the same as above. You can just use call() like this:

public_to_public_call
let _ = Token::at(collateral_asset)
.transfer_in_public(context.msg_sender(), context.this_address(), amount, nonce)
.call(&mut context);
Source code: noir-projects/noir-contracts/contracts/lending_contract/src/main.nr#L131-L135

Private -> Public calls

To call a public function from private, you will need to enqueue it like this:

enqueue_public
Lending::at(context.this_address())
._deposit(AztecAddress::from_field(on_behalf_of), amount, collateral_asset)
.enqueue(&mut context);
Source code: noir-projects/noir-contracts/contracts/lending_contract/src/main.nr#L117-L121

Public functions are always executed after private execution. To learn why, read the concepts overview.

Other call types

There are other call types, for example to ensure no state changes are made. You can learn more about them in the call types glossary.