From 21305831fc2dc3e63018f805b1c028f2afdbc634 Mon Sep 17 00:00:00 2001 From: LHerskind Date: Mon, 9 Oct 2023 13:50:41 +0000 Subject: [PATCH] chore: address comments --- .../concepts/foundation/accounts/authwit.md | 19 +++++++++++++------ .../resources/common_patterns/authwit.md | 12 ++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/docs/docs/concepts/foundation/accounts/authwit.md b/docs/docs/concepts/foundation/accounts/authwit.md index ce7ccf595d4..bb0e5ca367f 100644 --- a/docs/docs/concepts/foundation/accounts/authwit.md +++ b/docs/docs/concepts/foundation/accounts/authwit.md @@ -56,8 +56,9 @@ Adopting ERC20 for Aztec is not as simple as it might seem because of private st If you recall from [State model](./../state_model.md), private state is generally only known by its owner and those they have shared it with. Because it relies on secrets, private state might be "owned" by a contract, but it needs someone with knowledge of these secrets to actually spend it. You might see where this is going. -If we were to implement the `approve` with an allowance in private, you might know the allowance, but unless you also know about the individual notes that make up the user's balances, it would be of no use to you! It is private after all. +If we were to implement the `approve` with an allowance in private, you might know the allowance, but unless you also know about the individual notes that make up the user's balances, it would be of no use to you! It is private after all. To spend the user's funds you would need to know the decryption key, see [keys for more](../accounts/keys.md). +While this might sound limiting in what we can actually do, the main use of approvals have been for simplifying contract interactions that the user is doing. In the case of private transactions, this is executed on the user device, so it is not a blocker that the user need to tell the executor a secret - the user is the executor! ### So what can we do? A few more things we need to remember about private execution: @@ -98,11 +99,7 @@ action = H(defi, token, transfer_selector, H(alice_account, defi, 1000)); This can be read as "defi is allowed to call token transfer function with the arguments (alice_account, defi, 1000)". -With this out of the way, let's look at how this would work in the graph below. - -Note in particular that the request for a witness is done by the token contract, and the user will have to provide it to the contract before it can continue execution. The exact contents of the witness will differ between implementations as mentioned before, but for the sake of simplicity you can think of it as a signature, which the account contract can then use to validate if it really should allow the action. - -Since the request is made all the way into the contract where it is to be used, we don't need to pass it along as an extra input to the functions before it which gives us a cleaner interface. +With this out of the way, let's look at how this would work in the graph below. The exact contents of the witness will differ between implementations as mentioned before, but for the sake of simplicity you can think of it as a signature, which the account contract can then use to validate if it really should allow the action. ```mermaid sequenceDiagram @@ -124,6 +121,7 @@ sequenceDiagram deactivate Alice Token->>Token: throw if invalid AuthWit Token->>Token: transfer(Alice, Defi, 1000); + Token->>Defi: success deactivate Token Defi->>Defi: deposit(Token, 1000); deactivate Defi @@ -134,6 +132,10 @@ sequenceDiagram The call to the account contract for checking authentication should be a static call, meaning that it cannot change state or make calls that change state. If this call is not static, it could be used to re-enter the flow and change the state of the contract. ::: +:::danger Static call currently unsupported +The current execution layer does not implement static call. So currently you will be passing along the control flow :grimacing:. +::: + :::danger Re-entries The above flow could be re-entered at token transfer. It is mainly for show to illustrate a logic outline. ::: @@ -161,6 +163,7 @@ sequenceDiagram AC->>Token: AuthWit validity Token->>Token: throw if invalid AuthWit Token->>Token: transfer(Alice, Defi, 1000); + Token->>Defi: success deactivate Token Defi->>Defi: deposit(Token, 1000); deactivate Defi @@ -190,3 +193,7 @@ Also, most uses of the approvals are for contracts where the following interacti ### Other use-cases We don't need to limit ourselves to the `transfer` function, we can use the same scheme for any function that requires authentication. For example, for authenticating to burn or shield assets or to vote in a governance contract or perform an operation on a lending protocol. + +### Next Steps + +Check out the [developer documentation](./../../../dev_docs/contracts/resources/common_patterns/authwit.md) to see how to implement this in your own contracts. \ No newline at end of file diff --git a/docs/docs/dev_docs/contracts/resources/common_patterns/authwit.md b/docs/docs/dev_docs/contracts/resources/common_patterns/authwit.md index 2bb052b4909..6beb7ea887a 100644 --- a/docs/docs/dev_docs/contracts/resources/common_patterns/authwit.md +++ b/docs/docs/dev_docs/contracts/resources/common_patterns/authwit.md @@ -2,6 +2,8 @@ title: Authentication Witness description: Developer Documentation to use Authentication Witness for authentication actions on Aztec. --- +## Prerequisite reading +- [Authwit from Foundational Concepts](./../../../../concepts/foundation/accounts/authwit.md) ## Introduction @@ -20,8 +22,8 @@ authentication_witness_action = H( ); // Example action that authenticates: -// defi to transfer 1000 tokens to itself on behalf of alice_account -action = H( +// defi contract to transfer 1000 tokens to itself on behalf of alice_account +authentication_witness_action = H( defi, token, transfer_selector, @@ -51,12 +53,17 @@ sequenceDiagram deactivate Alice Token->>Token: throw if invalid AuthWit Token->>Token: transfer(Alice, Defi, 1000); + Token->>Defi: success deactivate Token Defi->>Defi: deposit(Token, 1000); deactivate Defi deactivate AC ``` +:::info +Note in particular that the request for a witness is done by the token contract, and the user will have to provide it to the contract before it can continue execution. Since the request is made all the way into the contract where it is to be used, we don't need to pass it along as an extra input to the functions before it which gives us a cleaner interface. +::: + As part of `AuthWit` we are assuming that the `on_behalf_of` implements the private and/or public functions: ```rust @@ -211,6 +218,7 @@ sequenceDiagram T->>CC: Have you approved this? CC->>T: Yes T-->>T: Burn + Token->>Defi: success deactivate T; TB-->>TB: Emit L2->L1 message deactivate TB;