Skip to content

Commit e3c1de7

Browse files
author
AztecBot
committed
Merge branch 'next' into ad/chore/ci-release-pr-canary
2 parents 5f5e5d8 + 2bd7ed5 commit e3c1de7

File tree

145 files changed

+7215
-2172
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

145 files changed

+7215
-2172
lines changed

boxes/boxes/vanilla/scripts/deploy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { type AztecNode } from '@aztec/aztec.js/node';
1414
import { SPONSORED_FPC_SALT } from '@aztec/constants';
1515
import { createStore } from '@aztec/kv-store/lmdb';
1616
import { SponsoredFPCContractArtifact } from '@aztec/noir-contracts.js/SponsoredFPC';
17-
import { getPXEConfig } from '@aztec/pxe/server';
17+
import { getPXEConfig, PXE_DATA_SCHEMA_VERSION } from '@aztec/pxe/server';
1818
import { getDefaultInitializer } from '@aztec/stdlib/abi';
1919
import { TestWallet } from '@aztec/test-wallet/server';
2020
import fs from 'fs';
@@ -34,7 +34,7 @@ async function setupWallet(aztecNode: AztecNode) {
3434
const store = await createStore('pxe', {
3535
dataDirectory: PXE_STORE_DIR,
3636
dataStoreMapSizeKb: 1e6,
37-
});
37+
}, PXE_DATA_SCHEMA_VERSION);
3838

3939
const config = getPXEConfig();
4040
config.dataDirectory = 'pxe';

docs/Nargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ members = [
33
"examples/contracts/counter_contract",
44
"examples/contracts/bob_token_contract",
55
"examples/contracts/nft",
6-
"examples/contracts/nft_bridge"
6+
"examples/contracts/nft_bridge",
7+
"examples/contracts/recursive_verification_contract"
78
]

docs/docs-developers/docs/tutorials/contract_tutorials/recursive_verification.md

Lines changed: 7 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ This is called "recursive" verification because the proof is verified inside an
1212
:::
1313

1414
:::tip Full Working Example
15-
The complete code for this tutorial is available at [aztec-examples/recursive_verification](https://github.com/AztecProtocol/aztec-examples/tree/v3.0.0-devnet.6-patch.1/recursive_verification). Clone it to follow along or use it as a reference.
15+
The complete code for this tutorial is available in the [docs/examples](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/docs/examples) directory. Clone it to follow along or use it as a reference.
1616
:::
1717

1818
## Prerequisites
@@ -131,16 +131,7 @@ circuit/
131131

132132
Replace the contents of `circuit/src/main.nr` with:
133133

134-
```rust
135-
fn main(x: u64, y: pub u64) {
136-
assert(x != y);
137-
}
138-
139-
#[test]
140-
fn test_main() {
141-
main(1, 2);
142-
}
143-
```
134+
#include_code circuit /docs/examples/circuits/hello_circuit/src/main.nr rust
144135

145136
This is intentionally minimal to focus on the verification pattern. In production, you would replace `assert(x != y)` with meaningful computations like:
146137

@@ -170,14 +161,7 @@ For example, you could create a zkpassport proof demonstrating that you are over
170161

171162
Update `circuit/Nargo.toml` (see [Noir crates and packages](https://noir-lang.org/docs/noir/modules_packages_crates/crates_and_packages) for more details):
172163

173-
```toml
174-
[package]
175-
name = "hello_circuit"
176-
type = "bin"
177-
authors = ["[YOUR_NAME]"]
178-
179-
[dependencies]
180-
```
164+
#include_code circuit_nargo_toml /docs/examples/circuits/hello_circuit/Nargo.toml toml
181165

182166
**Note**: This is a vanilla Noir circuit, not an Aztec contract. It has `type = "bin"` (binary) and no Aztec dependencies. The circuit is compiled with `nargo`, not `aztec compile`. This distinction is important—you can verify proofs from _any_ Noir circuit inside Aztec contracts.
183167

@@ -267,70 +251,7 @@ bb_proof_verification = { git = "https://github.com/AztecProtocol/aztec-packages
267251

268252
Replace the contents of `contract/src/main.nr` with:
269253

270-
```rust
271-
use aztec::macros::aztec;
272-
273-
#[aztec]
274-
pub contract ValueNotEqual {
275-
use aztec::{
276-
macros::{functions::{external, initializer, internal, only_self, view}, storage::storage},
277-
oracle::debug_log::debug_log_format,
278-
protocol::{address::AztecAddress, traits::ToField},
279-
state_vars::{Map, PublicImmutable, PublicMutable},
280-
};
281-
use bb_proof_verification::{UltraHonkVerificationKey, UltraHonkZKProof, verify_honk_proof};
282-
283-
#[storage]
284-
struct Storage<Context> {
285-
counters: Map<AztecAddress, PublicMutable<Field, Context>, Context>,
286-
vk_hash: PublicImmutable<Field, Context>,
287-
}
288-
289-
#[initializer]
290-
#[external("public")]
291-
fn constructor(headstart: Field, owner: AztecAddress, vk_hash: Field) {
292-
self.storage.counters.at(owner).write(headstart);
293-
self.storage.vk_hash.initialize(vk_hash);
294-
}
295-
296-
#[external("private")]
297-
fn increment(
298-
owner: AztecAddress,
299-
verification_key: UltraHonkVerificationKey,
300-
proof: UltraHonkZKProof,
301-
public_inputs: [Field; 1],
302-
) {
303-
debug_log_format("Incrementing counter for owner {0}", [owner.to_field()]);
304-
305-
// Read the stored VK hash - this is readable from private context
306-
// because PublicImmutable values are committed at deployment
307-
let vk_hash = self.storage.vk_hash.read();
308-
309-
// Verify the proof - this is the core operation
310-
// The function checks:
311-
// 1. The VK hashes to the stored vk_hash
312-
// 2. The proof is valid for the given VK and public inputs
313-
verify_honk_proof(verification_key, proof, public_inputs, vk_hash);
314-
315-
// If we reach here, the proof is valid
316-
// Enqueue a public function call to update state
317-
self.enqueue_self._increment_public(owner);
318-
}
319-
320-
#[only_self]
321-
#[external("public")]
322-
fn _increment_public(owner: AztecAddress) {
323-
let current = self.storage.counters.at(owner).read();
324-
self.storage.counters.at(owner).write(current + 1);
325-
}
326-
327-
#[view]
328-
#[external("public")]
329-
fn get_counter(owner: AztecAddress) -> Field {
330-
self.storage.counters.at(owner).read()
331-
}
332-
}
333-
```
254+
#include_code full_contract /docs/examples/contracts/recursive_verification_contract/src/main.nr rust
334255

335256
### Storage Variables Explained
336257

@@ -539,80 +460,7 @@ The proof generation script executes the circuit offchain and produces the proof
539460

540461
Create `scripts/generate_data.ts`:
541462

542-
```typescript
543-
import { Noir } from "@aztec/noir-noir_js";
544-
import circuitJson from "../circuit/target/hello_circuit.json" with { type: "json" };
545-
import { Barretenberg, UltraHonkBackend, deflattenFields } from "@aztec/bb.js";
546-
import fs from "fs";
547-
import { exit } from "process";
548-
549-
// Step 1: Initialize Barretenberg API (the proving system backend)
550-
// Barretenberg is the C++ library that implements UltraHonk
551-
// threads: 1 uses single-threaded mode (increase for faster proofs on multi-core machines)
552-
const barretenbergAPI = await Barretenberg.new({ threads: 1 });
553-
554-
// Step 2: Create Noir circuit instance from compiled bytecode
555-
// This loads the circuit definition so we can execute it
556-
const helloWorld = new Noir(circuitJson as any);
557-
558-
// Step 3: Execute circuit with inputs to generate witness
559-
// The witness is all intermediate values computed during circuit execution
560-
// x=1 (private), y=2 (public) - proves that 1 != 2
561-
const { witness: mainWitness } = await helloWorld.execute({ x: 1, y: 2 });
562-
563-
// Step 4: Create UltraHonk backend with circuit bytecode
564-
// The backend handles proof generation and verification
565-
const mainBackend = new UltraHonkBackend(circuitJson.bytecode, barretenbergAPI);
566-
567-
// Step 5: Generate proof targeting the noir-recursive verifier
568-
// verifierTarget: 'noir-recursive' creates a proof format suitable for
569-
// verification inside another Noir circuit (which is what Aztec contracts are)
570-
const mainProofData = await mainBackend.generateProof(mainWitness, {
571-
verifierTarget: "noir-recursive",
572-
});
573-
574-
// Step 6: Verify proof locally before saving
575-
// This catches errors early - if verification fails here, it will fail onchain too
576-
const isValid = await mainBackend.verifyProof(mainProofData, {
577-
verifierTarget: "noir-recursive",
578-
});
579-
console.log(`Proof verification: ${isValid ? "SUCCESS" : "FAILED"}`);
580-
581-
// Step 7: Generate recursive artifacts for onchain use
582-
// This converts the proof and VK into field element arrays that can be
583-
// passed to the Aztec contract
584-
const recursiveArtifacts = await mainBackend.generateRecursiveProofArtifacts(
585-
mainProofData.proof,
586-
mainProofData.publicInputs.length,
587-
);
588-
589-
// Step 8: Convert proof to field elements if needed
590-
// Some versions return empty proofAsFields, requiring manual conversion
591-
let proofAsFields = recursiveArtifacts.proofAsFields;
592-
if (proofAsFields.length === 0) {
593-
console.log("Using deflattenFields to convert proof...");
594-
proofAsFields = deflattenFields(mainProofData.proof).map((f) => f.toString());
595-
}
596-
597-
const vkAsFields = recursiveArtifacts.vkAsFields;
598-
599-
console.log(`VK size: ${vkAsFields.length}`); // Should be 115
600-
console.log(`Proof size: ${proofAsFields.length}`); // Should be 508
601-
console.log(`Public inputs: ${mainProofData.publicInputs.length}`); // Should be 1
602-
603-
// Step 9: Save all data to JSON for contract interaction
604-
const data = {
605-
vkAsFields: vkAsFields, // 115 field elements - the verification key
606-
vkHash: recursiveArtifacts.vkHash, // Hash of VK - stored in contract
607-
proofAsFields: proofAsFields, // 508 field elements - the proof
608-
publicInputs: mainProofData.publicInputs.map((p: string) => p.toString()),
609-
};
610-
611-
fs.writeFileSync("data.json", JSON.stringify(data, null, 2));
612-
await barretenbergAPI.destroy();
613-
console.log("Done");
614-
exit();
615-
```
463+
#include_code generate_data /docs/examples/ts/recursive_verification/scripts/generate_data.ts typescript
616464

617465
### Understanding the Proof Generation Pipeline
618466

@@ -900,22 +748,7 @@ This single line triggers a complex flow:
900748

901749
Create `scripts/sponsored_fpc.ts`:
902750

903-
```typescript
904-
import { getContractInstanceFromInstantiationParams } from "@aztec/aztec.js/contracts";
905-
import { Fr } from "@aztec/aztec.js/fields";
906-
import { SponsoredFPCContract } from "@aztec/noir-contracts.js/SponsoredFPC";
907-
908-
const SPONSORED_FPC_SALT = new Fr(BigInt(0));
909-
910-
export async function getSponsoredFPCInstance() {
911-
return await getContractInstanceFromInstantiationParams(
912-
SponsoredFPCContract.artifact,
913-
{
914-
salt: SPONSORED_FPC_SALT,
915-
},
916-
);
917-
}
918-
```
751+
#include_code sponsored_fpc /docs/examples/ts/recursive_verification/scripts/sponsored_fpc.ts typescript
919752

920753
This utility computes the address of the pre-deployed sponsored FPC contract. The salt ensures we get the same address every time. For more information about fee payment options, see [Paying Fees](../../aztec-js/how_to_pay_fees.md).
921754

@@ -955,7 +788,7 @@ The counter starts at 10 (set during deployment), and after successful proof ver
955788

956789
## Quick Reference
957790

958-
If you want to run all commands at once, or if you're starting fresh, here's the complete workflow. You can also clone the [full working example](https://github.com/AztecProtocol/aztec-examples/tree/main/recursive_verification) to get started quickly.
791+
If you want to run all commands at once, or if you're starting fresh, here's the complete workflow. You can also reference the [full working example](https://github.com/AztecProtocol/aztec-packages/tree/#include_aztec_version/docs/examples) in the main repository.
959792

960793
```bash
961794
# Install dependencies (after creating package.json and tsconfig.json)

docs/examples/bootstrap.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,28 @@ export NARGO=${NARGO:-"$REPO_ROOT/noir/noir-repo/target/release/nargo"}
99
export TRANSPILER=${TRANSPILER:-"$REPO_ROOT/avm-transpiler/target/release/avm-transpiler"}
1010
export STRIP_AZTEC_NR_PREFIX=${STRIP_AZTEC_NR_PREFIX:-"$REPO_ROOT/noir-projects/noir-contracts/scripts/strip_aztec_nr_prefix.sh"}
1111
export BB_HASH=${BB_HASH:-$("$REPO_ROOT/barretenberg/cpp/bootstrap.sh" hash)}
12+
export NOIR_HASH=${NOIR_HASH:-$("$REPO_ROOT/noir/bootstrap.sh" hash)}
13+
14+
function compile-circuits {
15+
echo_header "Compiling vanilla Noir circuits"
16+
local CIRCUITS_DIR="$REPO_ROOT/docs/examples/circuits"
17+
18+
if [ ! -d "$CIRCUITS_DIR" ]; then
19+
echo_stderr "No circuits directory found at $CIRCUITS_DIR"
20+
return 0
21+
fi
22+
23+
if [ ! -f "$CIRCUITS_DIR/Nargo.toml" ]; then
24+
echo_stderr "No workspace Nargo.toml found in $CIRCUITS_DIR"
25+
return 0
26+
fi
27+
28+
# Compile all circuits in the workspace
29+
echo_stderr "Compiling circuits workspace..."
30+
(cd "$CIRCUITS_DIR" && $NARGO compile --workspace)
31+
32+
echo_stderr "Vanilla circuits compiled"
33+
}
1234

1335
function compile {
1436
echo_header "Compiling example contracts"
@@ -121,8 +143,11 @@ function run_step {
121143
local step_func=$2
122144
local output exit_code
123145

146+
# Disable errexit for command substitution to properly capture exit code
147+
set +e
124148
output=$($step_func 2>&1)
125149
exit_code=$?
150+
set -e
126151
echo "$output"
127152

128153
if [[ $exit_code -ne 0 ]]; then
@@ -154,6 +179,7 @@ function post_failure_comment_for_steps {
154179

155180
case "$cmd" in
156181
"")
182+
run_step "Compile (Noir circuits)" compile-circuits
157183
run_step "Compile (Noir contracts)" compile
158184
run_step "Compile (Solidity)" compile-solidity
159185
run_step "TypeScript validation" validate-ts
@@ -167,6 +193,9 @@ case "$cmd" in
167193
fi
168194
fi
169195
;;
196+
compile-circuits)
197+
compile-circuits
198+
;;
170199
compile-solidity)
171200
compile-solidity
172201
;;

docs/examples/circuits/Nargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[workspace]
2+
members = [
3+
"hello_circuit"
4+
]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# docs:start:circuit_nargo_toml
2+
[package]
3+
name = "hello_circuit"
4+
type = "bin"
5+
authors = [""]
6+
7+
[dependencies]
8+
# docs:end:circuit_nargo_toml
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// docs:start:circuit
2+
fn main(x: u64, y: pub u64) {
3+
assert(x != y);
4+
}
5+
6+
#[test]
7+
fn test_main() {
8+
main(1, 2);
9+
}
10+
// docs:end:circuit
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# docs:start:nargo_toml
2+
[package]
3+
name = "recursive_verification_contract"
4+
type = "contract"
5+
authors = [""]
6+
compiler_version = ">=0.25.0"
7+
8+
[dependencies]
9+
aztec = { path = "../../../../noir-projects/aztec-nr/aztec" }
10+
bb_proof_verification = { path = "../../../../barretenberg/noir/bb_proof_verification" }
11+
# docs:end:nargo_toml

0 commit comments

Comments
 (0)