From 9412c219b9cd0f0cbc202e85d56442faa6e52060 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 22 Aug 2023 16:34:18 -0300 Subject: [PATCH 1/3] docs: Wallet dev docs --- .../docs/concepts/foundation/accounts/keys.md | 2 +- docs/docs/dev_docs/wallets/architecture.md | 28 ++++++++++ .../dev_docs/wallets/building_a_wallet.md | 3 -- docs/docs/dev_docs/wallets/main.md | 53 +++++++++++++++++++ .../aztec.js/src/account/entrypoint/index.ts | 2 + .../types/src/interfaces/aztec_rpc.ts | 2 + 6 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 docs/docs/dev_docs/wallets/architecture.md delete mode 100644 docs/docs/dev_docs/wallets/building_a_wallet.md diff --git a/docs/docs/concepts/foundation/accounts/keys.md b/docs/docs/concepts/foundation/accounts/keys.md index a8b7d182709..4a0e01a9b33 100644 --- a/docs/docs/concepts/foundation/accounts/keys.md +++ b/docs/docs/concepts/foundation/accounts/keys.md @@ -73,7 +73,7 @@ partial_address := hash(salt, contract_code, constructor_hash) address := hash(public_key, partial_address) ``` -This public key corresponds to the privacy master key of the account. In order to manage private state, such as receiving an encrypted note, an account needs to share its partial address and public key, along with its address. This allows anyone to verify that the public key corresponds to the intended address. +This public key corresponds to the privacy master key of the account. In order to manage private state, such as receiving an encrypted note, an account needs to share its partial address and public key, along with its address. This allows anyone to verify that the public key corresponds to the intended address. We call the address, partial address, and public key of a user their **complete address**. Contracts that are not meant to represent a user who handles private state, usually non-account contracts such as applications, do not need to provide a valid public key, and can instead just use zero to denote that they are not expected to receive private notes. diff --git a/docs/docs/dev_docs/wallets/architecture.md b/docs/docs/dev_docs/wallets/architecture.md new file mode 100644 index 00000000000..52654befe44 --- /dev/null +++ b/docs/docs/dev_docs/wallets/architecture.md @@ -0,0 +1,28 @@ +# Architecture + +Wallets expose to dapps an interface that allows them to act on behalf of the user, such as querying private state or sending transactions. As in Ethereum, wallets should require user confirmation whenever carrying out a potentially sensitive action requested by a dapp. + +## Overview + +Architecture-wise, a wallet is an instance of an **Aztec RPC Server** which manages user keys and private state and communicates with an **Aztec Node** for retrieving public information or broadcasting transactions. Note that the RPC server requires a local database for keeping private state, and is also expected to be continuously syncing new blocks for trial-decryption of user notes. + +Additionally, a wallet must implement an **Entrypoint** interface that defines [how to create an execution request](./main.md#transaction-lifecycle) out of a user intent for the specific implementation of account contract used by the wallet. Think of the entrypoint interface as the Javascript counterpart of an account contract, or the piece of code that knows how to format and authenticate a transaction based on the rules defined in Noir by the user's account. + +## Entrypoint interface + +The entrypoint interface is used for creating an execution request out of a set of function calls that describe user intents. Note that an account contract may not handle batching, in which case it is expected to throw if more than a single function call is requested. + +#include_code entrypoint-interface /yarn-project/aztec.js/src/account/entrypoint/index.ts typescript + +Refer to the page on [writing an account contract](./writing_an_account_contract.md) for an example on how to implement this interface. + +## RPC interface + +A wallet exposes the RPC interface to dapps by running an [Aztec RPC Server instance](https://github.com/AztecProtocol/aztec-packages/blob/95d1350b23b6205ff2a7d3de41a37e0bc9ee7640/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts). The Aztec RPC Server requires a keystore and a database implementation for storing keys, private state, and recipient encryption public keys. + +#include_code rpc-interface /yarn-project/types/src/interfaces/aztec_rpc.ts typescript + + + + + diff --git a/docs/docs/dev_docs/wallets/building_a_wallet.md b/docs/docs/dev_docs/wallets/building_a_wallet.md deleted file mode 100644 index b658a9b9a0b..00000000000 --- a/docs/docs/dev_docs/wallets/building_a_wallet.md +++ /dev/null @@ -1,3 +0,0 @@ -# Building a wallet - -Please use the [TUTORIAL-TEMPLATE](../../TUTORIAL_TEMPLATE.md) for standalone guides / tutorials. \ No newline at end of file diff --git a/docs/docs/dev_docs/wallets/main.md b/docs/docs/dev_docs/wallets/main.md index e69de29bb2d..56958e8d5c4 100644 --- a/docs/docs/dev_docs/wallets/main.md +++ b/docs/docs/dev_docs/wallets/main.md @@ -0,0 +1,53 @@ +# Wallets + +Wallets are the applications through which users manage their accounts. They also implement the interface for dapps to perform actions on behalf of a user. And in addition to these usual responsibilities present in other blockchains, wallets in Aztec also need to manage privacy keys and private state, as well as producing local proofs. + +In this page we will cover the main responsibilities of a wallet in the Aztec network. Refer to [_writing an account contract_](./writing_an_account_contract.md) for a tutorial on how to write a contract to back a user's account, or to [_wallet architecture](./architecture.md) for an overview of its architecture and a reference on the interface a wallet must implement. + +## Account setup + +The first step for any wallet is to let the user set up their [accounts](../../concepts/foundation/accounts/main.md). An account in Aztec is implemented by its corresponding account contract that the user must deploy to begin interacting with the network. A wallet must support at least one specific [account contract implementation](./writing_an_account_contract.md), which means being able to deploy such a contract, as well as formatting transactions for it. + +However, users must be able to receive funds in Aztec before deploying their account. A wallet should let a user generate a [deterministic complete address](../../concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys) without having to interact with the network, so they can share with others to receive funds. This requires that the wallet pins a specific contract implementation, its initialisation arguments, a deployment salt, and a privacy key. These values yield a deterministic address, so when the account contract is actually deployed, it is available at the precalculated address. Once the account contract is deployed, the user can start sending transactions using it as the transaction origin. + +## Transaction lifecycle + +Every transaction in Aztec is broadcasted to the network as its zero-knowledge proof of correct execution, in order to preserve privacy. This means that transaction proofs are generated on the wallet and not on a remote node. This is one of the biggest differences with regard to EVM chain wallets. + +A wallet is responsible for first **creating** an [execution request](../../concepts/foundation/accounts/main.md#execution-requests). This means going from an intent, such as _call transfer on this contract_, to an authenticated transaction formatted for the user's account contract. As an example, given an [ECDSA-based account](https://github.com/AztecProtocol/aztec-packages/blob/95d1350b23b6205ff2a7d3de41a37e0bc9ee7640/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr#L1), an execution request has the account contract as `origin`, calls its `entrypoint` function, and encodes the user intent as `payload`, which is signed using ECDSA with a private key managed by the wallet. + +Once the execution request is created, it is **simulated** to retrieve an execution trace. This provides the user with a list of the side effects of a transaction if it is successfully mined, and a trace to be fed into the prover. During this simulation, the wallet is responsible of providing data to the virtual machine, such as private notes, encryption keys, or nullifier secrets. + +:::info +Since private executions rely on a UTXO model, the side effects of a transaction cannot change when mined. However, the transaction can be dropped due to attempting to consume a private note that another transaction consumes before it is mined. Also, any side effects that arise from its public execution _can_ change, as in any EVM-based chain. +::: + +After the user greenlights the transaction, the wallet generates a **proof** for it that guarantees correct execution and hides all private information, which gets **sent** to the P2P network for inclusion in a next block. + +:::warning +There are no proofs generated as of the Sandbox release. This will be included in a future release before testnet. +::: +## Key management + +As in EVM-based chains, wallets are expected to manage user keys, or provide an interface to hardware wallets or alternate key stores. Keep in mind that in Aztec each account requires [two sets of keys](../../concepts/foundation/accounts/keys.md): privacy keys and authentication keys. Privacy keys are mandated by the protocol and used for encryption and nullification, whereas authentication keys are dependent on the account contract implementation rolled out by the wallet. Should the account contract support it, wallets must provide the user with the means to rotate or recover their authentication keys. + +:::info +Due to limitations in the current architecture, privacy keys need to be available in the wallet software itself and cannot be punted to an external keystore. This restriction may be lifted in a future release. +::: +## Recipient encryption keys + +Wallets are also expected to manage the public encryption keys of any recipients of local transactions. When creating an encrypted note for a recipient given their address, the wallet needs to provide their [complete address](../../concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys). This requires keeping a local registry of complete addresses for all recipients that the user intends to interact with. + +:::info +There is no built-in mechanism for broadcasting public encryption keys at the moment. In a future release, clients may automatically track the complete address that corresponds to an account contract deployment, though it will still be needed to manually add recipients who have not yet deployed their account contracts. +::: + +## Private state + +Last but not least, wallets also track the user's private state. Wallets currently rely on brute force decryption, where every new block is downloaded and its encrypted data blobs are attempted to be decrypted with the user decryption keys. Whenever a blob is decrypted properly, it is added to the corresponding account's private state. + +:::info +At the time of this writing, all private state is encrypted and broadcasted through the network, and eventually committed to L1. This means that a wallet can reconstruct its entire private state out of its encryption keys in the event of local data loss. +::: + +Note that wallets must also scan for private state in blocks prior to their deployment, since users may have received private state before deployment. diff --git a/yarn-project/aztec.js/src/account/entrypoint/index.ts b/yarn-project/aztec.js/src/account/entrypoint/index.ts index 7ec15f81187..00168fededb 100644 --- a/yarn-project/aztec.js/src/account/entrypoint/index.ts +++ b/yarn-project/aztec.js/src/account/entrypoint/index.ts @@ -11,6 +11,7 @@ export type CreateTxRequestOpts = { origin?: AztecAddress; }; +// docs:start:entrypoint-interface /** * Represents a transaction entrypoint in an account contract. * Knows how to assemble a transaction execution request given a set of function calls. @@ -24,3 +25,4 @@ export interface Entrypoint { */ createTxExecutionRequest(executions: FunctionCall[], opts?: CreateTxRequestOpts): Promise; } +// docs:end:entrypoint-interface diff --git a/yarn-project/types/src/interfaces/aztec_rpc.ts b/yarn-project/types/src/interfaces/aztec_rpc.ts index 69d8851c560..5a5159599f1 100644 --- a/yarn-project/types/src/interfaces/aztec_rpc.ts +++ b/yarn-project/types/src/interfaces/aztec_rpc.ts @@ -56,6 +56,7 @@ export type SyncStatus = { notes: Record; }; +// docs:start:rpc-interface /** * Represents an Aztec RPC implementation. * Provides functionality for all the operations needed to interact with the Aztec network, @@ -237,3 +238,4 @@ export interface AztecRPC { */ getSyncStatus(): Promise; } +// docs:end:rpc-interface From a4bcff13bea479b6230296b60767f2f72167a7db Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Thu, 24 Aug 2023 11:39:26 -0300 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Michael Connor --- docs/docs/dev_docs/wallets/main.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/dev_docs/wallets/main.md b/docs/docs/dev_docs/wallets/main.md index 56958e8d5c4..085f06786fa 100644 --- a/docs/docs/dev_docs/wallets/main.md +++ b/docs/docs/dev_docs/wallets/main.md @@ -8,11 +8,11 @@ In this page we will cover the main responsibilities of a wallet in the Aztec ne The first step for any wallet is to let the user set up their [accounts](../../concepts/foundation/accounts/main.md). An account in Aztec is implemented by its corresponding account contract that the user must deploy to begin interacting with the network. A wallet must support at least one specific [account contract implementation](./writing_an_account_contract.md), which means being able to deploy such a contract, as well as formatting transactions for it. -However, users must be able to receive funds in Aztec before deploying their account. A wallet should let a user generate a [deterministic complete address](../../concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys) without having to interact with the network, so they can share with others to receive funds. This requires that the wallet pins a specific contract implementation, its initialisation arguments, a deployment salt, and a privacy key. These values yield a deterministic address, so when the account contract is actually deployed, it is available at the precalculated address. Once the account contract is deployed, the user can start sending transactions using it as the transaction origin. +However, users must be able to receive funds in Aztec before deploying their account. A wallet should let a user generate a [deterministic complete address](../../concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys) without having to interact with the network, so they can share it with others to receive funds. This requires that the wallet pins a specific contract implementation, its initialisation arguments, a deployment salt, and a privacy key. These values yield a deterministic address, so when the account contract is actually deployed, it is available at the precalculated address. Once the account contract is deployed, the user can start sending transactions using it as the transaction origin. ## Transaction lifecycle -Every transaction in Aztec is broadcasted to the network as its zero-knowledge proof of correct execution, in order to preserve privacy. This means that transaction proofs are generated on the wallet and not on a remote node. This is one of the biggest differences with regard to EVM chain wallets. +Every transaction in Aztec is broadcast to the network as a zero-knowledge proof of correct execution, in order to preserve privacy. This means that transaction proofs are generated on the wallet and not on a remote node. This is one of the biggest differences with regard to EVM chain wallets. A wallet is responsible for first **creating** an [execution request](../../concepts/foundation/accounts/main.md#execution-requests). This means going from an intent, such as _call transfer on this contract_, to an authenticated transaction formatted for the user's account contract. As an example, given an [ECDSA-based account](https://github.com/AztecProtocol/aztec-packages/blob/95d1350b23b6205ff2a7d3de41a37e0bc9ee7640/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr#L1), an execution request has the account contract as `origin`, calls its `entrypoint` function, and encodes the user intent as `payload`, which is signed using ECDSA with a private key managed by the wallet. @@ -29,7 +29,7 @@ There are no proofs generated as of the Sandbox release. This will be included i ::: ## Key management -As in EVM-based chains, wallets are expected to manage user keys, or provide an interface to hardware wallets or alternate key stores. Keep in mind that in Aztec each account requires [two sets of keys](../../concepts/foundation/accounts/keys.md): privacy keys and authentication keys. Privacy keys are mandated by the protocol and used for encryption and nullification, whereas authentication keys are dependent on the account contract implementation rolled out by the wallet. Should the account contract support it, wallets must provide the user with the means to rotate or recover their authentication keys. +As in EVM-based chains, wallets are expected to manage user keys, or provide an interface to hardware wallets or alternative key stores. Keep in mind that in Aztec each account requires [two sets of keys](../../concepts/foundation/accounts/keys.md): privacy keys and authentication keys. Privacy keys are mandated by the protocol and used for encryption and nullification, whereas authentication keys are dependent on the account contract implementation rolled out by the wallet. Should the account contract support it, wallets must provide the user with the means to rotate or recover their authentication keys. :::info Due to limitations in the current architecture, privacy keys need to be available in the wallet software itself and cannot be punted to an external keystore. This restriction may be lifted in a future release. @@ -50,4 +50,4 @@ Last but not least, wallets also track the user's private state. Wallets current At the time of this writing, all private state is encrypted and broadcasted through the network, and eventually committed to L1. This means that a wallet can reconstruct its entire private state out of its encryption keys in the event of local data loss. ::: -Note that wallets must also scan for private state in blocks prior to their deployment, since users may have received private state before deployment. +Note that wallets must also scan for private state in blocks prior to the deployment of a user's account contract, since users may have received private state before deployment. From 83499bdfc4c3d686c59553029c1e5aed6a60c265 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Thu, 24 Aug 2023 15:59:29 -0300 Subject: [PATCH 3/3] Address comments from code review --- .../docs/concepts/foundation/accounts/main.md | 4 +-- docs/docs/dev_docs/wallets/architecture.md | 10 ++++--- docs/docs/dev_docs/wallets/main.md | 27 ++++++++++++------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/docs/concepts/foundation/accounts/main.md b/docs/docs/concepts/foundation/accounts/main.md index 9b994fc2f35..7343fd73f3a 100644 --- a/docs/docs/concepts/foundation/accounts/main.md +++ b/docs/docs/concepts/foundation/accounts/main.md @@ -62,9 +62,9 @@ def entryPoint(payload): Read more about how to write an account contract [here](../../../dev_docs/wallets/writing_an_account_contract.md). -### Accounts and wallets +### Account contracts and wallets -Account contracts are tightly coupled to the wallet software that users use to interact with the protocol. Dapps submit to the wallet software an execution request (eg "call swap in X contract"), and the wallet encodes and authenticates the request as a valid payload for the user's account contract. The account contract then validates the request encoded by the wallet, and executes the actions requested by the dapp. +Account contracts are tightly coupled to the wallet software that users use to interact with the protocol. Dapps submit to the wallet software one or more function calls to be executed (eg "call swap in X contract"), and the wallet encodes and authenticates the request as a valid payload for the user's account contract. The account contract then validates the request encoded and authenticated by the wallet, and executes the function calls requested by the dapp. ### Execution requests diff --git a/docs/docs/dev_docs/wallets/architecture.md b/docs/docs/dev_docs/wallets/architecture.md index 52654befe44..27818b48b9f 100644 --- a/docs/docs/dev_docs/wallets/architecture.md +++ b/docs/docs/dev_docs/wallets/architecture.md @@ -1,16 +1,18 @@ # Architecture -Wallets expose to dapps an interface that allows them to act on behalf of the user, such as querying private state or sending transactions. As in Ethereum, wallets should require user confirmation whenever carrying out a potentially sensitive action requested by a dapp. +Wallets expose to dapps an interface that allows them to act on behalf of the user, such as querying private state or sending transactions. Bear mind that, as in Ethereum, wallets should require user confirmation whenever carrying out a potentially sensitive action requested by a dapp. ## Overview -Architecture-wise, a wallet is an instance of an **Aztec RPC Server** which manages user keys and private state and communicates with an **Aztec Node** for retrieving public information or broadcasting transactions. Note that the RPC server requires a local database for keeping private state, and is also expected to be continuously syncing new blocks for trial-decryption of user notes. +Architecture-wise, a wallet is an instance of an **Aztec RPC Server** which manages user keys and private state. The RPC server also communicates with an **Aztec Node** for retrieving public information or broadcasting transactions. Note that the RPC server requires a local database for keeping private state, and is also expected to be continuously syncing new blocks for trial-decryption of user notes. -Additionally, a wallet must implement an **Entrypoint** interface that defines [how to create an execution request](./main.md#transaction-lifecycle) out of a user intent for the specific implementation of account contract used by the wallet. Think of the entrypoint interface as the Javascript counterpart of an account contract, or the piece of code that knows how to format and authenticate a transaction based on the rules defined in Noir by the user's account. +Additionally, a wallet must be able to handle one or more [account contract implementations](../../concepts/foundation/accounts/main.md#account-contracts-and-wallets). When a user creates a new account, the account is represented on-chain by an account contract. The wallet is responsible for deploying and interacting with this contract. A wallet may support multiple flavours of accounts, such as an account that uses ECDSA signatures, or one that relies on WebAuthn, or one that requires multi-factor authentication. For a user, the choice of what account implementation to use is then determined by the wallet they interact with. + +In code, this translates to a wallet implementing an **Entrypoint** interface that defines [how to create an _execution request_ out of an array of _function calls_](./main.md#transaction-lifecycle) for the specific implementation of an account contract. Think of the entrypoint interface as the Javascript counterpart of an account contract, or the piece of code that knows how to format and authenticate a transaction based on the rules defined in Noir by the user's account. ## Entrypoint interface -The entrypoint interface is used for creating an execution request out of a set of function calls that describe user intents. Note that an account contract may not handle batching, in which case it is expected to throw if more than a single function call is requested. +The entrypoint interface is used for creating an _execution request_ out of one or more _function calls_ requested by a dapp. Account contracts are expected to handle multiple function calls per transaction, since dapps may choose to batch multiple actions into a single request to the wallet. #include_code entrypoint-interface /yarn-project/aztec.js/src/account/entrypoint/index.ts typescript diff --git a/docs/docs/dev_docs/wallets/main.md b/docs/docs/dev_docs/wallets/main.md index 085f06786fa..1aee0f550cb 100644 --- a/docs/docs/dev_docs/wallets/main.md +++ b/docs/docs/dev_docs/wallets/main.md @@ -1,28 +1,34 @@ # Wallets -Wallets are the applications through which users manage their accounts. They also implement the interface for dapps to perform actions on behalf of a user. And in addition to these usual responsibilities present in other blockchains, wallets in Aztec also need to manage privacy keys and private state, as well as producing local proofs. +Wallets are the applications through which users manage their accounts. Users rely on wallets to browse through their accounts, monitor their balances, and create new accounts. Wallets also store seed phrases and private keys, or interact with external keystores such as hardware wallets. + +Wallets also provide an interface for dapps. Dapps may request access to see the user accounts, in order to show the state of those accounts in the context of the application, and request to send transactions from those accounts as the user interacts with the dapp. + +In addition to these usual responsibilities, wallets in Aztec also need to track private state. This implies keeping a local database of all private notes encrypted for any of the user's accounts, so dapps and contracts can query the user's private state. Aztec wallets are also responsible for producing local proofs of execution for private functions. In this page we will cover the main responsibilities of a wallet in the Aztec network. Refer to [_writing an account contract_](./writing_an_account_contract.md) for a tutorial on how to write a contract to back a user's account, or to [_wallet architecture](./architecture.md) for an overview of its architecture and a reference on the interface a wallet must implement. ## Account setup -The first step for any wallet is to let the user set up their [accounts](../../concepts/foundation/accounts/main.md). An account in Aztec is implemented by its corresponding account contract that the user must deploy to begin interacting with the network. A wallet must support at least one specific [account contract implementation](./writing_an_account_contract.md), which means being able to deploy such a contract, as well as formatting transactions for it. +The first step for any wallet is to let the user set up their [accounts](../../concepts/foundation/accounts/main.md). An account in Aztec is represented on-chain by its corresponding account contract that the user must deploy to begin interacting with the network. This account contract dictates how transactions are authenticated and executed. + +A wallet must support at least one specific [account contract implementation](./writing_an_account_contract.md), which means being able to deploy such a contract, as well as interacting with it when sending transactions. Code-wise, this requires [implementing the `AccountContract` interface](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec.js/src/account/contract/index.ts). -However, users must be able to receive funds in Aztec before deploying their account. A wallet should let a user generate a [deterministic complete address](../../concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys) without having to interact with the network, so they can share it with others to receive funds. This requires that the wallet pins a specific contract implementation, its initialisation arguments, a deployment salt, and a privacy key. These values yield a deterministic address, so when the account contract is actually deployed, it is available at the precalculated address. Once the account contract is deployed, the user can start sending transactions using it as the transaction origin. +Note that users must be able to receive funds in Aztec before deploying their account. A wallet should let a user generate a [deterministic complete address](../../concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys) without having to interact with the network, so they can share it with others to receive funds. This requires that the wallet pins a specific contract implementation, its initialisation arguments, a deployment salt, and a privacy key. These values yield a deterministic address, so when the account contract is actually deployed, it is available at the precalculated address. Once the account contract is deployed, the user can start sending transactions using it as the transaction origin. ## Transaction lifecycle Every transaction in Aztec is broadcast to the network as a zero-knowledge proof of correct execution, in order to preserve privacy. This means that transaction proofs are generated on the wallet and not on a remote node. This is one of the biggest differences with regard to EVM chain wallets. -A wallet is responsible for first **creating** an [execution request](../../concepts/foundation/accounts/main.md#execution-requests). This means going from an intent, such as _call transfer on this contract_, to an authenticated transaction formatted for the user's account contract. As an example, given an [ECDSA-based account](https://github.com/AztecProtocol/aztec-packages/blob/95d1350b23b6205ff2a7d3de41a37e0bc9ee7640/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr#L1), an execution request has the account contract as `origin`, calls its `entrypoint` function, and encodes the user intent as `payload`, which is signed using ECDSA with a private key managed by the wallet. +A wallet is responsible for **creating** an [_execution request_](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/types/src/tx_execution_request.ts) out of one or more [_function calls_](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/types/src/function_call.ts) requested by a dapp. For example, a dapp may request a wallet to "invoke the `transfer` function on the contract at `0x1234` with the following arguments", in response to a user action. The wallet [turns that into an execution request](../../concepts/foundation/accounts/main.md#execution-requests) with the signed instructions to execute that function call from the user's account contract. In an [ECDSA-based account](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/main.nr), for instance, this is an execution request that encodes the function call in the _entrypoint payload_, and includes its ECDSA signature with the account's signing private key. -Once the execution request is created, it is **simulated** to retrieve an execution trace. This provides the user with a list of the side effects of a transaction if it is successfully mined, and a trace to be fed into the prover. During this simulation, the wallet is responsible of providing data to the virtual machine, such as private notes, encryption keys, or nullifier secrets. +Once the _execution request_ is created, the wallet is responsible for **simulating** and **proving** the execution of its private functions. The simulation yields an execution trace, which can be used to provide the user with a list of side effects of the private execution of the transaction. During this simulation, the wallet is responsible of providing data to the virtual machine, such as private notes, encryption keys, or nullifier secrets. This execution trace is fed into the prover, which returns a zero-knowledge proof that guarantees correct execution and hides all private information. The output of this process is a [_transaction_](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/types/src/tx/tx.ts) object. :::info -Since private executions rely on a UTXO model, the side effects of a transaction cannot change when mined. However, the transaction can be dropped due to attempting to consume a private note that another transaction consumes before it is mined. Also, any side effects that arise from its public execution _can_ change, as in any EVM-based chain. +Since private functions rely on a UTXO model, the private execution trace of a transaction is determined exclusively by the notes used as inputs. Since these notes are immutable, the trace of a transaction is always the same, so any effects observed during simulation will be exactly the same when the transaction is mined. However, the transaction may be dropped if it attempts to consume a private note that another transaction nullified before it gets mined. Note that this applies only to private function execution. Public functions rely on an account model, similar to Ethereum, so their execution trace depends on the chain's public state at the point they are included in a block, which may have changed since the transaction was simulated locally. ::: -After the user greenlights the transaction, the wallet generates a **proof** for it that guarantees correct execution and hides all private information, which gets **sent** to the P2P network for inclusion in a next block. +Finally, the wallet **sends** the resulting _transaction_ object, which includes the proof of execution, to an Aztec Node. The transaction is then broadcasted through the peer-to-peer network, to be eventually picked up by a sequencer and included in a block. :::warning There are no proofs generated as of the Sandbox release. This will be included in a future release before testnet. @@ -44,10 +50,13 @@ There is no built-in mechanism for broadcasting public encryption keys at the mo ## Private state -Last but not least, wallets also track the user's private state. Wallets currently rely on brute force decryption, where every new block is downloaded and its encrypted data blobs are attempted to be decrypted with the user decryption keys. Whenever a blob is decrypted properly, it is added to the corresponding account's private state. +Last but not least, wallets also store the user's private state. Wallets currently rely on brute force decryption, where every new block is downloaded and its encrypted data blobs are attempted to be decrypted with the user decryption keys. Whenever a blob is decrypted properly, it is added to the corresponding account's private state. Note that wallets must also scan for private state in blocks prior to the deployment of a user's account contract, since users may have received private state before deployment. :::info At the time of this writing, all private state is encrypted and broadcasted through the network, and eventually committed to L1. This means that a wallet can reconstruct its entire private state out of its encryption keys in the event of local data loss. ::: -Note that wallets must also scan for private state in blocks prior to the deployment of a user's account contract, since users may have received private state before deployment. +Encrypted data blobs do not carry any public information as to whom their recipient is. Therefore, it is not possible for a remote node to identify the notes that belong to a user, and it is not possible for a wallet to query a remote node for its private state. As such, wallets need to keep a local database of their accounts private state, in order to be able to answer any queries on their private state. + +Dapps may require access to the user's private state, in order to show information relevant to the current application. For instance, a dapp for a token may require access to the user's private notes in the token contract in order to display the user's balance. It is responsibility of the wallet to require authorisation from the user before disclosing private state to a dapp. +