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
2 changes: 1 addition & 1 deletion yarn-project/acir-simulator/src/public/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ describe('ACIR public execution simulator', () => {
globalVariables.timestamp.value,
),
]);
});
}, 20000);
});

describe('Public -> Private / Cross Chain messaging', () => {
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/noir-contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

This package contains the source code and the Aztec ABIs for the example contracts used in tests.

## Disclaimer

Please note that any example contract set out herein is provided solely for informational purposes only and does not constitute any inducement to use or deploy. Any implementation of any such contract with an interface or any other infrastructure should be used in accordance with applicable laws and regulations.

## Setup

### Installing Noir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ contract Child {
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut context = Context::new(inputs, abi::hash_args([input]));

context.return_values = context.return_values.push(input + inputs.private_global_variables.chain_id + inputs.private_global_variables.version);
context.return_values.push(input + inputs.private_global_variables.chain_id + inputs.private_global_variables.version);

// Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel.
context.finish()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ contract EasyZkToken {
let storage = Storage::init();
let balances = storage.balances;

context = balances.at(owner).add(context, initial_supply, owner);
balances.at(owner).add(&mut context, initial_supply, owner);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay, new syntax! Just to check: the compiler will complain if we don't include this &mut keyword, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct! It results in something slightly more verbose and cumbersome than I'd have liked, because many end users won't be familiar with references, but now they have to be. But I guess Noir emulates Rust syntax, so this is unavoidable.
I think it's to prevent foot guns. The developer has to consciously say "I am aware that the context I am passing to this function could get mutated"


context = emit_unencrypted_log(context, "Balance set in constructor");
emit_unencrypted_log(&mut context, "Balance set in constructor");

// Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel.
context.finish()
Expand All @@ -57,9 +57,9 @@ contract EasyZkToken {
let storage = Storage::init();
let balances = storage.balances;

context = balances.at(owner).add(context, amount, owner);
balances.at(owner).add(&mut context, amount, owner);

context = emit_unencrypted_log(context, "Coins minted");
emit_unencrypted_log(&mut context, "Coins minted");

// Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel..
context.finish()
Expand All @@ -79,11 +79,11 @@ contract EasyZkToken {
let storage = Storage::init();
let balances = storage.balances;

context = balances.at(sender).sub(context, amount, sender);
balances.at(sender).sub(&mut context, amount, sender);

context = balances.at(recipient).add(context, amount, recipient);
balances.at(recipient).add(&mut context, amount, recipient);

context = emit_unencrypted_log(context, "Coins transferred");
emit_unencrypted_log(&mut context, "Coins transferred");

// Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel..
context.finish()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ impl EcdsaPublicKeyNote {
])[0]
}

fn set_header(mut self: Self, header: NoteHeader) -> Self {
fn set_header(&mut self, header: NoteHeader) {
self.header = header;
self
}

fn dummy() -> Self {
Expand Down Expand Up @@ -125,8 +124,8 @@ fn get_header(note: EcdsaPublicKeyNote) -> NoteHeader {
note.header
}

fn set_header(note: EcdsaPublicKeyNote, header: NoteHeader) -> EcdsaPublicKeyNote {
note.set_header(header)
fn set_header(note: &mut EcdsaPublicKeyNote, header: NoteHeader) {
note.set_header(header);
}

global EcdsaPublicKeyNoteInterface = NoteInterface {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,13 @@ contract EcdsaAccount {
// Initialise context
// 71 = ENTRYPOINT_PAYLOAD_SIZE(7) + 64
let mut args: BoundedVec<Field, 71> = BoundedVec::new(0);
args = args.push_array(payload.serialize());
for byte in signature { args = args.push(byte as Field); }
args.push_array(payload.serialize());
for byte in signature { args.push(byte as Field); }
let mut context = Context::new(inputs, abi::hash_args(args.storage));

// Load public key from storage
let storage = Storage::init();
let (context_1, public_key) = storage.public_key.get_note(context);
context = context_1;
let public_key = storage.public_key.get_note(&mut context);

// Verify payload signature using Ethereum's signing scheme
let payload_bytes: [u8; entrypoint::ENTRYPOINT_PAYLOAD_SIZE_IN_BYTES] = payload.to_be_bytes();
Expand All @@ -61,7 +60,8 @@ contract EcdsaAccount {
// debug_log::debug_log_array_with_prefix("challenge", challenge);
// debug_log::debug_log_array_with_prefix("signature", signature);

context = payload.execute_calls(context);
payload.execute_calls(&mut context);

context.finish()
}

Expand All @@ -74,16 +74,16 @@ contract EcdsaAccount {
let storage = Storage::init();

let mut args: BoundedVec<Field, 64> = BoundedVec::new(0);
for byte in signing_pub_key_x { args = args.push(byte as Field); }
for byte in signing_pub_key_y { args = args.push(byte as Field); }
for byte in signing_pub_key_x { args.push(byte as Field); }
for byte in signing_pub_key_y { args.push(byte as Field); }
let mut context = Context::new(inputs, abi::hash_args(args.storage));

let this = inputs.call_context.storage_contract_address;
let pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this);
context = storage.public_key.initialise(context, pub_key_note);
let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, inputs.call_context.storage_contract_address);
storage.public_key.initialise(&mut context, &mut pub_key_note);

context = emit_encrypted_log(
context,
emit_encrypted_log(
&mut context,
this,
storage.public_key.storage_slot,
this,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ contract Lending {
create_nullifier::create_nullifier,
};
use dep::aztec::public_call_stack_item::{
PublicCallStackItem,
call_public_function,
call_public_function_no_args,
PublicCallStackItem
call_public_function_no_args,
};
use crate::storage::{Storage, Tot, Account};

Expand Down Expand Up @@ -80,7 +80,7 @@ contract Lending {
owner: Field,
amount: Field
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut initialContext = Context::new(inputs, abi::hash_args([
let mut context = Context::new(inputs, abi::hash_args([
secret,
owner,
amount
Expand All @@ -97,11 +97,10 @@ contract Lending {
// Unshield tokens into this contract.

// _deposit(account, amount)
let (_callStackItem, mut context) = PublicCallStackItem::call(
let _callStackItem = context.call_public_function(
inputs.call_context.storage_contract_address,
3009041984,
[account, amount],
initialContext
[account, amount]
);

context.finish()
Expand Down Expand Up @@ -138,18 +137,17 @@ contract Lending {
secret: Field,
amount: Field
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut initialContext = Context::new(inputs, abi::hash_args([
let mut context = Context::new(inputs, abi::hash_args([
secret,
amount
]));

let me = inputs.call_context.msg_sender;
let account = Account::new(me, secret).key();
let (_callStackItem, mut context) = PublicCallStackItem::call(
let _callStackItem = context.call_public_function(
inputs.call_context.storage_contract_address,
1065861440,
[account, amount],
initialContext
[account, amount]
);

context.finish()
Expand Down Expand Up @@ -196,19 +194,18 @@ contract Lending {
secret: Field,
amount: Field
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut initialContext = Context::new(inputs, abi::hash_args([
let mut context = Context::new(inputs, abi::hash_args([
secret,
amount
]));

let me = inputs.call_context.msg_sender;
let account = Account::new(me, secret).key();

let (_callStackItem, mut context) = PublicCallStackItem::call(
let _callStackItem = context.call_public_function(
inputs.call_context.storage_contract_address,
1462609836,
[account, amount],
initialContext
[account, amount]
);

context.finish()
Expand Down Expand Up @@ -253,7 +250,7 @@ contract Lending {
owner: Field,
amount: Field
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut initialContext = Context::new(inputs, abi::hash_args([
let mut context = Context::new(inputs, abi::hash_args([
secret,
owner,
amount
Expand All @@ -269,11 +266,10 @@ contract Lending {

// @todo @lherskind Transfer tokens from me to this contract.

let (_callStackItem, mut context) = PublicCallStackItem::call(
let _callStackItem = context.call_public_function(
inputs.call_context.storage_contract_address,
3985016136,
[account, amount],
initialContext
[account, amount]
);

context.finish()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ contract NonNativeToken {
let mut context = Context::new(inputs, abi::hash_args([initial_supply, owner]));

let balance = storage.balances.at(owner);
context = send_note(context, balance, initial_supply, owner);
send_note(&mut context, balance, initial_supply, owner);

// Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel.
context.finish()
Expand Down Expand Up @@ -97,11 +97,10 @@ contract NonNativeToken {
let content_hash = get_mint_content_hash(amount, owner, canceller);

// Get the l1 message from an oracle call
let updated_context = context.consume_l1_to_l2_message(inputs, msg_key, content_hash, secret);
context = updated_context;
context.consume_l1_to_l2_message(inputs, msg_key, content_hash, secret);

let balance = storage.balances.at(owner);
context = send_note(context, balance, amount, owner);
send_note(&mut context, balance, amount, owner);

// Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel.
context.finish()
Expand All @@ -126,10 +125,10 @@ contract NonNativeToken {
]));

let sender_balance = storage.balances.at(sender);
context = spend_notes(context, sender_balance, amount, sender);
spend_notes(&mut context, sender_balance, amount, sender);

let content = get_withdraw_content_hash(amount, recipient, callerOnL1);
context = context.message_portal(content);
context.message_portal(content);

// Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel.
context.finish()
Expand Down Expand Up @@ -215,10 +214,10 @@ contract NonNativeToken {

// Gets the set of sender's notes and picks 2 of those.
let sender_balance = storage.balances.at(sender);
context = spend_notes(context, sender_balance, amount, sender);
spend_notes(&mut context, sender_balance, amount, sender);

let balance = storage.balances.at(recipient);
context = send_note(context, balance, amount, recipient);
send_note(&mut context, balance, amount, recipient);

// Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel.
context.finish()
Expand Down Expand Up @@ -266,11 +265,11 @@ contract NonNativeToken {

// Assert that the note exists within the tree
let public_note = TransparentNote::new_from_secret(amount, secret);
context = public_note.consume_in_secret(context, inputs.roots.private_data_tree_root, secret);
public_note.consume_in_secret(&mut context, inputs.roots.private_data_tree_root, secret);

// Mint the tokens
let balance = storage.balances.at(owner);
context = send_note(context, balance, amount, owner);
send_note(&mut context, balance, amount, owner);

context.finish()
}
Expand All @@ -288,16 +287,15 @@ contract NonNativeToken {

// Remove user balance
let sender_balance = storage.balances.at(owner);
context = spend_notes(context, sender_balance, amount, owner);
spend_notes(&mut context, sender_balance, amount, owner);

// enqueue a public function to perform the public state update.
let thisAddress = inputs.call_context.storage_contract_address;

// addUnshieldedBalance selector (in decimal)
// recompute by: `cast keccak addUnshieldedBalance(field,field)` -> convert to decimal
let pubEntryPointSelector = 753269941;
let (_callStackItem1, mut context1) = PublicCallStackItem::call(thisAddress, pubEntryPointSelector, [amount, recipient], context);
context = context1;
let _callStackItem1 = context.call_public_function(thisAddress, pubEntryPointSelector, [amount, recipient]);

context.finish()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ impl TransparentNote {
pedersen([self.amount, self.secretHash])[0]
}

fn consume_in_secret(self: Self, mut context: Context, root: Field, secret: Field) -> Context {
fn consume_in_secret(self: Self, context: &mut Context, root: Field, secret: Field) {
// Get the commitment value (before silo)
let commitment = self.get_commitment();

// Let the kernel perform the read.
context = context.push_read_request(commitment);
context.push_read_request(commitment);

// Get the commitment data, (where it is in the db)
let commitment_oracle_call = get_commitment(commitment);
Expand All @@ -50,7 +50,7 @@ impl TransparentNote {
assert(root == commitment_data.root);

// Calculate the nullifier
self.emit_nullifier(context, secret, commitment, commitment_data.leaf_index)
self.emit_nullifier(context, secret, commitment, commitment_data.leaf_index);
}

fn compute_secret_hash(secret: Field) -> Field {
Expand All @@ -63,7 +63,7 @@ impl TransparentNote {
assert(self.secretHash == hash);
}

fn emit_nullifier(_self: Self, mut context: Context, secret: Field, siloed_commitment: Field, index: Field) -> Context {
fn emit_nullifier(_self: Self, context: &mut Context, secret: Field, siloed_commitment: Field, index: Field) {
// Create a nullifier for the message based on its index in the tree

let nullifier = pedersen([secret, siloed_commitment, index])[0];
Expand Down
Loading