You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There's also a `get_notes` function that reads without nullifying, but use it with caution - the returned notes may have already been spent in another transaction.
Copy file name to clipboardExpand all lines: docs/docs-developers/docs/tutorials/js_tutorials/token_bridge.md
+26-26Lines changed: 26 additions & 26 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -108,7 +108,7 @@ touch src/nft.nr
108
108
109
109
In this file, you're going to create a **private note** that represents NFT ownership. This is a struct with macros that indicate it is a note that can be compared and packed:
You now have a note that represents the owner of a particular NFT. Next, move on to the contract itself.
114
114
@@ -134,36 +134,36 @@ Write the storage struct and a simple [initializer](../../foundational-topics/co
134
134
<!-- wrapped in a code block to add a "}" at the end -->
135
135
136
136
```rust
137
-
#include_codecontract_setup/docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft/src/main.nr raw
137
+
#include_codecontract_setup/docs/examples/contracts/nft/src/main.nr raw
138
138
}
139
139
```
140
140
141
141
### Utility Functions
142
142
143
143
Add an internal function to handle the `DelayedPublicMutable` value change. Mark the function as public and `#[only_self]` so only the contract can call it:
This function is marked with `#[only_self]`, meaning only the contract itself can call it. It uses `schedule_value_change` to update the `nfts` storage, preventing the same NFT from being minted twice or burned when it doesn't exist. You'll call this public function from a private function later using `enqueue_self`.
148
148
149
149
Another useful function checks how many notes a caller has. You can use this later to verify the claim and exit from L2:
Before anything else, you need to set the minter. This will be the bridge contract, so only the bridge contract can mint NFTs. This value doesn't need to change after initialization. Here's how to initialize the `PublicImmutable`:
Now for the magic - minting NFTs **privately**. The bridge will call this to mint to a user, deliver the note using [constrained message delivery](../../aztec-nr/framework-description/how_to_emit_event.md) (best practice when "sending someone a
160
160
note") and then [enqueue a public call](../../aztec-nr/framework-description/how_to_call_contracts.md) to the `_mark_nft_exists` function:
161
161
162
-
#include_code mint /docs/examples/tutorials/token_bridge_contract/contracts/aztec/nft/src/main.nr rust
162
+
#include_code mint /docs/examples/contracts/nft/src/main.nr rust
163
163
164
164
The bridge will also need to burn NFTs when users withdraw back to L1:
@@ -265,7 +265,7 @@ The secret prevents front-running. Certainly you don't want anyone to claim your
265
265
266
266
Similarly, exiting to L1 means burning the NFT on the L2 side and pushing a message through the protocol. To ensure only the L1 recipient can claim it, hash the `token_id` together with the `recipient`:
Initialize it with Aztec's registry, which holds the canonical contracts for Aztec-related contracts, including the Inbox and Outbox. These are the message-passing contracts—Aztec sequencers read any messages on these contracts.
333
333
334
334
```solidity
335
-
#include_code portal_setup /docs/examples/tutorials/token_bridge_contract/contracts/NFTPortal.sol raw
335
+
#include_code portal_setup /docs/examples/solidity/nft_bridge/NFTPortal.sol raw
336
336
}
337
337
```
338
338
339
339
The core logic is similar to the L2 logic. `depositToAztec` calls the `Inbox` canonical contract to send a message to Aztec, and `withdraw` calls the `Outbox` contract.
340
340
341
341
Add these two functions with explanatory comments:
This completes the setup. It's a lot of configuration, but you're dealing with four contracts across two chains.
410
410
411
411
### L1 → L2 Flow
412
412
413
413
Now for the main flow. Mint a CryptoPunk on L1, deposit it to Aztec, and claim it on Aztec. Put everything in the same script. To mint, call the L1 contract with `mint`, which will mint `tokenId = 0`:
The `Inbox` contract will emit an important log: `MessageSent(inProgress, index, leaf, updatedRollingHash);`. This log provides the **leaf index** of the message in the [L1-L2 Message Tree](../../aztec-nr/framework-description/ethereum-aztec-messaging/index.md)—the location of the message in the tree that will appear on L2. You need this index, plus the secret, to correctly claim and decrypt the message.
This extracts the logs from the deposit and retrieves the leaf index. You can now claim it on L2. However, for security reasons, at least 2 blocks must pass before a message can be claimed on L2. If you called `claim` on the L2 contract immediately, it would return "no message available".
428
428
429
429
Add a utility function to mine two blocks (it deploys a contract with a random salt):
Great! You can expand the L2 contract to add features like NFT transfers. For now, exit the NFT on L2 and redeem it on L1. Mine two blocks because of `DelayedMutable`:
Just like in the L1 → L2 flow, you need to know what to claim on L1. Where in the message tree is the message you want to claim? Use the utility `computeL2ToL1MembershipWitness`, which provides the leaf and the sibling path of the message:
0 commit comments