Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions boxes/boxes/react/src/contracts/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ contract BoxReact {
let new_number = FieldNote { value: number };

self.storage.numbers.at(owner).initialize(new_number).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
}

#[external("private")]
fn setNumber(number: Field, owner: AztecAddress) {
self.storage.numbers.at(owner).replace(|_old| FieldNote { value: number }).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
}

Expand Down
4 changes: 2 additions & 2 deletions boxes/boxes/vite/src/contracts/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ contract BoxReact {
let new_number = FieldNote { value: number };

self.storage.numbers.at(owner).initialize(new_number).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
}

#[external("private")]
fn setNumber(number: Field, owner: AztecAddress) {
self.storage.numbers.at(owner).replace(|_old| FieldNote { value: number }).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn transfer(to: AztecAddress, amount: u128) {

self.emit(Transfer { from, to, amount }).deliver_to(
to,
MessageDelivery.ONCHAIN_UNCONSTRAINED,
MessageDelivery::onchain_unconstrained(),
);
}
```
Expand All @@ -55,15 +55,15 @@ You can deliver the same event to multiple recipients with different delivery mo

```rust
let message = self.emit(Transfer { from, to, amount });
message.deliver_to(from, MessageDelivery.OFFCHAIN);
message.deliver_to(to, MessageDelivery.ONCHAIN_CONSTRAINED);
message.deliver_to(from, MessageDelivery::offchain());
message.deliver_to(to, MessageDelivery::onchain_constrained());
```

The `MessageDelivery` options are:

- **`ONCHAIN_CONSTRAINED`** - Constrained encryption with onchain delivery. Slowest proving but provides cryptographic guarantees that recipients can decrypt messages.
- **`ONCHAIN_UNCONSTRAINED`** - Unconstrained encryption with onchain delivery. Faster proving, but trusts the sender to encrypt correctly.
- **`OFFCHAIN`** - Unconstrained encryption with offchain delivery. Lowest cost, but requires custom infrastructure to deliver messages to recipients.
- **`onchain_constrained()`** - Constrained encryption with onchain delivery. Slowest proving but provides cryptographic guarantees that recipients can decrypt messages.
- **`onchain_unconstrained()`** - Unconstrained encryption with onchain delivery. Faster proving, but trusts the sender to encrypt correctly.
- **`offchain()`** - Unconstrained encryption with offchain delivery. Lowest cost, but requires custom infrastructure to deliver messages to recipients.

:::note
Emitting private events is optional. Onchain delivery publishes encrypted data to Ethereum blobs, inheriting Ethereum's data availability guarantees. You can choose to share information offchain instead.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub contract PrivateToken {
fn mint(amount: u128, recipient: AztecAddress) {
// Adding to the balance returns a MaybeNoteMessage
self.storage.balances.at(recipient).add(amount)
.deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
.deliver(MessageDelivery::onchain_constrained());
}
}
```
Expand All @@ -37,7 +37,7 @@ pub contract PrivateToken {

Aztec provides three delivery modes that offer different tradeoffs between cost, proving time, and guarantees:

### `MessageDelivery.OFFCHAIN`
### `MessageDelivery::offchain()`

**Fully offchain delivery with no guarantees.**

Expand Down Expand Up @@ -76,7 +76,7 @@ This is expected to be the most common delivery method when you don't need const
```rust
// Change note - sender is motivated to deliver to themselves
self.storage.balances.at(sender).add(change_amount)
.deliver(MessageDelivery.OFFCHAIN);
.deliver(MessageDelivery::offchain());
```

:::info TODO
Expand Down Expand Up @@ -119,7 +119,7 @@ await contract.methods.process_message(ciphertext, messageContext.toNoirStruct()

See the [aztec.js documentation](../../aztec-js/index.md) for more details on accessing transaction effects.

### `MessageDelivery.ONCHAIN_UNCONSTRAINED`
### `MessageDelivery::onchain_unconstrained()`

**Onchain delivery with no content guarantees.**

Expand All @@ -133,10 +133,10 @@ This mode provides the same low proving time as `OFFCHAIN` while avoiding the ne
```rust
// Minting to an admin who controls the contract
self.storage.balances.at(admin).add(amount)
.deliver(MessageDelivery.ONCHAIN_UNCONSTRAINED);
.deliver(MessageDelivery::onchain_unconstrained());
```

### `MessageDelivery.ONCHAIN_CONSTRAINED`
### `MessageDelivery::onchain_constrained()`

**Onchain delivery with guaranteed correct content.**

Expand All @@ -150,7 +150,7 @@ self.storage.balances.at(admin).add(amount)
```rust
// Minting to an arbitrary recipient - must guarantee delivery
self.storage.balances.at(recipient).add(amount)
.deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
.deliver(MessageDelivery::onchain_constrained());
```

## Choosing a Delivery Mode
Expand Down Expand Up @@ -199,7 +199,7 @@ You can deliver a note to an address other than the note's owner using `.deliver
```rust
// Create a note owned by `owner` but deliver it to `auditor`
self.storage.balances.at(owner).add(amount)
.deliver_to(auditor, MessageDelivery.ONCHAIN_CONSTRAINED);
.deliver_to(auditor, MessageDelivery::onchain_constrained());
```

**Important:** The recipient (e.g. an `auditor`) can see the note was created but **cannot use it** - only the owner can spend the note (this is authorized by the contract logic). The recipient also cannot see when/if the note is nullified.
Expand All @@ -219,12 +219,12 @@ fn transfer(amount: u128, sender: AztecAddress, recipient: AztecAddress) {
// Subtract from sender - unconstrained since sender is the caller
self.storage.balances.at(sender)
.sub(amount)
.deliver(MessageDelivery.ONCHAIN_UNCONSTRAINED);
.deliver(MessageDelivery::onchain_unconstrained());

// Add to recipient - constrained delivery for untrusted sender
self.storage.balances.at(recipient)
.add(amount)
.deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
.deliver(MessageDelivery::onchain_constrained());
}
```

Expand All @@ -238,6 +238,6 @@ fn constructor(admin: AztecAddress) {
// Use unconstrained delivery since we don't know if deployer is incentivized
self.storage.admin
.initialize(AddressNote { address: admin }, admin)
.deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
.deliver(MessageDelivery::onchain_constrained());
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,9 @@ When working with private state variables, many operations return a `NoteMessage
#### Delivery Methods

Private notes need to be communicated to their recipients so they know the note exists and can use it. The [`NoteMessage`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/note/struct.NoteMessage) wrapper forces you to make an explicit choice about how this happens:
- [`MessageDelivery.ONCHAIN_CONSTRAINED`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.ONCHAIN_CONSTRAINED): Verified in the circuit (most secure, but highest cost) - Use when the sender cannot be trusted to deliver correctly (e.g., protocol fees, multisig config updates). **Warning:** Currently [not fully constrained](https://github.com/AztecProtocol/aztec-packages/issues/14565) - the log's tag is unconstrained.
- [`MessageDelivery.ONCHAIN_UNCONSTRAINED`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.ONCHAIN_UNCONSTRAINED): Message stored onchain but no guarantees on content - Use when the sender is incentivized to deliver correctly but may not have an offchain channel to the recipient.
- [`MessageDelivery.OFFCHAIN`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDeliveryEnum#structfield.OFFCHAIN): Lowest cost, no onchain data - Use when the sender and recipient can communicate and the sender is incentivized to deliver correctly.
- [`MessageDelivery::onchain_constrained()`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDelivery#method.onchain_constrained): Verified in the circuit (most secure, but highest cost) - Use when the sender cannot be trusted to deliver correctly (e.g., protocol fees, multisig config updates). **Warning:** Currently [not fully constrained](https://github.com/AztecProtocol/aztec-packages/issues/14565) - the log's tag is unconstrained.
- [`MessageDelivery::onchain_unconstrained()`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDelivery#method.onchain_unconstrained): Message stored onchain but no guarantees on content - Use when the sender is incentivized to deliver correctly but may not have an offchain channel to the recipient.
- [`MessageDelivery::offchain()`](pathname:///aztec-nr-api/#api_ref_version/noir_aztec/messages/message_delivery/struct.MessageDelivery#method.offchain): Lowest cost, no onchain data - Use when the sender and recipient can communicate and the sender is incentivized to deliver correctly.

#include_code note_delivery /noir-projects/noir-contracts/contracts/app/private_token_contract/src/main.nr rust

Expand Down Expand Up @@ -324,7 +324,7 @@ fn perform_admin_action() {
// value of the counter and can update it again in the future.
self.storage.admin_call_count
.replace(|current| UintNote{ value: current.value + 1 }) // wouldn't it be great if we didn't have to deal with this wrapping and unwrapping?
.deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
.deliver(MessageDelivery::onchain_constrained());

// ...
}
Expand Down Expand Up @@ -381,7 +381,7 @@ This function allows us to get the note of a `PrivateMutable`, essentially readi
#[external("private")]
fn read_settings() {
let owner = self.msg_sender();
self.storage.user_settings.at(owner).get_note().deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
self.storage.user_settings.at(owner).get_note().deliver(MessageDelivery::onchain_constrained());
}
```

Expand Down Expand Up @@ -484,11 +484,11 @@ When initializing, you still pass an owner address, but this specifies who can d

```rust
// owner_address determines who can see the note, not where it's stored
self.storage.admin.initialize(note, owner_address).deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
self.storage.admin.initialize(note, owner_address).deliver(MessageDelivery::onchain_constrained());
```

:::warning
`SinglePrivateMutable` uses a nullify-and-recreate pattern when reading. Unless the caller is incentivized to deliver the note message correctly, you should use `MessageDelivery.ONCHAIN_CONSTRAINED` to prevent malicious actors from bricking the contract by failing to deliver the note.
`SinglePrivateMutable` uses a nullify-and-recreate pattern when reading. Unless the caller is incentivized to deliver the note message correctly, you should use `MessageDelivery::onchain_constrained()` to prevent malicious actors from bricking the contract by failing to deliver the note.
:::

## Containers
Expand Down Expand Up @@ -558,7 +558,7 @@ fn transfer(from: AztecAddress, to: AztecAddress, amount: u128) {

// Access the balance for the 'to' address
let new_note = UintNote { value: amount };
self.storage.balances.at(to).insert(new_note).deliver(MessageDelivery.ONCHAIN_UNCONSTRAINED);
self.storage.balances.at(to).insert(new_note).deliver(MessageDelivery::onchain_unconstrained());
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/docs-developers/docs/aztec-nr/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ A good example of this is writing to private state variables. These functions re

```rust
storage.votes.insert(new_vote); // compiler error - unused NoteMessage return value
storage.votes.insert(new_vote).deliver(MessageDelivery.ONCHAIN_CONSTRAINED); // deliver the note message onchain
storage.votes.insert(new_vote).deliver(MessageDelivery::onchain_constrained()); // deliver the note message onchain
```

## Contract Development
Expand Down
2 changes: 1 addition & 1 deletion docs/docs-developers/docs/aztec-nr/standards/escrow.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub fn _share_escrow(
) {
let event_struct = EscrowDetailsLogContent { escrow, master_secret_keys };
emit_event_in_private(context, event_struct).deliver_to(
account, MessageDelivery.ONCHAIN_CONSTRAINED,
account, MessageDelivery::onchain_constrained(),
);
}
```
Expand Down
16 changes: 15 additions & 1 deletion docs/docs-developers/docs/resources/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ Aztec is in active development. Each version may introduce breaking changes that

## TBD

### [Aztec.nr] `MessageDelivery` API syntax change

`MessageDelivery` variants are now accessed via constructor functions instead of dot notation:

```diff
- MessageDelivery.OFFCHAIN
+ MessageDelivery::offchain()

- MessageDelivery.ONCHAIN_UNCONSTRAINED
+ MessageDelivery::onchain_unconstrained()

- MessageDelivery.ONCHAIN_CONSTRAINED
+ MessageDelivery::onchain_constrained()
```

### [Aztec.js] `ExtendedDirectionalAppTaggingSecret` renamed to `AppTaggingSecret`

`ExtendedDirectionalAppTaggingSecret` has been renamed to `AppTaggingSecret`.
Expand All @@ -24,7 +39,6 @@ Aztec is in active development. Each version may introduce breaking changes that
```

**Impact**: Code importing or referencing `ExtendedDirectionalAppTaggingSecret` should update to `AppTaggingSecret`.

### [Aztec.nr] `public_checks` helpers moved to `aztec-nr`

The `privately_check_timestamp`, `privately_check_block_number`, and related caller helpers previously in `noir-contracts/contracts/protocol/public_checks_contract/src/utils.nr` are now in `aztec-nr/aztec/src/public_checks.nr`. Consumer contracts should update their imports:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Let’s create a constructor method to run on deployment that assigns an initial

#include_code constructor /docs/examples/contracts/counter_contract/src/main.nr rust

This function accesses the counters from storage. It adds the `headstart` value to the `owner`'s counter using `at().add()`, then calls `.deliver(MessageDelivery.ONCHAIN_CONSTRAINED)` to ensure the note is delivered onchain.
This function accesses the counters from storage. It adds the `headstart` value to the `owner`'s counter using `at().add()`, then calls `.deliver(MessageDelivery::onchain_constrained())` to ensure the note is delivered onchain.

We have annotated this and other functions with `#[external("private")]` which are ABI macros so the compiler understands it will handle private inputs.

Expand Down
10 changes: 5 additions & 5 deletions docs/examples/contracts/bob_token_contract/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub contract BobToken {
self.enqueue_self._deduct_public_balance(sender, amount);
// Add to private balance
self.storage.private_balances.at(sender).add(amount as u128).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
}
// docs:end:public_to_private
Expand All @@ -107,11 +107,11 @@ pub contract BobToken {
let sender = self.msg_sender();
// Spend sender's notes (consumes existing notes)
self.storage.private_balances.at(sender).sub(amount as u128).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
// Create new notes for recipient
self.storage.private_balances.at(to).add(amount as u128).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
}
// docs:end:transfer_private
Expand Down Expand Up @@ -144,7 +144,7 @@ pub contract BobToken {

// If check passes, mint tokens privately
self.storage.private_balances.at(employee).add(amount as u128).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
}
// docs:end:mint_private
Expand All @@ -155,7 +155,7 @@ pub contract BobToken {
let sender = self.msg_sender();
// Remove from private balance
self.storage.private_balances.at(sender).sub(amount as u128).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
// Enqueue public credit
self.enqueue_self._credit_public_balance(sender, amount);
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/contracts/counter_contract/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub contract Counter {
// We can name our initializer anything we want as long as it's marked as aztec(initializer)
fn initialize(headstart: u128, owner: AztecAddress) {
self.storage.counters.at(owner).add(headstart).deliver(
MessageDelivery.ONCHAIN_CONSTRAINED,
MessageDelivery::onchain_constrained(),
);
}
// docs:end:constructor
Expand All @@ -37,7 +37,7 @@ pub contract Counter {
#[external("private")]
fn increment(owner: AztecAddress) {
debug_log_format("Incrementing counter for owner {0}", [owner.to_field()]);
self.storage.counters.at(owner).add(1).deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
self.storage.counters.at(owner).add(1).deliver(MessageDelivery::onchain_constrained());
}
// docs:end:increment

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/contracts/nft/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub contract NFTPunk {

// we create an NFT note and insert it to the PrivateSet - a collection of notes meant to be read in private
let new_nft = NFTNote { token_id };
self.storage.owners.at(to).insert(new_nft).deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
self.storage.owners.at(to).insert(new_nft).deliver(MessageDelivery::onchain_constrained());

// calling the internal public function above to indicate that the NFT is taken
self.enqueue_self._mark_nft_exists(token_id, true);
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/webapp-tutorial/contracts/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub contract PodRacing {
.at(game_id)
.at(player)
.insert(GameRoundNote::new(track1, track2, track3, track4, track5, round, player))
.deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
.deliver(MessageDelivery::onchain_constrained());

self.enqueue(PodRacing::at(self.context.this_address()).validate_and_play_round(
player,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ impl<Storage, CallSelf, EnqueueSelf, CallSelfStatic, EnqueueSelfStatic, CallInte
/// let from = self.msg_sender();
///
/// let message: EventMessage = self.emit(Transfer { from, to, amount });
/// message.deliver_to(from, MessageDelivery.OFFCHAIN);
/// message.deliver_to(to, MessageDelivery.ONCHAIN_CONSTRAINED);
/// message.deliver_to(from, MessageDelivery::offchain());
/// message.deliver_to(to, MessageDelivery::onchain_constrained());
/// }
/// ```
///
Expand Down
Loading
Loading