Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Nov 12, 2024
1 parent 21e94ff commit 7c683a6
Show file tree
Hide file tree
Showing 21 changed files with 68 additions and 64 deletions.
2 changes: 1 addition & 1 deletion docs/docs/tutorials/codealong/aztecjs-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ Our output should now look like this:
Here, we used the same contract abstraction as was previously used for reading Alice's balance. But this time we called `send()` generating and sending a transaction to the network. After waiting for the transaction to settle we were able to check the new balance values.

Finally, the contract has 2 `mint` functions that can be used to generate new tokens for an account.
We will focus only on `mint_private`.
We will focus only on `mint_to_private`.
This function is public but it mints tokens privately.
This function takes:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Let’s do the similar for the private flow:

Here we want to send a message to mint tokens privately on Aztec! Some key differences from the previous method are:

- The content hash uses a different function name - `mint_private`. This is done to make it easy to separate concerns. If the contentHash between the public and private message was the same, then an attacker could consume a private message publicly!
- The content hash uses a different function name - `mint_to_private`. This is done to make it easy to separate concerns. If the contentHash between the public and private message was the same, then an attacker could consume a private message publicly!
- Since we want to mint tokens privately, we shouldn’t specify a `to` Aztec address (remember that Ethereum is completely public). Instead, we will use a secret hash - `secretHashForRedeemingMintedNotes`. Only he who knows the preimage to the secret hash can actually mint the notes. This is similar to the mechanism we use for message consumption on L2
- Like with the public flow, we move the user’s funds to the portal
- We now send the message to the inbox with the `recipient` (the sister contract on L2 along with the version of aztec the message is intended for) and the `secretHashForL2MessageConsumption` (such that on L2, the consumption of the message can be private).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ Now we will create a function to mint the amount privately. Paste this into your

#include_code call_mint_on_token /noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr rust

The `get_mint_private_content_hash` function is imported from the `token_portal_content_hash_lib`.
The `get_mint_to_private_content_hash` function is imported from the `token_portal_content_hash_lib`.

If the content hashes were constructed similarly for `mint_private` and `mint_to_publicly`, then content intended for private execution could have been consumed by calling the `claim_public` method. By making these two content hashes distinct, we prevent this scenario.
If the content hashes were constructed similarly for `mint_to_private` and `mint_to_public`, then content intended for private execution could have been consumed by calling the `claim_public` method. By making these two content hashes distinct, we prevent this scenario.

While we mint the tokens on L2, we _still don’t actually mint them to a certain address_. Instead we continue to pass the `secret_hash_for_redeeming_minted_notes` like we did on L1. This means that a user could reveal their secret for L2 message consumption for anyone to mint tokens on L2 but they can redeem these notes at a later time. **This enables a paradigm where an app can manage user’s secrets for L2 message consumption on their behalf**. **The app or any external party can also mint tokens on the user’s behalf should they be comfortable with leaking the secret for L2 Message consumption.** This doesn’t leak any new information to the app because their smart contract on L1 knew that a user wanted to move some amount of tokens to L2. The app still doesn’t know which address on L2 the user wants these notes to be in, but they can mint tokens nevertheless on their behalf.

To mint tokens privately, `claim_private` calls an internal function `_call_mint_on_token()` which then calls [token.mint_private()](../../token_contract.md#mint_private).
To mint tokens privately, `claim_private` calls an internal function `_call_mint_on_token()` which then calls [token.mint_to_private()](../../token_contract.md#mint_to_private).

In the next step we will see how we can cancel a message.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ These are functions that have transparent logic, will execute in a publicly veri
- `set_admin` enables the admin to be updated
- `set_minter` enables accounts to be added / removed from the approved minter list
- `mint_to_public` enables tokens to be minted to the public balance of an account
- `mint_private` enables tokens to be minted to the private balance of an account (with some caveats we will dig into)
- `mint_to_private` enables tokens to be minted to the private balance of an account (with some caveats we will dig into)
- `transfer_to_public` enables tokens to be moved from a public balance to a private balance, not necessarily the same account (step 1 of a 2 step process)
- `transfer_in_public` enables users to transfer tokens from one account's public balance to another account's public balance
- `burn_public` enables users to burn tokens
Expand Down Expand Up @@ -199,7 +199,7 @@ First, storage is initialized. Then the function checks that the `msg_sender` is

#include_code mint_to_public /noir-projects/noir-contracts/contracts/token_contract/src/main.nr rust

#### `mint_private`
#### `mint_to_private`

This public function allows an account approved in the public `minters` mapping to create new private tokens.

Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/test/portals/TokenPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ contract TokenPortal {
// Hash the message content to be reconstructed in the receiving contract - the signature below does not correspond
// to a real function. It's just an identifier of an action.
bytes32 contentHash =
Hash.sha256ToField(abi.encodeWithSignature("mint_private(uint256)", _amount));
Hash.sha256ToField(abi.encodeWithSignature("mint_to_private(uint256)", _amount));

// Hold the tokens in the portal
underlying.safeTransferFrom(msg.sender, address(this), _amount);
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/test/portals/TokenPortal.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ contract TokenPortalTest is Test {
return DataStructures.L1ToL2Msg({
sender: DataStructures.L1Actor(address(tokenPortal), block.chainid),
recipient: DataStructures.L2Actor(l2TokenAddress, 1),
content: Hash.sha256ToField(abi.encodeWithSignature("mint_private(uint256)", amount)),
content: Hash.sha256ToField(abi.encodeWithSignature("mint_to_private(uint256)", amount)),
secretHash: secretHashForL2MessageConsumption,
index: _index
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ contract Test {
utils::comparison::Comparator,
};
use dep::token_portal_content_hash_lib::{
get_mint_private_content_hash, get_mint_to_public_content_hash,
get_mint_to_private_content_hash, get_mint_to_public_content_hash,
};
use dep::value_note::value_note::ValueNote;
// TODO investigate why the macros require EmbeddedCurvePoint and EmbeddedCurveScalar
Expand Down Expand Up @@ -385,14 +385,14 @@ contract Test {
}

#[private]
fn consume_mint_private_message(
fn consume_mint_to_private_message(
amount: Field,
secret_for_L1_to_L2_message_consumption: Field,
portal_address: EthAddress,
message_leaf_index: Field,
) {
// Consume L1 to L2 message and emit nullifier
let content_hash = get_mint_private_content_hash(amount);
let content_hash = get_mint_to_private_content_hash(amount);
context.consume_l1_to_l2_message(
content_hash,
secret_for_L1_to_L2_message_consumption,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ contract TokenBridge {
use dep::aztec::prelude::{AztecAddress, EthAddress, SharedImmutable};

use dep::token_portal_content_hash_lib::{
get_mint_private_content_hash, get_mint_to_public_content_hash, get_withdraw_content_hash,
get_mint_to_private_content_hash, get_mint_to_public_content_hash,
get_withdraw_content_hash,
};

use dep::token::Token;
Expand Down Expand Up @@ -103,7 +104,7 @@ contract TokenBridge {
message_leaf_index: Field,
) {
// Consume L1 to L2 message and emit nullifier
let content_hash = get_mint_private_content_hash(amount);
let content_hash = get_mint_to_private_content_hash(amount);
context.consume_l1_to_l2_message(
content_hash,
secret_for_L1_to_L2_message_consumption,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use dep::aztec::oracle::random::random;
#[test]
unconstrained fn burn_private_on_behalf_of_self() {
let (env, token_contract_address, owner, _, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);
let burn_amount = mint_amount / 10;

// Burn less than balance
Expand All @@ -17,7 +17,7 @@ unconstrained fn burn_private_on_behalf_of_self() {
#[test]
unconstrained fn burn_private_on_behalf_of_other() {
let (env, token_contract_address, owner, recipient, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ true);
utils::setup_and_mint_to_private(/* with_account_contracts */ true);
let burn_amount = mint_amount / 10;

// Burn on behalf of other
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::test::OracleMock;
#[test]
unconstrained fn setup_refund_success() {
let (env, token_contract_address, owner, recipient, mint_amount) =
utils::setup_and_mint_private(true);
utils::setup_and_mint_to_private(true);

// Renaming owner and recipient to match naming in Token
let user = owner;
Expand Down Expand Up @@ -65,7 +65,7 @@ unconstrained fn setup_refund_success() {
#[test(should_fail_with = "Balance too low")]
unconstrained fn setup_refund_insufficient_funded_amount() {
let (env, token_contract_address, owner, recipient, _mint_amount) =
utils::setup_and_mint_private(true);
utils::setup_and_mint_to_private(true);

// Renaming owner and recipient to match naming in Token
let user = owner;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use dep::aztec::test::helpers::cheatcodes;
unconstrained fn transfer_private() {
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let (env, token_contract_address, owner, recipient, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);

// docs:start:txe_test_transfer_private
// Transfer tokens
Expand All @@ -23,7 +23,7 @@ unconstrained fn transfer_private() {
unconstrained fn transfer_private_to_self() {
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let (env, token_contract_address, owner, _, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);
// Transfer tokens
let transfer_amount = 1000;
Token::at(token_contract_address).transfer(owner, transfer_amount).call(&mut env.private());
Expand All @@ -36,7 +36,7 @@ unconstrained fn transfer_private_to_self() {
unconstrained fn transfer_private_to_non_deployed_account() {
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let (env, token_contract_address, owner, _, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);
let not_deployed = cheatcodes::create_account();
// Transfer tokens
let transfer_amount = 1000;
Expand All @@ -57,7 +57,7 @@ unconstrained fn transfer_private_to_non_deployed_account() {
unconstrained fn transfer_private_failure_more_than_balance() {
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let (env, token_contract_address, _, recipient, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);
// Transfer tokens
let transfer_amount = mint_amount + 1;
Token::at(token_contract_address).transfer(recipient, transfer_amount).call(&mut env.private());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use dep::authwit::cheatcodes as authwit_cheatcodes;
unconstrained fn transfer_private_on_behalf_of_other() {
// Setup with account contracts. Slower since we actually deploy them, but needed for authwits.
let (env, token_contract_address, owner, recipient, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ true);
utils::setup_and_mint_to_private(/* with_account_contracts */ true);
// Add authwit
// docs:start:private_authwit
let transfer_amount = 1000;
Expand All @@ -32,7 +32,7 @@ unconstrained fn transfer_private_on_behalf_of_other() {
unconstrained fn transfer_private_failure_on_behalf_of_self_non_zero_nonce() {
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let (env, token_contract_address, owner, recipient, _) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);
// Add authwit
let transfer_amount = 1000;
let transfer_private_from_call_interface =
Expand All @@ -51,7 +51,7 @@ unconstrained fn transfer_private_failure_on_behalf_of_self_non_zero_nonce() {
unconstrained fn transfer_private_failure_on_behalf_of_more_than_balance() {
// Setup with account contracts. Slower since we actually deploy them, but needed for authwits.
let (env, token_contract_address, owner, recipient, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ true);
utils::setup_and_mint_to_private(/* with_account_contracts */ true);
// Add authwit
let transfer_amount = mint_amount + 1;
let transfer_private_from_call_interface =
Expand All @@ -71,7 +71,7 @@ unconstrained fn transfer_private_failure_on_behalf_of_more_than_balance() {
unconstrained fn transfer_private_failure_on_behalf_of_other_without_approval() {
// Setup with account contracts. Slower since we actually deploy them, but needed for authwits.
let (env, token_contract_address, owner, recipient, _) =
utils::setup_and_mint_private(/* with_account_contracts */ true);
utils::setup_and_mint_to_private(/* with_account_contracts */ true);
// Add authwit
let transfer_amount = 1000;
let transfer_private_from_call_interface =
Expand All @@ -86,7 +86,7 @@ unconstrained fn transfer_private_failure_on_behalf_of_other_without_approval()
unconstrained fn transfer_private_failure_on_behalf_of_other_wrong_caller() {
// Setup with account contracts. Slower since we actually deploy them, but needed for authwits.
let (env, token_contract_address, owner, recipient, _) =
utils::setup_and_mint_private(/* with_account_contracts */ true);
utils::setup_and_mint_to_private(/* with_account_contracts */ true);
// Add authwit
let transfer_amount = 1000;
let transfer_private_from_call_interface =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ use std::test::OracleMock;
/// in `utils::setup_mint_and_transfer_to_private`.
#[test]
unconstrained fn transfer_to_private_internal_orchestration() {
// The transfer to private is done in `utils::setup_and_mint_private` and for this reason
// The transfer to private is done in `utils::setup_and_mint_to_private` and for this reason
// in this test we just call it and check the outcome.
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let (_, token_contract_address, user, _, amount) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);

// User's private balance should be equal to the amount
utils::check_private_balance(token_contract_address, user, amount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use dep::aztec::oracle::random::random;
unconstrained fn transfer_to_public_on_behalf_of_self() {
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let (env, token_contract_address, owner, _, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);

let transfer_to_public_amount = mint_amount / 10;
Token::at(token_contract_address)
Expand All @@ -24,7 +24,7 @@ unconstrained fn transfer_to_public_on_behalf_of_self() {
#[test]
unconstrained fn transfer_to_public_on_behalf_of_other() {
let (env, token_contract_address, owner, recipient, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ true);
utils::setup_and_mint_to_private(/* with_account_contracts */ true);

let transfer_to_public_amount = mint_amount / 10;
let transfer_to_public_call_interface = Token::at(token_contract_address).transfer_to_public(
Expand Down Expand Up @@ -54,7 +54,7 @@ unconstrained fn transfer_to_public_on_behalf_of_other() {
unconstrained fn transfer_to_public_failure_more_than_balance() {
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let (env, token_contract_address, owner, _, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);

let transfer_to_public_amount = mint_amount + 1;
Token::at(token_contract_address)
Expand All @@ -66,7 +66,7 @@ unconstrained fn transfer_to_public_failure_more_than_balance() {
unconstrained fn transfer_to_public_failure_on_behalf_of_self_non_zero_nonce() {
// Setup without account contracts. We are not using authwits here, so dummy accounts are enough
let (env, token_contract_address, owner, _, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ false);
utils::setup_and_mint_to_private(/* with_account_contracts */ false);

let transfer_to_public_amount = mint_amount + 1;
Token::at(token_contract_address)
Expand All @@ -77,7 +77,7 @@ unconstrained fn transfer_to_public_failure_on_behalf_of_self_non_zero_nonce() {
#[test(should_fail_with = "Balance too low")]
unconstrained fn transfer_to_public_failure_on_behalf_of_other_more_than_balance() {
let (env, token_contract_address, owner, recipient, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ true);
utils::setup_and_mint_to_private(/* with_account_contracts */ true);

let transfer_to_public_amount = mint_amount + 1;
let transfer_to_public_call_interface = Token::at(token_contract_address).transfer_to_public(
Expand All @@ -100,7 +100,7 @@ unconstrained fn transfer_to_public_failure_on_behalf_of_other_more_than_balance
#[test(should_fail_with = "Authorization not found for message hash")]
unconstrained fn transfer_to_public_failure_on_behalf_of_other_invalid_designated_caller() {
let (env, token_contract_address, owner, recipient, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ true);
utils::setup_and_mint_to_private(/* with_account_contracts */ true);

let transfer_to_public_amount = mint_amount + 1;
let transfer_to_public_call_interface = Token::at(token_contract_address).transfer_to_public(
Expand All @@ -123,7 +123,7 @@ unconstrained fn transfer_to_public_failure_on_behalf_of_other_invalid_designate
#[test(should_fail_with = "Authorization not found for message hash")]
unconstrained fn transfer_to_public_failure_on_behalf_of_other_no_approval() {
let (env, token_contract_address, owner, recipient, mint_amount) =
utils::setup_and_mint_private(/* with_account_contracts */ true);
utils::setup_and_mint_to_private(/* with_account_contracts */ true);

let transfer_to_public_amount = mint_amount + 1;
let transfer_to_public_call_interface = Token::at(token_contract_address).transfer_to_public(
Expand Down
Loading

0 comments on commit 7c683a6

Please sign in to comment.