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
@@ -80,7 +80,7 @@ The Pod Racing contract ([`src/main.nr`](./src/main.nr)) is a two-player competi
80
80
81
81
Open `src/main.nr` and look at the `Storage` struct:
82
82
83
-
#include_code storage /main.nr rust
83
+
#include_code storage /src/main.nr rust
84
84
85
85
**What is `Context`?** You'll notice `Context` appears as a generic parameter throughout the storage definition. In Aztec, the context is the execution environment passed to every function — it's how your contract accesses blockchain state like `context.msg_sender()` (the caller's address) and `context.block_number()`. Think of it as an expanded version of Solidity's global variables (`msg.sender`, `block.number`, etc.), but packaged as an object. The `<Context>` generic on storage types lets the same storage struct work in both public and private execution contexts. You don't need to construct it yourself — the framework provides `self.context` automatically in every contract function.
86
86
@@ -119,33 +119,33 @@ These functions should feel familiar if you've written Solidity.
119
119
120
120
#### `constructor()`
121
121
122
-
#include_code constructor /main.nr rust
122
+
#include_code constructor /src/main.nr rust
123
123
124
124
Sets the admin address. The `#[initializer]` macro means this runs once at deployment, like a Solidity constructor.
125
125
126
126
#### `create_game()`
127
127
128
-
#include_code create-game /main.nr rust
128
+
#include_code create-game /src/main.nr rust
129
129
130
130
Creates a new game. Checks the game ID isn't taken (player1 must be zero address), then writes a new `Race` struct with the caller as player1 and an expiration time.
131
131
132
132
#### `join_game()`
133
133
134
-
#include_code join-game /main.nr rust
134
+
#include_code join-game /src/main.nr rust
135
135
136
136
A second player joins. The `Race::join()` method validates that player1 exists, the player2 slot is empty, and the joiner isn't player1.
137
137
138
138
#### `finalize_game()`
139
139
140
-
#include_code finalize-game /main.nr rust
140
+
#include_code finalize-game /src/main.nr rust
141
141
142
142
After both players have revealed, this compares track scores, determines the winner, and updates the leaderboard.
143
143
144
144
#### The `Race` struct ([`src/race.nr`](./src/race.nr))
145
145
146
146
The `Race` struct stores all public game state. It has 17 fields:
147
147
148
-
#include_code race-struct /race.nr rust
148
+
#include_code race-struct /src/race.nr rust
149
149
150
150
Key methods:
151
151
@@ -159,7 +159,7 @@ This is the "aha moment" — the part with no Ethereum equivalent.
159
159
160
160
#### `play_round()`
161
161
162
-
#include_code play-round /main.nr rust
162
+
#include_code play-round /src/main.nr rust
163
163
164
164
Three things happen here that have no direct Ethereum equivalent:
165
165
@@ -169,7 +169,7 @@ Three things happen here that have no direct Ethereum equivalent:
The `#[note]` macro makes this a private state primitive. Each note stores one round's point allocation and the owner's address. Only the owner can read it.
184
184
@@ -234,13 +234,13 @@ Here's exactly what an outside observer can and cannot see at each step.
234
234
235
235
Some functions are labeled **"private, then public"** in the Type column. On Aztec, there are only two function types: `#[private]` and `#[public]`. But a private function can _enqueue_ a public function to run after it — within the same transaction. The private part runs first (on the user's machine, hidden from everyone), then the public part runs on-chain (visible to all). This is how the contract hides sensitive data while still updating shared public state.
236
236
237
-
| Step | Function | Type | Observer **CAN** see | Observer **CANNOT** see |
| 1 |`create_game`| public | Game created, player1 address, expiration block | Nothing hidden |
240
+
| 2 |`join_game`| public | Player2 joined, both addresses | Nothing hidden |
241
241
| 3 |`play_round`| private, then public | Round counter incremented (e.g. "player1 played round 1") | Point allocation across tracks |
242
-
| 4 |`finish_game`| private, then public | Final track totals revealed (e.g. "player1: 7,7,7,3,3") | Individual round allocations |
243
-
| 5 |`finalize_game`| public | Winner declared, leaderboard updated | Nothing hidden (all data public at this point) |
242
+
| 4 |`finish_game`| private, then public | Final track totals revealed (e.g. "player1: 7,7,7,3,3") | Individual round allocations |
243
+
| 5 |`finalize_game`| public | Winner declared, leaderboard updated | Nothing hidden (all data public at this point) |
244
244
245
245
The critical privacy window is between steps 3 and 4: both players have committed their strategies (as private notes), but neither can see the other's choices. This prevents the second player from gaining an advantage by observing the first player's moves.
The `unconstrained` keyword means this test runs outside the ZK circuit (it's a test, not a provable function). `utils::setup()` deploys a fresh contract and returns the environment, contract address, and admin.
@@ -455,7 +452,7 @@ Every Aztec account is a smart contract. There are no Externally Owned Accounts
455
452
456
453
The `SponsoredFPC` is a canonical Fee Payment Contract deployed at a deterministic address (salt = 0). It pays transaction fees on behalf of users, useful for onboarding when users don't have Fee Juice yet. On the local network it's pre-deployed.
> **Important:** Always call `.simulate()` before `.send()`. Simulation runs the transaction locally and surfaces revert reasons immediately. Without it, a failing transaction hangs until timeout with an opaque error.
495
484
@@ -510,20 +499,7 @@ The output includes the contract address, admin address, and instantiation data
510
499
3. Register the contract with the wallet: `wallet.registerContract(instance, PodRacingContract.artifact)`
It then deploys a Token contract from wallet1, creates an account on wallet2, mints tokens to wallet2's account, registers the token contract on wallet2, and reads balances.
712
602
@@ -749,13 +639,7 @@ Devnet uses real provers and connects to the Aztec devnet at `https://next.devne
749
639
750
640
**`scripts/profile_deploy.ts`** shows how to profile a transaction:
0 commit comments