Skip to content

Commit

Permalink
Minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
spalladino committed Aug 24, 2023
1 parent 2222a56 commit e740967
Showing 1 changed file with 12 additions and 12 deletions.
24 changes: 12 additions & 12 deletions docs/docs/dev_docs/wallets/writing_an_account_contract.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Writing an Account Contract

This tutorial will take you through the process for writing your own account contract in Noir, along with the Javascript glue code required for using it within a [wallet](./main.md).
This tutorial will take you through the process of writing your own account contract in Noir, along with the Typescript glue code required for using it within a [wallet](./main.md).

Writing your own account contract allows you to define the rules by which user transactions are authorised and paid for, as well as how their keys are managed and can be potentially rotated or recovered. In other words, lets you make the most out of [account abstraction](../../concepts/foundation/accounts/main.md#what-is-account-abstraction) in the Aztec network.

Expand All @@ -24,43 +24,43 @@ Public Key: 0x0ede151adaef1cfcc1b3e152ea39f00c5cda3f3857cef00decb049d283672dc71
```
:::

The important part of this contract is the `entrypoint` function, which will be the first function executed in any transaction sent from this account. This function has two main responsibilities: authenticating the transaction and executing any calls. It receives a `payload` with the list of function calls to execute, and a signature over that payload.
The important part of this contract is the `entrypoint` function, which will be the first function executed in any transaction originated from this account. This function has two main responsibilities: 1) authenticating the transaction and 2) executing calls. It receives a `payload` with the list of function calls to execute, as well as a signature over that payload.

#include_code entrypoint-struct yarn-project/noir-libs/noir-aztec/src/entrypoint.nr rust

:::info
Using the `EntrypointPayload`` struct is not mandatory. You can package the instructions to be carried out by your account contract however you want. However, the entrypoint payload already provides a set of helper functions, both in Noir and Typescript, that can save you a lot of time when writing an account contract.
Using the `EntrypointPayload`` struct is not mandatory. You can package the instructions to be carried out by your account contract however you want. However, the entrypoint payload already provides a set of helper functions, both in Noir and Typescript, that can save you a lot of time when writing a new account contract.
:::

Let's go step by step into the `entrypoint` function:
Let's go step by step into what the `entrypoint` function is doing:

#include_code entrypoint-init yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr rust

We first initialise the private function context using the provided arguments, as we do in any other function. We use a `BoundedVec` container to make it easy to collect the arguments into a single array to be hashed, but we could also have assembled it manually.

#include_code entrypoint-auth yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr rust

Next is authenticating the transaction. To do this, we serialise and Pedersen-hash the payload, which contains the instructions to be carried out, along with a nonce. We then assert that the signature verifies against the resulting hash and the contract public key. This makes a transaction with an invalid signature unprovable.
Next is authenticating the transaction. To do this, we serialise and Pedersen-hash the payload, which contains the instructions to be carried out along with a nonce. We then assert that the signature verifies against the resulting hash and the contract public key. This makes a transaction with an invalid signature unprovable.

#include_code entrypoint-auth yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr rust

Last, we actually execute the calls in the payload struct. The `execute_calls` function runs through the private and public calls included in the entrypoint payload and executes them:
Last, we execute the calls in the payload struct. The `execute_calls` helper function runs through the private and public calls included in the entrypoint payload and executes them:

#include_code entrypoint-execute-calls yarn-project/noir-libs/noir-aztec/src/entrypoint.nr rust

Note the usage of the `_with_packed_args` variant of [`call_public_function` and `call_private_function`](../contracts/functions.md#calling-functions). Due to Noir limitations, we cannot include more than a small number of arguments in a function call. However, we can bypass this restriction by using a hash of the arguments in a function call, which gets automatically expanded to the full set of arguments when the nested call is executed. We call this _argument packing_, and it will be especially relevant when writing the typescript side of things!
Note the usage of the `_with_packed_args` variant of [`call_public_function` and `call_private_function`](../contracts/functions.md#calling-functions). Due to Noir limitations, we cannot include more than a small number of arguments in a function call. However, we can bypass this restriction by using a hash of the arguments in a function call, which gets automatically expanded to the full set of arguments when the nested call is executed. We call this _argument packing_.

## The typescript side of things

Now that we have a valid Noir account contract, we need to write the typescript glue code that will take care of formatting and authenticating transactions so they can be processed by our contract, as well as deploying it. This takes the form of implementing the `AccountContract` interface:
Now that we have a valid Noir account contract, we need to write the typescript glue code that will take care of formatting and authenticating transactions so they can be processed by our contract, as well as deploying the contract during account setup. This takes the form of implementing the `AccountContract` interface:

#include_code account-contract-interface yarn-project/aztec.js/src/account/contract/index.ts typescript

The most interesting bit here is creating an `Entrypoint`, which is the piece of code that converts from a list of function calls requested by the user, into a transaction execution request that can be simulated and proven, and assembled into a transaction to be sent to the network:
The most interesting bit here is creating an `Entrypoint`, which is the piece of code that converts from a list of function calls requested by the user into a transaction execution request that can be simulated and proven:

#include_code entrypoint-interface yarn-project/aztec.js/src/account/entrypoint/index.ts typescript

For our account contract, we need to assemble the function calls into a payload, sign it using Schnorr, and encode the arguments for our `entrypoint` function. Let's see how it would look like:
For our account contract, we need to assemble the function calls into a payload, sign it using Schnorr, and encode these arguments for our `entrypoint` function. Let's see how it would look like:

#include_code account-contract yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts typescript

Expand All @@ -83,11 +83,11 @@ To create and deploy the account, we will use the `Account` class, which takes a

#include_code account-contract-deploy yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts typescript

Note that we get a [`Wallet` instance](./main.md) out of the account, which we can use for initialising the token contract class, so any transactions sent to it are sent from our wallet. We can then send a transaction to it and check its effects:
Note that we get a [`Wallet` instance](./main.md) out of the account, which we can use for initialising the token contract class after deployment, so any transactions sent to it are sent from our wallet. We can then send a transaction to it and check its effects:

#include_code account-contract-works yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts typescript

If we run this, we get `Balance of wallet is now 150`, which shows that the `mint` transaction was successfully executed.
If we run this, we get `Balance of wallet is now 150`, which shows that the `mint` call was successfully executed from our account contract.

To make sure that we are actually validating the provided signature in our account contract, we can try signing with a different key. To do this, we will set up a new `Account` instance pointing to the contract we already deployed but using a wrong signing key:

Expand Down

0 comments on commit e740967

Please sign in to comment.