diff --git a/docs/docs/developers/contracts/writing_contracts/functions/initializers.md b/docs/docs/developers/contracts/writing_contracts/functions/initializers.md new file mode 100644 index 00000000000..a673264a4b3 --- /dev/null +++ b/docs/docs/developers/contracts/writing_contracts/functions/initializers.md @@ -0,0 +1,32 @@ +--- +title: How to write an initializer function +--- + +This page explains how to write an initializer function. + +To learn more about initializers, read [this](./main.md#initializer-functions). + +Initializers are regular functions that set an "initialized" flag (a nullifier) for the contract. A contract can only be initialized once, and contract functions can only be called after the contract has been initialized, much like a constructor. However, if a contract defines no initializers, it can be called at any time. Additionally, you can define as many initializer functions in a contract as you want, both private and public. + +## Annotate with `#[aztec(private)]` and `#[aztec(initializer)]` + + +Define your initiaizer like so: + +```rust +#[aztec(private)] +#[aztec(initializer)] +fn constructor(){ + // function logic here +} +``` + +## Initializer with logic + +Initializers are commonly used to set an admin, such as this example: + +#include_code constructor /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust + +Here, the initializer is calling a public function. It can also call a private function. Learn more about calling functions from functions [here](../functions/call_functions.md). + +To see constructors in action, check out the [Aztec.nr getting started guide](../../../getting_started/aztecnr-getting-started.md). diff --git a/docs/docs/developers/contracts/writing_contracts/functions/main.md b/docs/docs/developers/contracts/writing_contracts/functions/main.md index 91b0fea0ca6..acd3b2c1e1e 100644 --- a/docs/docs/developers/contracts/writing_contracts/functions/main.md +++ b/docs/docs/developers/contracts/writing_contracts/functions/main.md @@ -6,17 +6,13 @@ Functions serve as the building blocks of smart contracts. Functions can be eith For a more practical guide of using multiple types of functions, follow the [token tutorial](../../../tutorials/writing_token_contract.md). -Currently, any function is "mutable" in the sense that it might alter state. However, we also support support static calls, similarly to EVM. A static call is essentially a call that does not alter state (it keeps state static). +Currently, any function is "mutable" in the sense that it might alter state. However, we also support support static calls, similarly to EVM. A static call is essentially a call that does not alter state (it keeps state static). -## Constructors +## Initializer functions -Every smart contract has a private `constructor` function which is called when the contract is deployed. +Smart contracts may have one, or many, initializer functions which are called when the contract is deployed. -A special constructor function must be declared within a contract's scope. - -A constructor doesn't have a name, because its purpose is clear: to initialize contract state. -In Aztec terminology, a constructor is always a 'private function' (i.e. it cannot be a public function). -A constructor behaves almost identically to any other function. It is just important for Aztec to be able to identify this function as special: it may only be called once, and will not be deployed as part of the contract. +Initializers are regular functions that set an "initialized" flag (a nullifier) for the contract. A contract can only be initialized once, and contract functions can only be called after the contract has been initialized, much like a constructor. However, if a contract defines no initializers, it can be called at any time. Additionally, you can define as many initializer functions in a contract as you want, both private and public. ## Oracles @@ -26,7 +22,7 @@ Explore this section to learn: - [How function visibility works in Aztec](./visibility.md) - [Public, private, and unconstrained functions](./public_private_unconstrained.md), and how to write them -- How to write a [constructor](./write_constructor.md) +- How to write an [initializer function](./initializers.md) - [Calling functions from within the same smart contract and from different contracts](./call_functions.md), including calling private functions from private functions, public from public, and even private from public - [Oracles](../oracles/main.md) and how Aztec smart contracts might use them -- [How functions work under the hood](./inner_workings.md) \ No newline at end of file +- [How functions work under the hood](./inner_workings.md) diff --git a/docs/docs/developers/contracts/writing_contracts/functions/write_constructor.md b/docs/docs/developers/contracts/writing_contracts/functions/write_constructor.md deleted file mode 100644 index 618f5ff1863..00000000000 --- a/docs/docs/developers/contracts/writing_contracts/functions/write_constructor.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: How to write a constructor ---- - -This page explains how to write a constructor function. - -To learn more about constructors, read [this](./main.md#constructors). - -## Annotate with `#[aztec(private)]` - -Currently, all constructors in Aztec must be private. - -Define your constructor like so: - -```rust -#[aztec(private)] -fn constructor() -``` - -## Option 1: Empty constructor - -Your constructor does not need to do anything; you can leave it blank like so: - -```rust -#[aztec(private)] -fn constructor() {} -``` - -## Option 2: Constructor with logic - -Constructors are commonly used to set an admin, such as this example: - -#include_code constructor /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust - -Here, the constructor is calling a public function. It can also call a private function. Learn more about calling functions from functions [here](../functions/call_functions.md). - -To see constructors in action, check out the [Aztec.nr getting started guide](../../../getting_started/aztecnr-getting-started.md). diff --git a/docs/docs/developers/limitations/main.md b/docs/docs/developers/limitations/main.md index baf3e719021..03a43d4d65d 100644 --- a/docs/docs/developers/limitations/main.md +++ b/docs/docs/developers/limitations/main.md @@ -29,7 +29,7 @@ Help shape and define: - It is a testing environment, it is insecure, unaudited and does not generate any proofs, its only for testing purposes; - Constructors can not call nor alter public state - - The constructor is executed exclusively in private domain, WITHOUT the ability to call public functions or alter public state. This means to set initial storage values, you need to follow a pattern similar to [proxies in Ethereum](https://blog.openzeppelin.com/proxy-patterns), where you `initialize` the contract with values after it have been deployed, see [constructor](../contracts/writing_contracts/functions/write_constructor.md). + - The constructor is executed exclusively in private domain, WITHOUT the ability to call public functions or alter public state. This means to set initial storage values, you need to follow a pattern similar to [proxies in Ethereum](https://blog.openzeppelin.com/proxy-patterns), where you `initialize` the contract with values after it have been deployed, see [initializer functions](../contracts/writing_contracts/functions/initializers.md). - Beware that what you think of as a `view` could alter state ATM! Notably the account could alter state or re-enter whenever the account contract's `is_valid` function is called. - `msg_sender` is currently leaking when doing private -> public calls - The `msg_sender` will always be set, if you call a public function from the private world, the `msg_sender` will be set to the private caller's address. See [function context](../contracts/writing_contracts/functions/context.md). diff --git a/docs/sidebars.js b/docs/sidebars.js index 1fb6ee6910f..3e23ca68acd 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -338,7 +338,7 @@ const sidebars = { "developers/contracts/writing_contracts/layout", "developers/contracts/writing_contracts/example_contract", { - label: "Functions and Constructors", + label: "Functions and Initializers", type: "category", link: { type: "doc", @@ -349,7 +349,7 @@ const sidebars = { "developers/contracts/writing_contracts/functions/public_private_unconstrained", "developers/contracts/writing_contracts/functions/visibility", "developers/contracts/writing_contracts/functions/call_functions", - "developers/contracts/writing_contracts/functions/write_constructor", + "developers/contracts/writing_contracts/functions/initializers", "developers/contracts/writing_contracts/functions/compute_note_hash_and_nullifier", "developers/contracts/writing_contracts/functions/inner_workings", ],