Skip to content

Commit

Permalink
Merge 9854558 into 20a33f2
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench authored Nov 27, 2024
2 parents 20a33f2 + 9854558 commit 19cee0e
Show file tree
Hide file tree
Showing 140 changed files with 13,606 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
Step-by-step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the VS Code Debugger
description:
Step by step guide on how to debug your Noir circuits with the VS Code Debugger configuration and features.
Step-by-step guide on how to debug your Noir circuits with the VS Code Debugger configuration and features.
keywords:
[
Nargo,
Expand Down Expand Up @@ -65,4 +65,4 @@ We just need to click the to the right of the line number 18. Once the breakpoin

Now we are debugging the `keccak256` function, notice the _Call Stack pane_ at the lower right. This lets us inspect the current call stack of our process.

That covers most of the current debugger functionalities. Check out [the reference](../../reference/debugger/debugger_vscode.md) for more details on how to configure the debugger.
That covers most of the current debugger functionalities. Check out [the reference](../../reference/debugger/debugger_vscode.md) for more details on how to configure the debugger.
2 changes: 1 addition & 1 deletion noir/noir-repo/docs/docs/how_to/how-to-oracles.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ This guide has 3 major steps:

An oracle is defined in a Noir program by defining two methods:

- An unconstrained method - This tells the compiler that it is executing an [unconstrained functions](../noir/concepts//unconstrained.md).
- An unconstrained method - This tells the compiler that it is executing an [unconstrained function](../noir/concepts//unconstrained.md).
- A decorated oracle method - This tells the compiler that this method is an RPC call.

An example of an oracle that returns a `Field` would be:
Expand Down
16 changes: 8 additions & 8 deletions noir/noir-repo/docs/docs/noir/concepts/globals.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ sidebar_position: 8
## Globals


Noir supports global variables. The global's type can be inferred by the compiler entirely:
Noir supports global variables. The global's type must be specified by the user:

```rust
global N = 5; // Same as `global N: Field = 5`
global N: Field = 5;

global TUPLE = (3, 2);
global TUPLE: (Field, Field) = (3, 2);

fn main() {
assert(N == 5);
Expand All @@ -28,7 +28,7 @@ fn main() {
Globals can be defined as any expression, so long as they don't depend on themselves - otherwise there would be a dependency cycle! For example:

```rust
global T = foo(T); // dependency error
global T: u32 = foo(T); // dependency error
```

:::
Expand All @@ -47,7 +47,7 @@ fn main(y : [Field; N]) {
A global from another module can be imported or referenced externally like any other name:

```rust
global N = 20;
global N: Field = 20;

fn main() {
assert(my_submodule::N != N);
Expand All @@ -62,7 +62,7 @@ When a global is used, Noir replaces the name with its definition on each occurr
This means globals defined using function calls will repeat the call each time they're used:

```rust
global RESULT = foo();
global RESULT: [Field; 100] = foo();

fn foo() -> [Field; 100] { ... }
```
Expand All @@ -78,5 +78,5 @@ to make the global public or `pub(crate)` to make it public to just its crate:

```rust
// This global is now public
pub global N = 5;
```
pub global N: u32 = 5;
```
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,10 @@ use std::hash::sha256;
use std::scalar_mul::fixed_base_embedded_curve;
```

Lastly, as demonstrated in the
[elliptic curve example](../standard_library/cryptographic_primitives/ec_primitives.md#examples), you
can import multiple items in the same line by enclosing them in curly braces:
Lastly, You can import multiple items in the same line by enclosing them in curly braces:

```rust
use std::ec::tecurve::affine::{Curve, Point};
use std::hash::{keccak256, sha256};
```

We don't have a way to consume libraries from inside a [workspace](./workspaces.md) as external dependencies right now.
Expand Down

This file was deleted.

32 changes: 31 additions & 1 deletion noir/noir-repo/docs/docs/noir/standard_library/mem.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,41 @@ fn checked_transmute<T, U>(value: T) -> U
Transmutes a value of one type into the same value but with a new type `U`.

This function is safe to use since both types are asserted to be equal later during compilation after the concrete values for generic types become known.
This function is useful for cases where the compiler may fails a type check that is expected to pass where
This function is useful for cases where the compiler may fail a type check that is expected to pass where
a user knows the two types to be equal. For example, when using arithmetic generics there are cases the compiler
does not see as equal, such as `[Field; N*(A + B)]` and `[Field; N*A + N*B]`, which users may know to be equal.
In these cases, `checked_transmute` can be used to cast the value to the desired type while also preserving safety
by checking this equality once `N`, `A`, `B` are fully resolved.

Note that since this safety check is performed after type checking rather than during, no error is issued if the function
containing `checked_transmute` is never called.

# `std::mem::array_refcount`

```rust
fn array_refcount<T, let N: u32>(array: [T; N]) -> u32 {}
```

Returns the internal reference count of an array value in unconstrained code.

Arrays only have reference count in unconstrained code - using this anywhere
else will return zero.

This function is mostly intended for debugging compiler optimizations but can also be used
to find where array copies may be happening in unconstrained code by placing it before array
mutations.

# `std::mem::slice_refcount`

```rust
fn slice_refcount<T>(slice: [T]) -> u32 {}
```

Returns the internal reference count of a slice value in unconstrained code.

Slices only have reference count in unconstrained code - using this anywhere
else will return zero.

This function is mostly intended for debugging compiler optimizations but can also be used
to find where slice copies may be happening in unconstrained code by placing it before slice
mutations.
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ way to write your derive handler. The arguments are as follows:
- `for_each_field`: An operation to be performed on each field. E.g. `|name| quote { (self.$name == other.$name) }`.
- `join_fields_with`: A separator to join each result of `for_each_field` with.
E.g. `quote { & }`. You can also use an empty `quote {}` for no separator.
- `body`: The result of the field operations are passed into this function for any final processing.
- `body`: The result of the field operations is passed into this function for any final processing.
This is the place to insert any setup/teardown code the trait requires. If the trait doesn't require
any such code, you can return the body as-is: `|body| body`.

Expand Down
2 changes: 1 addition & 1 deletion noir/noir-repo/docs/docs/noir/standard_library/meta/typ.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ If this is a tuple type, returns each element type of the tuple.
Retrieves the trait implementation that implements the given
trait constraint for this type. If the trait constraint is not
found, `None` is returned. Note that since the concrete trait implementation
for a trait constraint specified from a `where` clause is unknown,
for a trait constraint specified in a `where` clause is unknown,
this function will return `None` in these cases. If you only want to know
whether a type implements a trait, use `implements` instead.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
Step-by-step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
Step-by-step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
Step-by-step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
Step-by-step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
Step-by-step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
Step-by-step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
Step-by-step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Using the REPL Debugger
description:
Step by step guide on how to debug your Noir circuits with the REPL Debugger.
Step-by-step guide on how to debug your Noir circuits with the REPL Debugger.
keywords:
[
Nargo,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"words": [
"Cryptdoku"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: Oracles
description: This guide provides an in-depth understanding of how Oracles work in Noir programming. Learn how to use outside calculations in your programs, constrain oracles, and understand their uses and limitations.
keywords:
- Noir Programming
- Oracles
- JSON-RPC
- Foreign Call Handlers
- Constrained Functions
- Blockchain Programming
sidebar_position: 1
---

If you've seen "The Matrix" you may recall "The Oracle" as Gloria Foster smoking cigarettes and baking cookies. While she appears to "know things", she is actually providing a calculation of a pre-determined future. Noir Oracles are similar, in a way. They don't calculate the future (yet), but they allow you to use outside calculations in your programs.

![matrix oracle prediction](@site/static/img/memes/matrix_oracle.jpeg)

A Noir program is usually self-contained. You can pass certain inputs to it, and it will generate a deterministic output for those inputs. But what if you wanted to defer some calculation to an outside process or source?

Oracles are functions that provide this feature.

## Use cases

An example usage for Oracles is proving something on-chain. For example, proving that the ETH-USDC quote was below a certain target at a certain block time. Or even making more complex proofs like proving the ownership of an NFT as an anonymous login method.

Another interesting use case is to defer expensive calculations to be made outside of the Noir program, and then constraining the result; similar to the use of [unconstrained functions](../noir/concepts//unconstrained.md).

In short, anything that can be constrained in a Noir program but needs to be fetched from an external source is a great candidate to be used in oracles.

## Constraining oracles

Just like in The Matrix, Oracles are powerful. But with great power, comes great responsibility. Just because you're using them in a Noir program doesn't mean they're true. Noir has no superpowers. If you want to prove that Portugal won the Euro Cup 2016, you're still relying on potentially untrusted information.

To give a concrete example, Alice wants to login to the [NounsDAO](https://nouns.wtf/) forum with her username "noir_nouner" by proving she owns a noun without revealing her ethereum address. Her Noir program could have an oracle call like this:

```rust
#[oracle(getNoun)]
unconstrained fn get_noun(address: Field) -> Field
```

This oracle could naively resolve with the number of Nouns she possesses. However, it is useless as a trusted source, as the oracle could resolve to anything Alice wants. In order to make this oracle call actually useful, Alice would need to constrain the response from the oracle, by proving her address and the noun count belongs to the state tree of the contract.

In short, **Oracles don't prove anything. Your Noir program does.**

:::danger

If you don't constrain the return of your oracle, you could be clearly opening an attack vector on your Noir program. Make double-triple sure that the return of an oracle call is constrained!

:::

## How to use Oracles

On CLI, Nargo resolves oracles by making JSON RPC calls, which means it would require an RPC node to be running.

In JavaScript, NoirJS accepts and resolves arbitrary call handlers (that is, not limited to JSON) as long as they match the expected types the developer defines. Refer to [Foreign Call Handler](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) to learn more about NoirJS's call handling.

If you want to build using oracles, follow through to the [oracle guide](../how_to/how-to-oracles.md) for a simple example on how to do that.
Loading

0 comments on commit 19cee0e

Please sign in to comment.