diff --git a/docs/docs/about_aztec/history/history.mdx b/docs/docs/about_aztec/history/history.mdx index 9bd9c2995a1..605508013df 100644 --- a/docs/docs/about_aztec/history/history.mdx +++ b/docs/docs/about_aztec/history/history.mdx @@ -9,27 +9,32 @@ import Image from "@theme/IdealImage"; --- + ## Bitcoin The original blockchain. -**Programmability**: -- None. +**Programmability**: + +- None. - Transfer bitcoin only. -**Privacy**: +**Privacy**: + - None. --- ## Ethereum -**Programmability**: +**Programmability**: + - Turing complete smart contracts. -**Privacy**: -- Originally: None. -- Now: +**Privacy**: + +- Originally: None. +- Now: - some specific apps on L1 - some specific apps, deployed via L2, like zk.money and Aztec Connect. @@ -37,46 +42,54 @@ The original blockchain. ## ZCash -**Programmability**: -- None. +**Programmability**: + +- None. - Transfer ZCash only. -**Privacy**: +**Privacy**: + - Transfers of shielded zcash are private. --- ## zk.money -**Programmability**: +**Programmability**: + - Any custom ERC20 token (on Ethereum L1) can be deposited to L2, transferred within L2, and withdrawn from L2. -**Privacy**: +**Privacy**: + - Transfers of the ERC20 tokens within the L2 are private. --- ## Aztec Connect -**Programmability**: -- The functionality of zk.money, plus: -- Tokens can be sent from the L2 shielded pool to many L1 defi contracts, and the resulting tokens can be re-shielded. This gives privacy to L1 defi users. +**Programmability**: + +- The functionality of zk.money, plus: +- Tokens can be sent from the L2 shielded pool to many L1 DeFi contracts, and the resulting tokens can be re-shielded. This gives anonymity to L1 DeFi users. -**Privacy**: -- Transfers of the ERC20 tokens within the L2 are private. -- User defi interactions are private. +**Privacy**: + +- Transfers of the ERC20 tokens within the L2 are private. +- User DeFi interactions are anonymous. --- ## Aztec -**Programmability**: +**Programmability**: + - Fully programmable private smart contracts: - - private functions which can edit general private state - - cheap L2 public functions + - Private functions which can edit general private state + - Cheap L2 public functions - L1 (public) functions. -**Privacy**: +**Privacy**: + - Executing private functions grants: - Function privacy - Input privacy diff --git a/docs/docs/about_aztec/overview.mdx b/docs/docs/about_aztec/overview.mdx index cb727d36732..dde9f2c1192 100644 --- a/docs/docs/about_aztec/overview.mdx +++ b/docs/docs/about_aztec/overview.mdx @@ -4,21 +4,21 @@ title: Overview import ReactPlayer from "react-player/youtube"; -The next version of our rollup, Aztec, is a privacy-preserving, programmable extension to Ethereum. It is a layer 2 zk-rollup on Ethereum that enables programable privacy via composable smart contracts. +Aztec is an L2 that brings programmable privacy to Ethereum. ## Private Smart Contracts on Aztec A smart contract on Aztec is a collection of functions, written as ZK-SNARK circuits. These circuits can have different modes of execution: -1. Secret Functions -- can read and write private state, read historic public state, consume or send messages to / from L1, and read Ethereum state. Can call other secret functions in the same contract, or other contracts. They can call public functions. -2. Public Functions -- can read and write public state, write private state, consume or send messages to / from L1 and read Ethereum state. Can call other public functions on the same or other contracts. -3. Portal Contracts -- these are contracts on L1 that can receive messages from L2 or allow messages to be sent to L2 from L1 contracts. +1. Secret Functions -- can read and write private state, read historic public state, consume or send messages to / from Ethereum, and read Ethereum state. They can call other secret functions in the same contract, or other contracts, and can call public functions. +2. Public Functions -- can read and write public state, write private state, consume or send messages to / from Ethereum and read Ethereum state. They can call other public functions on the same or other contracts. +3. Portal Contracts -- these are contracts on Ethereum that can receive messages from Aztec or send messages to Aztec from Ethereum contracts. Using these different modes of execution, developers can build applications with user privacy, data privacy and code privacy. User privacy -- transactions may not reveal information about the sender or the recipient. -Data privacy -- transactions may not reveal information about the payload of the transaction, e.g the asset or value being transacted. +Data privacy -- transactions may not reveal information about the payload of the transaction, e.g., the asset or value being transacted. Code privacy -- transactions may not reveal the program logic. @@ -50,7 +50,7 @@ Contributors to Aztec uphold many of the values of the Ethereum community -- bui ## Noir -Noir is a domain specific programming language for writing zero knowledge circuits. On Aztec a smart contract is a collection of circuits that developers write using Noir. +Noir is a domain specific programming language for writing zero-knowledge circuits. On Aztec a smart contract is a collection of circuits that developers write using Noir. You can find more information and resources for learning about Noir smart contracts on [this page](../dev_docs/contracts/main.md). diff --git a/docs/docs/about_aztec/roadmap/cryptography_roadmap.md b/docs/docs/about_aztec/roadmap/cryptography_roadmap.md index 0cef1ff7e37..f24537c1a0b 100644 --- a/docs/docs/about_aztec/roadmap/cryptography_roadmap.md +++ b/docs/docs/about_aztec/roadmap/cryptography_roadmap.md @@ -2,26 +2,23 @@ title: Cryptography Roadmap --- -The cryptography team is currently working on [Barretenberg here](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg) +The cryptography team is currently working on [Barretenberg here.](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg) ## R&D projects -- Publish the Honk paper, describing practical considerations for constructing our cutting-edge proving system Honk along with formal proofs of its security properties. +Publish the Honk paper, describing practical considerations for constructing our cutting-edge proving system Honk along with formal proofs of its security properties. ## Honk -- Honk is a sumcheck-based zk-SNARK protocol with blazing-fast zk proof construction. We need Honk to allow users to prove correct execution of complicated, multi-step computations using recursion in a resource constraint environment like a cell phone. This is necessary for our mission, because we need to make sure our users' sensitive information never leaves their devices! -- List of Honk projects - - Completed: basic Honk prover and verifier with respectable construction and verification speeds, but no optimization. - - Upcoming: - - Bringing "Ultra" functionality to Honk: lookup tables, efficient range constraints, RAM, ROM, and more will result in orders-of-magnitude improvements to Honk's prover times. - - Recursion using cycles of curves will allow for efficient recursive verification of Honk proofs. Using this technique will lower the barrier to entry of our rollup providers, resulting in a more robust set of providers and greater security for the Aztec network. +Honk is a sumcheck-based zk-SNARK protocol with blazing-fast zk proof construction. We need Honk to allow users to prove correct execution of complicated, multi-step computations using recursion in a resource constraint environment like a cell phone. This is necessary for our mission, because we need to make sure our users' sensitive information never leaves their devices! -## Goblin projects +List of Honk projects: -- Goblin is a deferred verification framework thats allow for an order-of-magnitude increase in the complexity of computations that Aztec users can execute with full privacy. This corresponds to a 10x increase in the expressivity of Noir programs that can be run in practice without melting anybody's favorite phone or laptop. +- Completed: basic Honk prover and verifier with respectable construction and verification speeds, but no optimization. +- Upcoming: + - Bringing "Ultra" functionality to Honk: lookup tables, efficient range constraints, RAM, ROM, and more will result in orders-of-magnitude improvements to Honk's prover times. + - Recursion using cycles of curves will allow for efficient recursive verification of Honk proofs. Using this technique will lower the barrier to entry of our rollup providers, resulting in a more robust set of providers and greater security for the Aztec network. -Read more here. https://hackmd.io/@aztec-network/B19AA8812 +## Goblin projects -- List of Goblin projects - - Aside from some prototype code by Zac, we have not begun working on this yet. +Goblin is a deferred verification framework thats allow for an order-of-magnitude increase in the complexity of computations that Aztec users can execute with full privacy. This corresponds to a 10x increase in the expressivity of Noir programs that can be run in practice without melting anybody's favorite phone or laptop. Read more [here](https://hackmd.io/@aztec-network/B19AA8812). diff --git a/docs/docs/about_aztec/roadmap/features_initial_ldt.md b/docs/docs/about_aztec/roadmap/features_initial_ldt.md index 7b7f96d40d8..228cb2ee72a 100644 --- a/docs/docs/about_aztec/roadmap/features_initial_ldt.md +++ b/docs/docs/about_aztec/roadmap/features_initial_ldt.md @@ -1,87 +1,16 @@ --- -title: Initial Sandbox Features +title: Sandbox Features --- -import Disclaimer from "../../misc/common/\_disclaimer.mdx"; - - - -The Aztec Sandbox is intended to provide developers with a lightweight & fast node, with features similar to Ethereum's Ganache or Anvil 'local node' packages. +The Aztec Sandbox is intended to provide developers with a lightweight and fast local node. Developers should be able to quickly spin up local, emulated instances of an Ethereum blockchain and an Aztec encrypted rollup, and start deploying private contracts and submitting private txs. -Here's a summary of the features we intend to support with the first release of the Aztec Sandbox. - -## Aztec.nr Contracts - -See the source on Github [here](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec-nr). - -- Noir `contract` scopes. - - Declare a `contract`, containing a collection of state variables and functions. -- private state variables: - - `read`, `write`, and `delete` private state variables within private functions. -- public (non-private) state variables: - - Manipulate 'public' state in a familiar way to Ethereum state. -- private functions - - May read and modify private state. -- public functions - - May read and modify public state. -- `constructor` functions, for initialising contract state. -- `import` other Aztec.nr contracts, so their functions may be called. -- Nested function calls, for contract composability - - private functions can call private functions of other contracts, and receive return values. - - private functions can call public functions any contract. - - public functions can call private functions of any contract. - - public functions can call public functions of other contracts, and receive return values. - - private functions can be called recursively. - - public functions can be called recursively. -- Send messages from Aztec.nr contracts to Ethereum L1, for consumption by L1 smart contracts. - - Useful, for example, if writing an app to withdraw funds from L2 to L1. -- Consume messages which have been sent by: - - L1 functions. - - Useful, for example, if writing an app to deposit funds from L1 to L2. - - public L2 functions. -- Emit `event` data from a Aztec.nr Contract. - - Allows applications to subscribe to events which have been emitted by a Aztec.nr contract's functions, for example. -- Write `unconstrained` functions. - - These allow developers to write `pure` and `view` functions, which can perform calculations and retrieve state. E.g. for fetching contract-specific information, which may then be consumed by a dapp, without having to generate a zero-knowledge proof or interact with the 'network'. - -## `aztec.js` - -A typescript wrapper for making RPC calls to an Aztec Sandbox node. See the source on Github [here](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec.js). - -- Similar in purpose to `web3.js`/`ethers.js`/`viem`, but for interacting with Aztec Network nodes. The RPC interface for an Aztec node is necessarily different from that of an Ethereum node, because it deals with encrypted transactions and state variables. -- A library for public/private key management. -- Construct `Contract` instances from a Aztec.nr contract's JSON artifact. -- Deploy new contracts to the Aztec Sandbox. -- Construct tx requests, passing arguments to a function of a contract. -- Sign tx requests. -- Send txs to the Sandbox node, for simulating. -- Send txs to the Sandbox node, to be sent to the Sandbox network. -- Call `unconstrained` functions of a Aztec.nr contract, to perform `pure` calculations or retrieve state. - -## Aztec Sandbox Node - -A bundle of packages which emulate the actions of all eventual Aztec network participants. The goal is for developer experience to be akin to Ganache / Anvil. +The sandbox allows developers to: -- PXE client - - Simulate and/or execute private functions locally. -- Aztec Public Node - - Broadcasts a user's txs to the tx pool. - - Simulate public functions locally. -- Tx Pool - - An in-memory emulation of a tx pool. By default, a user's txs will be rolled-up into an L2 block immediately. -- Sequencer Node - - Reads the tx pool and bundles pending txs into a rollup block immediately. - - Orders txs. - - Executes public functions. - - Passes messages between L1 and L2. -- L1 Rollup smart contract - - Verifies the rollup's snark. - - Reconciles calldata with snark public inputs. - - Updates the rollup's state hash. -- L1 data archiver - - Gobbles up and stores all calldata, events, and state changes from L1 -- World state DB - - Reconstructs the Aztec Network's various trees. - - Allows tree state to be queried. +- Write and deploy Aztec contracts +- Leverage private and public state variables in contracts +- Write private and public functions in contracts +- Call private and public functions on other Aztec contracts (contract composability) +- Send messages between Aztec and Ethereum contracts +- Interact with the Aztec network using a familiar Typescript SDK ([aztec.js](https://github.com/AztecProtocol/aztec-packages/tree/master/yarn-project/aztec.js)) diff --git a/docs/docs/about_aztec/roadmap/main.md b/docs/docs/about_aztec/roadmap/main.md index 5e8f320137b..587f8751d6e 100644 --- a/docs/docs/about_aztec/roadmap/main.md +++ b/docs/docs/about_aztec/roadmap/main.md @@ -1,5 +1,14 @@ +--- +title: Roadmap +--- + import DocCardList from '@theme/DocCardList'; +import Image from '@theme/IdealImage'; + +The next major milestone on the journey to mainnet is launching our testnet. + + -# Roadmap +## Read more diff --git a/docs/docs/concepts/advanced/circuits/kernels/private_kernel.md b/docs/docs/concepts/advanced/circuits/kernels/private_kernel.md index 405a6163061..cc0632c986f 100644 --- a/docs/docs/concepts/advanced/circuits/kernels/private_kernel.md +++ b/docs/docs/concepts/advanced/circuits/kernels/private_kernel.md @@ -21,5 +21,5 @@ This circuit is executed by the user, on their own device. This is to ensure pri - Verifies a previous 'Private Kernel Proof', recursively, when verifying transactions which are composed of many private function calls. - Optionally can [deploy](../../contract_creation) a new private contract. -> Note: **This is the only core protocol circuit which actually needs to be "zk" (zero knowledge)!!!** That's because this is the only core protocol circuit which handles private data, and hence the only circuit for which proofs must not leak any information about witnesses! (The private data being handled includes: details of the Aztec.nr Contract function which has been executed; the address of the user who executed the function; the intelligible inputs and outputs of that function). -> This is a really interesting point. Most so-called "zk-Rollups" do not make use of this "zero knowledge" property. Their snarks are "snarks"; with no need for zero-knowledge, because they don't seek privacy; they only seek the 'succinct' computation-compression properties of snarks. Aztec's "zk-Rollup" actually makes use of "zero knowledge" snarks. That's why we sometimes call it a "zk-zk-Rollup", or "_actual_ zk-Rollup". +> Note: **This is the only core protocol circuit which actually needs to be "zk" (zero-knowledge)!!!** That's because this is the only core protocol circuit which handles private data, and hence the only circuit for which proofs must not leak any information about witnesses! (The private data being handled includes: details of the Aztec.nr Contract function which has been executed; the address of the user who executed the function; the intelligible inputs and outputs of that function). +> This is a really interesting point. Most so-called "zk-Rollups" do not make use of this "zero-knowledge" property. Their snarks are "snarks"; with no need for zero-knowledge, because they don't seek privacy; they only seek the 'succinct' computation-compression properties of snarks. Aztec's "zk-Rollup" actually makes use of "zero-knowledge" snarks. That's why we sometimes call it a "zk-zk-Rollup", or "_actual_ zk-Rollup". diff --git a/docs/docs/concepts/advanced/circuits/main.md b/docs/docs/concepts/advanced/circuits/main.md index 3f21cb79053..9a84f9cf60b 100644 --- a/docs/docs/concepts/advanced/circuits/main.md +++ b/docs/docs/concepts/advanced/circuits/main.md @@ -2,6 +2,12 @@ title: Circuits --- +Central to Aztec's operations are 'circuits' derived both from the core protocol and the developer-written Aztec.nr contracts. + +The core circuits enhance privacy by adding additional security checks and preserving transaction details - a characteristic Ethereum lacks. + +On this page, you’ll learn a bit more about these circuits and their integral role in promoting secure and efficient transactions within Aztec's privacy-centric framework. + ## Motivation In Aztec, circuits come from two sources: diff --git a/docs/docs/concepts/advanced/data_structures/indexed_merkle_tree.md b/docs/docs/concepts/advanced/data_structures/indexed_merkle_tree.md index 927a4e6a387..751b209dc9b 100644 --- a/docs/docs/concepts/advanced/data_structures/indexed_merkle_tree.md +++ b/docs/docs/concepts/advanced/data_structures/indexed_merkle_tree.md @@ -3,17 +3,24 @@ title: Indexed Merkle Tree --- import Image from "@theme/IdealImage"; -import Disclaimer from "../../../misc/common/\_disclaimer.mdx"; - +## Overview -## Indexed Merkle Trees +This article will introduce the concept of an indexed merkle tree, and how it can be used to improve the performance of nullifier trees in circuits. -This article will introduce the concept of an indexed merkle tree, and how it can be used to improve the performance of nullifier trees in circuits. The content was also covered in a presentation for the [Privacy + Scaling Explorations team at the Ethereum Foundation](https://pse.dev/). +This page will answer: + +- Why we need nullifier trees at all +- How indexed merkle trees work +- How they can be used for membership exclusion proofs +- How they can leverage batch insertions +- Tradoffs of using indexed merkle trees + +The content was also covered in a presentation for the [Privacy + Scaling Explorations team at the Ethereum Foundation](https://pse.dev/). -#### Primer on Nullifier Trees +## Primer on Nullifier Trees Currently the only feasible way to get privacy in public blockchains is via a UTXO model. In this model, state is stored in encrypted UTXO's in merkle trees. However, to maintain privacy, state can not be updated. The very act of performing an update leaks information. In order to simulate "updating" the state, we "destroy" old UTXO's and create new ones for each state update. Resulting in a merkle tree that is append-only. diff --git a/docs/docs/concepts/advanced/data_structures/trees.md b/docs/docs/concepts/advanced/data_structures/trees.md index ad801b6a051..97d11cc22e0 100644 --- a/docs/docs/concepts/advanced/data_structures/trees.md +++ b/docs/docs/concepts/advanced/data_structures/trees.md @@ -2,10 +2,18 @@ title: Trees --- -import Disclaimer from "../../../misc/common/\_disclaimer.mdx"; import Image from "@theme/IdealImage"; - +## Overview + +Data trees are how we keep track of all the data in the network. Each type of data is stored in it's own data tree. Different tree structures are used for different kinds of data, as the requirements for each are different. + +Data includes: + +- Private state +- Nullifiers to invalidate old private state +- Public state +- Contracts ## Private State Tree @@ -17,7 +25,7 @@ Any function of any Aztec contract may insert new leaves into the this tree. Once inserted into this tree, a leaf's value can never be modified. We enforce this, to prevent linkability of transactions. If an observer sees that 'tx A' inserted a leaf and 'tx B' modified that leaf, then the observer knows these two transactions are related in some way. This is a big 'no no' if we want to ensure privacy. -So, if an app needs to edit a private state variable (which will be represented by one or more leaves in the tree), it may do so in a manner inspired by [zerocash](http://zerocash-project.org/media/pdf/zerocash-extended-20140518.pdf). (See Nullifier Tree, further down this page). This allows the leaf to be 'nullified' and a new leaf value inserted into the next empty position in the tree, in a way which prevents observers from linking the old and new leaves. +So, if an app needs to edit a private state variable (which will be represented by one or more leaves in the tree), it may do so in a manner inspired by [zerocash](http://zerocash-project.org/media/pdf/zerocash-extended-20140518.pdf). (See [Nullifier Tree](#nullifier-tree)). This allows the leaf to be 'nullified' and a new leaf value inserted into the next empty position in the tree, in a way which prevents observers from linking the old and new leaves. @@ -136,6 +144,6 @@ The contract tree contains information about every function of every contract de - `treeOfHistoricPrivateDataTreeRoots`: for membership checks against historic roots of the `privateDataTree` - `treeOfHistoricContractTreeRoots`: for membership checks against historic roots of the `contractTree` -## Trees of valid Kernel/Rollup circuit VKs +## Trees of valid Kernel/Rollup circuit Verification Keys -Eventually, we'll have trees of VKs for various permutations of kernel/rollup circuits. Such permutations might be the number of public inputs, or the logic contained within the circuits. +Eventually, we'll have trees of verification keys for various permutations of kernel/rollup circuits. Such permutations might be the number of public inputs, or the logic contained within the circuits. diff --git a/docs/docs/concepts/foundation/accounts/main.md b/docs/docs/concepts/foundation/accounts/main.md index 26f9c234a27..5f6b1cf8595 100644 --- a/docs/docs/concepts/foundation/accounts/main.md +++ b/docs/docs/concepts/foundation/accounts/main.md @@ -2,13 +2,21 @@ **Every account in Aztec is a smart contract** which defines the rules for whether a transaction is or is not valid. This allows implementing different schemes for transaction signing, nonce management, and fee payments. However, encryption and nullifying keys, which are specific to private blockchains, are still enshrined at the protocol level. +In this section, you’ll learn about how Aztec defines AA (account abstraction) and its correlation with encryption keys and nullifying keys. We’ll go through: + +- The importance and implications of AA +- Understanding account contracts and wallets in relation to Aztec +- Concept of authorization and actions along with encryption +- The future of fee management in Aztec + ## Background We'll start with the mandatory "what is AA" section that every single article on the topic has, so you can skip this if you're familiar with the topic. ### What is account abstraction? -We'll refer to AA as the _ability to set the validity conditions of a transaction programmatically_ ([source](https://fuel-labs.ghost.io/account-abstraction-for-everyone-else/)). [Starknet](https://docs.starknet.io/documentation/architecture_and_concepts/Account_Abstraction/introduction/#account_abstraction) goes one step further and splits AA into three different components: +We'll refer to AA as the _ability to set the validity conditions of a transaction programmatically_ ([source](https://fuel-labs.ghost.io/account-abstraction-for-everyone-else/)). [Starknet](https://docs.starknet.io/documentation/architecture_and_concepts/Account_Abstraction/introduction/#account_abstraction) goes one step further and splits AA into three different components: + - Signature abstraction (defining when a signature is accepted) - Fee abstraction (paying fees) - Nonce abstraction (replay protection and ordering) @@ -19,7 +27,7 @@ The benefits of AA are multiple. We're not going to reiterate them all here, but ### Implementing at protocol vs application layer -Instead of implementing it at the protocol level as in Aztec, account abstraction can be implemented at the application layer of a network using smart accounts and meta-transactions. When implementing account abstraction on Ethereum, the transaction being sent to the network is still an Ethereum transaction, but its payload is interpreted as a "transaction execution request" that is validated and run by the smart contract wallet. +Instead of implementing it at the protocol level as in Aztec, account abstraction can be implemented at the application layer of a network using smart accounts and meta-transactions. When implementing account abstraction on Ethereum, the transaction being sent to the network is still an Ethereum transaction, but its payload is interpreted as a "transaction execution request" that is validated and run by the smart contract wallet. A simple example would be Gnosis Safe (see [_Account Abstraction is NOT coming_](https://safe.mirror.xyz/9KmZjEbFkmI79s28d9xar6JWYrE50F5AHpa5CR12YGI)), where it's the multisig contract responsibility to define when an execution request is valid by checking it carries N out of M signatures, and then executing it. [Argent](https://www.argent.xyz/blog/wtf-is-account-abstraction/) has also been working on smart wallets for years, and collaborating with network teams to implement AA natively at the protocol layer. @@ -50,11 +58,11 @@ def entryPoint(payload): let { privateCalls, publicCalls, nonce, signature } = payload; let payloadHash = hash(privateCalls, publicCalls, nonce); validateSignature(this.publicKey, signature, payloadHash); - + foreach privateCall in privateCalls: let { to, data, value } = privateCall; call(to, data, value); - + foreach publicCall in publicCalls: let { to, data, value, gasLimit } = publicCall; enqueueCall(to, data, value, gasLimit); @@ -90,11 +98,11 @@ A side-effect of not having nonces at the protocol level is that it is not possi Since the `entrypoint` interface is not enshrined, there is nothing that differentiates an account contract from an application one in the protocol. This means that a transaction can be initiated in any contract. This allows implementing functions that do not need to be called by any particular user and are just intended to advance the state of a contract. -As an example, we can think of a lottery contract, where at some point a prize needs to be paid out to its winners. This `pay` action does not require authentication and does not need to be executed by any user in particular, so anyone could submit a transaction that defines the lottery contract itself as `origin` and `pay` as entrypoint function. For an example implementation of a different use case, refer to the [`pokeable_token_contract`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/main.nr) in the repository. +As an example, we can think of a lottery contract, where at some point a prize needs to be paid out to its winners. This `pay` action does not require authentication and does not need to be executed by any user in particular, so anyone could submit a transaction that defines the lottery contract itself as `origin` and `pay` as entrypoint function. For an example implementation of a different use case, refer to the [`pokeable_token_contract`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/main.nr) in the repository. ### Account initialization -The protocol requires that every account is a contract for the purposes of sending a transaction. This means that a user needs to deploy their account contract as their first action when they want to interact with the network. +The protocol requires that every account is a contract for the purposes of sending a transaction. This means that a user needs to deploy their account contract as their first action when they want to interact with the network. However, this is not required when sitting on the receiving end. A user can deterministically derive their address from their encryption public key and the account contract they intend to deploy, and share this address with other users that want to interact with them _before_ they deploy the account contract. @@ -106,7 +114,7 @@ When executing a private function, this authorization is checked by requesting a The PXE is responsible for storing these auth witnesses and returning them to the requesting account contract. Auth witnesses can belong to the current user executing the local transaction, or to another user who shared it out-of-band. -However, during a public function execution, it is not possible to retrieve a value from the local oracle. To support authorizations in public functions, account contracts should save in contract storage what actions have been pre-authorized by their owner. +However, during a public function execution, it is not possible to retrieve a value from the local oracle. To support authorizations in public functions, account contracts should save in contract storage what actions have been pre-authorized by their owner. These two patterns combined allow an account contract to answer whether an action `is_valid` for a given user both in private and public contexts. @@ -122,4 +130,4 @@ NOTE: While we entertained the idea of abstracting note encryption, where accoun Fees are not implemented in the protocol at the time of this writing. Our goal is to abstract fee payments as well. This means that a transaction, in order to be considered valid, must prove that it has locked enough funds to pay for itself. However, this does not mandate where those funds come from, opening the door for easy implementation of paymasters or payment-in-kind via on-the-fly swaps. -However, there is one major consideration around public execution reverts. In the current design, if one of the public function executions enqueued in a transaction fails, then the entire transaction is reverted. But reverting the whole transaction would also revert the fee payment, and leave the sequencer with their hands empty after running the public execution. This means we will need to enshrine an initial verification and fee payment phase that is _not_ reverted if public execution fails. \ No newline at end of file +However, there is one major consideration around public execution reverts. In the current design, if one of the public function executions enqueued in a transaction fails, then the entire transaction is reverted. But reverting the whole transaction would also revert the fee payment, and leave the sequencer with their hands empty after running the public execution. This means we will need to enshrine an initial verification and fee payment phase that is _not_ reverted if public execution fails. diff --git a/docs/docs/concepts/foundation/communication/cross_chain_calls.md b/docs/docs/concepts/foundation/communication/cross_chain_calls.md index abd37f84fcf..f05bba66484 100644 --- a/docs/docs/concepts/foundation/communication/cross_chain_calls.md +++ b/docs/docs/concepts/foundation/communication/cross_chain_calls.md @@ -8,7 +8,18 @@ import Disclaimer from "../../../misc/common/\_disclaimer.mdx"; -In the following section, we will look at cross-chain communication, mixing L1 and L2 for composability and profits. +In Aztec, what we call _portals_ are the key element in facilitating communication between L1 and L2. While typical L2 solutions rely on synchronous communication with L1, Aztec's privacy-first nature means this is not possible. You can learn more about why in the previous section. + +Traditional L1<>L2 communication might involve direct calls between L2 nd L1 contracts. However, in Aztec, due to the privacy components and the way transactions are processed (kernel proofs built on historical data), direct calls between L1 and L2 would not be possible if we want to maintain privacy. + +Portals are the solution to this problem, acting as bridges for communication between the two layers. These portals can transmit messages from public functions in L1 to private functions in L2 and vice versa, thus enabling messaging while maintaining privacy. + +This page covers: + +- How portals enable privacy communication between L1 and L2 +- How messages are sent, received, and processed +- Message Boxes and how they work +- How and why linking of contracts between L1 and L2 occurs # Objective diff --git a/docs/docs/concepts/foundation/communication/public_private_calls.md b/docs/docs/concepts/foundation/communication/public_private_calls.md index 32b42b091dd..d175f149569 100644 --- a/docs/docs/concepts/foundation/communication/public_private_calls.md +++ b/docs/docs/concepts/foundation/communication/public_private_calls.md @@ -8,7 +8,14 @@ import Disclaimer from "../../../misc/common/\_disclaimer.mdx"; -The following section will try to outline what _private_ and _public_ functions can do, and give some intuition to why they have the limitations they have. +Aztec operates on a model of private and public functions that are able to work together. Private functions work by providing evidence of correct execution generated locally through kernel proofs. Public functions, on the other hand, are able to utilize the latest state to manage updates and perform alterations. + +On this page, you’ll learn: + +- How private and public functions work +- The role of public functions in managing state alterations and updates +- Communication and interactions between private and public functions +- How the sequencer manages the order of operations of private functions ### Objectives diff --git a/docs/docs/concepts/foundation/contracts.md b/docs/docs/concepts/foundation/contracts.md index 49321bcb9ed..0c976da2a66 100644 --- a/docs/docs/concepts/foundation/contracts.md +++ b/docs/docs/concepts/foundation/contracts.md @@ -2,6 +2,17 @@ title: Smart Contracts --- +Smart contracts in Aztec are privacy-first, and can include both public and private elements. They are written in Noir framework called Aztec.nr, and allow high-level programs to be convered into ZK circuits. + +On this page, you’ll learn how Aztec executes smart contracts for privacy and efficiency: + +- Role and structure of smart contracts within Aztec +- Intro into Noir programming language and how it converts to circuits +- The Aztec Kernel +- Transaction flow and confidentiality + +## Defining Aztec smart contracts + A "smart contract" is defined as a set of public and private functions written as Noir circuits. These functions operate on public and private state stored by a contract. Each function is represented as a ZK SNARK verification key, where the contract is uniquely described by the set of its verification keys, and stored in the Aztec Contracts tree. [Noir](https://noir-lang.org) is a programming language designed for converting high-level programs into ZK circuits. Based on Rust, the goal is to present an idiomatic way of writing private smart contracts that is familiar to Ethereum developers. Noir is under active development adding features such as contracts, functions and storage variables. diff --git a/docs/docs/concepts/foundation/state_model.md b/docs/docs/concepts/foundation/state_model.md index 1ecc52700bb..b02aefaf4bb 100644 --- a/docs/docs/concepts/foundation/state_model.md +++ b/docs/docs/concepts/foundation/state_model.md @@ -12,6 +12,18 @@ Internal to the Aztec network, public state is stored and updated by the sequenc ## Private State +Every smart contract needs a way to track information over time - that's what state is. In order to have both private and public transactions and storage in Aztec, we have to have public and private state. + +On this page, you’ll learn + +- Aztec's unique interpretation of private state +- Representation of private state in an append-only database +- Concept of 'deleting' private state variables using nullifiers +- How to modify private state +- How Aztec abstracts the UTXO model from developers + +## Private State on Aztec + Private state must be treated differently from public state and this must be expressed in the semantics of Aztec.nr. Private state is encrypted and therefore is "owned" by a user or a set of users (via shared secrets) that are able to decrypt the state. diff --git a/docs/docs/concepts/foundation/transactions.md b/docs/docs/concepts/foundation/transactions.md index 5b5974802fa..7e44497ae07 100644 --- a/docs/docs/concepts/foundation/transactions.md +++ b/docs/docs/concepts/foundation/transactions.md @@ -2,6 +2,15 @@ title: Transactions --- +Transactions on Aztec start with a call from Aztec.js or the Aztec CLI, which creates a request containing transaction details. This request moves to the Private Execution Environment (PXE) which simulates and processes it. Then the PXE interacts with the Aztec Node which uses the sequencer to ensure that all the transaction details are enqueued properly. The sequencer then submits the block to the rollup contract, and the transaction is successfully mined. + +On this page you'll learn: + +- The step-by-step process of sending a transaction on Aztec +- The role of components like PXE, Aztec Node, ACIR simulator, and the sequencer +- The Aztec Kernel and its two circuits: private and public, and how they execute function calls +- The call stacks for private & public functions and how they determine a transaction's completion + Sending a transaction See [this diagram](https://raw.githubusercontent.com/AztecProtocol/aztec-packages/2fa143e4d88b3089ebbe2a9e53645edf66157dc8/docs/static/img/sandbox_sending_a_tx.svg) for an in-depth overview of the transaction execution process. It highlights 3 different types of transaction execution: contract deployments, private transactions and public transactions. diff --git a/docs/docs/dev_docs/contracts/portals/main.md b/docs/docs/dev_docs/contracts/portals/main.md index a7b7340f17c..3d1448e8941 100644 --- a/docs/docs/dev_docs/contracts/portals/main.md +++ b/docs/docs/dev_docs/contracts/portals/main.md @@ -5,9 +5,9 @@ description: Documentation of Aztec's Portals and Cross-chain communication. ## What is a portal -A portal is the point of contact between L1 and a specific contract on Aztec. For applications such as token bridges, this is the point where the tokens are held on L1 while used in L2. +A portal is the point of contact between L1 and a specific contract on Aztec. For applications such as token bridges, this is the point where the tokens are are held on L1 while used in L2. -As outlined in the [foundational concepts](../../../concepts/foundation/communication/cross_chain_calls.md), an Aztec L2 contract is linked to *ONE* L1 address at time of deployment (specified by the developer). This L1 address is the only address that can send messages to that specific L2 contract, and the only address that can receive messages sent from the L2 contract to L1. Note, that a portal doesn't actually need to be a contract; a portal could be any address on L1. We say that an Aztec contract is attached to a portal. +As outlined in the [foundational concepts](../../../concepts/foundation/communication/cross_chain_calls.md), an Aztec L2 contract is linked to _ONE_ L1 address at time of deployment (specified by the developer). This L1 address is the only address that can send messages to that specific L2 contract, and the only address that can receive messages sent from the L2 contract to L1. Note, that a portal don't actually need to be a contract, it could be any address on L1. We say that an Aztec contract is attached to a portal. ## Passing data to the rollup @@ -17,24 +17,25 @@ The `Inbox` can be seen as a mailbox to the rollup, portals put messages into th When sending messages, we need to specify quite a bit of information beyond just the content that we are sharing. Namely we need to specify: -| Name | Type | Description | -| -------------- | ------- | ----------- | -| Recipient | `L2Actor` | The message recipient. This **MUST** match the rollup version and an Aztec contract that is **attached** to the contract making this call. If the recipient is not attached to the caller, the message cannot be consumed by it. | -| Deadline | `uint256` | The deadline for the message to be consumed. If the message has not been removed from the `Inbox` and included in a rollup block by this point, it can be *cancelled* by the portal (the portal must implement logic to cancel). | -| Content | `field` (~254 bits) | The content of the message. This is the data that will be passed to the recipient. The content is limited to be a single field. If the content is small enough it can just be passed along, otherwise it should be hashed and the hash passed along (you can use our [`Hash`](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/libraries/Hash.sol) utilities with `sha256ToField` functions) | -| Secret Hash | `field` (~254 bits) | A hash of a secret that is used when consuming the message on L2. Keep this preimage a secret to make the consumption private. To consume the message the caller must know the pre-image (the value that was hashed) - so make sure your app keeps track of the pre-images! Use the [`computeMessageSecretHash`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec.js/src/utils/secrets.ts) to compute it from a secret. | -| Fee | `uint64` | The fee to the sequencer for including the message. This is the amount of ETH that the sequencer will receive for including the message. Note that it is not a full `uint256` but only `uint64`| +| Name | Type | Description | +| ----------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Recipient | `L2Actor` | The message recipient. This **MUST** match the rollup version and an Aztec contract that is **attached** to the contract making this call. If the recipient is not attached to the caller, the message cannot be consumed by it. | +| Deadline | `uint256` | The deadline for the message to be consumed. If the message has not been removed from the `Inbox` and included in a rollup block by this point, it can be _cancelled_ by the portal (the portal must implement logic to cancel). | +| Content | `field` (~254 bits) | The content of the message. This is the data that will be passed to the recipient. The content is limited to be a single field. If the content is small enough it can just be passed along, otherwise it should be hashed and the hash passed along (you can use our [`Hash`](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/libraries/Hash.sol) utilities with `sha256ToField` functions) | +| Secret Hash | `field` (~254 bits) | A hash of a secret that is used when consuming the message on L2. Keep this preimage a secret to make the consumption private. To consume the message the caller must know the pre-image (the value that was hashed) - so make sure your app keeps track of the pre-images! Use the [`computeMessageSecretHash`](https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/aztec.js/src/utils/secrets.ts) to compute it from a secret. | +| Fee | `uint64` | The fee to the sequencer for including the message. This is the amount of ETH that the sequencer will receive for including the message. Note that it is not a full `uint256` but only `uint64` | -With all that information at hand, we can call the `sendL2Message` function on the Inbox. The function will return a `field` (inside `bytes32`) that is the hash of the message. This hash can be used as an identifier to spot when your message has been included in a rollup block. +With all that information at hand, we can call the `sendL2Message` function on the Inbox. The function will return a `field` (inside `bytes32`) that is the hash of the message. This hash can be used as an identifier to spot when your message has been included in a rollup block. #include_code send_l1_to_l2_message l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity As time passes, a sequencer will see your tx, the juicy fee provided and include it in a rollup block. Upon inclusion, it is removed from L1, and made available to be consumed on L2. -To consume the message, we can use the `consume_l1_to_l2_message` function within the `context` struct. -- The `msg_key` is the hash of the message returned by the `sendL2Message` call and is used to help the RPC find the correct message. -- The `content` is the content of the message, limited to one Field element. For content larger than one Field, we suggest using the `sha256` hash function truncated to a single Field element. `sha256` is suggested as it is cheap on L1 while still being managable on L2. -- The `secret` is the pre-image hashed using Pedersen to compute the `secretHash`. +To consume the message, we can use the `consume_l1_to_l2_message` function within the `context` struct. + +- The `msg_key` is the hash of the message returned by the `sendL2Message` call and is used to help the RPC find the correct message. +- The `content` is the content of the message, limited to one Field element. For content larger than one Field, we suggest using the `sha256` hash function truncated to a single Field element. `sha256` is suggested as it is cheap on L1 while still being managable on L2. +- The `secret` is the pre-image hashed using Pedersen to compute the `secretHash`. - If the `content` or `secret` does not match the entry at `msg_key` the message will not be consumed, and the transaction will revert. :::info @@ -69,17 +70,17 @@ Since the message consumption is emitting a nullifier the same message cannot be To pass data to L1, we use the `Outbox`. The `Outbox` is the mailbox for L2 to L1 messages. This is the location on L1 where all the messages from L2 will live, and where they can be consumed from. -Similarly to messages going to L2 from L1, a message can only be consumed by the recipient, however note that it is up to the portal contract to ensure that the sender is as expected! +Similarly to messages going to L2 from L1, a message can only be consumed by the recipient, however note that it is up to the portal contract to ensure that the sender is as expected! Recall that we mentioned the Aztec contract specifies what portal it is attached to at deployment. This value is stored in the rollup's contract tree, hence these links are not directly readable on L1. Also, it is possible to attach multiple aztec contracts to the same portal. The portal must ensure that the sender is as expected. One way to do this is to compute the addresses before deployment and store them as constants in the contract. However, a more flexible solution is to have an `initialize` function in the portal contract which can be used to set the address of the Aztec contract. In this model, the portal contract can check that the sender matches the value it has in storage. -To send a message to L1 from your Aztec contract, you must use the `message_portal` function on the `context`. When messaging to L1, only the `content` is required (as a `Field`). +To send a message to L1 from your Aztec contract, you must use the `message_portal` function on the `context`. When messaging to L1, only the `content` is required (as a `Field`). #include_code context_message_portal /yarn-project/aztec-nr/aztec/src/context.nr rust -When sending a message from L2 to L1 we don't need to pass recipient, deadline, secret nor fees. Recipient is populated with the attached portal and the remaining values are not needed as the message is inserted into the outbox at the same time as it was included in a block (for the inbox it could be inserted and then only included in rollup block later). +When sending a message from L2 to L1 we don't need to pass recipient, deadline, secret nor fees. Recipient is populated with the attached portal and the remaining values are not needed as the message is inserted into the outbox at the same time as it was included in a block (for the inbox it could be inserted and then only included in rollup block later). :::danger Access control on the L1 portal contract is essential to prevent consumption of messages sent from the wrong L2 contract. @@ -99,36 +100,38 @@ As noted earlier, the portal contract should check that the sender is as expecte #include_code token_portal_withdraw l1-contracts/test/portals/TokenPortal.sol solidity - ## How to deploy a contract with a portal + - Deploy to L1 using Viem, Foundry or your preferred tool; - Deploy to L2 passing in the address of the L1 portal as its portal contract; ```typescript - const deploymentTx = Contract.deploy(wallet).send({portalContract: tokenPortalAddress}); + const deploymentTx = Contract.deploy(wallet).send({ + portalContract: tokenPortalAddress, + }); ``` - Initialize l1 with l2 address for access control. - ## Considerations ### Structure of messages -The application developer should consider creating messages that follow a function call structure e.g., using a function signature and arguments. This will make it easier to prevent producing messages that could be misinterpreted by the recipient. -An example of a bad format would be using `amount, token_address, recipient_address` as the message for a withdraw function and `amount, token_address, on_behalf_of_address` for a deposit function. Any deposit could then also be mapped to a withdraw or vice versa. +The application developer should consider creating messages that follow a function call structure e.g., using a function signature and arguments. This will make it easier to prevent producing messages that could be misinterpreted by the recipient. -```solidity +An example of a bad format would be using `amount, token_address, recipient_address` as the message for a withdraw function and `amount, token_address, on_behalf_of_address` for a deposit function. Any deposit could then also be mapped to a withdraw or vice versa. + +```solidity // Don't to this! bytes memory message = abi.encode( - _amount, - _token, + _amount, + _token, _to ); // Do this! bytes memory message abi.encodeWithSignature( - "withdraw(uint256,address,address)", - _amount, - _token, + "withdraw(uint256,address,address)", + _amount, + _token, _to ); ``` @@ -157,7 +160,7 @@ As this requires logic on the portal itself, it is not something that the protoc The portal can call the `cancelL2Message` at the `Inbox` when `block.timestamp > deadline` for the message. -#include_code pending_l2_cancel l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity +#include_code pending_l2_cancel l1-contracts/src/core/interfaces/messagebridge/IInbox.sol solidity Building on our token example from earlier, this can be called like: @@ -166,26 +169,28 @@ Building on our token example from earlier, this can be called like: The example above ensure that the user can cancel their message if it is underpriced. ### Designated caller + Designating a caller grants the ability to specify who should be able to call a function that consumes a message. This is useful for ordering of batched messages. -When performing multiple cross-chain calls in one action it is important to consider the order of the calls. Say for example, that you want to perform a uniswap trade on L1 because you are a whale and slippage on L2 is too damn high. +When performing multiple cross-chain calls in one action it is important to consider the order of the calls. Say for example, that you want to perform a uniswap trade on L1 because you are a whale and slippage on L2 is too damn high. -Practically, you would withdraw funds from the rollup, swap them on L1, and then deposit the swapped funds back into the rollup. This is a fairly simple process, but it requires that the calls are done in the correct order. For one, if the swap is called before the funds are withdrawn, the swap will fail. And if the deposit is called before the swap, the funds might get lost! +You would practically, withdraw funds from the rollup, swap them on L1, and then deposit the swapped funds back into the rollup. This is a fairly simple process, but it requires that the calls are done in the correct order. For one, if the swap is called before the funds are withdrawn, the swap will fail. And if the deposit is called before the swap, the funds might get lost! As message boxes only will allow the recipient portal to consume the message, we can use this to our advantage to ensure that the calls are done in the correct order. Say that we include a designated "caller" in the messages, and that the portal contract checks that the caller matches the designated caller or designated is address(0) (anyone can call). When the message are to be consumed on L1, it can compute the message as seen below: ```solidity bytes memory message = abi.encodeWithSignature( - "withdraw(uint256,address,address)", - _amount, - _to, + "withdraw(uint256,address,address)", + _amount, + _to, _withCaller ? msg.sender : address(0) ); ``` This way, the message can be consumed by the portal contract, but only if the caller is the designated caller. By being a bit clever when specifying the designated caller, we can ensure that the calls are done in the correct order. For the Uniswap example, say that we have token portals implemented as we have done throughout this page, and a Uniswap portal implementing the designated caller. -We require that the Uniswap portal is the caller of the withdraw, and that the uniswap portal implementation is executing the withdraw before the swap. The order of execution can be constrained in the contract. Since all of the messages are emitted to L1 in the same transaction, we can leverage transaction atomicity to ensure success of failure of all messages. +We require that the Uniswap portal is the caller of the withdraw, and that the uniswap portal implementation is executing the withdraw before the swap. +The order of execution can be constrained in the contract. Since all of the messages are emitted to L1 in the same transaction, we can leverage transaction atomicity to ensure success of failure of all messages. Note, that crossing the L1/L2 chasm is asynchronous, so there could be a situation where the user has burned their assets on L2 but the swap fails on L1! This could be due to major price movements or the like. In such a case, the user could be stuck with funds on L1 that they cannot get back to L2 unless the portal contract implements a way to properly handle such errors. diff --git a/docs/docs/dev_docs/contracts/syntax/context.mdx b/docs/docs/dev_docs/contracts/syntax/context.mdx index e772b3866e2..bab10efeac7 100644 --- a/docs/docs/dev_docs/contracts/syntax/context.mdx +++ b/docs/docs/dev_docs/contracts/syntax/context.mdx @@ -9,12 +9,23 @@ import Image from "@theme/IdealImage"; # The Function Context ## What is the context -The context is an object that is made available within every function in `Aztec.nr`. As mentioned in the [kernel circuit documentation](../../../concepts/advanced/circuits/kernels/private_kernel.md). At the beginning of a function's execution, the context contains all of the kernel information that application needs to execute. During the lifecycle of a transaction, the function will update the context with each of it's side effects (created notes, nullifiers etc.). At the end of a function's execution the mutated context is returned to the kernel to be checked for validity. -Behind the scenes, Aztec noir will pass data the kernel needs to and from a circuit, this is abstracted away from the developer. In an developer's eyes; the context is a useful structure that allows access and mutate the state of the `Aztec` blockchain. +The context is an object that is made available within every function in `Aztec.nr`. As mentioned in the [kernel circuit documentation](../../../concepts/advanced/circuits/kernels/private_kernel.md). At the beginning of a function's execution, the context contains all of the kernel information that application needs to execute. During the lifecycle of a transaction, the function will update the context with each of it's side effects (created notes, nullifiers etc.). At the end of a function's execution the mutated context is returned to the kernel to be checked for validity. + +Behind the scenes, Aztec.nr will pass data the kernel needs to and from a circuit, this is abstracted away from the developer. In an developer's eyes; the context is a useful structure that allows access and mutate the state of the `Aztec` blockchain. + +On this page, you'll learn + +- The details and functionalities of the private context in Aztec.nr +- Difference between the private and public contexts and their unified APIs +- Components of the private context, such as inputs, historic block data, and contract deployment data +- Elements like return values, read requests, new commitments, and nullifiers in transaction processing +- Differences between the private and public contexts, especially the unique features and variables in the public context ## Two context's one API -The `Aztec` blockchain contains two environments [public and private](../../../concepts/foundation/state_model.md). + +The `Aztec` blockchain contains two environments [public and private](../../../concepts/foundation/state_model.md). + - Private, for private transactions taking place on user's devices. - Public, for public transactions taking place on the network's sequencers. @@ -28,7 +39,9 @@ The code snippet below shows what is contained within the private context. #include_code private-context /yarn-project/aztec-nr/aztec/src/context.nr rust ### Private Context Broken Down + #### Inputs + The context inputs includes all of the information that is passed from the kernel circuit into the application circuit. It contains the following values. #include_code private-context-inputs /yarn-project/aztec-nr/aztec/src/abi.nr rust @@ -41,82 +54,97 @@ First of all, the call context. The call context contains information about the current call being made: - 1. Msg Sender - - The message sender is the account (Aztec Contract) that sent the message to the current context. In the first call of the kernel circuit (often the account contract call), this value will be empty. For all subsequent calls the value will be the previous call. + - The message sender is the account (Aztec Contract) that sent the message to the current context. In the first call of the kernel circuit (often the account contract call), this value will be empty. For all subsequent calls the value will be the previous call. > The graphic below illustrates how the message sender changes throughout the kernel circuit iterations. + 2. Storage contract address - - This value is the address of the current context's contract address. This value will be the value of the current contract that is being executed except for when the current call is a delegate call (Warning: This is yet to be implemented). In this case the value will be that of the sending contract. -3. Portal Contract Address - - This value stores the current contract's linked [portal contract](../portals/main.md) address. As a quick recap, this value is the value of the contracts related ethereum l1 contract address, and will be the recipient of any messages that are created by this contract. + - This value is the address of the current context's contract address. This value will be the value of the current contract that is being executed except for when the current call is a delegate call (Warning: This is yet to be implemented). In this case the value will be that of the sending contract. + +3. Portal Contract Address + - This value stores the current contract's linked [portal contract](../portals/main.md) address. As a quick recap, this value is the value of the contracts related ethereum l1 contract address, and will be the recipient of any messages that are created by this contract. 4. Flags - - Furthermore there are a series of flags that are stored within the application context: - - is_delegate_call: Denotes whether the current call is a delegate call. If true, then the storage contract address will be the address of the sender. - - is_static_call: This will be set if and only if the current call is a static call. In a static call, state changing altering operations are not allowed. - - is_contract_deployment: This will be set if and only if the current call is the contract's constructor. + - Furthermore there are a series of flags that are stored within the application context: + - is_delegate_call: Denotes whether the current call is a delegate call. If true, then the storage contract address will be the address of the sender. + - is_static_call: This will be set if and only if the current call is a static call. In a static call, state changing altering operations are not allowed. + - is_contract_deployment: This will be set if and only if the current call is the contract's constructor. ### Historic Block Data -Another structure that is contained within the context is the Historic Block Data object. This object is a special one as it contains all of the roots of Aztec's data trees. + +Another structure that is contained within the context is the Historic Block Data object. This object is a special one as it contains all of the roots of Aztec's data trees. #include_code historic-block-data /yarn-project/aztec-nr/aztec/src/abi.nr rust ### Contract Deployment Data + Just like with the `is_contract_deployment` flag mentioned earlier. This data will only be set to true when the current transaction is one in which a contract is being deployed. #include_code contract-deployment-data /yarn-project/aztec-nr/aztec/src/abi.nr rust ### Private Global Variables + In the private execution context, we only have access to a subset of the total global variables, we are restricted to those which can be reliably proven by the kernel circuits. #include_code private-global-variables /yarn-project/aztec-nr/aztec/src/abi.nr rust ### Args Hash -To allow for flexibility in the number of arguments supported by Aztec functions, all function inputs are reduced to a singular value which can be proven from within the application. + +To allow for flexibility in the number of arguments supported by Aztec functions, all function inputs are reduced to a singular value which can be proven from within the application. The `args_hash` is the result of pedersen hashing all of a function's inputs. ### Return Values + The return values are a set of values that are returned from an applications execution to be passed to other functions through the kernel. Developers do not need to worry about passing their function return values to the `context` directly as `Aztec.nr` takes care of it for you. See the documentation surrounding `Aztec.nr` [macro expansion](./functions.md#after-expansion) for more details. return_values : BoundedVec, ### Read Requests + ### New Commitments + New commitments contains an array of all of the commitments created in the current execution context. ### New Nullifiers + New nullifiers contains an array of the new nullifiers emitted from the current execution context. ### Nullified Commitments + Nullified commitments is an optimization for introduced to help reduce state growth. There are often cases where commitments are created and nullified within the same transaction. In these cases there is no reason that these commitments should take up space on the node's commitment/nullifier trees. Keeping track of nullified commitments allows us to "cancel out" and prove these cases. ### Private Call Stack -The private call stack contains all of the external private function calls that have been created within the current context. Any function call objects are hashed and then pushed to the execution stack. + +The private call stack contains all of the external private function calls that have been created within the current context. Any function call objects are hashed and then pushed to the execution stack. The kernel circuit will orchestrate dispatching the calls and returning the values to the current context. ### Public Call Stack + The public call stack contains all of the external function calls that are created within the current context. Like the private call stack above, the calls are hashed and pushed to this stack. Unlike the private call stack, these calls are not executed client side. Whenever the function is sent to the network, it will have the public call stack attached to it. At this point the sequencer will take over and execute the transactions. ### New L2 to L1 msgs + New L2 to L1 messages contains messages that are delivered to the [l1 outbox](../../../concepts/foundation/communication/cross_chain_calls.md) on the execution of each rollup. ## Public Context + The Public Context includes all of the information passed from the `Public VM` into the execution environment. It is very similar to the [Private Context](#the-private-context), however it has some minor differences (detailed below). ### Public Context Inputs + In the current version of the system, the public context is almost a clone of the private execution context. It contains the same call context data, access to the same historic tree roots, however it does NOT have access to contract deployment data, this is due to traditional contract deployments only currently being possible from private transactions. #include_code public-context-inputs /yarn-project/aztec-nr/aztec/src/abi.nr rust - ### Public Global Variables + The public global variables are provided by the rollup sequencer and consequently contain some more values than the private global variables. #include_code public-global-variables /yarn-project/aztec-nr/aztec/src/abi.nr rust diff --git a/docs/docs/dev_docs/contracts/syntax/functions.md b/docs/docs/dev_docs/contracts/syntax/functions.md index c21ce8c56af..1c0868ba414 100644 --- a/docs/docs/dev_docs/contracts/syntax/functions.md +++ b/docs/docs/dev_docs/contracts/syntax/functions.md @@ -3,6 +3,17 @@ title: Functions description: This page covers functions, private and public functions composability, as well as their differences. --- +Functions serve as the building blocks of smart contracts. Functions can be either public, ie they can interact with other contracts and the blockchain, or private for internal contract use. Every smart contract also has a private `constructor` function which is called when the contract is deployed. There are also special oracle functions, which can get data from outside of the smart contract. In the context of Aztec, oracles are often used to get user-provided inputs. + +On this page, you’ll learn more about: + +- How function visibility works in Aztec +- A detailed understanding of public, private, and unconstrained functions, and how to write them +- How constructors work and remain private +- The process of calling functions from within the same smart contract and from different contracts, including calling private functions from private functions, public from public, and even private from public +- What oracles and how Aztec smart contracts might use them +- Built-in oracles + ## Visibility In Aztec there are multiple different types of visibility that can be applied to functions. Namely we have `data visibility` and `function visibility`. diff --git a/docs/docs/dev_docs/contracts/syntax/storage.md b/docs/docs/dev_docs/contracts/syntax/storage.md index 77ae0b61338..f6f011c3f57 100644 --- a/docs/docs/dev_docs/contracts/syntax/storage.md +++ b/docs/docs/dev_docs/contracts/syntax/storage.md @@ -2,12 +2,31 @@ title: Storage --- -In an Aztec.nr contract, storage is contained in a single struct that contains both public and private state variables. +Smart contracts rely on storage, acting as the persistent memory on the blockchain. In Aztec, because of its privacy-first architecture, the management of this storage can be a bit more complex. + +You control this storage in Aztec using the 'Storage' struct. This struct serves as the housing unit for all your smart contract's state variables - the data it needs to keep track of and maintain. + +These state variables come in two forms: public and private. Public variables are visible to anyone, and private variables remain hidden within the contract. + +Aztec.nr has a few abstractions to help define the type of data your contract holds. These include Singletons, ImmutableSingletons, Set, and Map. + +On this page, you’ll learn: + +- How to manage a smart contract's storage structure +- The distinctions and applications of public and private state variables +- How to use Singleton, ImmutableSingleton, Set, and Map +- An overview of 'notes' and the UTXO model +- Practical implications of Storage in real smart contracts + In an Aztec.nr contract, storage is to be defined as a single struct, that contains both public and private state variables. + +## Public and private state variables Public state variables can be read by anyone, while private state variables can only be read by their owner (or people whom the owner has shared the decrypted data/note viewing key with). Public state follows the ethereum style account model, where each contract has its own key-value datastore. Private state follows a UTXO model, where note contents (pre-images) are only known by the sender and those able to decrypt them - see ([state model](./../../../concepts/foundation/state_model.md) and [private/public execution](./../../../concepts/foundation/communication/public_private_calls.md)) for more background. +## Storage struct + :::info The struct **must** be called `Storage` for the Aztec.nr library to properly handle it (this will be relaxed in the future). ::: diff --git a/docs/docs/dev_docs/getting_started/quickstart.md b/docs/docs/dev_docs/getting_started/quickstart.md index b1abbf5b75e..b31f4cccd18 100644 --- a/docs/docs/dev_docs/getting_started/quickstart.md +++ b/docs/docs/dev_docs/getting_started/quickstart.md @@ -45,7 +45,7 @@ The current sandbox does not generate or verify proofs, but provides a working e - Node.js >= v18 (recommend installing with [nvm](https://github.com/nvm-sh/nvm)) - Docker and Docker Compose (Docker Desktop under WSL2 on windows) -## Installation +## Sandbox Installation You can run the Sandbox using either Docker or npm. @@ -79,7 +79,7 @@ You will also need an Ethereum node like Anvil or Hardhat running locally on por npx @aztec/aztec-sandbox ``` -### CLI +## CLI Installation To interact with the sandbox now that it's running locally, install the [Aztec CLI](https://www.npmjs.com/package/@aztec/cli): diff --git a/docs/docs/dev_docs/limitations/main.md b/docs/docs/dev_docs/limitations/main.md index d55bb375404..44a8e565989 100644 --- a/docs/docs/dev_docs/limitations/main.md +++ b/docs/docs/dev_docs/limitations/main.md @@ -12,7 +12,6 @@ The Aztec Sandbox and the Aztec Smart Contract Library are **prototypes**, and s - An 'unpolished' UX; - Missing information. - ## Why participate? Front-run the future! @@ -27,22 +26,23 @@ Help shape and define: - Core protocol improvements; ## Limitations developers need to know about + - 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/syntax/functions.md#constructor). + - 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/syntax/functions.md#constructor). - No static nor delegate calls (see [mutability](../contracts/syntax/functions.md#mutability)). - - These values are unused in the call-context. + - These values are unused in the call-context. - 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/syntax/context.mdx). - The initial `msg_sender` is 0, which can be problematic for some contracts, see [function visibility](../contracts/syntax/functions.md#function-visibility). -- Unencrypted logs don't link to the contract that emitted it, so essentially just a `debug_log`` that you can match values against. +- Unencrypted logs don't link to the contract that emitted it, so essentially just a `debug_log`` that you can match values against. - A note that is created and nullified in the same transaction will still emit an encrypted log. -- A limited amount of new commitments, nullifiers and calls that are supported by a transaction, see [circuit limitations](#circuit-limitations). +- A limited amount of new commitments, nullifiers and calls that are supported by a transaction, see [circuit limitations](#circuit-limitations). ## Limitations -There are plans to resolve all of the below. See also the [engineering roadmap](../../about_aztec/roadmap/engineering_roadmap.md). +There are plans to resolve all of the below. ### It is not audited @@ -72,7 +72,7 @@ Obviously, as development continues, the so-called 'circuits' will actually beco The Sandbox will execute more quickly. The logic of all 'circuits' is still in place*. Smart contract logic will be executed, and core protocol logic will be executed*. So invalid transactions will be caught\* and rejected. -\*Note: some core protocol circuit assertions and constraints still need to be written (see [GitHub](https://github.com/AztecProtocol/aztec-packages/issues)). This would be bad in an adversarial environment, but the Sandbox is not that. Naturally, proper circuits will need to be written - see the [engineering roadmap](../../about_aztec/roadmap/engineering_roadmap.md). +\*Note: some core protocol circuit assertions and constraints still need to be written (see [GitHub](https://github.com/AztecProtocol/aztec-packages/issues)). This would be bad in an adversarial environment, but the Sandbox is not that. Naturally, proper circuits will need to be written. ### No Fees! @@ -90,7 +90,7 @@ Apps won't yet be able to allow for any L2 fee logic. Once fees are introduced, The way in which keypairs and addresses are currently derived and implemented (inside the Sandbox) is greatly over-simplified, relative to future plans. -They're so over-simplified that they're known to be insecure. Other features have been prioritised so-far in Sandbox development. Please refer to the [future roadmap](../../about_aztec/roadmap/engineering_roadmap.md) +They're so over-simplified that they're known to be insecure. Other features have been prioritised so-far in Sandbox development. #### What are the consequences? @@ -130,7 +130,7 @@ A contract can't perform a delegatecall yet (if ever). Delegatecalls are quite a Ethereum has a notion of a 'full node' which keeps-up with the blockchain and stores the full chain state. Many users don't wish to run full nodes, so rely on 3rd-party 'full-node-as-a-service' infrastructure providers, who service blockchain queries from their users. -This pattern is likely to develop in Aztec as well, except there's a problem: privacy. If a privacy-seeking user makes a query to a 3rd-party 'full node', that user might leak data about who they are, or about their historic network activity, or about their future intentions. One solution to this problem is "always run a full node", but pragmatically, not everyone will. To protect less-advanced users' privacy, [research is underway](../../about_aztec/roadmap/engineering_roadmap.md) to explore how a privacy-seeking user may request and receive data from a 3rd-party node without revealing what that data is, nor who is making the request. +This pattern is likely to develop in Aztec as well, except there's a problem: privacy. If a privacy-seeking user makes a query to a 3rd-party 'full node', that user might leak data about who they are, or about their historic network activity, or about their future intentions. One solution to this problem is "always run a full node", but pragmatically, not everyone will. To protect less-advanced users' privacy, research is underway to explore how a privacy-seeking user may request and receive data from a 3rd-party node without revealing what that data is, nor who is making the request. ### No private data authentication @@ -209,7 +209,7 @@ Not only are there limits on a _per function_ basis, there are also limits on a **In particular, these _per-transaction_ limits will limit transaction call stack depths** in the Sandbox. That means if a function call results in a cascade of nested function calls, and each of those function calls outputs lots of state reads and writes, or logs (etc.), then all of that accumulated output data might exceed the per-transaction limits that we currently have. This would cause such transactions to fail. -There are [plans](../../about_aztec/roadmap/engineering_roadmap.md#proper-circuits) to relax all of this rigidity, by providing many 'sizes' of [kernel circuit](../../concepts/advanced/circuits/kernels/main.md), and introducing a 'bus' to ferry varying lengths of data between kernel iterations. But that'll all take some time. +There are plans to relax all of this rigidity, by providing many 'sizes' of [kernel circuit](../../concepts/advanced/circuits/kernels/main.md), and introducing a 'bus' to ferry varying lengths of data between kernel iterations. But that'll all take some time. > **In the mean time**, if you encounter a per-transaction limit when testing, and you're feeling adventurous, you could 'hack' the Sandbox to increase the limits. See here (TODO: link) for a guide. **However**, the limits cannot be increased indefinitely. So although we do anticipate that we'll be able to increase them a little bit, don't go mad and provide yourself with 1 million state transitions per transaction. That would be as unrealistic as artificially increasing Ethereum gas limits to 1 trillion. diff --git a/docs/docs/dev_docs/privacy/main.md b/docs/docs/dev_docs/privacy/main.md index 7ba987daeaa..2633c0ae31f 100644 --- a/docs/docs/dev_docs/privacy/main.md +++ b/docs/docs/dev_docs/privacy/main.md @@ -24,22 +24,18 @@ Emit encrypted events, or encrypted messages from a private smart contract funct Execute a private function without the world knowing which function you've executed. - - :::danger Privacy is not guaranteed without care. Although Aztec provides the tools for private smart contracts, information can still be leaked unless the dapp developer is careful. This page outlines some best practices to aid dapp developers. ::: - --- ## Leaky practices There are many caveats to the above. Since Aztec also enables interaction with the _public_ world (public L2 functions and L1 functions), private information can be accidentally leaked if developers aren't careful. - ### Crossing the private -> public boundary Any time a private function makes a call to a public function, information is leaked. Now, that might be perfectly fine in some use cases (it's up to the smart contract developer). Indeed, most interesting apps will require some public state. But let's have a look at some leaky patterns: @@ -51,12 +47,10 @@ Any time a private function makes a call to a public function, information is le - Emitting unencrypted events from a private function. The unencrypted event name and arguments will be publicly visible. - Sending L2->L1 messages from a private function. The entire message, and the resulting L1 function execution will all be publicly visible. - ### Crossing the public -> private boundary If a public function sends a message to be consumed by a private function, the act of consuming that message might be leaked if not following recommended patterns. See [here](../contracts/portals/inbox.md) for more details. - ### Timing of transactions Information about the nature of a transaction can be leaked based on the timing of that transaction. @@ -69,7 +63,6 @@ Suppose that every time Alice sends Bob a private token, 1 minute later a transa Tl;dr: app developers should think about the _timing_ of user transactions, and how this might leak information. - ### Function Fingerprints and Tx Fingerprints A 'Function Fingerprint' is any data which is exposed by a function to the outside world. A 'Tx Fingerprint' is any data which is exposed by a tx to the outside world. We're interested in minimising leakages of information from private txs. The leakiness of a Tx Fingerprint depends on the leakiness of its consituent functions' Function Fingerprints _and_ on the appearance of the tx's Tx Fingerprint as a whole. For a private function (and by extension, for a private tx), the following information _could_ be leaked (depending on the function, of course): @@ -82,7 +75,7 @@ A 'Function Fingerprint' is any data which is exposed by a function to the outsi - The contents of L2 -> L1 messages. - All unencrypted logs (topics and arguments). - The roots of all trees which have been read from. -- The _number_ of ['side effects'](https://en.wikipedia.org/wiki/Side_effect_(computer_science)): +- The _number_ of ['side effects'](): - \# new commitments - \# new nullifiers - \# bytes of encrypted logs @@ -90,18 +83,14 @@ A 'Function Fingerprint' is any data which is exposed by a function to the outsi - \# L2->L1 messages - \# nonzero roots[^1] - - > Note: many of these were mentioned in the ["Crossing the private -> public boundary"](#crossing-the-private---public-boundary) section. > Note: the calldata submitted to L1 is [encoded](https://github.com/AztecProtocol/aztec-packages/blob/master/l1-contracts/src/core/libraries/Decoder.sol) in such a way that all categories of data are packed together, when submitted. E.g. all commitments from all txs in a block are arranged as contiguous bytes of calldata. But that _doesn't_ mean the data from a particular tx is garbled in with all other txs' calldata: the distinct Tx Fingerprint of each tx can is publicly visible when a tx is submitted to the L2 tx pool. - #### Standardising Fingerprints If each private function were to have a unique Fingerprint, then all private functions would be distinguishable from each-other, and all of the efforts of the Aztec protocol to enable 'private function execution' would have been pointless. Standards need to be developed, to encourage smart contract developers to adhere to a restricted set of Tx Fingerprints. For example, a standard might propose that the number of new commitments, nullifiers, logs, etc. must always be equal, and must always equal a power of two. Such a standard would effectively group private functions/txs into 'privacy sets', where all functions/txs in a particular 'privacy set' would look indistinguishable from each-other, when executed. - ### Data queries It's not just the broadcasting of transactions to the network that can leak data. @@ -128,20 +117,18 @@ If a user runs their own node, there's no problem: they can query the latest sib But if a user is not running their own node, they would need to query the very-latest sibling path of their note(s) from some 3rd-party node. In order to query the sibling path of a leaf, the leaf's index needs to be provided as an argument. Revealing the leaf's index to a 3rd-party trivially reveals exactly the note(s) you're about to read. And since those notes were created in some prior transaction, the 3rd-party will be able to link you with that prior transaction. Suppose then that the 3rd-party also serviced the creator of said prior transaction: the 3rd-party will slowly be able to link more and more transactions, and gain more and more insight into a network which is meant to be private! -We're [researching](../../about_aztec/roadmap/engineering_roadmap.md) cryptographic ways to enable users to retrieve sibling paths from 3rd-parties without revealing leaf indices. +We're researching cryptographic ways to enable users to retrieve sibling paths from 3rd-parties without revealing leaf indices. > \* Note: due to the non-uniformity of Aztec transactions, the 'privacy set' of a transaction might not be the entire set of transactions that came before. See here (LINK). ##### Any query -Any query to a node leaks information to that node. - -We're [researching](../../about_aztec/roadmap/engineering_roadmap.md) cryptographic ways to enable users to query any data privately. - - +Any query to a node leaks information to that node. +We're researching cryptographic ways to enable users to query any data privately. --- + Footnotes -[^1]: All txs should set the kernel circuit public inputs for all roots to _valid_, _up-to-date_ nonzero values, so as to mask which trees have _actually_ been read from. The Sandbox will eventually automate this (see this [issue](https://github.com/AztecProtocol/aztec-packages/issues/1676)). \ No newline at end of file +[^1]: All txs should set the kernel circuit public inputs for all roots to _valid_, _up-to-date_ nonzero values, so as to mask which trees have _actually_ been read from. The Sandbox will eventually automate this (see this [issue](https://github.com/AztecProtocol/aztec-packages/issues/1676)). diff --git a/docs/docs/dev_docs/tutorials/main.md b/docs/docs/dev_docs/tutorials/main.md index da6889b6fc8..c294167c9d2 100644 --- a/docs/docs/dev_docs/tutorials/main.md +++ b/docs/docs/dev_docs/tutorials/main.md @@ -1,3 +1,7 @@ +--- +title: Tutorials +--- + import DocCardList from '@theme/DocCardList'; diff --git a/docs/docs/dev_docs/wallets/writing_an_account_contract.md b/docs/docs/dev_docs/wallets/writing_an_account_contract.md index 96639cff70d..b1f216b298c 100644 --- a/docs/docs/dev_docs/wallets/writing_an_account_contract.md +++ b/docs/docs/dev_docs/wallets/writing_an_account_contract.md @@ -2,6 +2,15 @@ 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). +You will learn: + +- How to write a custom account contract in Aztec.nr +- The entrypoint function for transaction authentication and call execution +- The AccountActions module and EntrypointPayload struct, necessary inclusions for any account contract +- Customizing authorization validation within the 'is_valid' function (using Schnorr signatures as an example) +- Typescript glue code to format and authenticate transactions +- Deploying and testing the account contract + Writing your own account contract allows you to define the rules by which user transactions are authorized and paid for, as well as how user keys are managed (including key rotation and recovery). In other words, writing an account contract lets you make the most out of [account abstraction](../../concepts/foundation/accounts/main.md#what-is-account-abstraction) in the Aztec network. It is highly recommended that you understand how an [account](../../concepts/foundation/accounts/main.md) is defined in Aztec, as well as the differences between privacy and authentication [keys](../../concepts/foundation/accounts/keys.md). You will also need to know how to write a [contract in Noir](../contracts/main.md), as well as some basic [Typescript](https://www.typescriptlang.org/). @@ -46,8 +55,8 @@ The `AccountActions` module provides default implementations for most of the acc #include_code is-valid yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr rust - For our account contract, we will take the hash of the action to authorize, request the corresponding auth witness from the oracle, and validate it against our hardcoded public key. If the signature is correct, we authorize the action. + ## The typescript side of things Now that we have a valid 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: @@ -64,7 +73,7 @@ As you can see in the snippet above, to fill in this base class, we need to defi - The deployment arguments. - How to create an auth witness. -In our case, the auth witness will be generated by Schnorr-signing over the message identifier using the hardcoded key. To do this, we are using the `Schnorr` signer from the `@aztec/circuits.js` package to sign over the payload hash. This signer maps to exactly the same signing scheme that Noir's standard library expects in `schnorr::verify_signature`. +In our case, the auth witness will be generated by Schnorr-signing over the message identifier using the hardcoded key. To do this, we are using the `Schnorr` signer from the `@aztec/circuits.js` package to sign over the payload hash. This signer maps to exactly the same signing scheme that Noir's standard library expects in `schnorr::verify_signature`. :::info More signing schemes are available in case you want to experiment with other types of keys. Check out Noir's [documentation on cryptographic primitives](https://noir-lang.org/standard_library/cryptographic_primitives). diff --git a/docs/netlify.toml b/docs/netlify.toml index 319a61df5e0..11f2bc45c62 100644 --- a/docs/netlify.toml +++ b/docs/netlify.toml @@ -98,10 +98,6 @@ from = "/aztec/cryptography/cryptography-roadmap" to = "/about_aztec/roadmap/cryptography_roadmap" -[[redirects]] - from = "/aztec/milestones" - to = "/about_aztec/roadmap/engineering_roadmap" - [[redirects]] from = "/aztec/milestones/features-initial-ldt" to = "/about_aztec/roadmap/features_initial_ldt" diff --git a/docs/sidebars.js b/docs/sidebars.js index f8934b0138c..5603e6ca046 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -46,7 +46,6 @@ const sidebars = { }, items: [ "about_aztec/roadmap/features_initial_ldt", - "about_aztec/roadmap/engineering_roadmap", "about_aztec/roadmap/cryptography_roadmap", ], }, diff --git a/docs/static/img/road_to_testnet.png b/docs/static/img/road_to_testnet.png new file mode 100644 index 00000000000..6753422ca83 Binary files /dev/null and b/docs/static/img/road_to_testnet.png differ