Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(noir): use #[aztec(private)] and #[aztec(public) attributes #1735

Merged
merged 17 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from 16 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
6 changes: 3 additions & 3 deletions yarn-project/aztec.js/src/abis/ecdsa_account_contract.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions yarn-project/aztec.js/src/abis/schnorr_account_contract.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion yarn-project/noir-contracts/scripts/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ if [ -f "$error_file" ]; then
rm "$error_file"
echo "Error occurred in one or more child processes. Exiting..."
exit 1
fi
fi
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod storage;
// A contract used along with `Parent` contract to test nested calls.
contract Child {
use dep::aztec::abi;
use dep::aztec::abi::Hasher;
use dep::aztec::abi::PrivateContextInputs;
use dep::aztec::abi::PublicContextInputs;
use dep::aztec::context::{
Expand All @@ -12,86 +13,61 @@ contract Child {
use crate::storage::Storage;
use dep::aztec::oracle::logs::emit_unencrypted_log;

fn constructor(
inputs: PrivateContextInputs,
) -> distinct pub abi::PrivateCircuitPublicInputs {
// Return private circuit public inputs. All private functions need to return this as it is part of the input of the private kernel.
PrivateContext::new(inputs, 0).finish()
}
#[aztec(private)]
fn constructor() {}

// Returns a sum of the input and the chain id and version of the contract in private circuit public input's return_values.
#[aztec(private)]
fn value(
inputs: PrivateContextInputs,
input: Field,
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut context = PrivateContext::new(inputs, abi::hash_args([input]));

) {
context.return_values.push(input + context.chain_id() + context.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()
}

// Returns base_value + 42.
open fn pubGetValue(inputs: PublicContextInputs, base_value: Field) -> pub abi::PublicCircuitPublicInputs {
let mut context = PublicContext::new(inputs, abi::hash_args([base_value]));

#[aztec(public)]
open fn pubGetValue(base_value: Field) {
let returnValue = base_value + context.chain_id() + context.version() + context.block_number() + context.timestamp();

context.return_values.push(returnValue);
context.finish()
}

// Sets `current_value` to `new_value`
open fn pubSetValue(inputs: PublicContextInputs, new_value: Field) -> pub abi::PublicCircuitPublicInputs {
let mut context = PublicContext::new(inputs, abi::hash_args([new_value]));

#[aztec(public)]
open fn pubSetValue(new_value: Field) {
let storage = Storage::init();
storage.current_value.write(new_value);
let _hash = emit_unencrypted_log(new_value);
context.return_values.push(new_value);
context.finish()
}

// Increments `current_value` by `new_value`
open fn pubIncValue(inputs: PublicContextInputs, new_value: Field) -> pub abi::PublicCircuitPublicInputs {
let mut context = PublicContext::new(inputs, abi::hash_args([new_value]));

#[aztec(public)]
open fn pubIncValue(new_value: Field) {
let storage = Storage::init();
let old_value = storage.current_value.read();
storage.current_value.write(old_value + new_value);
let _hash = emit_unencrypted_log(new_value);
context.return_values.push(new_value);
context.finish()
}

open fn setValueTwiceWithNestedFirst(
inputs: PublicContextInputs,
) -> pub abi::PublicCircuitPublicInputs {
let mut context = PublicContext::new(inputs, abi::hash_args([]));

#[aztec(public)]
open fn setValueTwiceWithNestedFirst() {
let pubSetValueSelector = 0x5b0f91b0;
let _ret = context.call_public_function(context.this_address(), pubSetValueSelector, [10]);

let storage = Storage::init();
storage.current_value.write(20);
let _hash = emit_unencrypted_log(20);

context.finish()
}

open fn setValueTwiceWithNestedLast(
inputs: PublicContextInputs,
) -> pub abi::PublicCircuitPublicInputs {
let mut context = PublicContext::new(inputs, abi::hash_args([]));

#[aztec(public)]
open fn setValueTwiceWithNestedLast() {
let storage = Storage::init();
storage.current_value.write(20);
let _hash = emit_unencrypted_log(20);

let pubSetValueSelector = 0x5b0f91b0;
let _ret = context.call_public_function(context.this_address(), pubSetValueSelector, [10]);

context.finish()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
mod storage;

contract EasyPrivateToken {
use dep::aztec::abi::Hasher;
use dep::value_note::{
balance_utils,
value_note::{
Expand All @@ -25,62 +26,41 @@ contract EasyPrivateToken {
/**
* Initialise the contract's initial state variables.
*/
#[aztec(private)]
fn constructor(
/*********************************/
inputs: PrivateContextInputs,
/*********************************/
initial_supply: u120,
owner: Field,
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut context = PrivateContext::new(inputs, abi::hash_args([initial_supply as Field, owner]));
) {
let storage = Storage::init();
let balances = storage.balances;

balances.at(owner).add(&mut context, 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()
}

// Mints `amount` of tokens to `owner`.
#[aztec(private)]
fn mint(
//*********************************/
// Should eventually be hidden:
inputs: PrivateContextInputs,
//*********************************/
amount: u120,
owner: Field,
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut context = PrivateContext::new(inputs, abi::hash_args([amount as Field, owner]));
) {
let storage = Storage::init();
let balances = storage.balances;

balances.at(owner).add(&mut context, 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()
}

// Transfers `amount` of tokens from `sender` to a `recipient`.
#[aztec(private)]
fn transfer(
//*********************************/
// Should eventually be hidden:
inputs: PrivateContextInputs,
//*********************************/
amount: u120,
sender: Field,
recipient: Field,
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut context = PrivateContext::new(inputs, abi::hash_args([amount as Field, sender, recipient]));
) {
let storage = Storage::init();
let balances = storage.balances;

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

balances.at(recipient).add(&mut context, 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()
}

// Helper function to get the balance of a user ("unconstrained" is a Noir alternative of Solidity's "view" function).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ contract EcdsaAccount {
use dep::aztec::abi;
use dep::aztec::abi::PrivateContextInputs;
use dep::aztec::abi::CallContext;
use dep::aztec::abi::Hasher;
use dep::aztec::context::PrivateContext;
use dep::aztec::log::emit_encrypted_log;
use dep::aztec::oracle::get_public_key::get_public_key;
Expand All @@ -29,19 +30,11 @@ contract EcdsaAccount {
use crate::ecdsa_public_key_note::ECDSA_PUBLIC_KEY_NOTE_LEN;

// All calls made by this account will be routed through this entrypoint
#[aztec(private)]
fn entrypoint(
inputs: pub PrivateContextInputs,
payload: pub EntrypointPayload, // contains a set of arguments, selectors, targets and a nonce
signature: pub [u8;64],
) -> distinct pub abi::PrivateCircuitPublicInputs {

// Initialise context
// ENTRYPOINT_PAYLOAD_SIZE(13) + 64
let mut args: BoundedVec<Field, 77> = BoundedVec::new(0);
args.push_array(payload.serialize());
for byte in signature { args.push(byte as Field); }
let mut context = PrivateContext::new(inputs, abi::hash_args(args.storage));

) {
// Load public key from storage
let storage = Storage::init();
let public_key = storage.public_key.get_note(&mut context);
Expand All @@ -61,23 +54,16 @@ contract EcdsaAccount {
assert(verification == true);

payload.execute_calls(&mut context);

context.finish()
}

// Creates a new account out of an ECDSA public key to use for signature verification
#[aztec(private)]
fn constructor(
inputs: pub PrivateContextInputs,
signing_pub_key_x: pub [u8;32],
signing_pub_key_y: pub [u8;32],
) -> distinct pub abi::PrivateCircuitPublicInputs {
) {
let storage = Storage::init();

let mut args: BoundedVec<Field, 64> = BoundedVec::new(0);
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 = PrivateContext::new(inputs, abi::hash_args(args.storage));

let this = context.this_address();
let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this);
storage.public_key.initialise(&mut context, &mut pub_key_note);
Expand All @@ -89,8 +75,6 @@ contract EcdsaAccount {
get_public_key(this),
pub_key_note.serialise(),
);

context.finish()
}

// Computes note hash and nullifier.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod private_token_contract_interface;
contract Escrow {
use dep::std;
use dep::aztec::abi;
use dep::aztec::abi::Hasher;
use dep::aztec::abi::PrivateContextInputs;
use dep::aztec::abi::CallContext;
use dep::aztec::private_call_stack_item::PrivateCallStackItem;
Expand All @@ -30,11 +31,10 @@ contract Escrow {
use crate::private_token_contract_interface::PrivateTokenContractInterface;

// Creates a new instance
#[aztec(private)]
fn constructor(
inputs: pub PrivateContextInputs,
owner: pub Field
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut context = PrivateContext::new(inputs, abi::hash_args([owner]));
) {
let this = context.this_address();

let storage = Storage::init();
Expand All @@ -47,18 +47,15 @@ contract Escrow {
get_public_key(this),
note.serialise(),
);

context.finish()
}

// Withdraws balance. Requires that msg.sender is registered as an owner.
#[aztec(private)]
fn withdraw(
inputs: pub PrivateContextInputs,
token: pub Field,
amount: pub Field,
recipient: pub Field,
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut context = PrivateContext::new(inputs, abi::hash_args([token, amount, recipient]));
) {
let this = context.this_address();
let sender = context.msg_sender();
let storage = Storage::init();
Expand All @@ -71,10 +68,7 @@ contract Escrow {
assert(note.address == sender);
assert(note.owner == this);

// TODO: Can we dynamically get this selector?
let _callStackItem = PrivateTokenContractInterface::at(token).transfer(&mut context, amount, recipient);

context.finish()
}

unconstrained fn compute_note_hash_and_nullifier(contract_address: Field, nonce: Field, storage_slot: Field, preimage: [Field; ADDRESS_NOTE_LEN]) -> [Field; 4] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod storage;

contract ExamplePublicStateIncrement {
use dep::aztec::abi;
use dep::aztec::abi::Hasher;
use dep::aztec::abi::PrivateContextInputs;
use dep::aztec::abi::PublicContextInputs;
use dep::aztec::context::{
Expand All @@ -18,41 +19,28 @@ contract ExamplePublicStateIncrement {
};

// call initialise_a();
#[aztec(private)]
fn constructor(
inputs: PrivateContextInputs,
) -> distinct pub abi::PrivateCircuitPublicInputs {
let mut context = PrivateContext::new(inputs, 0);

) {
let initialise_a_function_selector: Field = 1234;
let _return_values = context.call_public_function_no_args(context.this_address(), initialise_a_function_selector);

context.finish()
}

// a = 100;
open internal fn initialise_a(
inputs: PublicContextInputs,
) -> pub abi::PublicCircuitPublicInputs {
let mut context = PublicContext::new(inputs, abi::hash_args([]));

#[aztec(public)]
open internal fn initialise_a() {
let storage = Storage::init();
storage.a.write(100);

context.finish()
}

// a += b;
#[aztec(public)]
open fn increment_a(
inputs: PublicContextInputs,
b: Field,
) -> pub abi::PublicCircuitPublicInputs {
let mut context = PublicContext::new(inputs, abi::hash_args([b]));

) {
let storage = Storage::init();
let mut a = storage.a.read();
a += b;
storage.a.write(a);

context.finish()
}
}
Loading