5151 }
5252 }
5353
54+ /// Makes the call to this private function.
55+ ///
56+ /// # Arguments
57+ /// * `context` - The PrivateContext -- made magically available to the body
58+ /// of every #[private] function as `context`, through the
59+ /// #[private] annotation's macro.
60+ ///
61+ /// # Returns
62+ /// * `T` - Whatever data the called function has returned.
63+ ///
64+ /// This enables contracts to interact with each other while maintaining
65+ /// privacy. This "composability" of private contract functions is a key
66+ /// feature of the Aztec network.
67+ ///
68+ /// If a user's transaction includes multiple private function calls, then
69+ /// by the design of Aztec, the following information will remain private[1]:
70+ /// - The function selectors and contract addresses of all private function
71+ /// calls will remain private, so an observer of the public mempool will
72+ /// not be able to look at a tx and deduce which private functions have
73+ /// been executed.
74+ /// - The arguments and return values of all private function calls will
75+ /// remain private.
76+ /// - The person who initiated the tx will remain private.
77+ /// - The notes and nullifiers and private logs that are emitted by all
78+ /// private function calls will (if designed well) not leak any user
79+ /// secrets, nor leak which functions have been executed.
80+ ///
81+ /// [1] Caveats: Some of these privacy guarantees depend on how app
82+ /// developers design their smart contracts. Some actions _can_ leak
83+ /// information, such as:
84+ /// - Calling an internal public function.
85+ /// - Calling a public function and not setting msg_sender to Option::none
86+ /// (see https://github.com/AztecProtocol/aztec-packages/pull/16433)
87+ /// - Calling any public function will always leak details about the nature
88+ /// of the transaction, so devs should be careful in their contract
89+ /// designs. If it can be done in a private function, then that will give
90+ /// the best privacy.
91+ /// - Not padding the side-effects of a tx to some standardised, uniform
92+ /// size. The kernel circuits can take hints to pad side-effects, so a
93+ /// wallet should be able to request for a particular amount of padding.
94+ /// Wallets should ideally agree on some standard.
95+ /// - Padding should include:
96+ /// - Padding the lengths of note & nullifier arrays
97+ /// - Padding private logs with random fields, up to some standardised
98+ /// size.
99+ /// See also: https://docs.aztec.network/developers/reference/considerations/privacy_considerations
100+ ///
101+ /// # Advanced
102+ /// * The call is added to the private call stack and executed by kernel
103+ /// circuits after this function completes
104+ /// * The called function can modify its own contract's private state
105+ /// * Side effects from the called function are included in this transaction
106+ /// * The call inherits the current transaction's context and gas limits
107+ ///
108+ /// # Arguments
109+ /// * `context` - The PrivateContext -- made magically available to the body
110+ /// of every #[private] function as `context`, through the
111+ /// #[private] annotation's macro.
112+ ///
113+ /// # Returns
114+ /// * `T` - Whatever data the called function has returned.
115+ ///
54116 pub fn call (self , context : &mut PrivateContext ) -> T {
55117 execution_cache:: store (self .args , self .args_hash );
56118 let returns_hash = context .call_private_function_with_args_hash (
@@ -65,6 +127,22 @@ where
65127 returns_hash .get_preimage ()
66128 }
67129
130+ /// Makes a _read-only_ call to this private function.
131+ ///
132+ /// This is similar to Solidity's `staticcall`. The called function
133+ /// cannot modify state, emit L2->L1 messages, nor emit events. Any nested
134+ /// calls are constrained to also be staticcalls.
135+ ///
136+ /// See `call` for more general info on private function calls.
137+ ///
138+ /// # Arguments
139+ /// * `context` - The PrivateContext -- made magically available to the body
140+ /// of every #[private] function as `context`, through the
141+ /// #[private] annotation's macro.
142+ ///
143+ /// # Returns
144+ /// * `T` - Whatever data the called function has returned.
145+ ///
68146 pub fn view (self , context : &mut PrivateContext ) -> T {
69147 execution_cache:: store (self .args , self .args_hash );
70148 let returns_hash = context .call_private_function_with_args_hash (
@@ -132,6 +210,17 @@ impl<let M: u32, T> PrivateStaticCallInterface<M, T> {
132210 }
133211 }
134212
213+ /// Makes a read-only call to this private function.
214+ ///
215+ /// This is similar to Solidity's `staticcall`. The called function
216+ /// cannot modify state, emit L2->L1 messages, nor emit events. Any nested
217+ /// calls are constrained to also be staticcalls.
218+ ///
219+ /// # Arguments
220+ /// * `context` - The PrivateContext -- made magically available to the body
221+ /// of every #[private] function as `context`, through the
222+ /// #[private] annotation's macro.
223+ ///
135224 pub fn view (self , context : &mut PrivateContext ) -> T
136225 where
137226 T : Deserialize ,
@@ -208,6 +297,18 @@ where
208297 self
209298 }
210299
300+ /// Makes the call to this public function.
301+ ///
302+ /// Will revert if the called function reverts or runs out of gas.
303+ ///
304+ /// # Arguments
305+ /// * `context` - The PublicContext -- made magically available to the body
306+ /// of every #[public] function as `context`, through the
307+ /// #[public] annotation's macro.
308+ ///
309+ /// # Returns
310+ /// * `T` - Whatever data the called function has returned.
311+ ///
211312 pub unconstrained fn call (self , context : &mut PublicContext ) -> T {
212313 let returns = context .call_public_function (
213314 self .target_contract ,
@@ -220,6 +321,22 @@ where
220321 Deserialize ::deserialize (returns .as_array ())
221322 }
222323
324+ /// Makes a read-only call to this public function.
325+ ///
326+ /// This is similar to Solidity's `staticcall`. The called function
327+ /// cannot modify state or emit events. Any nested calls are constrained to
328+ /// also be staticcalls.
329+ ///
330+ /// Will revert if the called function reverts or runs out of gas.
331+ ///
332+ /// # Arguments
333+ /// * `context` - The PublicContext -- made magically available to the body
334+ /// of every #[public] function as `context`, through the
335+ /// #[public] annotation's macro.
336+ ///
337+ /// # Returns
338+ /// * `T` - Whatever data the called function has returned.
339+ ///
223340 pub unconstrained fn view (self , context : &mut PublicContext ) -> T {
224341 let returns = context .static_call_public_function (
225342 self .target_contract ,
@@ -232,6 +349,35 @@ where
232349 Deserialize ::deserialize (returns .as_array ())
233350 }
234351
352+ /// Enqueues a call to this public function, to be executed later.
353+ ///
354+ /// Unlike private functions which execute immediately on the user's device,
355+ /// public function calls are "enqueued" and executed some time later by a
356+ /// block proposer.
357+ ///
358+ /// This means a public function cannot return any values back to a private
359+ /// function, because by the time the public function is being executed,
360+ /// the private function which called it has already completed execution.
361+ /// (In fact, the private function has been executed and proven, along with
362+ /// all other private function calls of the user's tx. A single proof of the
363+ /// tx has been submitted to the Aztec network, and some time later a
364+ /// proposer has picked the tx up from the mempool and begun executing all
365+ /// of the enqueued public functions).
366+ ///
367+ /// # Privacy warning
368+ /// Enqueueing a public function call is an inherently leaky action.
369+ /// Many interesting applications will require some interaction with public
370+ /// state, but smart contract developers should try to use public function
371+ /// calls sparingly, and carefully.
372+ /// _Internal_ public function calls are especially leaky, because they
373+ /// completely leak which private contract made the call.
374+ /// See also: https://docs.aztec.network/developers/reference/considerations/privacy_considerations
375+ ///
376+ /// # Arguments
377+ /// * `context` - The PrivateContext -- made magically available to the body
378+ /// of every #[private] function as `context`, through the
379+ /// #[private] annotation's macro.
380+ ///
235381 pub fn enqueue (self , context : &mut PrivateContext ) {
236382 let calldata = self .args .push_front (self .selector .to_field ());
237383 let calldata_hash = hash_calldata (calldata );
@@ -244,6 +390,17 @@ where
244390 )
245391 }
246392
393+ /// Enqueues a read-only call to this public function.
394+ ///
395+ /// This is similar to Solidity's `staticcall`. The called function
396+ /// cannot modify state, emit L2->L1 messages, nor emit events. Any nested
397+ /// calls are constrained to also be staticcalls.
398+ ///
399+ /// # Arguments
400+ /// * `context` - The PrivateContext -- made magically available to the body
401+ /// of every #[private] function as `context`, through the
402+ /// #[private] annotation's macro.
403+ ///
247404 pub fn enqueue_view (self , context : &mut PrivateContext ) {
248405 let calldata = self .args .push_front (self .selector .to_field ());
249406 let calldata_hash = hash_calldata (calldata );
@@ -256,6 +413,37 @@ where
256413 )
257414 }
258415
416+ /// Enqueues a call to this public function, and designates it to be the
417+ /// teardown function for this tx. Only one teardown function call can be
418+ /// made by a tx.
419+ ///
420+ /// Niche function: Only wallet developers and paymaster contract developers
421+ /// (aka Fee-payment contracts) will need to make use of this function.
422+ ///
423+ /// Aztec supports a three-phase execution model: setup, app logic, teardown.
424+ /// The phases exist to enable a fee payer to take on the risk of paying
425+ /// a transaction fee, safe in the knowledge that their payment (in whatever
426+ /// token or method the user chooses) will succeed, regardless of whether
427+ /// the app logic will succeed. The "setup" phase ensures the fee payer
428+ /// has sufficient balance to pay the proposer their fees.
429+ /// The teardown phase is primarily intended to: calculate exactly
430+ /// how much the user owes, based on gas consumption, and refund the user
431+ /// any change.
432+ ///
433+ /// Note: in some cases, the cost of refunding the user (i.e. DA costs of
434+ /// tx side-effects) might exceed the refund amount. For app logic with
435+ /// fairly stable and predictable gas consumption, a material refund amount
436+ /// is unlikely. For app logic with unpredictable gas consumption, a
437+ /// refund might be important to the user (e.g. if a hefty function reverts
438+ /// very early). Wallet/FPC/Paymaster developers should be mindful of this.
439+ ///
440+ /// See `enqueue` for more information about enqueuing public function calls.
441+ ///
442+ /// # Arguments
443+ /// * `context` - The PrivateContext -- made magically available to the body
444+ /// of every #[private] function as `context`, through the
445+ /// #[private] annotation's macro.
446+ ///
259447 pub fn set_as_teardown (self , context : &mut PrivateContext ) {
260448 let calldata = self .args .push_front (self .selector .to_field ());
261449 let calldata_hash = hash_calldata (calldata );
@@ -328,6 +516,22 @@ where
328516 self
329517 }
330518
519+ /// Makes the read-only call to this public function.
520+ ///
521+ /// This is similar to Solidity's `staticcall`. The called function
522+ /// cannot modify state or emit events. Any nested calls are constrained to
523+ /// also be staticcalls.
524+ ///
525+ /// Will revert if the called function reverts or runs out of gas.
526+ ///
527+ /// # Arguments
528+ /// * `context` - The PublicContext -- made magically available to the body
529+ /// of every #[public] function as `context`, through the
530+ /// #[public] annotation's macro.
531+ ///
532+ /// # Returns
533+ /// * `T` - Whatever data the called function has returned.
534+ ///
331535 pub unconstrained fn view (self , context : &mut PublicContext ) -> T {
332536 let returns = context .static_call_public_function (
333537 self .target_contract ,
@@ -338,6 +542,17 @@ where
338542 Deserialize ::deserialize (returns .as_array ())
339543 }
340544
545+ /// Enqueues a read-only call to this public function.
546+ ///
547+ /// This is similar to Solidity's `staticcall`. The called function
548+ /// cannot modify state, emit L2->L1 messages, nor emit events. Any nested
549+ /// calls are constrained to also be staticcalls.
550+ ///
551+ /// # Arguments
552+ /// * `context` - The PrivateContext -- made magically available to the body
553+ /// of every #[private] function as `context`, through the
554+ /// #[private] annotation's macro.
555+ ///
341556 pub fn enqueue_view (self , context : &mut PrivateContext ) {
342557 let calldata = self .args .push_front (self .selector .to_field ());
343558 let calldata_hash = hash_calldata (calldata );
0 commit comments