Skip to content

Commit 764cb46

Browse files
authored
chore(docs): Update token bridge tutorial (AztecProtocol#3773)
This PR adds source code references to code that was previously hard coded. It also adds a couple of functions that are in the implementation but were not referenced in the tutorial. - removes references to the `utils.nr` file that is no longer used in the implementation in noir-contracts. - Adds the FORK_URL and FORK_BLOCK_NUMBER env vars to the sandbox reference page # Checklist: Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge. - [ ] If the pull request requires a cryptography review (e.g. cryptographic algorithm implementations) I have added the 'crypto' tag. - [ ] I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code. - [ ] Every change is related to the PR description. - [ ] I have [linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this pull request to relevant issues (if any exist).
1 parent 4dd076c commit 764cb46

File tree

8 files changed

+38
-71
lines changed

8 files changed

+38
-71
lines changed

docs/docs/dev_docs/cli/sandbox-reference.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ MODE='sandbox' # Option to start the sandbox or a standalone part of the system.
6161
AZTEC_NODE_PORT=8079 # The port that the Aztec node wil be listening to (default: 8079)
6262
PXE_PORT=8080 # The port that the PXE will be listening to (default: 8080)
6363

64-
64+
# Ethereum Forking (Optional: not enabled by default) #
65+
FORK_BLOCK_NUMBER=0 # The block number to fork from
66+
FORK_URL="" # The URL of the Ethereum node to fork from
6567

6668
## Polling intervals ##
6769
ARCHIVER_POLLING_INTERVAL_MS=50
@@ -78,7 +80,6 @@ Variables like `DEPLOY_AZTEC_CONTRACTS` & `AZTEC_NODE_PORT` are valid here as de
7880
`TEST_ACCOUNTS` cannot be used here because the Aztec node does not control an Aztec account to deploy contracts from.
7981

8082
```sh
81-
8283
# P2P config #
8384
# Configuration variables for connecting a Node to the Aztec Node P2P network. You'll need a running P2P-Bootstrap node to connect to.
8485
P2P_ENABLED='false' # A flag to enable P2P networking for this node. (default: false)

docs/docs/dev_docs/tutorials/token_portal/depositing_to_aztec.md

+6-42
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,7 @@ In this step, we will write our token portal contract on L1.
88

99
In `l1-contracts/contracts` in your file called `TokenPortal.sol` paste this:
1010

11-
```solidity
12-
pragma solidity ^0.8.20;
13-
14-
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
15-
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
16-
17-
// Messaging
18-
import {IRegistry} from "@aztec/l1-contracts/src/core/interfaces/messagebridge/IRegistry.sol";
19-
import {IInbox} from "@aztec/l1-contracts/src/core/interfaces/messagebridge/IInbox.sol";
20-
import {DataStructures} from "@aztec/l1-contracts/src/core/libraries/DataStructures.sol";
21-
import {Hash} from "@aztec/l1-contracts/src/core/libraries/Hash.sol";
22-
23-
contract TokenPortal {
24-
using SafeERC20 for IERC20;
25-
26-
IRegistry public registry;
27-
IERC20 public underlying;
28-
bytes32 public l2TokenAddress;
29-
30-
function initialize(address _registry, address _underlying, bytes32 _l2TokenAddress) external {
31-
registry = IRegistry(_registry);
32-
underlying = IERC20(_underlying);
33-
l2TokenAddress = _l2TokenAddress;
34-
}
35-
}
36-
```
11+
#include_code init /l1-contracts/test/portals/TokenPortal.sol solidity
3712

3813
This imports relevant files including the interfaces used by the Aztec rollup. And initializes the contract with the following parameters:
3914

@@ -45,20 +20,7 @@ Create a basic ERC20 contract that can mint tokens to anyone. We will use this t
4520

4621
Create a file `PortalERC20.sol` in the same folder and add:
4722

48-
```solidity
49-
// SPDX-License-Identifier: Apache-2.0
50-
pragma solidity ^0.8.0;
51-
52-
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
53-
54-
contract PortalERC20 is ERC20 {
55-
constructor() ERC20("Portal", "PORTAL") {}
56-
57-
function mint(address to, uint256 amount) external {
58-
_mint(to, amount);
59-
}
60-
}
61-
```
23+
#include_code contract /l1-contracts/test/portals/PortalERC20.sol solidity
6224

6325
## Depositing tokens to Aztec publicly
6426

@@ -108,8 +70,10 @@ Note that because L1 is public, everyone can inspect and figure out the fee, con
10870

10971
**So how do we privately consume the message on Aztec?**
11072

111-
On Aztec, anytime something is consumed, we emit a nullifier hash and add it to the nullifier tree. This prevents double-spends. The nullifier hash is a hash of the message that is consumed. So without the secret, one could reverse engineer the expected nullifier hash that might be emitted on L2 upon message consumption. Hence, to consume the message on L2, the user provides a secret to the private noir function, which computes the hash and asserts that it matches to what was provided in the L1->L2 message. This secret is then included in the nullifier hash computation and emits this nullifier. This way, anyone inspecting the blockchain, won’t know which nullifier hash corresponds to the L1->L2 message consumption.
73+
On Aztec, anytime something is consumed (i.e. deleted), we emit a nullifier hash and add it to the nullifier tree. This prevents double-spends. The nullifier hash is a hash of the message that is consumed. So without the secret, one could reverse engineer the expected nullifier hash that might be emitted on L2 upon message consumption. To consume the message on L2, the user provides a secret to the private function, which computes the hash and asserts that it matches to what was provided in the L1->L2 message. This secret is included in the nullifier hash computation and the nullifier is added to the nullifier tree. Anyone inspecting the blockchain won’t know which nullifier hash corresponds to the L1->L2 message consumption.
11274

113-
Note: the secret hashes are Pedersen hashes since the hash has to be computed on L2, and sha256 hash is very expensive for zk circuits. The content hash however is a sha256 hash truncated to a field as clearly shown before.
75+
:::note
76+
Secret hashes are Pedersen hashes since the hash has to be computed on L2 and sha256 hash is very expensive for zk circuits. The content hash however is a sha256 hash truncated to a field as shown before.
77+
:::
11478

11579
In the next step we will start writing our L2 smart contract to mint these tokens on L2.

docs/docs/dev_docs/tutorials/token_portal/minting_on_aztec.md

+7-17
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,18 @@ In this step we will start writing our Aztec.nr bridge smart contract and write
66

77
## Initial contract setup
88

9-
In our `token-bridge` Noir project in `aztec-contracts`, under `src` there is an example `main.nr` file. Delete all the code in here and paste this to define imports and initialize the constructor:
9+
In our `token-bridge` Aztec project in `aztec-contracts`, under `src` there is an example `main.nr` file. Paste this to define imports and initialize the constructor:
1010

11-
```rust
12-
mod util;
13-
#include_code token_bridge_imports /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr raw
14-
use crate::token_interface::Token;
15-
use crate::util::{get_mint_public_content_hash, get_mint_private_content_hash, get_withdraw_content_hash};
16-
#include_code token_bridge_storage_and_constructor /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr raw
17-
```
11+
#include_code token_bridge_imports /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
1812

19-
This imports Aztec-related dependencies and our two helper files `token_interface.nr` and `util.nr`.
13+
#include_code token_bridge_storage_and_constructor /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
14+
15+
This imports Aztec-related dependencies and our helper file `token_interface.nr`.
2016
(The code above will give errors right now - this is because we haven't implemented util and token_interface yet.)
2117

2218
In `token_interface.nr`, add this:
23-
#include_code token_bridge_token_interface /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/token_interface.nr rust
2419

25-
We will write `util.nr` as needed.
20+
#include_code token_bridge_token_interface /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/token_interface.nr rust
2621

2722
## Consume the L1 message
2823

@@ -31,9 +26,6 @@ In the previous step, we have moved our funds to the portal and created a L1->L2
3126
In `main.nr`, now paste this `claim_public` function:
3227
#include_code claim_public /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
3328

34-
In your `util.nr` paste this `mint_public_content_hash` function:
35-
#include_code mint_public_content_hash_nr /yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/src/lib.nr rust
36-
3729
The `claim_public` function enables anyone to consume the message on the user's behalf and mint tokens for them on L2. This is fine as the minting of tokens is done publicly anyway.
3830

3931
**What’s happening here?**
@@ -55,9 +47,7 @@ Now we will create a function to mint the amount privately. Paste this into your
5547

5648
#include_code call_mint_on_token /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
5749

58-
Then inside your `util.nr`, paste this:
59-
60-
#include_code get_mint_private_content_hash /yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/src/lib.nr rust
50+
The `get_mint_private_content_hash` function is imported from the `token_portal_content_hash_lib`.
6151

6252
If the content hashes were constructed similarly for `mint_private` and `mint_publicly`, then content intended for private execution could have been consumed by calling the `claim_public` method. By making these two content hashes distinct, we prevent this scenario.
6353

docs/docs/dev_docs/tutorials/token_portal/setup.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ aztec-contracts
4848
└── token_bridge
4949
├── Nargo.toml
5050
├── src
51-
├── main
51+
├── main.nr
5252
```
5353

5454
Inside `Nargo.toml` add the following content:
@@ -62,8 +62,7 @@ type = "contract"
6262

6363
[dependencies]
6464
aztec = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="yarn-project/aztec-nr/aztec" }
65-
value_note = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="yarn-project/aztec-nr/value-note"}
66-
safe_math = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="yarn-project/aztec-nr/safe-math"}
65+
token_portal_content_hash_lib = { git="https://github.com/AztecProtocol/aztec-packages/", tag="aztec-packages-v0.16.9", directory="yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib" }
6766
protocol_types = { git="https://github.com/AztecProtocol/aztec-packages/", tag="#include_aztec_version", directory="yarn-project/noir-protocol-circuits/src/crates/types"}
6867
```
6968

@@ -76,7 +75,6 @@ aztec-contracts
7675
├── src
7776
├── main.nr
7877
├── token_interface.nr
79-
├── util.nr
8078
```
8179

8280
# Create a JS hardhat project
@@ -110,8 +108,6 @@ This is what your `l1-contracts` should look like:
110108

111109
```tree
112110
├── README.md
113-
├── artifacts
114-
├── cache
115111
├── contracts
116112
├── hardhat.config.js
117113
├── node_modules
@@ -138,6 +134,8 @@ yarn add @aztec/aztec.js @aztec/noir-contracts @aztec/types @aztec/foundation @a
138134
yarn add -D jest @jest/globals ts-jest
139135
```
140136

137+
If you are going to track this repo using git, consider adding a `.gitignore` file to your `src` directory and adding `node_modules` to it.
138+
141139
In `package.json`, add:
142140

143141
```json

docs/docs/dev_docs/tutorials/token_portal/withdrawing_to_l1.md

+11-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ Go back to your `main.nr` and paste this:
1010

1111
#include_code exit_to_l1_public /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
1212

13-
For this to work we will need this helper function, in `util.nr`:
14-
15-
#include_code get_withdraw_content_hash /yarn-project/noir-contracts/src/contracts/token_portal_content_hash_lib/src/lib.nr rust
13+
For this to work we import the `get_withdraw_content_hash` helper function from the `token_portal_content_hash_lib`.
1614

1715
**What’s happening here?**
1816

@@ -53,6 +51,16 @@ We also use a `_withCaller` parameter to determine the appropriate party that ca
5351

5452
We call this pattern _designed caller_ which enables a new paradigm **where we can construct other such portals that talk to the token portal and therefore create more seamless crosschain legos** between L1 and L2.
5553

54+
Before we can compile and use the contract, we need to add two additional functions.
55+
56+
We need a function that let's us read the token value.
57+
58+
#include_code read_token /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
59+
60+
And the `compute_note_hash_and_nullifier` required on every contract.
61+
62+
#include_code compute_note_hash_and_nullifier_placeholder /yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr rust
63+
5664
## Compile code
5765

5866
Congratulations, you have written all the contracts we need for this tutorial! Now let's compile them.

l1-contracts/test/portals/PortalERC20.sol

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// SPDX-License-Identifier: Apache-2.0
2+
// docs:start:contract
23
pragma solidity ^0.8.0;
34

45
import "@oz/token/ERC20/ERC20.sol";
@@ -10,3 +11,4 @@ contract PortalERC20 is ERC20 {
1011
_mint(to, amount);
1112
}
1213
}
14+
// docs:end:contract

l1-contracts/test/portals/TokenPortal.sol

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// docs:start:init
12
pragma solidity >=0.8.18;
23

34
import {IERC20} from "@oz/token/ERC20/IERC20.sol";
@@ -23,6 +24,7 @@ contract TokenPortal {
2324
underlying = IERC20(_underlying);
2425
l2TokenAddress = _l2TokenAddress;
2526
}
27+
// docs:end:init
2628

2729
// docs:start:deposit_public
2830
/**

yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ contract TokenBridge {
1919
types::type_serialization::address_serialization::AddressSerializationMethods,
2020
selector::compute_selector,
2121
};
22-
// docs:end:token_bridge_imports
2322

2423
use dep::token_portal_content_hash_lib::{get_mint_public_content_hash, get_mint_private_content_hash, get_withdraw_content_hash};
2524

2625
use crate::token_interface::Token;
26+
// docs:end:token_bridge_imports
2727

2828
// docs:start:token_bridge_storage_and_constructor
2929
// Storage structure, containing all storage, and specifying what slots they use.
@@ -148,9 +148,11 @@ contract TokenBridge {
148148

149149
// /// Unconstrained ///
150150

151+
// docs:start:read_token
151152
unconstrained fn token() -> pub AztecAddress {
152153
storage.token.read()
153154
}
155+
// docs:end:read_token
154156

155157
#[aztec(public)]
156158
internal fn _initialize(token: AztecAddress) {

0 commit comments

Comments
 (0)