diff --git a/docs/docs/dev_docs/tutorials/writing_token_contract.md b/docs/docs/dev_docs/tutorials/writing_token_contract.md index afac795f6cc1..d1e3c2e60d6c 100644 --- a/docs/docs/dev_docs/tutorials/writing_token_contract.md +++ b/docs/docs/dev_docs/tutorials/writing_token_contract.md @@ -413,7 +413,7 @@ Internal functions are functions that can only be called by this contract. The f #### `_initialize` -This function is called via the [constructor](#constructor). Note that it is not actually marked `internal` right now--this is because this functionality is still being worked on. +This function is called via the [constructor](#constructor). This function sets the creator of the contract (passed as `msg_sender` from the constructor) as the admin and makes them a minter. diff --git a/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr index a6c1c6d1553e..97cc1b92b611 100644 --- a/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/token_bridge_contract/src/main.nr @@ -2,7 +2,7 @@ mod util; mod token_interface; // Minimal implementation of the token bridge that can move funds between L1 <> L2. -// The bridge has a corresponding Portal contract on L1 that it is attached to +// The bridge has a corresponding Portal contract on L1 that it is attached to // And corresponds to a Token on L2 that uses the `AuthWit` accounts pattern. // Bridge has to be set as a minter on the token before it can be used @@ -40,9 +40,8 @@ contract TokenBridge { // Constructs the contract. #[aztec(private)] fn constructor() { - // Currently not possible to execute public calls from constructor as code not yet available to sequencer. - // let selector = compute_selector("_initialize((Field))"); - // let _callStackItem = context.call_public_function(context.this_address(), selector, [context.msg_sender()]); + let selector = compute_selector("_initialize((Field))"); + let _callStackItem = context.call_public_function(context.this_address(), selector, [context.msg_sender()]); } // docs:start:claim_public @@ -59,7 +58,7 @@ contract TokenBridge { // Consume message and emit nullifier context.consume_l1_to_l2_message(msg_key, content_hash, secret); - // Mint tokens + // Mint tokens Token::at(storage.token.read()).mint_public(context, to.address, amount); 1 @@ -68,7 +67,7 @@ contract TokenBridge { // docs:start:exit_to_l1_public // Burns the appropriate amount of tokens and creates a L2 to L1 withdraw message publicly - // Requires `msg.sender` to give approval to the bridge to burn tokens on their behalf using witness signatures + // Requires `msg.sender` to give approval to the bridge to burn tokens on their behalf using witness signatures #[aztec(public)] fn exit_to_l1_public( recipient: EthereumAddress, // ethereum address to withdraw to @@ -78,11 +77,11 @@ contract TokenBridge { ) -> Field { // Send an L2 to L1 message let content = get_withdraw_content_hash(recipient.address, amount, callerOnL1.address); - context.message_portal(content); + context.message_portal(content); - // Burn tokens + // Burn tokens Token::at(storage.token.read()).burn_public(context, context.msg_sender(), amount, nonce); - + 1 } // docs:end:exit_to_l1_public @@ -101,10 +100,10 @@ contract TokenBridge { let content_hash = get_mint_private_content_hash(amount, secret_hash_for_redeeming_minted_notes, canceller.address); context.consume_l1_to_l2_message(msg_key, content_hash, secret_for_L1_to_L2_message_consumption); - // Mint tokens on L2 - // `mint_private` on token is public. So we call an internal public function + // Mint tokens on L2 + // `mint_private` on token is public. So we call an internal public function // which then calls the public method on the token contract. - // Since the secret_hash is passed, no secret is leaked. + // Since the secret_hash is passed, no secret is leaked. context.call_public_function( context.this_address(), compute_selector("_call_mint_on_token(Field,Field)"), @@ -116,7 +115,7 @@ contract TokenBridge { // docs:start:exit_to_l1_private // Burns the appropriate amount of tokens and creates a L2 to L1 withdraw message privately - // Requires `msg.sender` (caller of the method) to give approval to the bridge to burn tokens on their behalf using witness signatures + // Requires `msg.sender` (caller of the method) to give approval to the bridge to burn tokens on their behalf using witness signatures #[aztec(private)] fn exit_to_l1_private( recipient: EthereumAddress, // ethereum address to withdraw to @@ -129,7 +128,7 @@ contract TokenBridge { let content = get_withdraw_content_hash(recipient.address, amount, callerOnL1.address); context.message_portal(content); - // Assert that user provided token address is same as seen in storage. + // Assert that user provided token address is same as seen in storage. context.call_public_function(context.this_address(), compute_selector("_assert_token_is_same(Field)"), [token.address]); // Burn tokens @@ -138,20 +137,15 @@ contract TokenBridge { 1 } /// docs:end:exit_to_l1_private - - // /// Unconstrained /// + + // /// Unconstrained /// unconstrained fn token() -> Field { storage.token.read() } - /// SHOULD BE Internal /// - - // We cannot do this from the constructor currently - // Since this should be internal, for now, we ignore the safety checks of it, as they are - // enforced by it being internal and only called from the constructor. #[aztec(public)] - fn _initialize(token: AztecAddress) { + internal fn _initialize(token: AztecAddress) { storage.token.write(token.address); } diff --git a/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr index f9871004b296..3c0c669bb683 100644 --- a/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/token_contract/src/main.nr @@ -119,9 +119,8 @@ contract Token { // docs:start:constructor #[aztec(private)] fn constructor() { - // Currently not possible to execute public calls from constructor as code not yet available to sequencer. - // let selector = compute_selector("_initialize((Field))"); - // let _callStackItem = context.call_public_function(context.this_address(), selector, [context.msg_sender()]); + let selector = compute_selector("_initialize((Field))"); + let _callStackItem = context.call_public_function(context.this_address(), selector, [context.msg_sender()]); } // docs:end:constructor @@ -282,7 +281,6 @@ contract Token { let pending_shields = storage.pending_shields; let balance = storage.balances.at(to.address); let mut public_note = TransparentNote::new_from_secret(amount, secret); - // docs:start:assert_contains_and_remove_publicly_created pending_shields.assert_contains_and_remove_publicly_created(&mut public_note); // docs:end:assert_contains_and_remove_publicly_created @@ -343,7 +341,7 @@ contract Token { 1 } // docs:end:transfer - + // docs:start:burn #[aztec(private)] fn burn( @@ -370,14 +368,9 @@ contract Token { } // docs:end:burn - /// SHOULD BE Internal /// - // docs:start:initialize - // We cannot do this from the constructor currently - // Since this should be internal, for now, we ignore the safety checks of it, as they are - // enforced by it being internal and only called from the constructor. #[aztec(public)] - fn _initialize( + internal fn _initialize( new_admin: AztecAddress, ) { storage.admin.write(new_admin.address); @@ -409,7 +402,7 @@ contract Token { } // docs:end:reduce_total_supply - /// Unconstrained /// + /// Unconstrained /// // docs:start:admin unconstrained fn admin() -> Field {